spanner: Race condition in (*BatchReadOnlyTransaction).Execute() #1895
Labels
api: spanner
Issues related to the Spanner API.
priority: p2
Moderately-important priority. Fix may not be included in next release.
type: bug
Error or flaw in code with unintended results or allowing sub-optimal usage patterns.
Client
Spanner
Environment
Any
Code
The following code counts the total number of rows using
PartitionRead()
.It'll exhibit the race condition by showing varying total counts at the end of each run.
Of course this only works if your table has more than one partition.
Expected behavior
PartitionRead()
reads all rows.Actual behavior
A race condition. 😢
Cause
Each partition points to the same
rreq
/qreq
.For instance for
rreq
line 137 in the following code section:google-cloud-go/spanner/batch.go
Lines 124 to 139 in a1a1bde
During the call in
Execution()
therreq
/qreq
fields are then mutated without locks of any kind.For instance for
rreq
line 264 in the following code section:google-cloud-go/spanner/batch.go
Lines 262 to 275 in a1a1bde
The documentation of that function also doesn't mention it's not safe for concurrent use, nor that it mutates it's argument.
I suppose the struct field
pt
exists because this was an attempt to reduce the data size after a call toMarshalBinary()
?In that case I'd like to kindly suggest to simply copy the
rreq
/qreq
fields within theExecution()
method and mutate the copy only. 🙂Additional context
Intermediate fix:
👉 Should I submit a fix?
I already did so in the past, but last time you told me to open an issue beforehand. 😄
The text was updated successfully, but these errors were encountered: