badger icon indicating copy to clipboard operation
badger copied to clipboard

badger crash in memory mode on windows x86

Open yixinin opened this issue 2 years ago • 0 comments

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")
	}

yixinin avatar Sep 07 '22 01:09 yixinin