-
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-21.1: sql: properly synchronize the internal executor iterator #62923
Merged
yuzefovich
merged 5 commits into
cockroachdb:release-21.1
from
yuzefovich:backport21.1-62581
Apr 9, 2021
Merged
release-21.1: sql: properly synchronize the internal executor iterator #62923
yuzefovich
merged 5 commits into
cockroachdb:release-21.1
from
yuzefovich:backport21.1-62581
Apr 9, 2021
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
`SetColumns` contract allows for the argument to be nil, yet the iterator of the streaming internal executor expects that column schema, if set, is non-nil. I don't think this could happen in practice, but theoretically previously we could encounter an assertion error due to none of the four fields in `ieIteratorResult` object being non-nil, and now this is fixed. Release note: None
Release note: None
We recently merged an update to the internal executor to make it streaming. Currently it is implemented by having two goroutines (the iterator, "the consumer"; and the connExecutor, "the producer"). The communication between them is done on the buffered channel. As a result, both goroutines can run concurrently. However, a crucial point was overlooked - our `kv.Txn`s cannot be used concurrently. Imagine a plan that reads from two tables each of which is populated via the internal executor: if we read from the first, and then from the second concurrently, we will have the concurrent usage of the txn for that plan. This commit the problem by carving out a new abstraction to optionally synchronize the execution of the internal executor with its corresponding iterator. The abstraction comes in sync and async flavors. In the sync form, the ieResultChannel ensures that the reader and writer do not concurrently operate, and, additionally provides a mechanism whereby the reader may ensure that the writer observes an error when its attempts to publish the previous row returns. This last point is critical to ensure that transactions are not erroneously used after it has become unsafe. The async flavor is still used by the internal executor when it doesn't return an iterator directly and executes the query to completion itself. Release note: None (no stable release with this bug).
When finishing sending on the ieSyncResultChannel we do not need to and should not close the channel used to unblock the sender. Doing so can result in a panic if the reader is concurrently trying to unblock the sender. We could close that channel but there's no obvious reason to. Fixes cockroachdb#62939 Release note: None
The async and sync implementations were too close to justify two structs. Also, the async behavior of not stopping the writer in case the reader called close wasn't desireable. This commit unifies the implementation. It also ensures that we propagate context errors in all cases triggered by the closure of the done channel. It also makes closing the channel idempotent. Additionally, this commit transitions the execution flow into draining state without setting our customer error on the resultWriter. Release note: None
01622ca
to
80352be
Compare
@ajwerner the fix to DistSQLReceiver has been merged and I cherry-picked all streaming internal executor fixes into this PR. RFAL. |
ajwerner
approved these changes
Apr 9, 2021
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
Thanks a lot Andrew for working on this with me! |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Backport 3/3 commits from #62581.
Backport 1/1 commits from #62962.
Backport 1/1 commits from #63010.
/cc @cockroachdb/release
sql: fix an edge case in the internal executor
SetColumns
contract allows for the argument to be nil, yet theiterator of the streaming internal executor expects that column schema,
if set, is non-nil. I don't think this could happen in practice, but
theoretically previously we could encounter an assertion error due to
none of the four fields in
ieIteratorResult
object being non-nil, andnow this is fixed.
Release note: None
sql: add context to IncrementRowsAffected interface
Release note: None
sql: properly synchronize the internal executor iterator
We recently merged an update to the internal executor to make it
streaming. Currently it is implemented by having two goroutines (the
iterator, "the consumer"; and the connExecutor, "the producer"). The
communication between them is done on the buffered channel. As a result,
both goroutines can run concurrently.
However, a crucial point was overlooked - our
kv.Txn
s cannot be usedconcurrently. Imagine a plan that reads from two tables each of which is
populated via the internal executor: if we read from the first, and then
from the second concurrently, we will have the concurrent usage of the
txn for that plan.
This commit the problem by carving out a new abstraction to optionally
synchronize the execution of the internal executor with its corresponding
iterator. The abstraction comes in sync and async flavors. In the sync
form, the ieResultChannel ensures that the reader and writer do not
concurrently operate, and, additionally provides a mechanism whereby the
reader may ensure that the writer observes an error when its attempts to
publish the previous row returns. This last point is critical to ensure
that transactions are not erroneously used after it has become unsafe.
The async flavor is still used by the internal executor when it doesn't
return an iterator directly and executes the query to completion itself.
Fixes: #62415.
Release note: None (no stable release with this bug).
sql: fix bug in close of ieSyncResultChannel
When finishing sending on the ieSyncResultChannel we do not need to and should
not close the channel used to unblock the sender. Doing so can result in a
panic if the reader is concurrently trying to unblock the sender. We could
close that channel but there's no obvious reason to.
Fixes #62939
Release note: None
sql: clean up ieResultChannel concepts and fix race condition
The async and sync implementations were too close to justify two structs.
Also, the async behavior of not stopping the writer in case the reader
called close wasn't desireable. This commit unifies the implementation.
It also ensures that we propagate context errors in all cases triggered
by the closure of the done channel. It also makes closing the channel
idempotent.
Additionally, this commit transitions the execution flow into draining
state without setting our customer error on the resultWriter.
Fixes #62948
Release note: None