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/pgwire: send placeholder BackendKeyData #60281

Merged
merged 1 commit into from
Feb 10, 2021

Conversation

rafiss
Copy link
Collaborator

@rafiss rafiss commented Feb 9, 2021

fixes #13191

Some tools expect this message to be returned at connection time and
will not connect without it. CockroachDB does not support pgwire
cancellation, but we can still send a placeholder value here, and
continue ignoring cancellation requests like we already do.

Added a small test to make sure nothing broke.

Release note (sql change): When a connection is established, CockroachDB
will now return a placeholder BackendKeyData message in the response.
This is for compatibility with some tools, but using the BackendKeyData
to cancel a query will still have no effect, just the same as before.

@cockroach-teamcity
Copy link
Member

This change is Reviewable

@rafiss rafiss requested review from jordanlewis, a team and asubiotto February 9, 2021 23:37
@rafiss
Copy link
Collaborator Author

rafiss commented Feb 9, 2021

@asubiotto @jordanlewis i've requested your review since you may have more context from #13009

Copy link
Member

@jordanlewis jordanlewis left a comment

Choose a reason for hiding this comment

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

Can you add some pgwire data driven tests for this too? I'm actually surprised we didn't see any failures in those, since we're changing what we're sending - what explains that?

What ORM/driver does this change target, again? Do we have tests for it?

Overall I think this looks good. Have you already gone spelunking for why we didn't merge a placeholder BackendKeyData originally? I vaguely recall @asubiotto sending a PR for this, but it obviously never got merged and I wonder why that's the case.

@rafiss
Copy link
Collaborator Author

rafiss commented Feb 10, 2021

Can you add some pgwire data driven tests for this too? I'm actually surprised we didn't see any failures in those, since we're changing what we're sending - what explains that?

i think it's because this message is during the connection handshake, and those tests only include assertions after the connection has been established. i'll look into enhancing those tests.

What ORM/driver does this change target, again? Do we have tests for it?

the tool mentioned in #13191 (which is the issue that prompted my attention here) is the py-postgresql driver for python3. the tool mentioned in #13009 (which was Alfonso's earlier PR) is pgpool. we don't have tests for these tools. i'm not sure if we should, since our approach has only been to test tools that we want to document support for, but i'm open to hearing an argument in favor of testing now.

Overall I think this looks good. Have you already gone spelunking for why we didn't merge a placeholder BackendKeyData originally? I vaguely recall @asubiotto sending a PR for this, but it obviously never got merged and I wonder why that's the case.

Alfonso's comment (#13009 (comment)) describes why. at that time, it seems that we were waiting until there was telemetry and unimplemented errors for when we received a CancelRequest message. we now do have this in place.

@jordanlewis
Copy link
Member

Ok, sounds good. We need to have at least some test that this functionality is actually usable by clients - that they receive the key data without larger issues. I suppose all of the ORM tests will check this automatically too.

LGTM if you can check via the pgwire datadriven tests (or really any pgwire test that actually inspects the bytes) that we're sending the cancel data message - would be a shame if we had a regression here and never noticed.

Copy link
Contributor

@asubiotto asubiotto left a comment

Choose a reason for hiding this comment

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

Reviewed 3 of 3 files at r1.
Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (waiting on @rafiss)


pkg/sql/pgwire/conn.go, line 310 at r1 (raw file):

		// normally used by clients to send a CancelRequest message:
		// https://www.postgresql.org/docs/9.6/static/protocol-flow.html#AEN112861
		// CockroachDB currently ignores all CancelRequests.

Is this actually ignored or do we return some unimplemented error? If the former, would it make sense/be a lot of work to return an error? OK to do this work separately.


pkg/sql/pgwire/conn_test.go, line 1525 at r1 (raw file):

}

// TestReadTimeoutConn asserts that a readTimeoutConn performs reads normally

nit: name


pkg/sql/pgwire/conn_test.go, line 1545 at r1 (raw file):

	ctx, cancel := context.WithCancel(context.Background())

	// Delay execution for just a bit until db.QueryContext has begun.

Hmm, this looks like it's going to be flaky. You could use one of the executor testing knob callbacks (Before{Prepare,Execute}) in StartServer to only cancel the context once it receives the select pg_sleep statement on the server side.

@asubiotto
Copy link
Contributor

Thanks for this change BTW! Good to close such an early issue.

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! 0 of 0 LGTMs obtained (waiting on @asubiotto)


pkg/sql/pgwire/conn.go, line 310 at r1 (raw file):

Previously, asubiotto (Alfonso Subiotto Marqués) wrote…

Is this actually ignored or do we return some unimplemented error? If the former, would it make sense/be a lot of work to return an error? OK to do this work separately.

we don't return an error, since it is actually quite common for clients to call already. we do have telemetry on it:

func handleCancel(conn net.Conn) error {
// Since we don't support this, close the door in the client's
// face. Make a note of that use in telemetry.
telemetry.Inc(sqltelemetry.CancelRequestCounter)
_ = conn.Close()
return nil
}

the data here shows that tools frequently invoke this, so it could potentially have far-reaching effects to change this to be an error: #41335 (comment)


pkg/sql/pgwire/conn_test.go, line 1525 at r1 (raw file):

