提交 05f55e86 编写于 作者: J Jimmy Yih

Fix lazy VACUUM to not wait for AccessExclusiveLock during drop phase

We expect lazy VACUUM to skip drop phase if it cannot acquire the
relation's AccessExclusiveLock. This commit properly sets the dontWait
flag to True when calling try_relation_open during drop phase. We also
change the dontWait part of try_relation_open to not error out because
callers should be the ones to handle an invalid relation.
上级 ad470347
......@@ -979,28 +979,12 @@ try_relation_open(Oid relationId, LOCKMODE lockmode, bool noWait)
/*
* noWait is a Greenplum addition to the open_relation code
* basically to support INSERT ... FOR UPDATE NOWAIT. Our NoWait
* handling needs to be more tollerant of failed locks than standard
* handling needs to be more tolerant of failed locks than standard
* postgres largely due to the fact that we have to promote certain
* update locks in order to handle distributed updates.
*/
if (!ConditionalLockRelationOid(relationId, lockmode))
{
/* Get the name for error reporting */
char *relname = get_rel_name(relationId);
/*
* If the relation was dropped then accept the lock
* failure and return null.
*/
if (relname == NULL)
return NULL;
/* Otherwise report the failed lock */
ereport(ERROR,
(errcode(ERRCODE_LOCK_NOT_AVAILABLE),
errmsg("could not obtain lock on relation \"%s\"",
relname)));
}
return NULL;
}
}
......
......@@ -5374,6 +5374,7 @@ open_relation_and_check_permission(VacuumStmt *vacstmt,
{
Relation onerel;
LOCKMODE lmode;
bool dontWait = false;
/*
* If this is a drop transaction and there is another parallel drop transaction
......@@ -5412,7 +5413,10 @@ open_relation_and_check_permission(VacuumStmt *vacstmt,
* For analyze, we use ShareUpdateExclusiveLock.
*/
if (isDropTransaction)
{
lmode = AccessExclusiveLock;
dontWait = true;
}
else if (!vacstmt->vacuum)
lmode = ShareUpdateExclusiveLock;
else
......@@ -5424,9 +5428,9 @@ open_relation_and_check_permission(VacuumStmt *vacstmt,
* There's a race condition here: the rel may have gone away since the
* last time we saw it. If so, we don't need to vacuum it.
*/
onerel = try_relation_open(relid, lmode, false);
onerel = try_relation_open(relid, lmode, dontWait);
if (!onerel)
if (!RelationIsValid(onerel))
return NULL;
/*
......
......@@ -11,7 +11,7 @@ insert into ao select generate_series(1, 10);
2: BEGIN;
2: DELETE FROM ao WHERE a < 5;
2: COMMIT;
2&: VACUUM ao;
2&: VACUUM FULL ao;
1: FETCH NEXT IN cur;
1: FETCH NEXT IN cur;
1: FETCH NEXT IN cur;
......
......@@ -29,7 +29,7 @@ DELETE FROM ao WHERE a < 128;
1: SELECT COUNT(*) FROM ao;
1: SELECT * FROM locktest_master WHERE coalesce = 'ao';
1: SELECT * FROM locktest_segments WHERE coalesce = 'ao';
2&: VACUUM ao;
2&: VACUUM FULL ao;
1: COMMIT;
2<:
1: SELECT COUNT(*) FROM ao;
......
......@@ -27,7 +27,7 @@ BEGIN
DELETE 4
2: COMMIT;
COMMIT
2&: VACUUM ao; <waiting ...>
2&: VACUUM FULL ao; <waiting ...>
1: FETCH NEXT IN cur;
a
-
......
......@@ -66,7 +66,7 @@ coalesce|mode |locktype|node
--------+---------------+--------+----------
ao |AccessShareLock|relation|n segments
(1 row)
2&: VACUUM ao; <waiting ...>
2&: VACUUM FULL ao; <waiting ...>
1: COMMIT;
COMMIT
2<: <... completed>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册