diff options
author | Simon Riggs | 2015-04-05 15:37:08 +0000 |
---|---|---|
committer | Simon Riggs | 2015-04-05 15:37:08 +0000 |
commit | 0ef0396ae1687bf738d4703773d55467c36b2bcd (patch) | |
tree | 451d674fdb2860511bb3f006bba2176263245c3f /src/backend/commands | |
parent | ca6805338fba010cc3f8b842905d7a62e280b7ab (diff) |
Reduce lock levels of some trigger DDL and add FKs
Reduce lock levels to ShareRowExclusive for the following SQL
CREATE TRIGGER (but not DROP or ALTER)
ALTER TABLE ENABLE TRIGGER
ALTER TABLE DISABLE TRIGGER
ALTER TABLE … ADD CONSTRAINT FOREIGN KEY
Original work by Simon Riggs, extracted and refreshed by Andreas Karlsson
New test cases added by Andreas Karlsson
Reviewed by Noah Misch, Andres Freund, Michael Paquier and Simon Riggs
Diffstat (limited to 'src/backend/commands')
-rw-r--r-- | src/backend/commands/tablecmds.c | 35 | ||||
-rw-r--r-- | src/backend/commands/trigger.c | 4 |
2 files changed, 20 insertions, 19 deletions
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index eecc30f783f..06e4332d2ac 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -2892,13 +2892,8 @@ AlterTableGetLockLevel(List *cmds) break; /* - * These subcommands affect write operations only. XXX - * Theoretically, these could be ShareRowExclusiveLock. + * These subcommands affect write operations only. */ - case AT_ColumnDefault: - case AT_ProcessedConstraint: /* becomes AT_AddConstraint */ - case AT_AddConstraintRecurse: /* becomes AT_AddConstraint */ - case AT_ReAddConstraint: /* becomes AT_AddConstraint */ case AT_EnableTrig: case AT_EnableAlwaysTrig: case AT_EnableReplicaTrig: @@ -2907,6 +2902,14 @@ AlterTableGetLockLevel(List *cmds) case AT_DisableTrig: case AT_DisableTrigAll: case AT_DisableTrigUser: + cmd_lockmode = ShareRowExclusiveLock; + break; + + /* + * These subcommands affect write operations only. XXX + * Theoretically, these could be ShareRowExclusiveLock. + */ + case AT_ColumnDefault: case AT_AlterConstraint: case AT_AddIndex: /* from ADD CONSTRAINT */ case AT_AddIndexConstraint: @@ -2918,6 +2921,9 @@ AlterTableGetLockLevel(List *cmds) break; case AT_AddConstraint: + case AT_ProcessedConstraint: /* becomes AT_AddConstraint */ + case AT_AddConstraintRecurse: /* becomes AT_AddConstraint */ + case AT_ReAddConstraint: /* becomes AT_AddConstraint */ if (IsA(cmd->def, Constraint)) { Constraint *con = (Constraint *) cmd->def; @@ -2943,11 +2949,9 @@ AlterTableGetLockLevel(List *cmds) /* * We add triggers to both tables when we add a * Foreign Key, so the lock level must be at least - * as strong as CREATE TRIGGER. XXX Might be set - * down to ShareRowExclusiveLock though trigger - * info is accessed by pg_get_triggerdef + * as strong as CREATE TRIGGER. */ - cmd_lockmode = AccessExclusiveLock; + cmd_lockmode = ShareRowExclusiveLock; break; default: @@ -6193,16 +6197,13 @@ ATAddForeignKeyConstraint(AlteredTableInfo *tab, Relation rel, ListCell *old_pfeqop_item = list_head(fkconstraint->old_conpfeqop); /* - * Grab an exclusive lock on the pk table, so that someone doesn't delete - * rows out from under us. (Although a lesser lock would do for that - * purpose, we'll need exclusive lock anyway to add triggers to the pk - * table; trying to start with a lesser lock will just create a risk of - * deadlock.) + * Grab ShareRowExclusiveLock on the pk table, so that someone doesn't + * delete rows out from under us. */ if (OidIsValid(fkconstraint->old_pktable_oid)) - pkrel = heap_open(fkconstraint->old_pktable_oid, AccessExclusiveLock); + pkrel = heap_open(fkconstraint->old_pktable_oid, ShareRowExclusiveLock); else - pkrel = heap_openrv(fkconstraint->pktable, AccessExclusiveLock); + pkrel = heap_openrv(fkconstraint->pktable, ShareRowExclusiveLock); /* * Validity checks (permission checks wait till we have the column diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c index e491c5ba772..098893f4944 100644 --- a/src/backend/commands/trigger.c +++ b/src/backend/commands/trigger.c @@ -165,9 +165,9 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString, referenced; if (OidIsValid(relOid)) - rel = heap_open(relOid, AccessExclusiveLock); + rel = heap_open(relOid, ShareRowExclusiveLock); else - rel = heap_openrv(stmt->relation, AccessExclusiveLock); + rel = heap_openrv(stmt->relation, ShareRowExclusiveLock); /* * Triggers must be on tables or views, and there are additional |