Add columns with volatile DEFAULT
s without an ACCESS_EXCLUSIVE
table lock
#694
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Ensure that adding a new column (with an
add_column
operation) does not take anACCESS_EXCLUSIVE
lock on the table even when the column has a volatileDEFAULT
expression.Adding a column with a
DEFAULT
expression in Postgres can have one of two different locking behaviours depending on the expression used as theDEFAULT
:DEFAULT
expressions, the column addition can use the fast-path optimization to add the column default; this is a catalog-only operation and so holds a lock only for a very short time.DEFAULT
expressions, the fast-path optimization cannot be used; the change requires a full table rewrite - this means holding anACCESS_EXCLUSIVE
lock on the table until the rewrite is complete.This PR makes
add_column
operations aware of this distinction and able to add columns with volatile defaults without taking anACCESS_EXCLUSIVE
lock on the table.When adding a column with a
DEFAULT
:DEFAULT
.Now the operation knows whether the column can be added using the fast-path
DEFAULT
optimization. In the case where the column can use the optimization, the column can be added with aDEFAULT
directly. In the case where the fast-path optimization can't be used:DEFAULT
valueup
trigger to backfill the column using the columnDEFAULT
expressionDEFAULT
to the column on migration completionThis avoids the
ACCESS_EXCLUSIVE
lock; effectively replacing the table rewrite that would have caused it with a backfill operation instead.If the column to be added has a volatile
DEFAULT
and aNOT NULL
constraint, the column must be added with aNOT NULL ... NOT VALID
constraint to allow the column to be added without aDEFAULT
; the constraint is validated and upgraded on migration completion.For a non-volatile
DEFAULT
s, the operation must setup
to the same expression as is set indefault
. The operation will fail and roll back if they differ.References
Volatile vs non-volatile functions:
The fast-path optimization for non-volatile column
DEFAULT
expressions is explained here:Fixes #643