Previously, asubiotto (Alfonso Subiotto Marqués) wrote…

nit: name

fixed


pkg/sql/pgwire/conn_test.go, line 1545 at r1 (raw file):

Previously, asubiotto (Alfonso Subiotto Marqués) wrote…

Hmm, this looks like it's going to be flaky. You could use one of the executor testing knob callbacks (Before{Prepare,Execute}) in StartServer to only cancel the context once it receives the select pg_sleep statement on the server side.

nice! thanks for this pointer. for some context, i just copied this test from the lib/pq test suite: https://github.com/lib/pq/blob/4604d39ddc9f62e2ca152114c73aec99b77a3468/go18_test.go#L116

using callbacks is way better though

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! 0 of 0 LGTMs obtained (waiting on @asubiotto)


pkg/sql/pgwire/conn.go, line 310 at r1 (raw file):
the Postgres docs make CancelRequest seem like a "best-effort" thing so, i think it's dine to not have an error even though we don't do anything

A CancelRequest message will be ignored unless it contains the same key data (PID and secret key) passed to the frontend during connection start-up. If the request matches the PID and secret key for a currently executing backend, the processing of the current query is aborted. (In the existing implementation, this is done by sending a special signal to the backend process that is processing the query.)

The cancellation signal might or might not have any effect — for example, if it arrives after the backend has finished processing the query, then it will have no effect. If the cancellation is effective, it results in the current command being terminated early with an error message.


pkg/sql/pgwire/conn_test.go, line 1545 at r1 (raw file):

Previously, rafiss (Rafi Shamim) wrote…

nice! thanks for this pointer. for some context, i just copied this test from the lib/pq test suite: https://github.com/lib/pq/blob/4604d39ddc9f62e2ca152114c73aec99b77a3468/go18_test.go#L116

using callbacks is way better though

Done.

@rafiss
Copy link
Collaborator Author

rafiss commented Feb 10, 2021

this is ready for another look. i've added a test to pkg/testutils/pgtest/pgtest.go that shows the BackendKeyData being received.

Copy link
Contributor

@asubiotto asubiotto 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 3 files at r2.
Reviewable status: :shipit: complete! 1 of 0 LGTMs obtained (waiting on @jordanlewis and @rafiss)


pkg/sql/pgwire/conn_test.go, line 1557 at r2 (raw file):

	// Cancellation has no effect on ongoing query.
	if _, err := db.QueryContext(cancelCtx, "select pg_sleep(0.2)"); err != nil {

nit: ok to make this 0?

@rafiss
Copy link
Collaborator Author

rafiss commented Feb 10, 2021

it looks like i need to update sqlproxy to be aware of BackendKeyData. gonna clear this with the CC team.

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 @jordanlewis)


pkg/sql/pgwire/conn_test.go, line 1557 at r2 (raw file):

Previously, asubiotto (Alfonso Subiotto Marqués) wrote…

nit: ok to make this 0?

done

Some tools expect this message to be returned at connection time and
will not connect without it. CockroachDB does not support pgwire
cancellation, but we can still send a placeholder value here, and
continue ignoring cancellation requests like we already do.

Added a pgwire cancellation test to make sure nothing broke, as well as
a pgwire-level test to make sure the BackendKeyData is sent to the
client.

Release note (sql change): When a connection is established, CockroachDB
will now return a placeholder BackendKeyData message in the response.
This is for compatibility with some tools, but using the BackendKeyData
to cancel a query will still have no effect, just the same as before.
@rafiss rafiss requested a review from spaskob February 10, 2021 17:52
@rafiss
Copy link
Collaborator Author

rafiss commented Feb 10, 2021

@spaskob i see that this affects an area of sqlproxy that you worked on. can you please take a look at the changes? also, can you confirm that this update to sqlproxy will be able to be deployed before CockroachDB 21.1 is released?

@spaskob
Copy link
Contributor

spaskob commented Feb 10, 2021

Thanks @rafiss for fixing the sqlproxy code. The change looks good to me. Do you mind running https://github.com/cockroachdb/cockroach/blob/master/pkg/ccl/sqlproxyccl/run_proxy.sh to make sure the proxy works e2e?

@rafiss
Copy link
Collaborator Author

rafiss commented Feb 10, 2021

@spaskob thanks! that test passes for me locally.

how often does sqlproxy get released? as long as it's released before CC uses CRDB 21.1 we should be good.

@rafiss
Copy link
Collaborator Author

rafiss commented Feb 10, 2021

thanks for the reviews all!

bors r=asubiotto,spaskob

Copy link
Contributor

@spaskob spaskob left a comment

Choose a reason for hiding this comment

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

There's no release schedule I will pick up this commit after you merge and create a ticket to release it.

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

Copy link
Contributor

@spaskob spaskob left a comment

Choose a reason for hiding this comment

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

:lgtm:

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

@craig
Copy link
Contributor

craig bot commented Feb 10, 2021

Build succeeded:

@craig craig bot merged commit 5095a3c into cockroachdb:master Feb 10, 2021
@rafiss rafiss deleted the dummy-backendkey branch February 11, 2021 01:44
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.

pgwire: python3 py-postgresql driver error
5 participants