Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG]: Panic when closing DB while other goroutines doing reads #1923

Closed
mdogan opened this issue Apr 5, 2023 · 5 comments · Fixed by #1987
Closed

[BUG]: Panic when closing DB while other goroutines doing reads #1923

mdogan opened this issue Apr 5, 2023 · 5 comments · Fixed by #1987
Labels
kind/bug Something is broken. status/accepted We accept to investigate or work on it.

Comments

@mdogan
Copy link

mdogan commented Apr 5, 2023

What version of Badger are you using?

Both v3.2103.5 and v4.1.0

What version of Go are you using?

  • go1.19.7 darwin/arm64
  • go1.19.7 linux/amd64

Have you tried reproducing the issue with the latest release?

Yes

What is the hardware spec (RAM, CPU, OS)?

  • macOS 13.3, arm64
  • Linux Mint 21.1, kernel 5.15.0-67, amd64

What steps will reproduce the bug?

  • Create an empty db
  • Write a single key
  • Start reading the key concurrently from multiple goroutines
  • Close the database on the main goroutine
func main() {
  var dir = "somedir"
  db, err := badger.Open(badger.DefaultOptions(dir))
  if err != nil {
    log.Fatalln(err)
  }

  key := []byte("key")
  err = db.Update(func(txn *badger.Txn) error {
    return txn.Set(key, []byte("value"))
  })
  if err != nil {
    log.Fatalln(err)
  }

  var wg sync.WaitGroup
  for i := 0; i < 10; i++ {
    wg.Add(1)
    go func() {
        defer wg.Done()
	for {
	    err := db.View(func(txn *badger.Txn) error {
	    _, err := txn.Get(key)
	    return err
	})
	if err != nil {
	  log.Println(err)
	  break
	}
      }
    }()
  }

  time.Sleep(time.Second)
  err = db.Close()
  if err != nil {
    log.Fatalln(err)
  }
  wg.Wait()
}

Expected behavior and actual result.

Expecting to see; reader goroutines to return badger.ErrDBClosed error when database is closed.

But got a panic:

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x2 addr=0x0 pc=0x1023cca10]

goroutine 29 [running]:
github.com/dgraph-io/badger/v4.(*memTable).IncrRef(...)
        /Users/mm/.go/pkg/mod/github.com/dgraph-io/badger/[email protected]/memtable.go:229
github.com/dgraph-io/badger/v4.(*DB).getMemTables(0x1400015f200)
        /Users/mm/.go/pkg/mod/github.com/dgraph-io/badger/[email protected]/db.go:693 +0x130
github.com/dgraph-io/badger/v4.(*DB).get(0x1400015f200, {0x140079d5fe0, 0xb, 0xb})
        /Users/mm/.go/pkg/mod/github.com/dgraph-io/badger/[email protected]/db.go:727 +0x64
github.com/dgraph-io/badger/v4.(*Txn).Get(0x14007ae6f80, {0x1400009bd00, 0x3, 0x3})
        /Users/mm/.go/pkg/mod/github.com/dgraph-io/badger/[email protected]/txn.go:479 +0x228
main.main.func2.1(0x1400015f200?)
...

Additional information

No response

@mdogan mdogan added the kind/bug Something is broken. label Apr 5, 2023
@mdogan
Copy link
Author

mdogan commented Apr 5, 2023

When I try to read the key on the same goroutine after closing the database, there's no panic but a ErrDBClosed error as expected:

func main() {
	db, err := badger.Open(badger.DefaultOptions(dir))
	if err != nil {
		log.Fatalln(err)
	}

	key := []byte("key")
	err = db.Update(func(txn *badger.Txn) error {
		return txn.Set(key, []byte("value"))
	})
	if err != nil {
		log.Fatalln(err)
	}

	err = db.Close()
	if err != nil {
		log.Fatalln(err)
	}

	err = db.View(func(txn *badger.Txn) error {
		_, err := txn.Get(key)
		return err
	})
	if err != nil {
		log.Println(err)
	}
}

@mangalaman93
Copy link
Member

Hi @mdogan, Thank you for filling a detailed issue. You are right I think that we could have better protection around closing the database. Though, usually it is expected that no operation is in flight or done after database is closed. If you have a solution, please feel free to create a PR for it. This would be a low priority issue for us, but we will try to get to it as soon as we can.

@solracsf
Copy link

solracsf commented Aug 4, 2023

Will this (or any other fix) be backported to v3?

@mangalaman93
Copy link
Member

@solracsf we do not have such plans, but if you are looking for something specific, please let us know. We may consider it. Additionally, we don't have major changes from v3 to v4, it should be easy enough for you to upgrade. If you are facing issues in upgrade, do let us know.

@solracsf
Copy link

solracsf commented Aug 4, 2023

Ok thanks, no problem, will consider v3 as deprecated and plan to upgrade to v4 (as soon as our app support Go 1.19+, actually on 1.18). 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/bug Something is broken. status/accepted We accept to investigate or work on it.
3 participants