Skip to content

Commit

Permalink
storage: add a scan benchmark with resolved intents
Browse files Browse the repository at this point in the history
It stresses the case where many versions were written
transactionally and all were resolved.

This is the benchmark mentioned in
cockroachdb/pebble#1067
to justify the Pebble seek noop optimization.

Release justification: Non-production code change that
adds a benchmark.

Release note: None
  • Loading branch information
sumeerbhola committed Mar 1, 2021
1 parent 8a31338 commit de2f6f9
Showing 1 changed file with 61 additions and 5 deletions.
66 changes: 61 additions & 5 deletions pkg/storage/bench_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ func BenchmarkExportToSst(b *testing.B) {
const numIntentKeys = 1000

func setupKeysWithIntent(
b *testing.B, eng Engine, numVersions int, numFlushedVersions int,
b *testing.B, eng Engine, numVersions int, numFlushedVersions int, resolveAll bool,
) roachpb.LockUpdate {
txnIDCount := 2 * numVersions
val := []byte("value")
Expand Down Expand Up @@ -179,7 +179,7 @@ func setupKeysWithIntent(
Txn: txn.TxnMeta,
Status: roachpb.COMMITTED,
}
if i < numVersions {
if i < numVersions || resolveAll {
batch := eng.NewBatch()
for j := 0; j < numIntentKeys; j++ {
key := makeKey(nil, j)
Expand All @@ -198,6 +198,8 @@ func setupKeysWithIntent(
return lockUpdate
}

// BenchmarkIntentScan compares separated and interleaved intents, when
// reading the intent and latest version for a range of keys.
func BenchmarkIntentScan(b *testing.B) {
skip.UnderShort(b, "setting up unflushed data takes too long")
for _, sep := range []bool{false, true} {
Expand All @@ -209,7 +211,7 @@ func BenchmarkIntentScan(b *testing.B) {
eng := setupMVCCInMemPebbleWithSettings(
b, makeSettingsForSeparatedIntents(false, sep))
numFlushedVersions := (percentFlushed * numVersions) / 100
setupKeysWithIntent(b, eng, numVersions, numFlushedVersions)
setupKeysWithIntent(b, eng, numVersions, numFlushedVersions, false /* resolveAll */)
lower := makeKey(nil, 0)
iter := eng.NewMVCCIterator(MVCCKeyAndIntentsIterKind, IterOptions{
LowerBound: lower,
Expand Down Expand Up @@ -258,6 +260,58 @@ func BenchmarkIntentScan(b *testing.B) {
}
}

// BenchmarkScanAllIntentsResolved compares separated and interleaved intents,
// when reading the latest version for a range of keys, when all the intents
// have been resolved.
func BenchmarkScanAllIntentsResolved(b *testing.B) {
skip.UnderShort(b, "setting up unflushed data takes too long")
for _, sep := range []bool{false, true} {
b.Run(fmt.Sprintf("separated=%t", sep), func(b *testing.B) {
for _, numVersions := range []int{200} {
b.Run(fmt.Sprintf("versions=%d", numVersions), func(b *testing.B) {
for _, percentFlushed := range []int{0, 50, 90, 100} {
b.Run(fmt.Sprintf("percent-flushed=%d", percentFlushed), func(b *testing.B) {
eng := setupMVCCInMemPebbleWithSettings(
b, makeSettingsForSeparatedIntents(false, sep))
numFlushedVersions := (percentFlushed * numVersions) / 100
setupKeysWithIntent(b, eng, numVersions, numFlushedVersions, true /* resolveAll */)
lower := makeKey(nil, 0)
iter := eng.NewMVCCIterator(MVCCKeyAndIntentsIterKind, IterOptions{
LowerBound: lower,
UpperBound: makeKey(nil, numIntentKeys),
})
iter.SeekGE(MVCCKey{Key: lower})
var buf []byte
b.ResetTimer()
for i := 0; i < b.N; i++ {
valid, err := iter.Valid()
if err != nil {
b.Fatal(err)
}
if !valid {
iter.SeekGE(MVCCKey{Key: lower})
} else {
// Read latest version.
k := iter.UnsafeKey()
if !k.IsValue() {
b.Fatalf("expected value %s", k.String())
}
// Skip to next key.
buf = append(buf[:0], k.Key...)
buf = roachpb.BytesNext(buf)
iter.SeekGE(MVCCKey{Key: buf})
}
}
})
}
})
}
})
}
}

// BenchmarkIntentResolution compares separated and interleaved intents, when
// doing intent resolution for individual intents.
func BenchmarkIntentResolution(b *testing.B) {
skip.UnderShort(b, "setting up unflushed data takes too long")
for _, sep := range []bool{false, true} {
Expand All @@ -269,7 +323,7 @@ func BenchmarkIntentResolution(b *testing.B) {
eng := setupMVCCInMemPebbleWithSettings(
b, makeSettingsForSeparatedIntents(false, sep))
numFlushedVersions := (percentFlushed * numVersions) / 100
lockUpdate := setupKeysWithIntent(b, eng, numVersions, numFlushedVersions)
lockUpdate := setupKeysWithIntent(b, eng, numVersions, numFlushedVersions, false /* resolveAll */)
keys := make([]roachpb.Key, numIntentKeys)
for i := range keys {
keys[i] = makeKey(nil, i)
Expand Down Expand Up @@ -298,6 +352,8 @@ func BenchmarkIntentResolution(b *testing.B) {
}
}

// BenchmarkIntentRangeResolution compares separated and interleaved intents,
// when doing ranged intent resolution.
func BenchmarkIntentRangeResolution(b *testing.B) {
skip.UnderShort(b, "setting up unflushed data takes too long")
for _, sep := range []bool{false, true} {
Expand All @@ -309,7 +365,7 @@ func BenchmarkIntentRangeResolution(b *testing.B) {
eng := setupMVCCInMemPebbleWithSettings(
b, makeSettingsForSeparatedIntents(false, sep))
numFlushedVersions := (percentFlushed * numVersions) / 100
lockUpdate := setupKeysWithIntent(b, eng, numVersions, numFlushedVersions)
lockUpdate := setupKeysWithIntent(b, eng, numVersions, numFlushedVersions, false /* resolveAll */)
keys := make([]roachpb.Key, numIntentKeys+1)
for i := range keys {
keys[i] = makeKey(nil, i)
Expand Down

0 comments on commit de2f6f9

Please sign in to comment.