-
Notifications
You must be signed in to change notification settings - Fork 3.9k
Commit
Add SELECT FOR SHARE locking to FK parent checks. Under serializable isolation, this locking is only used when `enable_implicit_fk_locking_for_serializable` is set. Under weaker isolation levels (snapshot and read committed) this locking is always used. We only need to lock during the insertion-side FK checks, which verify the existence of a parent row. Deletion-side FK checks verify the non-existence of a child row, and these do not need to lock. Instead, to prevent concurrent inserts or updates to the child that would violate the FK constraint, we rely on the intent(s) created by the deletion conflicting with the FK locking of those concurrent inserts or updates. Fixes: #80683 Informs: #100156 Epic: CRDB-25322 Release note (sql change): Add a new session variable, `enable_implicit_fk_locking_for_serializable`, which controls locking during foreign key checks under serializable isolation. With this set to true, foreign key checks of the referenced (parent) table, such as those performed during an INSERT or UPDATE of the referencing (child) table, will lock the referenced row using SELECT FOR SHARE locking. (This is somewhat analogous to the existing `enable_implicit_select_for_update` variable but applies to the foreign key checks of a mutation statement instead of the initial row fetch.) Under weaker isolation levels such as read committed, SELECT FOR SHARE locking will always be used to ensure the database maintains the foreign key constraint, regardless of the current setting of `enable_implicit_fk_locking_for_serializable`.
- Loading branch information
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
# LogicTest: !local-mixed-22.2-23.1 | ||
|
||
# Some foreign key checks are prohibited under weaker isolation levels until we | ||
# improve locking. See #80683, #100156, #100193. | ||
|
||
statement ok | ||
CREATE TABLE jars (j INT PRIMARY KEY) | ||
|
||
statement ok | ||
CREATE TABLE cookies (c INT PRIMARY KEY, j INT REFERENCES jars (j)) | ||
|
||
statement ok | ||
SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL READ COMMITTED | ||
|
||
statement ok | ||
INSERT INTO jars VALUES (1), (2) | ||
|
||
# Foreign key checks of the parent require durable shared locking under weaker | ||
# isolation levels, and are not yet supported. | ||
query error pgcode 0A000 guaranteed-durable locking not yet implemented | ||
INSERT INTO cookies VALUES (1, 1) | ||
|
||
statement ok | ||
BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE | ||
|
||
statement ok | ||
INSERT INTO cookies VALUES (1, 1) | ||
|
||
statement ok | ||
COMMIT | ||
|
||
query error pgcode 0A000 guaranteed-durable locking not yet implemented | ||
UPDATE cookies SET j = 2 WHERE c = 1 | ||
|
||
# Foreign key checks of the child do not require locking. | ||
query error violates foreign key constraint | ||
UPDATE jars SET j = j + 4 | ||
|
||
query error violates foreign key constraint | ||
DELETE FROM jars WHERE j = 1 | ||
|
||
statement ok | ||
DELETE FROM cookies WHERE c = 1 | ||
|
||
statement ok | ||
DELETE FROM jars WHERE j = 1 |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.