@@ -1079,35 +1079,46 @@ func (ds *DistSender) initAndVerifyBatch(ctx context.Context, ba *kvpb.BatchRequ
1079
1079
return kvpb .NewErrorf ("empty batch" )
1080
1080
}
1081
1081
1082
- if ba .MaxSpanRequestKeys != 0 || ba .TargetBytes != 0 {
1083
- // Verify that the batch contains only specific requests. Verify that a
1084
- // batch with a ReverseScan only contains ReverseScan range requests.
1085
- var foundForward , foundReverse bool
1086
- for _ , req := range ba .Requests {
1087
- inner := req .GetInner ()
1088
- switch inner .(type ) {
1089
- case * kvpb.ScanRequest , * kvpb.ResolveIntentRangeRequest ,
1090
- * kvpb.DeleteRangeRequest , * kvpb.RevertRangeRequest ,
1091
- * kvpb.ExportRequest , * kvpb.QueryLocksRequest , * kvpb.IsSpanEmptyRequest :
1092
- // Accepted forward range requests.
1093
- foundForward = true
1082
+ // Verify that forward and reverse range requests are never in the same
1083
+ // batch. Also verify that the batch with limits contains only specific
1084
+ // requests.
1085
+ var foundForward , foundReverse bool
1086
+ var disallowedReq string
1087
+ for _ , req := range ba .Requests {
1088
+ inner := req .GetInner ()
1089
+ switch inner .(type ) {
1090
+ case * kvpb.ScanRequest , * kvpb.ResolveIntentRangeRequest ,
1091
+ * kvpb.DeleteRangeRequest , * kvpb.RevertRangeRequest ,
1092
+ * kvpb.ExportRequest , * kvpb.QueryLocksRequest , * kvpb.IsSpanEmptyRequest :
1093
+ // Accepted forward range requests.
1094
+ foundForward = true
1094
1095
1095
- case * kvpb.ReverseScanRequest :
1096
- // Accepted reverse range requests.
1097
- foundReverse = true
1096
+ case * kvpb.ReverseScanRequest :
1097
+ // Accepted reverse range requests.
1098
+ foundReverse = true
1098
1099
1099
- case * kvpb.QueryIntentRequest , * kvpb.EndTxnRequest ,
1100
- * kvpb.GetRequest , * kvpb.ResolveIntentRequest , * kvpb.DeleteRequest , * kvpb.PutRequest :
1101
- // Accepted point requests that can be in batches with limit.
1100
+ case * kvpb.QueryIntentRequest , * kvpb.EndTxnRequest ,
1101
+ * kvpb.GetRequest , * kvpb.ResolveIntentRequest , * kvpb.DeleteRequest , * kvpb.PutRequest :
1102
+ // Accepted point requests that can be in batches with limit. No
1103
+ // need to set disallowedReq.
1102
1104
1103
- default :
1104
- return kvpb .NewErrorf ("batch with limit contains %s request" , inner .Method ())
1105
- }
1106
- }
1107
- if foundForward && foundReverse {
1108
- return kvpb .NewErrorf ("batch with limit contains both forward and reverse scans" )
1105
+ default :
1106
+ disallowedReq = inner .Method ().String ()
1109
1107
}
1110
1108
}
1109
+ if foundForward && foundReverse {
1110
+ return kvpb .NewErrorf ("batch contains both forward and reverse requests" )
1111
+ }
1112
+ if (ba .MaxSpanRequestKeys != 0 || ba .TargetBytes != 0 ) && disallowedReq != "" {
1113
+ return kvpb .NewErrorf ("batch with limit contains %s request" , disallowedReq )
1114
+ }
1115
+ // Also verify that IsReverse is set accordingly on the batch header.
1116
+ if foundForward && ba .Header .IsReverse {
1117
+ return kvpb .NewErrorf ("batch contains forward requests but IsReverse is set" )
1118
+ }
1119
+ if foundReverse && ! ba .Header .IsReverse {
1120
+ return kvpb .NewErrorf ("batch contains reverse requests but IsReverse is not set" )
1121
+ }
1111
1122
1112
1123
switch ba .WaitPolicy {
1113
1124
case lock .WaitPolicy_Block , lock .WaitPolicy_Error :
@@ -1249,7 +1260,6 @@ func (ds *DistSender) Send(
1249
1260
if err != nil {
1250
1261
return nil , kvpb .NewError (err )
1251
1262
}
1252
- isReverse := ba .IsReverse ()
1253
1263
1254
1264
// Determine whether this part of the BatchRequest contains a committing
1255
1265
// EndTxn request.
@@ -1263,9 +1273,9 @@ func (ds *DistSender) Send(
1263
1273
var rpl * kvpb.BatchResponse
1264
1274
var pErr * kvpb.Error
1265
1275
if withParallelCommit {
1266
- rpl , pErr = ds .divideAndSendParallelCommit (ctx , ba , rs , isReverse , 0 /* batchIdx */ )
1276
+ rpl , pErr = ds .divideAndSendParallelCommit (ctx , ba , rs , 0 /* batchIdx */ )
1267
1277
} else {
1268
- rpl , pErr = ds .divideAndSendBatchToRanges (ctx , ba , rs , isReverse , withCommit , 0 /* batchIdx */ )
1278
+ rpl , pErr = ds .divideAndSendBatchToRanges (ctx , ba , rs , withCommit , 0 /* batchIdx */ )
1269
1279
}
1270
1280
1271
1281
if pErr == errNo1PCTxn {
@@ -1456,7 +1466,7 @@ type response struct {
1456
1466
// method is never invoked recursively, but it is exposed to maintain symmetry
1457
1467
// with divideAndSendBatchToRanges.
1458
1468
func (ds * DistSender ) divideAndSendParallelCommit (
1459
- ctx context.Context , ba * kvpb.BatchRequest , rs roachpb.RSpan , isReverse bool , batchIdx int ,
1469
+ ctx context.Context , ba * kvpb.BatchRequest , rs roachpb.RSpan , batchIdx int ,
1460
1470
) (br * kvpb.BatchResponse , pErr * kvpb.Error ) {
1461
1471
// Search backwards, looking for the first pre-commit QueryIntent.
1462
1472
swapIdx := - 1
@@ -1472,7 +1482,7 @@ func (ds *DistSender) divideAndSendParallelCommit(
1472
1482
if swapIdx == - 1 {
1473
1483
// No pre-commit QueryIntents. Nothing to split.
1474
1484
log .VEvent (ctx , 3 , "no pre-commit QueryIntents found, sending batch as-is" )
1475
- return ds .divideAndSendBatchToRanges (ctx , ba , rs , isReverse , true /* withCommit */ , batchIdx )
1485
+ return ds .divideAndSendBatchToRanges (ctx , ba , rs , true /* withCommit */ , batchIdx )
1476
1486
}
1477
1487
1478
1488
// Swap the EndTxn request and the first pre-commit QueryIntent. This
@@ -1499,7 +1509,8 @@ func (ds *DistSender) divideAndSendParallelCommit(
1499
1509
if err != nil {
1500
1510
return br , kvpb .NewError (err )
1501
1511
}
1502
- qiIsReverse := false // QueryIntentRequests do not carry the isReverse flag
1512
+ // No need to process QueryIntentRequests in the reverse order.
1513
+ qiBa .IsReverse = false
1503
1514
qiBatchIdx := batchIdx + 1
1504
1515
qiResponseCh := make (chan response , 1 )
1505
1516
@@ -1525,7 +1536,7 @@ func (ds *DistSender) divideAndSendParallelCommit(
1525
1536
1526
1537
// Send the batch with withCommit=true since it will be inflight
1527
1538
// concurrently with the EndTxn batch below.
1528
- reply , pErr := ds .divideAndSendBatchToRanges (ctx , qiBa , qiRS , qiIsReverse , true /* withCommit */ , qiBatchIdx )
1539
+ reply , pErr := ds .divideAndSendBatchToRanges (ctx , qiBa , qiRS , true /* withCommit */ , qiBatchIdx )
1529
1540
qiResponseCh <- response {reply : reply , positions : positions , pErr : pErr }
1530
1541
}
1531
1542
@@ -1556,10 +1567,7 @@ func (ds *DistSender) divideAndSendParallelCommit(
1556
1567
if err != nil {
1557
1568
return nil , kvpb .NewError (err )
1558
1569
}
1559
- // Note that we don't need to recompute isReverse for the updated batch
1560
- // since we only separated out QueryIntentRequests which don't carry the
1561
- // isReverse flag.
1562
- br , pErr = ds .divideAndSendBatchToRanges (ctx , ba , rs , isReverse , true /* withCommit */ , batchIdx )
1570
+ br , pErr = ds .divideAndSendBatchToRanges (ctx , ba , rs , true /* withCommit */ , batchIdx )
1563
1571
1564
1572
// Wait for the QueryIntent-only batch to complete and stitch
1565
1573
// the responses together.
@@ -1728,12 +1736,6 @@ func mergeErrors(pErr1, pErr2 *kvpb.Error) *kvpb.Error {
1728
1736
// is trimmed against each range which is part of the span and sent
1729
1737
// either serially or in parallel, if possible.
1730
1738
//
1731
- // isReverse indicates the direction that the provided span should be
1732
- // iterated over while sending requests. It is passed in by callers
1733
- // instead of being recomputed based on the requests in the batch to
1734
- // prevent the iteration direction from switching midway through a
1735
- // batch, in cases where partial batches recurse into this function.
1736
- //
1737
1739
// withCommit indicates that the batch contains a transaction commit
1738
1740
// or that a transaction commit is being run concurrently with this
1739
1741
// batch. Either way, if this is true then sendToReplicas will need
@@ -1743,12 +1745,7 @@ func mergeErrors(pErr1, pErr2 *kvpb.Error) *kvpb.Error {
1743
1745
// being processed by this method. It's specified as non-zero when
1744
1746
// this method is invoked recursively.
1745
1747
func (ds * DistSender ) divideAndSendBatchToRanges (
1746
- ctx context.Context ,
1747
- ba * kvpb.BatchRequest ,
1748
- rs roachpb.RSpan ,
1749
- isReverse bool ,
1750
- withCommit bool ,
1751
- batchIdx int ,
1748
+ ctx context.Context , ba * kvpb.BatchRequest , rs roachpb.RSpan , withCommit bool , batchIdx int ,
1752
1749
) (br * kvpb.BatchResponse , pErr * kvpb.Error ) {
1753
1750
// Clone the BatchRequest's transaction so that future mutations to the
1754
1751
// proto don't affect the proto in this batch.
@@ -1758,7 +1755,7 @@ func (ds *DistSender) divideAndSendBatchToRanges(
1758
1755
// Get initial seek key depending on direction of iteration.
1759
1756
var scanDir ScanDirection
1760
1757
var seekKey roachpb.RKey
1761
- if ! isReverse {
1758
+ if ! ba . IsReverse {
1762
1759
scanDir = Ascending
1763
1760
seekKey = rs .Key
1764
1761
} else {
@@ -1773,7 +1770,7 @@ func (ds *DistSender) divideAndSendBatchToRanges(
1773
1770
// Take the fast path if this batch fits within a single range.
1774
1771
if ! ri .NeedAnother (rs ) {
1775
1772
resp := ds .sendPartialBatch (
1776
- ctx , ba , rs , isReverse , withCommit , batchIdx , ri .Token (),
1773
+ ctx , ba , rs , withCommit , batchIdx , ri .Token (),
1777
1774
)
1778
1775
// resp.positions remains nil since the original batch is fully
1779
1776
// contained within a single range.
@@ -1895,7 +1892,7 @@ func (ds *DistSender) divideAndSendBatchToRanges(
1895
1892
}
1896
1893
1897
1894
if pErr == nil && couldHaveSkippedResponses {
1898
- fillSkippedResponses (ba , br , seekKey , resumeReason , isReverse )
1895
+ fillSkippedResponses (ba , br , seekKey , resumeReason )
1899
1896
}
1900
1897
}()
1901
1898
@@ -1975,7 +1972,7 @@ func (ds *DistSender) divideAndSendBatchToRanges(
1975
1972
// If we can reserve one of the limited goroutines available for parallel
1976
1973
// batch RPCs, send asynchronously.
1977
1974
if canParallelize && ! lastRange && ! ds .disableParallelBatches {
1978
- if ds .sendPartialBatchAsync (ctx , curRangeBatch , curRangeRS , isReverse , withCommit , batchIdx , ri .Token (), responseCh , positions ) {
1975
+ if ds .sendPartialBatchAsync (ctx , curRangeBatch , curRangeRS , withCommit , batchIdx , ri .Token (), responseCh , positions ) {
1979
1976
asyncSent = true
1980
1977
} else {
1981
1978
asyncThrottled = true
@@ -1990,7 +1987,7 @@ func (ds *DistSender) divideAndSendBatchToRanges(
1990
1987
}()
1991
1988
}
1992
1989
return ds .sendPartialBatch (
1993
- ctx , curRangeBatch , curRangeRS , isReverse , withCommit , batchIdx , ri .Token (),
1990
+ ctx , curRangeBatch , curRangeRS , withCommit , batchIdx , ri .Token (),
1994
1991
)
1995
1992
}()
1996
1993
resp .positions = positions
@@ -2077,7 +2074,6 @@ func (ds *DistSender) sendPartialBatchAsync(
2077
2074
ctx context.Context ,
2078
2075
ba * kvpb.BatchRequest ,
2079
2076
rs roachpb.RSpan ,
2080
- isReverse bool ,
2081
2077
withCommit bool ,
2082
2078
batchIdx int ,
2083
2079
routing rangecache.EvictionToken ,
@@ -2099,7 +2095,7 @@ func (ds *DistSender) sendPartialBatchAsync(
2099
2095
ds .metrics .AsyncSentCount .Inc (1 )
2100
2096
ds .metrics .AsyncInProgress .Inc (1 )
2101
2097
defer ds .metrics .AsyncInProgress .Dec (1 )
2102
- resp := ds .sendPartialBatch (ctx , ba , rs , isReverse , withCommit , batchIdx , routing )
2098
+ resp := ds .sendPartialBatch (ctx , ba , rs , withCommit , batchIdx , routing )
2103
2099
resp .positions = positions
2104
2100
responseCh <- resp
2105
2101
}(ctx )
@@ -2163,7 +2159,6 @@ func (ds *DistSender) sendPartialBatch(
2163
2159
ctx context.Context ,
2164
2160
ba * kvpb.BatchRequest ,
2165
2161
rs roachpb.RSpan ,
2166
- isReverse bool ,
2167
2162
withCommit bool ,
2168
2163
batchIdx int ,
2169
2164
routingTok rangecache.EvictionToken ,
@@ -2191,7 +2186,7 @@ func (ds *DistSender) sendPartialBatch(
2191
2186
2192
2187
if ! routingTok .Valid () {
2193
2188
var descKey roachpb.RKey
2194
- if isReverse {
2189
+ if ba . IsReverse {
2195
2190
descKey = rs .EndKey
2196
2191
} else {
2197
2192
descKey = rs .Key
@@ -2207,7 +2202,7 @@ func (ds *DistSender) sendPartialBatch(
2207
2202
// replica, while detecting hazardous cases where the follower does
2208
2203
// not have the latest information and the current descriptor did
2209
2204
// not result in a successful send.
2210
- routingTok , err = ds .getRoutingInfo (ctx , descKey , prevTok , isReverse )
2205
+ routingTok , err = ds .getRoutingInfo (ctx , descKey , prevTok , ba . IsReverse )
2211
2206
if err != nil {
2212
2207
log .VErrEventf (ctx , 1 , "range descriptor re-lookup failed: %s" , err )
2213
2208
// We set pErr if we encountered an error getting the descriptor in
@@ -2230,7 +2225,7 @@ func (ds *DistSender) sendPartialBatch(
2230
2225
}
2231
2226
if ! intersection .Equal (rs ) {
2232
2227
log .Eventf (ctx , "range shrunk; sub-dividing the request" )
2233
- reply , pErr = ds .divideAndSendBatchToRanges (ctx , ba , rs , isReverse , withCommit , batchIdx )
2228
+ reply , pErr = ds .divideAndSendBatchToRanges (ctx , ba , rs , withCommit , batchIdx )
2234
2229
return response {reply : reply , pErr : pErr }
2235
2230
}
2236
2231
}
@@ -2332,7 +2327,7 @@ func (ds *DistSender) sendPartialBatch(
2332
2327
// batch here would give a potentially larger response slice
2333
2328
// with unknown mapping to our truncated reply).
2334
2329
log .VEventf (ctx , 1 , "likely split; will resend. Got new descriptors: %s" , tErr .Ranges )
2335
- reply , pErr = ds .divideAndSendBatchToRanges (ctx , ba , rs , isReverse , withCommit , batchIdx )
2330
+ reply , pErr = ds .divideAndSendBatchToRanges (ctx , ba , rs , withCommit , batchIdx )
2336
2331
return response {reply : reply , pErr : pErr }
2337
2332
}
2338
2333
break
@@ -2381,7 +2376,6 @@ func fillSkippedResponses(
2381
2376
br * kvpb.BatchResponse ,
2382
2377
nextKey roachpb.RKey ,
2383
2378
resumeReason kvpb.ResumeReason ,
2384
- isReverse bool ,
2385
2379
) {
2386
2380
// Some requests might have no response at all if we used a batch-wide
2387
2381
// limit; simply create trivial responses for those. Note that any type
@@ -2411,7 +2405,7 @@ func fillSkippedResponses(
2411
2405
for i , resp := range br .Responses {
2412
2406
req := ba .Requests [i ].GetInner ()
2413
2407
hdr := resp .GetInner ().Header ()
2414
- maybeSetResumeSpan (req , & hdr , nextKey , isReverse )
2408
+ maybeSetResumeSpan (req , & hdr , nextKey , ba . IsReverse )
2415
2409
if hdr .ResumeSpan != nil {
2416
2410
hdr .ResumeReason = resumeReason
2417
2411
}
0 commit comments