Skip to content

Commit

Permalink
crl-release-23.1: db: wrap error when creating Reader with backing fi…
Browse files Browse the repository at this point in the history
…lenum

Backport of #2633

Informs cockroachlabs/support#2643
  • Loading branch information
sumeerbhola authored and RaduBerinde committed Oct 6, 2023
1 parent 5e685e4 commit 043c379
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 1 deletion.
3 changes: 3 additions & 0 deletions table_cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -937,6 +937,9 @@ func (v *tableCacheValue) load(meta *fileMetadata, c *tableCacheShard, dbOpts *t
cacheOpts := private.SSTableCacheOpts(dbOpts.cacheID, meta.FileNum).(sstable.ReaderOption)
v.reader, v.err = sstable.NewReader(f, dbOpts.opts, cacheOpts, dbOpts.filterMetrics)
}
if v.err != nil {
v.err = errors.Wrapf(v.err, "pebble: backing file %s error", errors.Safe(meta.FileNum))
}
if v.err == nil {
if meta.SmallestSeqNum == meta.LargestSeqNum {
v.reader.Properties.GlobalSeqNum = meta.LargestSeqNum
Expand Down
59 changes: 58 additions & 1 deletion table_cache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -794,9 +794,10 @@ func TestTableCacheRetryAfterFailure(t *testing.T) {
require.NoError(t, err)

fs.setOpenError(true /* enabled */)
if _, _, err := c.newIters(context.Background(), &fileMetadata{FileNum: 0}, nil, internalIterOpts{}); err == nil {
if _, _, err = c.newIters(context.Background(), &fileMetadata{FileNum: 0}, nil, internalIterOpts{}); err == nil {
t.Fatalf("expected failure, but found success")
}
require.Equal(t, "pebble: backing file 000000 error: injected error", err.Error())
fs.setOpenError(false /* enabled */)
var iter internalIterator
iter, _, err = c.newIters(context.Background(), &fileMetadata{FileNum: 0}, nil, internalIterOpts{})
Expand All @@ -805,6 +806,62 @@ 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 objstorage.Writable interface.
type memFile struct {
buf bytes.Buffer
}

var _ objstorage.Writable = (*memFile)(nil)

// Finish is part of the objstorage.Writable interface.
func (*memFile) Finish() error {
return nil
}

// Abort is part of the objstorage.Writable interface.
func (*memFile) Abort() {}

// Write is part of the objstorage.Writable interface.
func (f *memFile) Write(p []byte) error {
_, err := f.buf.Write(p)
return err
}

func TestTableCacheErrorBadMagicNumber(t *testing.T) {
var file memFile
tw := sstable.NewWriter(&file, sstable.WriterOptions{TableFormat: sstable.TableFormatPebblev2})
tw.Set([]byte("a"), nil)
require.NoError(t, tw.Close())
buf := file.buf.Bytes()
// Bad magic number.
buf[len(buf)-1] = 0
fs := &tableCacheTestFS{
FS: vfs.NewMem(),
}
const testFileNum = 3
objProvider, err := objstorage.Open(objstorage.DefaultSettings(fs, ""))
require.NoError(t, err)
w, _, err := objProvider.Create(fileTypeTable, base.FileNum(testFileNum), objstorage.CreateOptions{})
w.Write(buf)
require.NoError(t, w.Finish())
opts := &Options{}
opts.EnsureDefaults()
opts.Cache = NewCache(8 << 20) // 8 MB
defer opts.Cache.Unref()
c := newTableCacheContainer(nil, opts.Cache.NewID(), objProvider, opts, tableCacheTestCacheSize)
require.NoError(t, err)
defer c.close()

m := &fileMetadata{FileNum: testFileNum}
if _, _, err = c.newIters(context.Background(), m, nil, internalIterOpts{}); err == nil {
t.Fatalf("expected failure, but found success")
}
require.Equal(t,
"pebble: backing 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",
Expand Down

0 comments on commit 043c379

Please sign in to comment.