Skip to content

Commit

Permalink
storage,kv: faster intent resolution over a key range
Browse files Browse the repository at this point in the history
When all the intents on a range are known to be separated,
as indicated by MCCStats, and a ResolveIntentRangeRequest
needs to be processed (for a transaction that did enough
writes that we did not track individual intent keys), we
avoid iterating over MVCC key-value pairs to find those
intents, and instead iterate over the separated lock table
key space.

A new iterForKeyVersions interface is introduced which
provides a narrow iterator interface to be used by
mvccResolveWriteIntent that resolves individual intents.
This interface is only for iterating over a single key,
and is implemented by the usual MVCCIterator and by the
new separatedIntentAndVersionIter. The latter serves
both as a way to find intents over a range and for
individual intent resolution, in an optimized manner.

There are new benchmarks which vary the sparseness
(sparseness of N means that 1 of every N key has an
intent that is for the txn for which intent resolution
is being performed) and whether the remaining N-1 keys
have an intent from a different transaction
(other-txn-intents=true) or not (the former results
in the cost of at least parsing the MVCCMetadata to
compare txn IDs).

Full results are below. Two things to note are:
- The percent-flushed={0,50} sometimes show a regression.
  These are atypical cases where the SingleDelete to
  remove the intent has not been flushed so the intent
  Set and SingleDelete are both alive. This would be
  a pathalogical case when the LSM is unhealthy. Even
  then the regression is < 170%.
- The percent-flushed=100 cases are the typical one.
  Once sparseness increases to 100 or 1000 we see speed
  gains close to 100x, as indicated by the following:

IntentRangeResolution/separated=true/versions=10/sparseness=1/other-txn-intents=false/percent-flushed=100-16        235µs ± 2%      58µs ± 3%   -75.52%  (p=0.008 n=5+5)
IntentRangeResolution/separated=true/versions=10/sparseness=100/other-txn-intents=false/percent-flushed=100-16      154µs ± 2%       2µs ± 4%   -98.72%  (p=0.008 n=5+5)
IntentRangeResolution/separated=true/versions=10/sparseness=1000/other-txn-intents=false/percent-flushed=100-16     137µs ± 1%       1µs ± 2%   -99.07%  (p=0.008 n=5+5)

