@@ -48,15 +48,20 @@ var bufferedWritesScanTransformEnabled = settings.RegisterBoolSetting(
48
48
settings .ApplicationLevel ,
49
49
"kv.transaction.write_buffering.transformations.scans.enabled" ,
50
50
"if enabled, locking scans and reverse scans with replicated durability are transformed to unreplicated durability" ,
51
- true ,
51
+ metamorphic . ConstantWithTestBool ( "kv.transaction.write_buffering.transformations.scans.enabled" , true /* defaultValue */ ) ,
52
52
)
53
53
54
+ const defaultBufferSize = 1 << 22 // 4MB
54
55
var bufferedWritesMaxBufferSize = settings .RegisterByteSizeSetting (
55
56
settings .ApplicationLevel ,
56
57
"kv.transaction.write_buffering.max_buffer_size" ,
57
58
"if non-zero, defines that maximum size of the " +
58
59
"buffer that will be used to buffer transactional writes per-transaction" ,
59
- 1 << 22 , // 4MB
60
+ int64 (metamorphic .ConstantWithTestRange ("kv.transaction.write_buffering.max_buffer_size" ,
61
+ defaultBufferSize , // default
62
+ 1 , // min
63
+ defaultBufferSize , // max
64
+ )),
60
65
settings .NonNegativeInt ,
61
66
settings .WithPublic ,
62
67
)
@@ -267,17 +272,18 @@ func (twb *txnWriteBuffer) SendLocked(
267
272
return twb .flushBufferAndSendBatch (ctx , ba )
268
273
}
269
274
270
- if twb .batchRequiresFlush (ctx , ba ) {
275
+ // We check if scan transforms are enabled once and use that answer until the
276
+ // end of SendLocked.
277
+ transformScans := bufferedWritesScanTransformEnabled .Get (& twb .st .SV )
278
+
279
+ if twb .batchRequiresFlush (ctx , ba , transformScans ) {
271
280
return twb .flushBufferAndSendBatch (ctx , ba )
272
281
}
273
282
274
283
// Check if buffering writes from the supplied batch will run us over
275
284
// budget. If it will, we shouldn't buffer writes from the current batch,
276
285
// and flush the buffer.
277
286
maxSize := bufferedWritesMaxBufferSize .Get (& twb .st .SV )
278
- // We check if scan transforms are enabled once and use that answer until the
279
- // end of SendLocked.
280
- transformScans := bufferedWritesScanTransformEnabled .Get (& twb .st .SV )
281
287
bufSize := twb .estimateSize (ba , transformScans ) + twb .bufferSize
282
288
283
289
// NB: if bufferedWritesMaxBufferSize is set to 0 then we effectively disable
@@ -331,7 +337,9 @@ func (twb *txnWriteBuffer) SendLocked(
331
337
return twb .mergeResponseWithRequestRecords (ctx , rr , br )
332
338
}
333
339
334
- func (twb * txnWriteBuffer ) batchRequiresFlush (ctx context.Context , ba * kvpb.BatchRequest ) bool {
340
+ func (twb * txnWriteBuffer ) batchRequiresFlush (
341
+ ctx context.Context , ba * kvpb.BatchRequest , transformScans bool ,
342
+ ) bool {
335
343
for _ , ru := range ba .Requests {
336
344
req := ru .GetInner ()
337
345
switch req .(type ) {
@@ -477,7 +485,7 @@ func (twb *txnWriteBuffer) estimateSize(ba *kvpb.BatchRequest, transformScans bo
477
485
estimate += scratch .size ()
478
486
estimate += lockKeyInfoSize
479
487
case * kvpb.GetRequest :
480
- if t . KeyLockingDurability == lock . Replicated {
488
+ if IsReplicatedLockingRequest ( t ) {
481
489
scratch .key = t .Key
482
490
estimate += scratch .size ()
483
491
estimate += lockKeyInfoSize
@@ -514,9 +522,7 @@ func (twb *txnWriteBuffer) estimateSize(ba *kvpb.BatchRequest, transformScans bo
514
522
// the buffer. Here, we assume at least 1 key will be returned that is
515
523
// about the size of the scan start boundary. We try to protect from large
516
524
// buffer overflows by transforming the batch's MaxSpanRequestKeys later.
517
- shouldTransform := t .KeyLockingStrength > lock .None && t .KeyLockingDurability == lock .Replicated
518
- shouldTransform = shouldTransform && transformScans
519
- if shouldTransform {
525
+ if IsReplicatedLockingRequest (t ) && transformScans {
520
526
scratch .key = t .Key
521
527
scratch .vals [0 ] = bufferedValue {
522
528
seq : t .Sequence ,
@@ -525,9 +531,7 @@ func (twb *txnWriteBuffer) estimateSize(ba *kvpb.BatchRequest, transformScans bo
525
531
}
526
532
case * kvpb.ReverseScanRequest :
527
533
// See the comment on the ScanRequest case for more details.
528
- shouldTransform := t .KeyLockingStrength > lock .None && t .KeyLockingDurability == lock .Replicated
529
- shouldTransform = shouldTransform && transformScans
530
- if shouldTransform {
534
+ if IsReplicatedLockingRequest (t ) && transformScans {
531
535
scratch .key = t .Key
532
536
scratch .vals [0 ] = bufferedValue {
533
537
seq : t .Sequence ,
@@ -932,7 +936,7 @@ func (twb *txnWriteBuffer) applyTransformations(
932
936
_ , lockStr , served := twb .maybeServeRead (t .Key , t .Sequence )
933
937
934
938
requiresAdditionalLocking := t .KeyLockingStrength > lockStr
935
- requiresLockTransform := t . KeyLockingStrength != lock . None && t . KeyLockingDurability == lock . Replicated
939
+ requiresLockTransform := IsReplicatedLockingRequest ( t )
936
940
requestRequired := requiresAdditionalLocking || ! served
937
941
938
942
if requestRequired && requiresLockTransform {
@@ -953,9 +957,7 @@ func (twb *txnWriteBuffer) applyTransformations(
953
957
// Regardless of whether the scan overlaps with any writes in the buffer
954
958
// or not, we must send the request to the KV layer. We can't know for
955
959
// sure that there's nothing else to read.
956
- shouldTransform := t .KeyLockingStrength > lock .None && t .KeyLockingDurability == lock .Replicated
957
- shouldTransform = shouldTransform && transformScans
958
- if shouldTransform {
960
+ if IsReplicatedLockingRequest (t ) && transformScans {
959
961
var scanReqU kvpb.RequestUnion
960
962
scanReq := t .ShallowCopy ().(* kvpb.ScanRequest )
961
963
scanReq .KeyLockingDurability = lock .Unreplicated
@@ -973,9 +975,7 @@ func (twb *txnWriteBuffer) applyTransformations(
973
975
// Regardless of whether the reverse scan overlaps with any writes in the
974
976
// buffer or not, we must send the request to the KV layer. We can't know
975
977
// for sure that there's nothing else to read.
976
- shouldTransform := t .KeyLockingStrength > lock .None && t .KeyLockingDurability == lock .Replicated
977
- shouldTransform = shouldTransform && transformScans
978
- if shouldTransform {
978
+ if IsReplicatedLockingRequest (t ) && transformScans {
979
979
var rScanReqU kvpb.RequestUnion
980
980
rScanReq := t .ShallowCopy ().(* kvpb.ReverseScanRequest )
981
981
rScanReq .KeyLockingDurability = lock .Unreplicated
@@ -1635,6 +1635,19 @@ func (twb *txnWriteBuffer) addToBuffer(
1635
1635
}
1636
1636
}
1637
1637
1638
+ func IsReplicatedLockingRequest (req kvpb.Request ) bool {
1639
+ switch r := req .(type ) {
1640
+ case * kvpb.ScanRequest :
1641
+ return r .KeyLockingStrength > lock .None && r .KeyLockingDurability == lock .Replicated
1642
+ case * kvpb.ReverseScanRequest :
1643
+ return r .KeyLockingStrength > lock .None && r .KeyLockingDurability == lock .Replicated
1644
+ case * kvpb.GetRequest :
1645
+ return r .KeyLockingStrength > lock .None && r .KeyLockingDurability == lock .Replicated
1646
+ default :
1647
+ return false
1648
+ }
1649
+ }
1650
+
1638
1651
// addDurableLockedReadToBuffer adds a locking read to the given buffer.
1639
1652
//
1640
1653
// TODO(ssd): Determine if we need to track the kvnemesis sequence number for
0 commit comments