From 7d3c5ff41ec2322df8da996c231f17c7fa003620 Mon Sep 17 00:00:00 2001 From: sumeerbhola Date: Tue, 13 Jun 2023 11:52:23 -0400 Subject: [PATCH] crl-release-22.2: db: wrap error when creating Reader with backing filenum Backport of https://github.com/cockroachdb/pebble/pull/2633 Informs https://github.com/cockroachlabs/support/issues/2643 --- table_cache.go | 3 +++ table_cache_test.go | 53 ++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/table_cache.go b/table_cache.go index 88c20c5eb8..b3619330d2 100644 --- a/table_cache.go +++ b/table_cache.go @@ -888,6 +888,9 @@ func (v *tableCacheValue) load(meta *fileMetadata, c *tableCacheShard, dbOpts *t reopenOpt := sstable.FileReopenOpt{FS: dbOpts.fs, Filename: v.filename} v.reader, v.err = sstable.NewReader(f, dbOpts.opts, cacheOpts, dbOpts.filterMetrics, reopenOpt) } + if v.err != nil { + v.err = errors.Wrapf(v.err, "pebble: file %s error", errors.Safe(meta.FileNum)) + } if v.err == nil { if meta.SmallestSeqNum == meta.LargestSeqNum { v.reader.Properties.GlobalSeqNum = meta.LargestSeqNum diff --git a/table_cache_test.go b/table_cache_test.go index eb43a76ea2..1c1e1b452c 100644 --- a/table_cache_test.go +++ b/table_cache_test.go @@ -808,12 +808,13 @@ func TestTableCacheRetryAfterFailure(t *testing.T) { require.NoError(t, err) fs.setOpenError(true /* enabled */) - if _, _, err := c.newIters( + if _, _, err = c.newIters( &fileMetadata{FileNum: 0}, nil, /* iter options */ internalIterOpts{}); err == nil { t.Fatalf("expected failure, but found success") } + require.Equal(t, "pebble: file 000000 error: injected error", err.Error()) fs.setOpenError(false /* enabled */) var iter internalIterator iter, _, err = c.newIters( @@ -825,6 +826,56 @@ func TestTableCacheRetryAfterFailure(t *testing.T) { fs.validate(t, c, nil) } +// memFile is a file-like struct that buffers all data written to it in memory. +// Implements the sstable.writeCloseSyncer interface. +type memFile struct { + *bytes.Buffer +} + +// Sync is part of the writeCloseSyncer interface. +func (*memFile) Sync() error { + return nil +} + +// Close is part of the writeCloseSynce interface. +func (*memFile) Close() error { + return nil +} + +func TestTableCacheErrorBadMagicNumber(t *testing.T) { + file := memFile{Buffer: &bytes.Buffer{}} + tw := sstable.NewWriter(&file, sstable.WriterOptions{TableFormat: sstable.TableFormatPebblev2}) + tw.Set([]byte("a"), nil) + require.NoError(t, tw.Close()) + buf := file.Bytes() + // Bad magic number. + buf[len(buf)-1] = 0 + fs := &tableCacheTestFS{ + FS: vfs.NewMem(), + } + const testFileNum = 3 + f, err := fs.Create(base.MakeFilepath(fs, "", fileTypeTable, base.FileNum(testFileNum))) + require.NoError(t, err) + _, err = f.Write(buf) + require.NoError(t, err) + require.NoError(t, f.Close()) + opts := &Options{} + opts.EnsureDefaults() + opts.Cache = NewCache(8 << 20) // 8 MB + defer opts.Cache.Unref() + c := newTableCacheContainer(nil, opts.Cache.NewID(), "", fs, opts, tableCacheTestCacheSize) + require.NoError(t, err) + defer c.close() + + m := &fileMetadata{FileNum: testFileNum} + if _, _, err = c.newIters(m, nil, internalIterOpts{}); err == nil { + t.Fatalf("expected failure, but found success") + } + require.Equal(t, + "pebble: file 000003 error: pebble/table: invalid table (bad magic number: 0xf09faab3f09faa00)", + err.Error()) +} + func TestTableCacheEvictClose(t *testing.T) { errs := make(chan error, 10) db, err := Open("test",