Skip to content

Conversation

shayonj
Copy link
Owner

@shayonj shayonj commented Oct 7, 2025

No description provided.

@shayonj shayonj force-pushed the s/fk-low-lock branch 4 times, most recently from 96cc6e0 to 1329d9c Compare October 8, 2025 21:07
@shayonj shayonj changed the title Allow reads to proceed during FK/trigger drops by reducing relation-level lock from AccessExclusive to ShareRowExclusive Reduce lock level for FK/trigger drops to allow concurrent reads Oct 8, 2025
@shayonj shayonj force-pushed the s/fk-low-lock branch 3 times, most recently from 84be57e to 4ac7da1 Compare October 8, 2025 22:34
Dropping a foreign key constraint or a table that owns an FK currently
blocks reads on the referenced table due to AccessExclusiveLock taken while
removing the FK's internal RI triggers and constraint metadata.  In busy
systems, this brief full-read outage can cause user-visible timeouts for
otherwise read-only traffic.

This change narrows the lock reduction to the safe scope, retaining
AccessExclusiveLock on the table that owns the constraint and reducing
locks only on the referenced table's RI action-trigger removal:

1. RemoveTriggerById(): use ShareRowExclusiveLock only for internal RI
   action triggers on the referenced table; all other triggers remain
   at AccessExclusiveLock.
2. dropconstraint_internal(): when dropping an FK, open the referenced
   table with ShareRowExclusiveLock to match trigger deletion and allow
   concurrent reads.

The table being dropped or directly altered (the constraint-owning table)
continues to acquire AccessExclusiveLock as before. Only the referenced
tables of foreign keys see the reduced lock level.

Examples of affected operations:
- ALTER TABLE fktable DROP CONSTRAINT: AccessExclusive on fktable (unchanged),
  ShareRowExclusive on the referenced pktable, allowing SELECTs on pktable.
- DROP TABLE fktable: AccessExclusive on fktable (unchanged), and
  ShareRowExclusive on the referenced pktable while removing RI action triggers.
- Self-referential FKs: the altered table still takes AccessExclusive, so
  SELECTs on that table block (unchanged).

Correctness is preserved because:
- Writers are serialized: ShareRowExclusive conflicts with RowExclusiveLock
  and stronger, so no DML can race RI trigger removal.
- Relcache invalidation at commit ensures metadata changes become visible
  to subsequent queries.
- Prepared plans continue to work; plans depending on the owning table's
  constraints remain protected by AccessExclusive on that table.

Updated isolation tests:
- fk-drop-constraint-concurrency: new permutation asserting a SELECT cursor
  on the referencing table blocks the FK drop (owning table remains at
  AccessExclusive); also covers regular FKs, DROP TABLE of the FK table,
  self-referential FKs, and relcache invalidation.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant