Skip to content

Commit 1ae507a

Browse files
committed
kvcoord: always check for buffered writes when checking for locks
When reading through code for an unrelated reason we noted that there was a call checking for acquired locks but not buffered writes. This is concerning since the reasoning for why we need to check for acquired locks almost always implies we should also check for buffered writes. In the particular case of RollbackToSavepoint, I believe the omission has no impact. Namely: - Previous writes have been cleared from the buffer and thus aren't in danger of failing to be rolled back. - Subsequent writes will bump the sequence number and thus those writes are not in danger of being erroneously rolled back. - Subsequent reads cannot read the data that should have been rolled back because it will have been cleared from the buffer. Further, for real-world SQL transactions, we never have a buffered write without having at least 1 lock. However, for the avoidance fo doubt, we now check both and add a new method to avoid missing checks in the future. Fixes #155975 Release note: None
1 parent b2be406 commit 1ae507a

File tree

2 files changed

+8
-5
lines changed

2 files changed

+8
-5
lines changed

pkg/kv/kvclient/kvcoord/txn_coord_sender.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -527,8 +527,7 @@ func (tc *TxnCoordSender) Send(
527527
return nil, pErr
528528
}
529529

530-
if ba.IsSingleEndTxnRequest() && !tc.interceptorAlloc.txnPipeliner.hasAcquiredLocks() &&
531-
!tc.interceptorAlloc.txnWriteBuffer.hasBufferedWrites() {
530+
if ba.IsSingleEndTxnRequest() && !tc.hasAcquiredLocksOrBufferedWritesLocked() {
532531
return nil, tc.finalizeNonLockingTxnLocked(ctx, ba)
533532
}
534533

@@ -1724,3 +1723,7 @@ func (tc *TxnCoordSender) hasPerformedWritesLocked() bool {
17241723
func (tc *TxnCoordSender) hasBufferedWritesLocked() bool {
17251724
return tc.interceptorAlloc.txnWriteBuffer.hasBufferedWrites()
17261725
}
1726+
1727+
func (tc *TxnCoordSender) hasAcquiredLocksOrBufferedWritesLocked() bool {
1728+
return tc.interceptorAlloc.txnPipeliner.hasAcquiredLocks() || tc.interceptorAlloc.txnWriteBuffer.hasBufferedWrites()
1729+
}

pkg/kv/kvclient/kvcoord/txn_coord_sender_savepoints.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,12 +89,12 @@ func (tc *TxnCoordSender) CreateSavepoint(ctx context.Context) (kv.SavepointToke
8989
// We also increment the write sequence if any writes are buffered since
9090
// a buffered write will not appears as a lock acquisition in the
9191
// pipeliner. For SQL-generated transactions, this additional check is
92-
// unnecessary since we won't ever have buffered writes wihout also at
92+
// unnecessary since we won't ever have buffered writes without also at
9393
// least 1 locked row. However, for other types of KV transactions such
9494
// as those generated by KVNemesis we may have blind Put or Delete
9595
// requests that would be erroneously rolled back if we didn't increment
9696
// the sequence here.
97-
if tc.interceptorAlloc.txnPipeliner.hasAcquiredLocks() || tc.interceptorAlloc.txnWriteBuffer.hasBufferedWrites() {
97+
if tc.hasAcquiredLocksOrBufferedWritesLocked() {
9898
if err := tc.interceptorAlloc.txnSeqNumAllocator.stepWriteSeqLocked(ctx); err != nil {
9999
return nil, err
100100
}
@@ -160,7 +160,7 @@ func (tc *TxnCoordSender) RollbackToSavepoint(ctx context.Context, s kv.Savepoin
160160
// TODO(nvanbenschoten): once #113765 is resolved, we should make this
161161
// unconditional and push the write sequence increment into
162162
// txnSeqNumAllocator.rollbackToSavepointLocked.
163-
if tc.interceptorAlloc.txnPipeliner.hasAcquiredLocks() {
163+
if tc.hasAcquiredLocksOrBufferedWritesLocked() {
164164
tc.mu.txn.AddIgnoredSeqNumRange(
165165
enginepb.IgnoredSeqNumRange{
166166
Start: sp.seqNum, End: tc.interceptorAlloc.txnSeqNumAllocator.writeSeq,

0 commit comments

Comments
 (0)