-
Notifications
You must be signed in to change notification settings - Fork 3.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
release-23.2: opt: add lock operator #112138
Conversation
Release note (sql change): Change the following error message: ``` statement error cannot execute FOR UPDATE in a read-only transaction ``` to this to match PostgreSQL: ``` statement error cannot execute SELECT FOR UPDATE in a read-only transaction ```
Add a new implementation of `SELECT FOR UPDATE` and `SELECT FOR SHARE` statements. Instead of locking during the initial row fetch, this new implementation constructs a `Lock` operator on the top of the query plan which performs the locking phase using a locking semi-join lookup. During optbuilder we build plans with both `Lock` operators and initial-row-fetch locking. During execbuilder we decide which implementation to use based on the isolation level and whether `optimizer_use_lock_op_for_serializable` is set. If the new implementation is chosen, `Lock` operators become locking semi-LookupJoins. In some cases these new plans will have superfluous lookup joins. A future PR will optimize away some of these superfluous lookup joins. Fixes: #57031, #75457 Epic: CRDB-25322 Release note (sql change): Add a new session variable, `optimizer_use_lock_op_for_serializable`, which when set enables a new implementation of `SELECT FOR UPDATE`. This new implementation of `SELECT FOR UPDATE` acquires row locks *after* any joins and filtering, and always acquires row locks on the primary index of the table being locked. This more closely matches `SELECT FOR UPDATE` behavior in PostgreSQL, but at the cost of more round trips from gateway node to replica leaseholder. Under read committed isolation (and other isolation levels weaker than serializable) we will always use this new implementation of `SELECT FOR UPDATE` regardless of the value of `optimizer_use_lock_op_for_serializable` to ensure correctness.
4cef6e7
to
e129694
Compare
2ec05b3
to
aae01f9
Compare
Thanks for opening a backport. Please check the backport criteria before merging:
If some of the basic criteria cannot be satisfied, ensure that the exceptional criteria are satisfied within.
Add a brief release justification to the body of your PR to justify this backport. Some other things to consider:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewable status:
complete! 1 of 0 LGTMs obtained (waiting on @mgartner, @michae2, and @msirek)
@mgartner this is the last of the read committed functionality. It just missed the branch cut by about an hour, so I had to backport. PTAL when you get the chance. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
In some cases these new plans will have superfluous lookup joins. A
future PR will optimize away some of these superfluous lookup joins.
Is this planned for 23.2 or later?
The work hasn't been done yet, but maybe 23.2 if I get to it and the backport is small enough and you think it's a good idea. |
Backport 2/2 commits from #111662 on behalf of @michae2.
/cc @cockroachdb/release
execbuilder: change error message to match PostgreSQL
Release note (sql change): Change the following error message:
to this to match PostgreSQL:
opt: add lock operator
Add a new implementation of
SELECT FOR UPDATE
andSELECT FOR SHARE
statements. Instead of locking during the initial row fetch, this new
implementation constructs a
Lock
operator on the top of the query planwhich performs the locking phase using a locking semi-join lookup.
During optbuilder we build plans with both
Lock
operators andinitial-row-fetch locking. During execbuilder we decide which
implementation to use based on the isolation level and whether
optimizer_use_lock_op_for_serializable
is set. If the newimplementation is chosen,
Lock
operators become lockingsemi-LookupJoins.
In some cases these new plans will have superfluous lookup joins. A
future PR will optimize away some of these superfluous lookup joins.
Fixes: #57031, #75457
Epic: CRDB-25322
Release note (sql change): Add a new session variable,
optimizer_use_lock_op_for_serializable
, which when set enables a newimplementation of
SELECT FOR UPDATE
. This new implementation ofSELECT FOR UPDATE
acquires row locks after any joins and filtering,and always acquires row locks on the primary index of the table being
locked. This more closely matches
SELECT FOR UPDATE
behavior inPostgreSQL, but at the cost of more round trips from gateway node to
replica leaseholder.
Under read committed isolation (and other isolation levels weaker than
serializable) we will always use this new implementation of
SELECT FOR UPDATE
regardless of the value ofoptimizer_use_lock_op_for_serializable
to ensure correctness.Release justification: part of the read committed commitment for 23.2.