From 1f7056099728035b55efcd8f889c7b705a68b6de Mon Sep 17 00:00:00 2001 From: Simon Riggs Date: Mon, 4 Jul 2011 09:30:50 +0100 Subject: Reset ALTER TABLE lock levels to AccessExclusiveLock in all cases. Locks on inheritance parent remain at lower level, as they were before. Remove entry from 9.1 release notes. --- src/backend/commands/tablecmds.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'src') diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index fcfe1faeb45..029d33a223d 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -2573,6 +2573,31 @@ AlterTableInternal(Oid relid, List *cmds, bool recurse) LOCKMODE AlterTableGetLockLevel(List *cmds) { + /* + * Late in 9.1 dev cycle a number of issues were uncovered with access + * to catalog relations, leading to the decision to re-enforce all DDL + * at AccessExclusiveLock level by default. + * + * The issues are that there is a pervasive assumption in the code that + * the catalogs will not be read unless an AccessExclusiveLock is held. + * If that rule is relaxed, we must protect against a number of potential + * effects - infrequent, but proven possible with test cases where + * multiple DDL operations occur in a stream against frequently accessed + * tables. + * + * 1. Catalog tables are read using SnapshotNow, which has a race bug + * that allows a scan to return no valid rows even when one is present + * in the case of a commit of a concurrent update of the catalog table. + * SnapshotNow also ignores transactions in progress, so takes the + * latest committed version without waiting for the latest changes. + * + * 2. Relcache needs to be internally consistent, so unless we lock the + * definition during reads we have no way to guarantee that. + * + * 3. Catcache access isn't coordinated at all so refreshes can occur at + * any time. + */ +#ifdef REDUCED_ALTER_TABLE_LOCK_LEVELS ListCell *lcmd; LOCKMODE lockmode = ShareUpdateExclusiveLock; @@ -2721,6 +2746,9 @@ AlterTableGetLockLevel(List *cmds) if (cmd_lockmode > lockmode) lockmode = cmd_lockmode; } +#else + LOCKMODE lockmode = AccessExclusiveLock; +#endif return lockmode; } -- cgit v1.2.3