diff options
| author | Robert Haas | 2011-07-09 02:19:30 +0000 |
|---|---|---|
| committer | Robert Haas | 2011-07-09 02:19:30 +0000 |
| commit | 4240e429d0c2d889d0cda23c618f94e12c13ade7 (patch) | |
| tree | 306e1fac6085c29b55287f383ce8831d947e1312 /src/include | |
| parent | 9d522cb35d8b4f266abadd0d019f68eb8802ae05 (diff) | |
Try to acquire relation locks in RangeVarGetRelid.
In the previous coding, we would look up a relation in RangeVarGetRelid,
lock the resulting OID, and then AcceptInvalidationMessages(). While
this was sufficient to ensure that we noticed any changes to the
relation definition before building the relcache entry, it didn't
handle the possibility that the name we looked up no longer referenced
the same OID. This was particularly problematic in the case where a
table had been dropped and recreated: we'd latch on to the entry for
the old relation and fail later on. Now, we acquire the relation lock
inside RangeVarGetRelid, and retry the name lookup if we notice that
invalidation messages have been processed meanwhile. Many operations
that would previously have failed with an error in the presence of
concurrent DDL will now succeed.
There is a good deal of work remaining to be done here: many callers
of RangeVarGetRelid still pass NoLock for one reason or another. In
addition, nothing in this patch guards against the possibility that
the meaning of an unqualified name might change due to the creation
of a relation in a schema earlier in the user's search path than the
one where it was previously found. Furthermore, there's nothing at
all here to guard against similar race conditions for non-relations.
For all that, it's a start.
Noah Misch and Robert Haas
Diffstat (limited to 'src/include')
| -rw-r--r-- | src/include/catalog/namespace.h | 4 | ||||
| -rw-r--r-- | src/include/commands/trigger.h | 2 | ||||
| -rw-r--r-- | src/include/rewrite/rewriteRemove.h | 2 | ||||
| -rw-r--r-- | src/include/storage/sinval.h | 4 |
4 files changed, 9 insertions, 3 deletions
diff --git a/src/include/catalog/namespace.h b/src/include/catalog/namespace.h index 7e1e194794..4bcbc20497 100644 --- a/src/include/catalog/namespace.h +++ b/src/include/catalog/namespace.h @@ -15,6 +15,7 @@ #define NAMESPACE_H #include "nodes/primnodes.h" +#include "storage/lock.h" /* @@ -47,7 +48,8 @@ typedef struct OverrideSearchPath } OverrideSearchPath; -extern Oid RangeVarGetRelid(const RangeVar *relation, bool failOK); +extern Oid RangeVarGetRelid(const RangeVar *relation, LOCKMODE lockmode, + bool missing_ok, bool nowait); extern Oid RangeVarGetCreationNamespace(const RangeVar *newRelation); extern Oid RangeVarGetAndCheckCreationNamespace(const RangeVar *newRelation); extern void RangeVarAdjustRelationPersistence(RangeVar *newRelation, Oid nspid); diff --git a/src/include/commands/trigger.h b/src/include/commands/trigger.h index ad97871d98..fe21298b64 100644 --- a/src/include/commands/trigger.h +++ b/src/include/commands/trigger.h @@ -112,7 +112,7 @@ extern Oid CreateTrigger(CreateTrigStmt *stmt, const char *queryString, Oid constraintOid, Oid indexOid, bool isInternal); -extern void DropTrigger(Oid relid, const char *trigname, +extern void DropTrigger(RangeVar *relation, const char *trigname, DropBehavior behavior, bool missing_ok); extern void RemoveTriggerById(Oid trigOid); extern Oid get_trigger_oid(Oid relid, const char *name, bool missing_ok); diff --git a/src/include/rewrite/rewriteRemove.h b/src/include/rewrite/rewriteRemove.h index 90df04591f..b9a63bad7b 100644 --- a/src/include/rewrite/rewriteRemove.h +++ b/src/include/rewrite/rewriteRemove.h @@ -17,7 +17,7 @@ #include "nodes/parsenodes.h" -extern void RemoveRewriteRule(Oid owningRel, const char *ruleName, +extern void RemoveRewriteRule(RangeVar *relation, const char *ruleName, DropBehavior behavior, bool missing_ok); extern void RemoveRewriteRuleById(Oid ruleOid); diff --git a/src/include/storage/sinval.h b/src/include/storage/sinval.h index e9ce0257ac..aba474d237 100644 --- a/src/include/storage/sinval.h +++ b/src/include/storage/sinval.h @@ -116,6 +116,10 @@ typedef union } SharedInvalidationMessage; +/* Counter of messages processed; don't worry about overflow. */ +extern uint64 SharedInvalidMessageCounter; + + extern void SendSharedInvalidMessages(const SharedInvalidationMessage *msgs, int n); extern void ReceiveSharedInvalidMessages( |
