Put back AcceptInvalidationMessages calls in heap_openrv(_extended).

These calls were removed in commit 4240e429d0
as part of a general refactoring and improvement of DDL locking.  However,
there's a problem not solved by the rewrite, which is that GRANT/REVOKE
update pg_class.relacl without taking any particular lock on the target
table as such.  If another backend fails to do AcceptInvalidationMessages,
it won't notice a recently-committed change in ACLs.  Bug #7557 from Piotr
Czachur demonstrates that there's at least one code path in 9.2.0 in which
a command fails to do any AcceptInvalidationMessages calls at all, if the
current transaction already holds all the locks it will need.

Since we're hard up against the release deadline for 9.2.1, fix this by
putting back the AcceptInvalidationMessages calls in heap_openrv and
heap_openrv_extended, thereby restoring the historical behavior in this
area.  We ought to look for a more elegant and perhaps more bulletproof
solution, but there's no time for that right now.
This commit is contained in:
Tom Lane 2012-09-19 17:10:37 -04:00
parent f1f722dacc
commit 96cc18eef6
1 changed files with 21 additions and 0 deletions

View File

@ -986,6 +986,20 @@ relation_openrv(const RangeVar *relation, LOCKMODE lockmode)
{
Oid relOid;
/*
* Check for shared-cache-inval messages before trying to open the
* relation. This is needed even if we already hold a lock on the
* relation, because GRANT/REVOKE are executed without taking any lock on
* the target relation, and we want to be sure we see current ACL
* information. We can skip this if asked for NoLock, on the assumption
* that such a call is not the first one in the current command, and so we
* should be reasonably up-to-date already. (XXX this all could stand to
* be redesigned, but for the moment we'll keep doing this like it's been
* done historically.)
*/
if (lockmode != NoLock)
AcceptInvalidationMessages();
/* Look up and lock the appropriate relation using namespace search */
relOid = RangeVarGetRelid(relation, lockmode, false);
@ -1008,6 +1022,13 @@ relation_openrv_extended(const RangeVar *relation, LOCKMODE lockmode,
{
Oid relOid;
/*
* Check for shared-cache-inval messages before trying to open the
* relation. See comments in relation_openrv().
*/
if (lockmode != NoLock)
AcceptInvalidationMessages();
/* Look up and lock the appropriate relation using namespace search */
relOid = RangeVarGetRelid(relation, lockmode, missing_ok);