@@ -1069,35 +1069,46 @@ func (ds *DistSender) initAndVerifyBatch(ctx context.Context, ba *kvpb.BatchRequ
1069
1069
return kvpb .NewErrorf ("empty batch" )
1070
1070
}
1071
1071
1072
- if ba .MaxSpanRequestKeys != 0 || ba .TargetBytes != 0 {
1073
- // Verify that the batch contains only specific requests. Verify that a
1074
- // batch with a ReverseScan only contains ReverseScan range requests.
1075
- var foundForward , foundReverse bool
1076
- for _ , req := range ba .Requests {
1077
- inner := req .GetInner ()
1078
- switch inner .(type ) {
1079
- case * kvpb.ScanRequest , * kvpb.ResolveIntentRangeRequest ,
1080
- * kvpb.DeleteRangeRequest , * kvpb.RevertRangeRequest ,
1081
- * kvpb.ExportRequest , * kvpb.QueryLocksRequest , * kvpb.IsSpanEmptyRequest :
1082
- // Accepted forward range requests.
1083
- foundForward = true
1072
+ // Verify that forward and reverse range requests are never in the same
1073
+ // batch. Also verify that the batch with limits contains only specific
1074
+ // requests.
1075
+ var foundForward , foundReverse bool
1076
+ var disallowedReq string
1077
+ for _ , req := range ba .Requests {
1078
+ inner := req .GetInner ()
1079
+ switch inner .(type ) {
1080
+ case * kvpb.ScanRequest , * kvpb.ResolveIntentRangeRequest ,
1081
+ * kvpb.DeleteRangeRequest , * kvpb.RevertRangeRequest ,
1082
+ * kvpb.ExportRequest , * kvpb.QueryLocksRequest , * kvpb.IsSpanEmptyRequest :
1083
+ // Accepted forward range requests.
1084
+ foundForward = true
1084
1085
1085
- case * kvpb.ReverseScanRequest :
1086
- // Accepted reverse range requests.
1087
- foundReverse = true
1086
+ case * kvpb.ReverseScanRequest :
1087
+ // Accepted reverse range requests.
1088
+ foundReverse = true
1088
1089
1089
- case * kvpb.QueryIntentRequest , * kvpb.EndTxnRequest ,
1090
- * kvpb.GetRequest , * kvpb.ResolveIntentRequest , * kvpb.DeleteRequest , * kvpb.PutRequest :
1091
- // Accepted point requests that can be in batches with limit.
1090
+ case * kvpb.QueryIntentRequest , * kvpb.EndTxnRequest ,
1091
+ * kvpb.GetRequest , * kvpb.ResolveIntentRequest , * kvpb.DeleteRequest , * kvpb.PutRequest :
1092
+ // Accepted point requests that can be in batches with limit. No
1093
+ // need to set disallowedReq.
1092
1094
1093
- default :
1094
- return kvpb .NewErrorf ("batch with limit contains %s request" , inner .Method ())
1095
- }
1096
- }
1097
- if foundForward && foundReverse {
1098
- return kvpb .NewErrorf ("batch with limit contains both forward and reverse scans" )
1095
+ default :
1096
+ disallowedReq = inner .Method ().String ()
1099
1097
}
1100
1098
}
1099
+ if foundForward && foundReverse {
1100
+ return kvpb .NewErrorf ("batch contains both forward and reverse requests" )
1101
+ }
1102
+ if (ba .MaxSpanRequestKeys != 0 || ba .TargetBytes != 0 ) && disallowedReq != "" {
1103
+ return kvpb .NewErrorf ("batch with limit contains %s request" , disallowedReq )
1104
+ }
1105
+ // Also verify that IsReverse is set accordingly on the batch header.
1106
+ if foundForward && ba .Header .IsReverse {
1107
+ return kvpb .NewErrorf ("batch contains forward requests but IsReverse is set" )
1108
+ }
1109
+ if foundReverse && ! ba .Header .IsReverse {
1110
+ return kvpb .NewErrorf ("batch contains reverse requests but IsReverse is not set" )
1111
+ }
1101
1112
1102
1113
switch ba .WaitPolicy {
1103
1114
case lock .WaitPolicy_Block , lock .WaitPolicy_Error :
@@ -1239,7 +1250,6 @@ func (ds *DistSender) Send(
1239
1250
if err != nil {
1240
1251
return nil , kvpb .NewError (err )
1241
1252
}
1242
- isReverse := ba .IsReverse ()
1243
1253
1244
1254
// Determine whether this part of the BatchRequest contains a committing
1245
1255
// EndTxn request.
@@ -1253,9 +1263,9 @@ func (ds *DistSender) Send(
1253
1263
var rpl * kvpb.BatchResponse
1254
1264
var pErr * kvpb.Error
1255
1265
if withParallelCommit {
1256
- rpl , pErr = ds .divideAndSendParallelCommit (ctx , ba , rs , isReverse , 0 /* batchIdx */ )
1266
+ rpl , pErr = ds .divideAndSendParallelCommit (ctx , ba , rs , 0 /* batchIdx */ )
1257
1267
} else {
1258
- rpl , pErr = ds .divideAndSendBatchToRanges (ctx , ba , rs , isReverse , withCommit , 0 /* batchIdx */ )
1268
+ rpl , pErr = ds .divideAndSendBatchToRanges (ctx , ba , rs , withCommit , 0 /* batchIdx */ )
1259
1269
}
1260
1270
1261
1271
if pErr == errNo1PCTxn {
@@ -1446,7 +1456,7 @@ type response struct {
1446
1456
// method is never invoked recursively, but it is exposed to maintain symmetry
1447
1457
// with divideAndSendBatchToRanges.
1448
1458
func (ds * DistSender ) divideAndSendParallelCommit (
1449
- ctx context.Context , ba * kvpb.BatchRequest , rs roachpb.RSpan , isReverse bool , batchIdx int ,
1459
+ ctx context.Context , ba * kvpb.BatchRequest , rs roachpb.RSpan , batchIdx int ,
1450
1460
) (br * kvpb.BatchResponse , pErr * kvpb.Error ) {
1451
1461
// Search backwards, looking for the first pre-commit QueryIntent.
1452
1462
swapIdx := - 1
@@ -1462,7 +1472,7 @@ func (ds *DistSender) divideAndSendParallelCommit(
1462
1472
if swapIdx == - 1 {
1463
1473
// No pre-commit QueryIntents. Nothing to split.
1464
1474
log .VEvent (ctx , 3 , "no pre-commit QueryIntents found, sending batch as-is" )
1465
- return ds .divideAndSendBatchToRanges (ctx , ba , rs , isReverse , true /* withCommit */ , batchIdx )
1475
+ return ds .divideAndSendBatchToRanges (ctx , ba , rs , true /* withCommit */ , batchIdx )
1466
1476
}
1467
1477
1468
1478
// Swap the EndTxn request and the first pre-commit QueryIntent. This
@@ -1489,7 +1499,8 @@ func (ds *DistSender) divideAndSendParallelCommit(
1489
1499
if err != nil {
1490
1500
return br , kvpb .NewError (err )
1491
1501
}
1492
- qiIsReverse := false // QueryIntentRequests do not carry the isReverse flag
1502
+ // No need to process QueryIntentRequests in the reverse order.
1503
+ qiBa .IsReverse = false
1493
1504
qiBatchIdx := batchIdx + 1
1494
1505
qiResponseCh := make (chan response , 1 )
1495
1506
@@ -1519,7 +1530,7 @@ func (ds *DistSender) divideAndSendParallelCommit(
1519
1530
1520
1531
// Send the batch with withCommit=true since it will be inflight
1521
1532
// concurrently with the EndTxn batch below.
1522
- reply , pErr := ds .divideAndSendBatchToRanges (ctx , qiBa , qiRS , qiIsReverse , true /* withCommit */ , qiBatchIdx )
1533
+ reply , pErr := ds .divideAndSendBatchToRanges (ctx , qiBa , qiRS , true /* withCommit */ , qiBatchIdx )
1523
1534
qiResponseCh <- response {reply : reply , positions : positions , pErr : pErr }
1524
1535
}); err != nil {
1525
1536
return nil , kvpb .NewError (err )
@@ -1534,10 +1545,7 @@ func (ds *DistSender) divideAndSendParallelCommit(
1534
1545
if err != nil {
1535
1546
return nil , kvpb .NewError (err )
1536
1547
}
1537
- // Note that we don't need to recompute isReverse for the updated batch
1538
- // since we only separated out QueryIntentRequests which don't carry the
1539
- // isReverse flag.
1540
- br , pErr = ds .divideAndSendBatchToRanges (ctx , ba , rs , isReverse , true /* withCommit */ , batchIdx )
1548
+ br , pErr = ds .divideAndSendBatchToRanges (ctx , ba , rs , true /* withCommit */ , batchIdx )
1541
1549
1542
1550
// Wait for the QueryIntent-only batch to complete and stitch
1543
1551
// the responses together.
@@ -1706,12 +1714,6 @@ func mergeErrors(pErr1, pErr2 *kvpb.Error) *kvpb.Error {
1706
1714
// is trimmed against each range which is part of the span and sent
1707
1715
// either serially or in parallel, if possible.
1708
1716
//
1709
- // isReverse indicates the direction that the provided span should be
1710
- // iterated over while sending requests. It is passed in by callers
1711
- // instead of being recomputed based on the requests in the batch to
1712
- // prevent the iteration direction from switching midway through a
1713
- // batch, in cases where partial batches recurse into this function.
1714
- //
1715
1717
// withCommit indicates that the batch contains a transaction commit
1716
1718
// or that a transaction commit is being run concurrently with this
1717
1719
// batch. Either way, if this is true then sendToReplicas will need
@@ -1721,12 +1723,7 @@ func mergeErrors(pErr1, pErr2 *kvpb.Error) *kvpb.Error {
1721
1723
// being processed by this method. It's specified as non-zero when
1722
1724
// this method is invoked recursively.
1723
1725
func (ds * DistSender ) divideAndSendBatchToRanges (
1724
- ctx context.Context ,
1725
- ba * kvpb.BatchRequest ,
1726
- rs roachpb.RSpan ,
1727
- isReverse bool ,
1728
- withCommit bool ,
1729
- batchIdx int ,
1726
+ ctx context.Context , ba * kvpb.BatchRequest , rs roachpb.RSpan , withCommit bool , batchIdx int ,
1730
1727
) (br * kvpb.BatchResponse , pErr * kvpb.Error ) {
1731
1728
// Clone the BatchRequest's transaction so that future mutations to the
1732
1729
// proto don't affect the proto in this batch.
@@ -1736,7 +1733,7 @@ func (ds *DistSender) divideAndSendBatchToRanges(
1736
1733
// Get initial seek key depending on direction of iteration.
1737
1734
var scanDir ScanDirection
1738
1735
var seekKey roachpb.RKey
1739
- if ! isReverse {
1736
+ if ! ba . IsReverse {
1740
1737
scanDir = Ascending
1741
1738
seekKey = rs .Key
1742
1739
} else {
@@ -1751,7 +1748,7 @@ func (ds *DistSender) divideAndSendBatchToRanges(
1751
1748
// Take the fast path if this batch fits within a single range.
1752
1749
if ! ri .NeedAnother (rs ) {
1753
1750
resp := ds .sendPartialBatch (
1754
- ctx , ba , rs , isReverse , withCommit , batchIdx , ri .Token (),
1751
+ ctx , ba , rs , withCommit , batchIdx , ri .Token (),
1755
1752
)
1756
1753
// resp.positions remains nil since the original batch is fully
1757
1754
// contained within a single range.
@@ -1873,7 +1870,7 @@ func (ds *DistSender) divideAndSendBatchToRanges(
1873
1870
}
1874
1871
1875
1872
if pErr == nil && couldHaveSkippedResponses {
1876
- fillSkippedResponses (ba , br , seekKey , resumeReason , isReverse )
1873
+ fillSkippedResponses (ba , br , seekKey , resumeReason )
1877
1874
}
1878
1875
}()
1879
1876
@@ -1953,7 +1950,7 @@ func (ds *DistSender) divideAndSendBatchToRanges(
1953
1950
// If we can reserve one of the limited goroutines available for parallel
1954
1951
// batch RPCs, send asynchronously.
1955
1952
if canParallelize && ! lastRange && ! ds .disableParallelBatches {
1956
- if ds .sendPartialBatchAsync (ctx , curRangeBatch , curRangeRS , isReverse , withCommit , batchIdx , ri .Token (), responseCh , positions ) {
1953
+ if ds .sendPartialBatchAsync (ctx , curRangeBatch , curRangeRS , withCommit , batchIdx , ri .Token (), responseCh , positions ) {
1957
1954
asyncSent = true
1958
1955
} else {
1959
1956
asyncThrottled = true
@@ -1968,7 +1965,7 @@ func (ds *DistSender) divideAndSendBatchToRanges(
1968
1965
}()
1969
1966
}
1970
1967
return ds .sendPartialBatch (
1971
- ctx , curRangeBatch , curRangeRS , isReverse , withCommit , batchIdx , ri .Token (),
1968
+ ctx , curRangeBatch , curRangeRS , withCommit , batchIdx , ri .Token (),
1972
1969
)
1973
1970
}()
1974
1971
resp .positions = positions
@@ -2055,7 +2052,6 @@ func (ds *DistSender) sendPartialBatchAsync(
2055
2052
ctx context.Context ,
2056
2053
ba * kvpb.BatchRequest ,
2057
2054
rs roachpb.RSpan ,
2058
- isReverse bool ,
2059
2055
withCommit bool ,
2060
2056
batchIdx int ,
2061
2057
routing rangecache.EvictionToken ,
@@ -2074,7 +2070,7 @@ func (ds *DistSender) sendPartialBatchAsync(
2074
2070
ds .metrics .AsyncSentCount .Inc (1 )
2075
2071
ds .metrics .AsyncInProgress .Inc (1 )
2076
2072
defer ds .metrics .AsyncInProgress .Dec (1 )
2077
- resp := ds .sendPartialBatch (ctx , ba , rs , isReverse , withCommit , batchIdx , routing )
2073
+ resp := ds .sendPartialBatch (ctx , ba , rs , withCommit , batchIdx , routing )
2078
2074
resp .positions = positions
2079
2075
responseCh <- resp
2080
2076
},
@@ -2142,7 +2138,6 @@ func (ds *DistSender) sendPartialBatch(
2142
2138
ctx context.Context ,
2143
2139
ba * kvpb.BatchRequest ,
2144
2140
rs roachpb.RSpan ,
2145
- isReverse bool ,
2146
2141
withCommit bool ,
2147
2142
batchIdx int ,
2148
2143
routingTok rangecache.EvictionToken ,
@@ -2170,7 +2165,7 @@ func (ds *DistSender) sendPartialBatch(
2170
2165
2171
2166
if ! routingTok .Valid () {
2172
2167
var descKey roachpb.RKey
2173
- if isReverse {
2168
+ if ba . IsReverse {
2174
2169
descKey = rs .EndKey
2175
2170
} else {
2176
2171
descKey = rs .Key
@@ -2186,7 +2181,7 @@ func (ds *DistSender) sendPartialBatch(
2186
2181
// replica, while detecting hazardous cases where the follower does
2187
2182
// not have the latest information and the current descriptor did
2188
2183
// not result in a successful send.
2189
- routingTok , err = ds .getRoutingInfo (ctx , descKey , prevTok , isReverse )
2184
+ routingTok , err = ds .getRoutingInfo (ctx , descKey , prevTok , ba . IsReverse )
2190
2185
if err != nil {
2191
2186
log .VErrEventf (ctx , 1 , "range descriptor re-lookup failed: %s" , err )
2192
2187
// We set pErr if we encountered an error getting the descriptor in
@@ -2209,7 +2204,7 @@ func (ds *DistSender) sendPartialBatch(
2209
2204
}
2210
2205
if ! intersection .Equal (rs ) {
2211
2206
log .Eventf (ctx , "range shrunk; sub-dividing the request" )
2212
- reply , pErr = ds .divideAndSendBatchToRanges (ctx , ba , rs , isReverse , withCommit , batchIdx )
2207
+ reply , pErr = ds .divideAndSendBatchToRanges (ctx , ba , rs , withCommit , batchIdx )
2213
2208
return response {reply : reply , pErr : pErr }
2214
2209
}
2215
2210
}
@@ -2311,7 +2306,7 @@ func (ds *DistSender) sendPartialBatch(
2311
2306
// batch here would give a potentially larger response slice
2312
2307
// with unknown mapping to our truncated reply).
2313
2308
log .VEventf (ctx , 1 , "likely split; will resend. Got new descriptors: %s" , tErr .Ranges )
2314
- reply , pErr = ds .divideAndSendBatchToRanges (ctx , ba , rs , isReverse , withCommit , batchIdx )
2309
+ reply , pErr = ds .divideAndSendBatchToRanges (ctx , ba , rs , withCommit , batchIdx )
2315
2310
return response {reply : reply , pErr : pErr }
2316
2311
}
2317
2312
break
@@ -2360,7 +2355,6 @@ func fillSkippedResponses(
2360
2355
br * kvpb.BatchResponse ,
2361
2356
nextKey roachpb.RKey ,
2362
2357
resumeReason kvpb.ResumeReason ,
2363
- isReverse bool ,
2364
2358
) {
2365
2359
// Some requests might have no response at all if we used a batch-wide
2366
2360
// limit; simply create trivial responses for those. Note that any type
@@ -2390,7 +2384,7 @@ func fillSkippedResponses(
2390
2384
for i , resp := range br .Responses {
2391
2385
req := ba .Requests [i ].GetInner ()
2392
2386
hdr := resp .GetInner ().Header ()
2393
- maybeSetResumeSpan (req , & hdr , nextKey , isReverse )
2387
+ maybeSetResumeSpan (req , & hdr , nextKey , ba . IsReverse )
2394
2388
if hdr .ResumeSpan != nil {
2395
2389
hdr .ResumeReason = resumeReason
2396
2390
}
0 commit comments