Skip to content

Commit cc42b89

Browse files
authored
Merge pull request #154749 from jeffswenson/backport25.4-154540
release-25.4: backupsink: fix ooming in TestFileSSTSinkWrite
2 parents b2f55d0 + a438490 commit cc42b89

File tree

1 file changed

+28
-16
lines changed

1 file changed

+28
-16
lines changed

pkg/backup/backupsink/file_sst_sink_test.go

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ package backupsink
88
import (
99
"context"
1010
"fmt"
11+
"math/rand"
1112
"reflect"
1213
"strconv"
1314
"strings"
@@ -122,6 +123,15 @@ func TestFileSSTSinkExtendOneFile(t *testing.T) {
122123
require.Equal(t, 1, len(progDetails.Files))
123124
}
124125

126+
func randomValue(n int64) []byte {
127+
// Create random data so that it does not compress well.
128+
b := make([]byte, n)
129+
for i := range b {
130+
b[i] = byte(rand.Int())
131+
}
132+
return b
133+
}
134+
125135
// TestFileSSTSinkWrite tests the contents of flushed files and the internal
126136
// unflushed files of the FileSSTSink under different write scenarios. Each test
127137
// writes a sequence of exportedSpans into a FileSSTSink. The test then verifies
@@ -133,6 +143,12 @@ func TestFileSSTSinkWrite(t *testing.T) {
133143
defer log.Scope(t).Close(t)
134144

135145
ctx := context.Background()
146+
testTargetFileSize := int64(10 << 10)
147+
148+
// Override the fileSpanByteLimit so we can test going over the limit without
149+
// needing large buffers that may oom the test node.
150+
defer func(oldLimit int64) { fileSpanByteLimit = oldLimit }(fileSpanByteLimit)
151+
fileSpanByteLimit = testTargetFileSize / 2
136152

137153
type testCase struct {
138154
name string
@@ -145,8 +161,7 @@ func TestFileSSTSinkWrite(t *testing.T) {
145161
//
146162
// TODO (msbutler): we currently don't test expected error handling. If this
147163
// is non-empty, we just skip the test.
148-
errorExplanation string
149-
noSSTSizeOverride bool
164+
errorExplanation string
150165
}
151166

152167
for _, tt := range []testCase{{name: "out-of-order-key-boundary",
@@ -278,7 +293,7 @@ func TestFileSSTSinkWrite(t *testing.T) {
278293
{
279294
name: "size-flush",
280295
exportSpans: []ExportedSpan{
281-
newExportedSpanBuilder("a", "c").withKVs([]kvAndTS{{key: "a", timestamp: 10, value: make([]byte, 20<<20)}, {key: "b", timestamp: 10}}).build(),
296+
newExportedSpanBuilder("a", "c").withKVs([]kvAndTS{{key: "a", timestamp: 10, value: randomValue(testTargetFileSize)}, {key: "b", timestamp: 10}}).build(),
282297
newExportedSpanBuilder("d", "f").withKVs([]kvAndTS{{key: "d", timestamp: 10}, {key: "e", timestamp: 10}}).build(),
283298
},
284299
flushedSpans: []roachpb.Spans{
@@ -292,7 +307,7 @@ func TestFileSSTSinkWrite(t *testing.T) {
292307
// No flush can occur between two versions of the same key. Further, we must combine flushes which split a row.
293308
name: "no-size-flush-if-mid-mvcc",
294309
exportSpans: []ExportedSpan{
295-
newRawExportedSpanBuilder(s2k0("a"), s2k0("c"), s2k0("c")).withKVs([]kvAndTS{{key: "a", timestamp: 10, value: make([]byte, 20<<20)}, {key: "c", timestamp: 10}}).build(),
310+
newRawExportedSpanBuilder(s2k0("a"), s2k0("c"), s2k0("c")).withKVs([]kvAndTS{{key: "a", timestamp: 10, value: randomValue(testTargetFileSize)}, {key: "c", timestamp: 10}}).build(),
296311
newRawExportedSpanBuilder(s2k0("c"), s2k0("f"), s2k0("f")).withKVs([]kvAndTS{{key: "c", timestamp: 8}, {key: "f", timestamp: 10}}).build(),
297312
},
298313
flushedSpans: []roachpb.Spans{},
@@ -305,9 +320,9 @@ func TestFileSSTSinkWrite(t *testing.T) {
305320
name: "no-size-flush-mid-col-family",
306321
exportSpans: []ExportedSpan{
307322
newRawExportedSpanBuilder(s2kWithColFamily("c", 0), s2kWithColFamily("c", 1), s2kWithColFamily("c", 1)).withKVs([]kvAndTS{
308-
{key: "c", timestamp: 10, value: make([]byte, 20<<20)}}).build(),
323+
{key: "c", timestamp: 10, value: randomValue(testTargetFileSize)}}).build(),
309324
newRawExportedSpanBuilder(s2kWithColFamily("c", 1), s2kWithColFamily("c", 2), s2kWithColFamily("c", 2)).withKVs([]kvAndTS{
310-
{key: "c", timestamp: 10, value: make([]byte, 20<<20)}}).buildWithEncoding(func(stingedKey string) roachpb.Key { return s2kWithColFamily(stingedKey, 1) }),
325+
{key: "c", timestamp: 10, value: randomValue(testTargetFileSize)}}).buildWithEncoding(func(stingedKey string) roachpb.Key { return s2kWithColFamily(stingedKey, 1) }),
311326
},
312327
flushedSpans: []roachpb.Spans{},
313328
unflushedSpans: []roachpb.Spans{
@@ -318,7 +333,7 @@ func TestFileSSTSinkWrite(t *testing.T) {
318333
// It's safe to flush at the range boundary.
319334
name: "size-flush-at-range-boundary",
320335
exportSpans: []ExportedSpan{
321-
newRawExportedSpanBuilder(s2k("a"), s2k("d"), s2k("d")).withKVs([]kvAndTS{{key: "a", timestamp: 10, value: make([]byte, 20<<20)}, {key: "c", timestamp: 10}}).build(),
336+
newRawExportedSpanBuilder(s2k("a"), s2k("d"), s2k("d")).withKVs([]kvAndTS{{key: "a", timestamp: 10, value: randomValue(testTargetFileSize)}, {key: "c", timestamp: 10}}).build(),
322337
},
323338
flushedSpans: []roachpb.Spans{
324339
{{Key: s2k("a"), EndKey: s2k("d")}},
@@ -332,7 +347,7 @@ func TestFileSSTSinkWrite(t *testing.T) {
332347
// row between two column families.
333348
name: "trim-resume-key",
334349
exportSpans: []ExportedSpan{
335-
newRawExportedSpanBuilder(s2k0("a"), s2k0("c"), s2k("c")).withKVs([]kvAndTS{{key: "a", timestamp: 10, value: make([]byte, 20<<20)}}).build(),
350+
newRawExportedSpanBuilder(s2k0("a"), s2k0("c"), s2k("c")).withKVs([]kvAndTS{{key: "a", timestamp: 10, value: randomValue(testTargetFileSize)}}).build(),
336351
},
337352
flushedSpans: []roachpb.Spans{
338353
{{Key: s2k0("a"), EndKey: s2k("c")}},
@@ -344,24 +359,23 @@ func TestFileSSTSinkWrite(t *testing.T) {
344359
// even if the next span's start key matches the file's end key.
345360
name: "file-size-cut",
346361
exportSpans: []ExportedSpan{
347-
newExportedSpanBuilder("a", "c").withKVs([]kvAndTS{{key: "a", timestamp: 10, value: make([]byte, 64<<20)}, {key: "b", timestamp: 10}}).build(),
362+
newExportedSpanBuilder("a", "c").withKVs([]kvAndTS{{key: "a", timestamp: 10, value: randomValue(fileSpanByteLimit)}, {key: "b", timestamp: 10}}).build(),
348363
newExportedSpanBuilder("c", "f").withKVs([]kvAndTS{{key: "c", timestamp: 10}, {key: "e", timestamp: 10}}).build(),
349364
},
350365
flushedSpans: []roachpb.Spans{},
351366
unflushedSpans: []roachpb.Spans{
352367
{{Key: s2k0("a"), EndKey: s2k0("c")}, {Key: s2k0("c"), EndKey: s2k0("f")}},
353368
},
354-
noSSTSizeOverride: true,
355369
},
356370
{
357371
// No file cut can occur between the two column families of the same row,
358372
// even if the file is sufficiently large to get cut.
359373
name: "no-file-cut-mid-col-family",
360374
exportSpans: []ExportedSpan{
361375
newRawExportedSpanBuilder(s2kWithColFamily("c", 0), s2kWithColFamily("c", 1), s2kWithColFamily("c", 1)).withKVs([]kvAndTS{
362-
{key: "c", timestamp: 10, value: make([]byte, 65<<20)}}).build(),
376+
{key: "c", timestamp: 10, value: randomValue(testTargetFileSize)}}).build(),
363377
newRawExportedSpanBuilder(s2kWithColFamily("c", 1), s2kWithColFamily("c", 2), s2kWithColFamily("c", 2)).withKVs([]kvAndTS{
364-
{key: "c", timestamp: 10, value: make([]byte, 20<<20)}}).buildWithEncoding(func(stingedKey string) roachpb.Key { return s2kWithColFamily(stingedKey, 1) }),
378+
{key: "c", timestamp: 10, value: randomValue(testTargetFileSize / 2)}}).buildWithEncoding(func(stingedKey string) roachpb.Key { return s2kWithColFamily(stingedKey, 1) }),
365379
},
366380
flushedSpans: []roachpb.Spans{},
367381
unflushedSpans: []roachpb.Spans{
@@ -377,9 +391,7 @@ func TestFileSSTSinkWrite(t *testing.T) {
377391
return
378392
}
379393
st := cluster.MakeTestingClusterSettings()
380-
if !tt.noSSTSizeOverride {
381-
targetFileSize.Override(ctx, &st.SV, 10<<10)
382-
}
394+
targetFileSize.Override(ctx, &st.SV, testTargetFileSize)
383395

384396
sink, store := fileSSTSinkTestSetup(t, st, elide)
385397
defer func() {
@@ -534,7 +546,7 @@ func TestFileSSTSinkStats(t *testing.T) {
534546
sinkStats{hlc.Timestamp{WallTime: 10}, 3, 3, 0, 0, 0, 1}},
535547
{
536548
// Write an exported span that comes after all spans so far. This span has enough data for a size flush.
537-
newExportedSpanBuilder("g", "h").withKVs([]kvAndTS{{key: "g", timestamp: 10, value: make([]byte, 20<<20)}}).build(),
549+
newExportedSpanBuilder("g", "h").withKVs([]kvAndTS{{key: "g", timestamp: 10, value: randomValue(10 << 10)}}).build(),
538550
sinkStats{hlc.Timestamp{WallTime: 0}, 0, 4, 1, 0, 1, 1}},
539551
{
540552
// Write the first exported span after the flush.

0 commit comments

Comments
 (0)