-
Notifications
You must be signed in to change notification settings - Fork 3.7k
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
kv: shallow copy BatchRequest on mutate in tryBumpBatchTimestamp #124634
Conversation
It looks like your PR touches production code but doesn't add or edit any test code. Did you consider adding tests to your PR? Thank you for contributing to CockroachDB. Please ensure you have followed the guidelines for creating a PR. My owl senses detect your PR is good for review. Please keep an eye out for any test failures in CI. I have added a few people who may be able to assist in reviewing:
🦉 Hoot! I am a Blathers, a bot for CockroachDB. My owner is dev-inf. |
It looks like your PR touches production code but doesn't add or edit any test code. Did you consider adding tests to your PR? Thank you for updating your pull request. My owl senses detect your PR is good for review. Please keep an eye out for any test failures in CI. 🦉 Hoot! I am a Blathers, a bot for CockroachDB. My owner is dev-inf. |
txn := ba.Txn.Clone() | ||
txn.BumpReadTimestamp(ts) | ||
readTs := ba.Txn.ReadTimestamp | ||
ba = ba.ShallowCopy() |
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.
This won't currently have the desired effect, as we're not doing anything with the shallow copy. We'll need to return it if we don't want to mutate the provided reference.
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.
Thanks for guidance, I am trying to understand this pattern - the data race happens a pointer level, we return a new shallow copy pointer on mutate to prevent race on the same pointer down the line. But this approach cannot prevent the race of the value in memory right?
9dfcdaf
to
a15b420
Compare
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.
Reviewed 4 of 5 files at r2, all commit messages.
Reviewable status:complete! 0 of 0 LGTMs obtained (waiting on @kvoli, @lyang24, and @stevendanna)
pkg/kv/kvserver/replica_batch_updates.go
line 245 at r1 (raw file):
Previously, lyang24 (Lanqing Yang) wrote…
Thanks for guidance, I am trying to understand this pattern - the data race happens a pointer level, we return a new shallow copy pointer on mutate to prevent race on the same pointer down the line. But this approach cannot prevent the race of the value in memory right?
I don't fully understand the question. There's aliasing on the heap memory, so we treat it as copy-on-write to avoid mutating the memory that others are reading.
pkg/kv/kvserver/replica_batch_updates.go
line 233 at r2 (raw file):
if ba.Txn == nil { log.VEventf(ctx, 2, "bumping batch timestamp to %s from %s", ts, ba.Timestamp) ba.Timestamp = ts
We'll need a ba = ba.ShallowCopy()
here as well.
pkg/kv/kvserver/replica_batch_updates.go
line 247 at r2 (raw file):
shallowCopy := ba.ShallowCopy() shallowCopy.Txn = txn shallowCopy.Timestamp = readTs // Refresh just updated ReadTimestamp
We should just be able to do:
ba = ba.ShallowCopy()
ba.Txn = ba.Txn.Clone()
ba.Txn.BumpReadTimestamp(ts)
ba.Timestamp = ba.Txn.ReadTimestamp // Refresh just updated ReadTimestamp
return ba, true
pkg/kv/kvserver/replica_read.go
line 493 at r2 (raw file):
latchesHeld := g != nil var serverSideRetryOk bool ba, serverSideRetryOk = canDoServersideRetry(ctx, pErr, ba, g, hlc.Timestamp{})
I don't think we want to call canDoServersideRetry
if latchesHeld == false
.
pkg/kv/kvserver/replica_send.go
line 813 at r2 (raw file):
// re-acquire them if the retry is allowed. var serverSideRetryOk bool if ba, serverSideRetryOk = canDoServersideRetry(ctx, pErr, ba, nil /* g */, hlc.Timestamp{} /* deadline */); !serverSideRetryOk {
nit: var ok bool
is probably sufficient here. It's pretty clear what the value's meaning is without the longer serverSideRetryOk
. Same thing elsewhere in this PR.
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! 0 of 0 LGTMs obtained (waiting on @kvoli, @nvanbenschoten, and @stevendanna)
pkg/kv/kvserver/replica_batch_updates.go
line 245 at r1 (raw file):
Previously, nvanbenschoten (Nathan VanBenschoten) wrote…
I don't fully understand the question. There's aliasing on the heap memory, so we treat it as copy-on-write to avoid mutating the memory that others are reading.
oh my original thinking is this technique works great for read write data race (that is the case we care solving) but for future references this approach will probably not work for write write data race no?
pkg/kv/kvserver/replica_batch_updates.go
line 233 at r2 (raw file):
Previously, nvanbenschoten (Nathan VanBenschoten) wrote…
We'll need a
ba = ba.ShallowCopy()
here as well.
good call thanks
pkg/kv/kvserver/replica_batch_updates.go
line 247 at r2 (raw file):
Previously, nvanbenschoten (Nathan VanBenschoten) wrote…
We should just be able to do:
ba = ba.ShallowCopy() ba.Txn = ba.Txn.Clone() ba.Txn.BumpReadTimestamp(ts) ba.Timestamp = ba.Txn.ReadTimestamp // Refresh just updated ReadTimestamp return ba, true
done thanks
pkg/kv/kvserver/replica_read.go
line 493 at r2 (raw file):
Previously, nvanbenschoten (Nathan VanBenschoten) wrote…
I don't think we want to call
canDoServersideRetry
iflatchesHeld == false
.
great call
pkg/kv/kvserver/replica_send.go
line 813 at r2 (raw file):
Previously, nvanbenschoten (Nathan VanBenschoten) wrote…
nit:
var ok bool
is probably sufficient here. It's pretty clear what the value's meaning is without the longerserverSideRetryOk
. Same thing elsewhere in this PR.
thanks will apply the same thinking in future
pkg/kv/kvserver/replica_write.go
line 400 at r2 (raw file):
minCommitTS := r.MinTxnCommitTS(ctx, ba.Txn.ID, ba.Txn.Key) if ba.Timestamp.Less(minCommitTS) { ba.Txn.WriteTimestamp = minCommitTS
I am reviewing it again, we might need a shallow copy here?
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! 0 of 0 LGTMs obtained (waiting on @kvoli, @nvanbenschoten, and @stevendanna)
pkg/kv/kvserver/replica_read.go
line 496 at r3 (raw file):
ba, ok = canDoServersideRetry(ctx, pErr, ba, g, hlc.Timestamp{}) } if !latchesHeld || !ok {
we might just get aways with !ok
as the condition here, up to the style preference
This avoids a data race on tryBumpBatchTimestamp, which was fallout from the new logging introduced in ba13697. Fixes: cockroachdb#124553 Release note: None
22bcdfe
to
3b5b022
Compare
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.
Thanks @lyang24!
bors r+
Build succeeded: |
This avoids a data race on tryBumpBatchTimestamp, which was fallout from the new logging introduced in ba13697.
Fixes: #124553
Release note: None