Skip to content
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

sql: disallow schema changes for READ COMMITTED transactions #107216

Merged
merged 1 commit into from
Jul 26, 2023

Conversation

rafiss
Copy link
Collaborator

@rafiss rafiss commented Jul 19, 2023

Due to how descriptor leasing works, schema changes are not safe in weaker isolation transactions. Until they are safe, we disallow them.

fixes #100143
Release note: None

@rafiss rafiss requested review from nvanbenschoten, michae2 and a team July 19, 2023 22:23
@rafiss rafiss requested a review from a team as a code owner July 19, 2023 22:23
@cockroach-teamcity
Copy link
Member

This change is Reviewable

Copy link
Collaborator

@michae2 michae2 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:lgtm:

Reviewed 3 of 10 files at r1, all commit messages.
Reviewable status: :shipit: complete! 1 of 0 LGTMs obtained (waiting on @nvanbenschoten and @rafiss)


pkg/sql/opt/exec/execbuilder/relational.go line 171 at r1 (raw file):

	if opt.IsDDLOp(e) {
		if b.evalCtx.Txn.IsoLevel().ToleratesWriteSkew() {

I think there are a few cases where we have a nil Txn in execbuilder, so for this reason I've been using b.evalCtx.TxnIsoLevel instead of b.evalCtx.Txn.IsoLevel().

Copy link
Collaborator Author

@rafiss rafiss left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewable status: :shipit: complete! 1 of 0 LGTMs obtained (waiting on @michae2 and @nvanbenschoten)


pkg/sql/opt/exec/execbuilder/relational.go line 171 at r1 (raw file):

Previously, michae2 (Michael Erickson) wrote…

I think there are a few cases where we have a nil Txn in execbuilder, so for this reason I've been using b.evalCtx.TxnIsoLevel instead of b.evalCtx.Txn.IsoLevel().

ah ok good to know. i was wondering why that was there. but if Txn is nil, wouldn't it be likely that TxnIsoLevel is the zero-value (which is serializable)?

Copy link
Member

@nvanbenschoten nvanbenschoten left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:lgtm: mod the resolution to Michael's question.

Reviewed 10 of 10 files at r1, all commit messages.
Reviewable status: :shipit: complete! 2 of 0 LGTMs obtained (waiting on @michae2 and @rafiss)


pkg/sql/table.go line 111 at r1 (raw file):

	ctx context.Context, tableDesc *tabledesc.Mutable, jobDesc string, mutationID descpb.MutationID,
) error {
	if p.Txn().IsoLevel().ToleratesWriteSkew() {

Why is this check needed if we already have the execbuilder-level check? For statements that bypass the optimizer?

Copy link
Collaborator Author

@rafiss rafiss left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewable status: :shipit: complete! 2 of 0 LGTMs obtained (waiting on @michae2 and @nvanbenschoten)


pkg/sql/table.go line 111 at r1 (raw file):

Previously, nvanbenschoten (Nathan VanBenschoten) wrote…

Why is this check needed if we already have the execbuilder-level check? For statements that bypass the optimizer?

yeah that was the idea. some statements, like CREATE ROLE, cause a schema change (i.e., update the object descriptor), but I wasn't sure how to make the optimizer classify them as DDL. i've tracked that down now, so we no longer need this logic. thanks for the nudge on this.

(it required changing the StatementReturnType() of the statement, which should be safe to do for those operations. i also audited the other statements, and nothing else seemed off.)

@rafiss rafiss force-pushed the read-committed-schema-changes branch from 0c3ffd8 to 6f535ca Compare July 21, 2023 03:40
@rafiss rafiss requested a review from a team as a code owner July 21, 2023 03:40
Copy link
Collaborator

@michae2 michae2 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 2 of 2 files at r2, all commit messages.
Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (and 2 stale) (waiting on @nvanbenschoten and @rafiss)


pkg/sql/opt/exec/execbuilder/relational.go line 171 at r1 (raw file):

Previously, rafiss (Rafi Shamim) wrote…

ah ok good to know. i was wondering why that was there. but if Txn is nil, wouldn't it be likely that TxnIsoLevel is the zero-value (which is serializable)?

I forget exactly why I did this. Maybe I was just seeing ghosts (the ghosts being the other Txn* fields in eval.Context). Let's see if any tests can tell us why: #107363

Copy link
Collaborator

@michae2 michae2 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (and 2 stale) (waiting on @nvanbenschoten and @rafiss)


pkg/sql/opt/exec/execbuilder/relational.go line 171 at r1 (raw file):

Previously, michae2 (Michael Erickson) wrote…

I forget exactly why I did this. Maybe I was just seeing ghosts (the ghosts being the other Txn* fields in eval.Context). Let's see if any tests can tell us why: #107363

Ok, I guess our answer is: when using MakeTestingEvalContext in various tests the eval.Context.Txn.Sender is nil, so calling eval.Context.Txn.IsoLevel() will result in a nil pointer exception.

Copy link
Collaborator

@michae2 michae2 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:lgtm: I think we can defer answering this question for now if tests are passing, since this seems to be a test-only concern.

Reviewable status: :shipit: complete! 1 of 0 LGTMs obtained (and 1 stale) (waiting on @nvanbenschoten and @rafiss)

Due to how descriptor leasing works, schema changes are not safe in
weaker isolation transactions. Until they are safe, we disallow them.

This includes a small change to the grammar so that SET with empty key
names is consistently parsed, separate from the special SET ROW syntax.

Release note: None
@rafiss rafiss force-pushed the read-committed-schema-changes branch from 6f535ca to a30e7b0 Compare July 25, 2023 21:25
@rafiss
Copy link
Collaborator Author

rafiss commented Jul 26, 2023

tftr!

bors r=michae2

@craig
Copy link
Contributor

craig bot commented Jul 26, 2023

This PR was included in a batch that timed out, it will be automatically retried

@craig
Copy link
Contributor

craig bot commented Jul 26, 2023

This PR was included in a batch that timed out, it will be automatically retried

@craig
Copy link
Contributor

craig bot commented Jul 26, 2023

Build succeeded:

@craig craig bot merged commit 8c52fea into cockroachdb:master Jul 26, 2023
7 checks passed
@rafiss rafiss deleted the read-committed-schema-changes branch August 1, 2023 03:56
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.

sql: don't allow schema changes in weak isolation transactions
4 participants