Full results:
name                                                                                                             old time/op    new time/op    delta
IntentRangeResolution/separated=true/versions=10/sparseness=1/other-txn-intents=false/percent-flushed=0-16          450µs ± 5%     234µs ± 2%   -48.07%  (p=0.008 n=5+5)
IntentRangeResolution/separated=true/versions=10/sparseness=1/other-txn-intents=false/percent-flushed=50-16         294µs ± 3%     101µs ± 4%   -65.49%  (p=0.008 n=5+5)
IntentRangeResolution/separated=true/versions=10/sparseness=1/other-txn-intents=false/percent-flushed=100-16        235µs ± 2%      58µs ± 3%   -75.52%  (p=0.008 n=5+5)
IntentRangeResolution/separated=true/versions=10/sparseness=100/other-txn-intents=false/percent-flushed=0-16        494µs ± 7%     218µs ± 6%   -55.84%  (p=0.008 n=5+5)
IntentRangeResolution/separated=true/versions=10/sparseness=100/other-txn-intents=false/percent-flushed=50-16       251µs ± 2%      57µs ± 3%   -77.29%  (p=0.008 n=5+5)
IntentRangeResolution/separated=true/versions=10/sparseness=100/other-txn-intents=false/percent-flushed=100-16      154µs ± 2%       2µs ± 4%   -98.72%  (p=0.008 n=5+5)
IntentRangeResolution/separated=true/versions=10/sparseness=100/other-txn-intents=true/percent-flushed=0-16         343µs ± 5%     236µs ± 2%   -31.28%  (p=0.008 n=5+5)
IntentRangeResolution/separated=true/versions=10/sparseness=100/other-txn-intents=true/percent-flushed=50-16        240µs ± 1%      74µs ± 2%   -69.02%  (p=0.008 n=5+5)
IntentRangeResolution/separated=true/versions=10/sparseness=100/other-txn-intents=true/percent-flushed=100-16       203µs ± 1%      30µs ± 1%   -84.97%  (p=0.008 n=5+5)
IntentRangeResolution/separated=true/versions=10/sparseness=1000/other-txn-intents=false/percent-flushed=0-16       516µs ± 4%     274µs ±13%   -46.91%  (p=0.008 n=5+5)
IntentRangeResolution/separated=true/versions=10/sparseness=1000/other-txn-intents=false/percent-flushed=50-16      256µs ± 2%      57µs ± 1%   -77.67%  (p=0.016 n=4+5)
IntentRangeResolution/separated=true/versions=10/sparseness=1000/other-txn-intents=false/percent-flushed=100-16     137µs ± 1%       1µs ± 2%   -99.07%  (p=0.008 n=5+5)
IntentRangeResolution/separated=true/versions=10/sparseness=1000/other-txn-intents=true/percent-flushed=0-16        325µs ± 2%     237µs ± 1%   -26.98%  (p=0.008 n=5+5)
IntentRangeResolution/separated=true/versions=10/sparseness=1000/other-txn-intents=true/percent-flushed=50-16       232µs ± 4%      72µs ± 1%   -68.89%  (p=0.008 n=5+5)
IntentRangeResolution/separated=true/versions=10/sparseness=1000/other-txn-intents=true/percent-flushed=100-16      199µs ± 1%      30µs ± 0%   -84.87%  (p=0.016 n=5+4)
IntentRangeResolution/separated=true/versions=100/sparseness=1/other-txn-intents=false/percent-flushed=0-16        2.08ms ± 1%    2.68ms ± 8%   +28.57%  (p=0.016 n=4+5)
IntentRangeResolution/separated=true/versions=100/sparseness=1/other-txn-intents=false/percent-flushed=50-16        592µs ± 4%     596µs ± 7%      ~     (p=1.000 n=5+5)
IntentRangeResolution/separated=true/versions=100/sparseness=1/other-txn-intents=false/percent-flushed=100-16       242µs ± 2%      59µs ± 3%   -75.73%  (p=0.016 n=4+5)
IntentRangeResolution/separated=true/versions=100/sparseness=100/other-txn-intents=false/percent-flushed=0-16      3.04ms ± 5%    2.60ms ± 3%   -14.59%  (p=0.008 n=5+5)
IntentRangeResolution/separated=true/versions=100/sparseness=100/other-txn-intents=false/percent-flushed=50-16      840µs ± 4%     539µs ± 3%   -35.87%  (p=0.008 n=5+5)
IntentRangeResolution/separated=true/versions=100/sparseness=100/other-txn-intents=false/percent-flushed=100-16     163µs ± 6%       2µs ± 6%   -98.75%  (p=0.008 n=5+5)
IntentRangeResolution/separated=true/versions=100/sparseness=100/other-txn-intents=true/percent-flushed=0-16        936µs ±38%    2497µs ±12%  +166.83%  (p=0.008 n=5+5)
IntentRangeResolution/separated=true/versions=100/sparseness=100/other-txn-intents=true/percent-flushed=50-16       281µs ±12%     551µs ± 2%   +95.64%  (p=0.008 n=5+5)
IntentRangeResolution/separated=true/versions=100/sparseness=100/other-txn-intents=true/percent-flushed=100-16      209µs ±13%      31µs ± 9%   -84.95%  (p=0.008 n=5+5)
IntentRangeResolution/separated=true/versions=100/sparseness=1000/other-txn-intents=false/percent-flushed=0-16     3.04ms ± 6%    2.55ms ± 0%      ~     (p=0.333 n=5+1)

