badger
badger copied to clipboard
badger crash in memory mode on windows x86
env: GOARCH=386 GOOS=windows
won't crash on GOARCH=amd64
option MemTableSize
smaller, easier appear
panic log:
panic({0x1e4e7c0, 0x3e58ac8})
/usr/local/go/src/runtime/panic.go:838 +0x1ba
os.(*File).Name(...)
/usr/local/go/src/os/file.go:57
github.com/dgraph-io/badger/v3/table.(*Table).block(0x1b01a770, 0x6, 0x1)
/go/pkg/mod/github.com/dgraph-io/badger/[email protected]/table/table.go:583 +0x85d
github.com/dgraph-io/badger/v3/table.(*Iterator).seekHelper(0x2106a0e0, 0x6, {0x23272078, 0x13, 0x13})
/go/pkg/mod/github.com/dgraph-io/badger/[email protected]/table/iterator.go:254 +0x44
github.com/dgraph-io/badger/v3/table.(*Iterator).seekFrom(0x2106a0e0, {0x23272078, 0x13, 0x13}, 0x0)
/go/pkg/mod/github.com/dgraph-io/badger/[email protected]/table/iterator.go:294 +0x128
github.com/dgraph-io/badger/v3/table.(*Iterator).seek(...)
/go/pkg/mod/github.com/dgraph-io/badger/[email protected]/table/iterator.go:310
github.com/dgraph-io/badger/v3/table.(*Iterator).Seek(0x2106a0e0, {0x23272078, 0x13, 0x13})
/go/pkg/mod/github.com/dgraph-io/badger/[email protected]/table/iterator.go:424 +0x51
github.com/dgraph-io/badger/v3.(*levelHandler).get(0x1b167810, {0x23272078, 0x13, 0x13})
/go/pkg/mod/github.com/dgraph-io/badger/[email protected]/level_handler.go:293 +0x24f
github.com/dgraph-io/badger/v3.(*levelsController).get(0x1b1677c0, {0x23272078, 0x13, 0x13}, {0x0, 0x0, 0x0, {0x0, 0x0, 0x0}, ...}, ...)
/go/pkg/mod/github.com/dgraph-io/badger/[email protected]/levels.go:1601 +0x1e1
github.com/dgraph-io/badger/v3.(*DB).get(0x1b234000, {0x23272078, 0x13, 0x13})
/go/pkg/mod/github.com/dgraph-io/badger/[email protected]/db.go:751 +0x443
github.com/dgraph-io/badger/v3.(*Txn).Get(0x14c60720, {0x1aea61f0, 0xb, 0xb})
/go/pkg/mod/github.com/dgraph-io/badger/[email protected]/txn.go:478 +0x373
open db
var opt = badger.DefaultOptions("").WithInMemory(true)
db, err := badger.Open(opt)
in memory mode, MmapFile.Fd assign to nil
// OpenInMemoryTable is similar to OpenTable but it opens a new table from the provided data.
// OpenInMemoryTable is used for L0 tables.
func OpenInMemoryTable(data []byte, id uint64, opt *Options) (*Table, error) {
mf := &z.MmapFile{
Data: data,
Fd: nil, // here
}
t := &Table{
MmapFile: mf,
ref: 1, // Caller is given one reference.
opt: opt,
tableSize: len(data),
IsInmemory: true,
id: id, // It is important that each table gets a unique ID.
}
if err := t.initBiggestAndSmallest(); err != nil {
return nil, err
}
return t, nil
}
use t.Fd.Name() while t.Fd is nil, panic here
if err = t.decompress(blk); err != nil {
return nil, y.Wrapf(err,
"failed to decode compressed data in file: %s at offset: %d, len: %d",
t.Fd.Name(), blk.offset, ko.Len()) // panic
}
unexpected data block read
var err error
if blk.data, err = t.read(blk.offset, int(ko.Len())); err != nil {
return nil, y.Wrapf(err,
"failed to read from file: %s at offset: %d, len: %d",
t.Filename(), blk.offset, ko.Len())
}
if blk.data first 8 bytes is a very big number, z.Calloc may oom
// decompress decompresses the data stored in a block.
func (t *Table) decompress(b *block) error {
var dst []byte
var err error
// Point to the original b.data
src := b.data
switch t.opt.Compression {
case options.None:
// Nothing to be done here.
return nil
case options.Snappy:
if sz, err := snappy.DecodedLen(b.data); err == nil {
dst = z.Calloc(sz, "Table.Decompress") // may oom here
} else {
dst = z.Calloc(len(b.data)*4, "Table.Decompress") // Take a guess.
}
b.data, err = snappy.Decode(dst, b.data)
if err != nil {
z.Free(dst)
return y.Wrap(err, "failed to decompress")
}
case options.ZSTD:
sz := int(float64(t.opt.BlockSize) * 1.2)
dst = z.Calloc(sz, "Table.Decompress")
b.data, err = y.ZSTDDecompress(dst, b.data)
if err != nil {
z.Free(dst)
return y.Wrap(err, "failed to decompress")
}
default:
return errors.New("Unsupported compression type")
}