name                                                                                                             old alloc/op   new alloc/op   delta
IntentRangeResolution/separated=true/versions=10/sparseness=1/other-txn-intents=false/percent-flushed=0-16         12.8kB ± 0%    13.0kB ± 0%    +0.92%  (p=0.008 n=5+5)
IntentRangeResolution/separated=true/versions=10/sparseness=1/other-txn-intents=false/percent-flushed=50-16        12.8kB ± 0%    13.0kB ± 0%    +0.94%  (p=0.016 n=5+4)
IntentRangeResolution/separated=true/versions=10/sparseness=1/other-txn-intents=false/percent-flushed=100-16       12.9kB ± 0%    13.0kB ± 0%    +0.59%  (p=0.016 n=5+4)
IntentRangeResolution/separated=true/versions=10/sparseness=100/other-txn-intents=false/percent-flushed=0-16       1.75kB ± 0%    0.29kB ± 0%      ~     (p=0.079 n=4+5)
IntentRangeResolution/separated=true/versions=10/sparseness=100/other-txn-intents=false/percent-flushed=50-16      1.75kB ± 0%    0.29kB ± 0%   -83.18%  (p=0.008 n=5+5)
IntentRangeResolution/separated=true/versions=10/sparseness=100/other-txn-intents=false/percent-flushed=100-16     1.75kB ± 0%    0.29kB ± 0%   -83.22%  (p=0.008 n=5+5)
IntentRangeResolution/separated=true/versions=10/sparseness=100/other-txn-intents=true/percent-flushed=0-16        12.8kB ± 0%    11.4kB ± 0%   -11.37%  (p=0.008 n=5+5)
IntentRangeResolution/separated=true/versions=10/sparseness=100/other-txn-intents=true/percent-flushed=50-16       12.8kB ± 0%    11.4kB ± 0%      ~     (p=0.079 n=4+5)
IntentRangeResolution/separated=true/versions=10/sparseness=100/other-txn-intents=true/percent-flushed=100-16      12.8kB ± 0%    11.4kB ± 0%   -11.41%  (p=0.000 n=5+4)
IntentRangeResolution/separated=true/versions=10/sparseness=1000/other-txn-intents=false/percent-flushed=0-16      1.66kB ± 0%    0.17kB ± 0%   -89.61%  (p=0.008 n=5+5)
IntentRangeResolution/separated=true/versions=10/sparseness=1000/other-txn-intents=false/percent-flushed=50-16     1.66kB ± 0%    0.17kB ± 0%   -89.61%  (p=0.008 n=5+5)
IntentRangeResolution/separated=true/versions=10/sparseness=1000/other-txn-intents=false/percent-flushed=100-16    1.66kB ± 0%    0.17kB ± 0%   -89.63%  (p=0.008 n=5+5)
IntentRangeResolution/separated=true/versions=10/sparseness=1000/other-txn-intents=true/percent-flushed=0-16       12.8kB ± 0%    11.4kB ± 0%   -11.50%  (p=0.008 n=5+5)
IntentRangeResolution/separated=true/versions=10/sparseness=1000/other-txn-intents=true/percent-flushed=50-16      12.8kB ± 0%    11.4kB ± 0%      ~     (p=0.079 n=4+5)
IntentRangeResolution/separated=true/versions=10/sparseness=1000/other-txn-intents=true/percent-flushed=100-16     12.8kB ± 0%    11.4kB ± 0%   -11.53%  (p=0.029 n=4+4)
IntentRangeResolution/separated=true/versions=100/sparseness=1/other-txn-intents=false/percent-flushed=0-16        12.8kB ± 0%    13.0kB ± 0%    +0.95%  (p=0.016 n=5+4)
IntentRangeResolution/separated=true/versions=100/sparseness=1/other-txn-intents=false/percent-flushed=50-16       12.8kB ± 0%    13.0kB ± 0%    +0.95%  (p=0.008 n=5+5)
IntentRangeResolution/separated=true/versions=100/sparseness=1/other-txn-intents=false/percent-flushed=100-16      12.9kB ± 0%    13.0kB ± 0%    +0.54%  (p=0.016 n=5+4)
IntentRangeResolution/separated=true/versions=100/sparseness=100/other-txn-intents=false/percent-flushed=0-16      1.75kB ± 0%    0.29kB ± 0%   -83.14%  (p=0.008 n=5+5)
IntentRangeResolution/separated=true/versions=100/sparseness=100/other-txn-intents=false/percent-flushed=50-16     1.75kB ± 0%    0.29kB ± 0%   -83.19%  (p=0.008 n=5+5)
IntentRangeResolution/separated=true/versions=100/sparseness=100/other-txn-intents=false/percent-flushed=100-16    1.75kB ± 0%    0.29kB ± 0%   -83.22%  (p=0.008 n=5+5)
IntentRangeResolution/separated=true/versions=100/sparseness=100/other-txn-intents=true/percent-flushed=0-16       12.8kB ± 0%    11.4kB ± 0%   -11.37%  (p=0.000 n=5+4)
IntentRangeResolution/separated=true/versions=100/sparseness=100/other-txn-intents=true/percent-flushed=50-16      12.8kB ± 0%    11.4kB ± 0%   -11.37%  (p=0.008 n=5+5)
IntentRangeResolution/separated=true/versions=100/sparseness=100/other-txn-intents=true/percent-flushed=100-16     12.8kB ± 0%    11.4kB ± 0%   -11.41%  (p=0.000 n=5+4)
IntentRangeResolution/separated=true/versions=100/sparseness=1000/other-txn-intents=false/percent-flushed=0-16     1.66kB ± 0%    0.17kB ± 0%   -89.56%  (p=0.000 n=5+1)

name                                                                                                             old allocs/op  new allocs/op  delta
IntentRangeResolution/separated=true/versions=10/sparseness=1/other-txn-intents=false/percent-flushed=0-16            401 ± 0%       404 ± 0%    +0.75%  (p=0.008 n=5+5)
IntentRangeResolution/separated=true/versions=10/sparseness=1/other-txn-intents=false/percent-flushed=50-16           401 ± 0%       404 ± 0%    +0.75%  (p=0.008 n=5+5)
IntentRangeResolution/separated=true/versions=10/sparseness=1/other-txn-intents=false/percent-flushed=100-16          401 ± 0%       404 ± 0%    +0.75%  (p=0.008 n=5+5)
IntentRangeResolution/separated=true/versions=10/sparseness=100/other-txn-intents=false/percent-flushed=0-16          104 ± 0%         8 ± 0%   -92.31%  (p=0.008 n=5+5)
IntentRangeResolution/separated=true/versions=10/sparseness=100/other-txn-intents=false/percent-flushed=50-16         104 ± 0%         8 ± 0%   -92.31%  (p=0.008 n=5+5)
IntentRangeResolution/separated=true/versions=10/sparseness=100/other-txn-intents=false/percent-flushed=100-16        104 ± 0%         8 ± 0%   -92.31%  (p=0.008 n=5+5)
IntentRangeResolution/separated=true/versions=10/sparseness=100/other-txn-intents=true/percent-flushed=0-16           401 ± 0%       305 ± 0%   -23.94%  (p=0.008 n=5+5)
IntentRangeResolution/separated=true/versions=10/sparseness=100/other-txn-intents=true/percent-flushed=50-16          401 ± 0%       305 ± 0%   -23.94%  (p=0.008 n=5+5)
IntentRangeResolution/separated=true/versions=10/sparseness=100/other-txn-intents=true/percent-flushed=100-16         401 ± 0%       305 ± 0%   -23.94%  (p=0.008 n=5+5)
IntentRangeResolution/separated=true/versions=10/sparseness=1000/other-txn-intents=false/percent-flushed=0-16         102 ± 0%         3 ± 0%   -97.06%  (p=0.008 n=5+5)
IntentRangeResolution/separated=true/versions=10/sparseness=1000/other-txn-intents=false/percent-flushed=50-16        102 ± 0%         3 ± 0%   -97.06%  (p=0.008 n=5+5)
IntentRangeResolution/separated=true/versions=10/sparseness=1000/other-txn-intents=false/percent-flushed=100-16       102 ± 0%         3 ± 0%   -97.06%  (p=0.008 n=5+5)
IntentRangeResolution/separated=true/versions=10/sparseness=1000/other-txn-intents=true/percent-flushed=0-16          401 ± 0%       303 ± 0%   -24.44%  (p=0.008 n=5+5)
IntentRangeResolution/separated=true/versions=10/sparseness=1000/other-txn-intents=true/percent-flushed=50-16         401 ± 0%       303 ± 0%   -24.44%  (p=0.008 n=5+5)
IntentRangeResolution/separated=true/versions=10/sparseness=1000/other-txn-intents=true/percent-flushed=100-16        401 ± 0%       303 ± 0%   -24.44%  (p=0.008 n=5+5)
IntentRangeResolution/separated=true/versions=100/sparseness=1/other-txn-intents=false/percent-flushed=0-16           401 ± 0%       404 ± 0%    +0.75%  (p=0.008 n=5+5)
IntentRangeResolution/separated=true/versions=100/sparseness=1/other-txn-intents=false/percent-flushed=50-16          401 ± 0%       404 ± 0%    +0.75%  (p=0.008 n=5+5)
IntentRangeResolution/separated=true/versions=100/sparseness=1/other-txn-intents=false/percent-flushed=100-16         401 ± 0%       404 ± 0%    +0.75%  (p=0.008 n=5+5)
IntentRangeResolution/separated=true/versions=100/sparseness=100/other-txn-intents=false/percent-flushed=0-16         104 ± 0%         8 ± 0%   -92.31%  (p=0.008 n=5+5)
IntentRangeResolution/separated=true/versions=100/sparseness=100/other-txn-intents=false/percent-flushed=50-16        104 ± 0%         8 ± 0%   -92.31%  (p=0.008 n=5+5)
IntentRangeResolution/separated=true/versions=100/sparseness=100/other-txn-intents=false/percent-flushed=100-16       104 ± 0%         8 ± 0%   -92.31%  (p=0.008 n=5+5)
IntentRangeResolution/separated=true/versions=100/sparseness=100/other-txn-intents=true/percent-flushed=0-16          401 ± 0%       305 ± 0%   -23.94%  (p=0.008 n=5+5)
IntentRangeResolution/separated=true/versions=100/sparseness=100/other-txn-intents=true/percent-flushed=50-16         401 ± 0%       305 ± 0%   -23.94%  (p=0.008 n=5+5)
IntentRangeResolution/separated=true/versions=100/sparseness=100/other-txn-intents=true/percent-flushed=100-16        401 ± 0%       305 ± 0%   -23.94%  (p=0.008 n=5+5)
IntentRangeResolution/separated=true/versions=100/sparseness=1000/other-txn-intents=false/percent-flushed=0-16        102 ± 0%         3 ± 0%   -97.06%  (p=0.000 n=5+1)

Release note (performance improvement): Intent resolution for transactions
that write many intents such that we track intent ranges, for the purpose
of intent resolution, is much faster (potentially 100x) when using the
separated lock table.
  • Loading branch information
sumeerbhola committed Jun 10, 2021
1 parent 4fb18c8 commit 4d09f18
Show file tree
Hide file tree
Showing 8 changed files with 403 additions and 97 deletions.
2 changes: 1 addition & 1 deletion pkg/kv/kvserver/batch_spanset_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -543,7 +543,7 @@ func TestSpanSetMVCCResolveWriteIntentRange(t *testing.T) {
Status: roachpb.PENDING,
}
if _, _, err := storage.MVCCResolveWriteIntentRange(
ctx, batch, nil /* ms */, intent, 0,
ctx, batch, nil /* ms */, intent, 0, false,
); err != nil {
t.Fatal(err)
}
Expand Down
3 changes: 2 additions & 1 deletion pkg/kv/kvserver/batcheval/cmd_end_transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -492,8 +492,9 @@ func resolveLocalLocks(
externalLocks = append(externalLocks, outSpans...)
if inSpan != nil {
update.Span = *inSpan
// TODO: don't hardwire onlySeparatedIntents=false
num, resumeSpan, err := storage.MVCCResolveWriteIntentRange(
ctx, readWriter, ms, update, resolveAllowance)
ctx, readWriter, ms, update, resolveAllowance, false)
if err != nil {
return err
}
Expand Down
11 changes: 10 additions & 1 deletion pkg/kv/kvserver/batcheval/cmd_resolve_intent_range.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,17 @@ func ResolveIntentRange(

update := args.AsLockUpdate()

onlySeparatedIntents := false
stats := cArgs.EvalCtx.GetMVCCStats()
if stats.ContainsEstimates == 0 && stats.IntentCount == stats.SeparatedIntentCount {
// Stats incorrectness manifested as there being non-zero interleaved
// intents, can leave unresolved interleaved intents for a committed
// transaction whose transaction record is garbage collected (which would
// cause those intents to be incorrectly rolled back).
onlySeparatedIntents = true
}
numKeys, resumeSpan, err := storage.MVCCResolveWriteIntentRange(
ctx, readWriter, ms, update, h.MaxSpanRequestKeys)
ctx, readWriter, ms, update, h.MaxSpanRequestKeys, onlySeparatedIntents)
if err != nil {
return result.Result{}, err
}
Expand Down
188 changes: 132 additions & 56 deletions pkg/storage/bench_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,19 +144,34 @@ func BenchmarkExportToSst(b *testing.B) {
const numIntentKeys = 1000

func setupKeysWithIntent(
b *testing.B, eng Engine, numVersions int, numFlushedVersions int, resolveAll bool,
b *testing.B,
eng Engine,
numVersions int,
numFlushedVersions int,
resolveAll bool,
lockUpdateTxnHasLatestVersionStride int,
resolveIntentForLatestVersionWhenNonLockUpdateTxn bool,
) roachpb.LockUpdate {
txnIDCount := 2 * numVersions
val := []byte("value")
var lockUpdate roachpb.LockUpdate
for i := 1; i <= numVersions; i++ {
adjustTxnID := func(txnID int) int {
// Assign txn IDs in a deterministic way that will mimic the end result of
// random assignment -- the live intent is centered between dead intents,
// when we have separated intents.
txnID := i
if i%2 == 0 {
if txnID%2 == 0 {
txnID = txnIDCount - txnID
}
return txnID
}
txnIDWithLatestVersion := adjustTxnID(numVersions)
otherTxnWithLatestVersion := txnIDCount + 2
otherTxnUUID := uuid.FromUint128(uint128.FromInts(0, uint64(otherTxnWithLatestVersion)))
val := []byte("value")
var rvLockUpdate roachpb.LockUpdate
for i := 1; i <= numVersions; i++ {
// Assign txn IDs in a deterministic way that will mimic the end result of
// random assignment -- the live intent is centered between dead intents,
// when we have separated intents.
txnID := adjustTxnID(i)
txnUUID := uuid.FromUint128(uint128.FromInts(0, uint64(txnID)))
ts := hlc.Timestamp{WallTime: int64(i)}
txn := roachpb.Transaction{
Expand All @@ -170,24 +185,62 @@ func setupKeysWithIntent(
ReadTimestamp: ts,
GlobalUncertaintyLimit: ts,
}
lockUpdate := roachpb.LockUpdate{
Txn: txn.TxnMeta,
Status: roachpb.COMMITTED,
}
var otherTxn roachpb.Transaction
var otherLockUpdate roachpb.LockUpdate
if txnID == txnIDWithLatestVersion {
rvLockUpdate = lockUpdate
if lockUpdateTxnHasLatestVersionStride != 1 {
otherTxn = roachpb.Transaction{
TxnMeta: enginepb.TxnMeta{
ID: otherTxnUUID,
Key: []byte("foo"),
WriteTimestamp: ts,
MinTimestamp: ts,
},
Status: roachpb.PENDING,
ReadTimestamp: ts,
GlobalUncertaintyLimit: ts,
}
otherLockUpdate = roachpb.LockUpdate{
Txn: otherTxn.TxnMeta,
Status: roachpb.COMMITTED,
}
}
}
value := roachpb.Value{RawBytes: val}
batch := eng.NewBatch()
for j := 0; j < numIntentKeys; j++ {
putTxn := &txn
if txnID == txnIDWithLatestVersion && j%lockUpdateTxnHasLatestVersionStride != 0 {
putTxn = &otherTxn
}
key := makeKey(nil, j)
require.NoError(b, MVCCPut(context.Background(), batch, nil, key, ts, value, &txn))
require.NoError(b, MVCCPut(context.Background(), batch, nil, key, ts, value, putTxn))
}
require.NoError(b, batch.Commit(true))
batch.Close()
lockUpdate = roachpb.LockUpdate{
Txn: txn.TxnMeta,
Status: roachpb.COMMITTED,
}
if i < numVersions || resolveAll {
if i < numVersions || resolveAll || resolveIntentForLatestVersionWhenNonLockUpdateTxn {
batch := eng.NewBatch()
for j := 0; j < numIntentKeys; j++ {
key := makeKey(nil, j)
lockUpdate.Key = key
found, err := MVCCResolveWriteIntent(context.Background(), batch, nil, lockUpdate)
lu := lockUpdate
latestVersionNonLockUpdateTxn := false
if txnID == txnIDWithLatestVersion && j%lockUpdateTxnHasLatestVersionStride != 0 {
lu = otherLockUpdate
latestVersionNonLockUpdateTxn = true
}
lu.Key = key
if i == numVersions && !resolveAll && !latestVersionNonLockUpdateTxn {
// Only here because of
// resolveIntentForLatestVersionWhenNonLockUpdateTxn, and this key
// is not one that should be resolved.
continue
}
found, err := MVCCResolveWriteIntent(context.Background(), batch, nil, lu)
require.Equal(b, true, found)
require.NoError(b, err)
}
Expand All @@ -198,7 +251,7 @@ func setupKeysWithIntent(
require.NoError(b, eng.Flush())
}
}
return lockUpdate
return rvLockUpdate
}

// BenchmarkIntentScan compares separated and interleaved intents, when
Expand All @@ -216,7 +269,8 @@ func BenchmarkIntentScan(b *testing.B) {
eng := setupMVCCInMemPebbleWithSettings(
b, makeSettingsForSeparatedIntents(false, sep))
numFlushedVersions := (percentFlushed * numVersions) / 100
setupKeysWithIntent(b, eng, numVersions, numFlushedVersions, false /* resolveAll */)
setupKeysWithIntent(b, eng, numVersions, numFlushedVersions, false, /* resolveAll */
1, false /* resolveIntentForLatestVersionWhenNotLockUpdate */)
lower := makeKey(nil, 0)
iter := eng.NewMVCCIterator(MVCCKeyAndIntentsIterKind, IterOptions{
LowerBound: lower,
Expand Down Expand Up @@ -280,7 +334,8 @@ func BenchmarkScanAllIntentsResolved(b *testing.B) {
eng := setupMVCCInMemPebbleWithSettings(
b, makeSettingsForSeparatedIntents(false, sep))
numFlushedVersions := (percentFlushed * numVersions) / 100
setupKeysWithIntent(b, eng, numVersions, numFlushedVersions, true /* resolveAll */)
setupKeysWithIntent(b, eng, numVersions, numFlushedVersions, true, /* resolveAll */
1, false /* resolveIntentForLatestVersionWhenNotLockUpdate */)
lower := makeKey(nil, 0)
var iter MVCCIterator
var buf []byte
Expand Down Expand Up @@ -351,7 +406,8 @@ func BenchmarkScanOneAllIntentsResolved(b *testing.B) {
eng := setupMVCCInMemPebbleWithSettings(
b, makeSettingsForSeparatedIntents(false, sep))
numFlushedVersions := (percentFlushed * numVersions) / 100
setupKeysWithIntent(b, eng, numVersions, numFlushedVersions, true /* resolveAll */)
setupKeysWithIntent(b, eng, numVersions, numFlushedVersions, true, /* resolveAll */
1, false /* resolveIntentForLatestVersionWhenNotLockUpdate */)
lower := makeKey(nil, 0)
upper := makeKey(nil, numIntentKeys)
buf := append([]byte(nil), lower...)
Expand Down Expand Up @@ -403,7 +459,9 @@ func BenchmarkIntentResolution(b *testing.B) {
eng := setupMVCCInMemPebbleWithSettings(
b, makeSettingsForSeparatedIntents(false, sep))
numFlushedVersions := (percentFlushed * numVersions) / 100
lockUpdate := setupKeysWithIntent(b, eng, numVersions, numFlushedVersions, false /* resolveAll */)
lockUpdate := setupKeysWithIntent(b, eng, numVersions, numFlushedVersions,
false /* resolveAll */, 1,
false /* resolveIntentForLatestVersionWhenNotLockUpdate */)
keys := make([]roachpb.Key, numIntentKeys)
for i := range keys {
keys[i] = makeKey(nil, i)
Expand Down Expand Up @@ -440,45 +498,63 @@ func BenchmarkIntentRangeResolution(b *testing.B) {

for _, sep := range []bool{false, true} {
b.Run(fmt.Sprintf("separated=%t", sep), func(b *testing.B) {
for _, numVersions := range []int{10, 100, 200, 400} {
for _, numVersions := range []int{10, 100, 400} {
b.Run(fmt.Sprintf("versions=%d", numVersions), func(b *testing.B) {
for _, percentFlushed := range []int{0, 50, 80, 90, 100} {
b.Run(fmt.Sprintf("percent-flushed=%d", percentFlushed), func(b *testing.B) {
eng := setupMVCCInMemPebbleWithSettings(
b, makeSettingsForSeparatedIntents(false, sep))
numFlushedVersions := (percentFlushed * numVersions) / 100
lockUpdate := setupKeysWithIntent(b, eng, numVersions, numFlushedVersions, false /* resolveAll */)
keys := make([]roachpb.Key, numIntentKeys+1)
for i := range keys {
keys[i] = makeKey(nil, i)
for _, sparseness := range []int{1, 100, 1000} {
b.Run(fmt.Sprintf("sparseness=%d", sparseness), func(b *testing.B) {
otherTxnUnresolvedIntentsCases := []bool{false, true}
if sparseness == 1 {
// Every intent is owned by the main txn.
otherTxnUnresolvedIntentsCases = []bool{false}
}
keys[numIntentKeys] = makeKey(nil, numIntentKeys)
batch := eng.NewBatch()
numKeysPerRange := 100
numRanges := numIntentKeys / numKeysPerRange
b.ResetTimer()
for i := 0; i < b.N; i++ {
if i > 0 && i%numRanges == 0 {
// Wrapped around.
b.StopTimer()
batch.Close()
batch = eng.NewBatch()
b.StartTimer()
}
rangeNum := i % numRanges
lockUpdate.Key = keys[rangeNum*numKeysPerRange]
lockUpdate.EndKey = keys[(rangeNum+1)*numKeysPerRange]
resolved, span, err := MVCCResolveWriteIntentRange(
context.Background(), batch, nil, lockUpdate, 1000 /* max */)
if err != nil {
b.Fatal(err)
}
if resolved != int64(numKeysPerRange) {
b.Fatalf("expected to resolve %d, actual %d", numKeysPerRange, resolved)
}
if span != nil {
b.Fatal("unexpected resume span")
}
for _, haveOtherTxnUnresolvedIntents := range otherTxnUnresolvedIntentsCases {
b.Run(fmt.Sprintf("other-txn-intents=%t", haveOtherTxnUnresolvedIntents), func(b *testing.B) {
for _, percentFlushed := range []int{0, 50, 100} {
b.Run(fmt.Sprintf("percent-flushed=%d", percentFlushed), func(b *testing.B) {
eng := setupMVCCInMemPebbleWithSettings(
b, makeSettingsForSeparatedIntents(false, sep))
numFlushedVersions := (percentFlushed * numVersions) / 100
lockUpdate := setupKeysWithIntent(b, eng, numVersions, numFlushedVersions,
false /* resolveAll */, sparseness, !haveOtherTxnUnresolvedIntents)
keys := make([]roachpb.Key, numIntentKeys+1)
for i := range keys {
keys[i] = makeKey(nil, i)
}
batch := eng.NewBatch()
numKeysPerRange := 100
numRanges := numIntentKeys / numKeysPerRange
var resolvedCount int64
expectedResolvedCount := int64(numIntentKeys / sparseness)
b.ResetTimer()
for i := 0; i < b.N; i++ {
if i > 0 && i%numRanges == 0 {
// Wrapped around.
b.StopTimer()
if resolvedCount != expectedResolvedCount {
b.Fatalf("expected to resolve %d, actual %d",
expectedResolvedCount, resolvedCount)
}
resolvedCount = 0
batch.Close()
batch = eng.NewBatch()
b.StartTimer()
}
rangeNum := i % numRanges
lockUpdate.Key = keys[rangeNum*numKeysPerRange]
lockUpdate.EndKey = keys[(rangeNum+1)*numKeysPerRange]
resolved, span, err := MVCCResolveWriteIntentRange(
context.Background(), batch, nil, lockUpdate, 1000 /* max */, sep)
if err != nil {
b.Fatal(err)
}
resolvedCount += resolved
if span != nil {
b.Fatal("unexpected resume span")
}
}
})
}
})
}
})
}
Expand Down
Loading

0 comments on commit 4d09f18

Please sign in to comment.