Skip to content

Instantly share code, notes, and snippets.

@jsherer
Created June 6, 2014 00:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jsherer/90a4cdc833dab8b4db12 to your computer and use it in GitHub Desktop.
Save jsherer/90a4cdc833dab8b4db12 to your computer and use it in GitHub Desktop.
This file illustrates a panic in boltdb when lots of keys are deleted in a single transaction
/*
this file illustrates a panic in boltdb when lots of keys are deleted in a single transaction
*/
package main
import (
"encoding/binary"
"log"
"github.com/boltdb/bolt"
)
/*
insert 10,000,000 16-byte keys (with nil values) into a database
then, try to delete all of them at once.
*/
func main() {
db, err := bolt.Open("try-to-crash.bolt", 0600)
if err != nil {
panic(err)
}
defer db.Close()
k := make([]byte, 16)
// insert 10,000,000 keys (10000 transactions of 1000 keys a piece)
for i := uint64(0); i < 10000; i++ {
err := db.Update(func(tx *bolt.Tx) error {
b, err := tx.CreateBucketIfNotExists([]byte("0"))
if err != nil {
return err
}
j := uint64(0)
for ; j < 1000; j++ {
binary.BigEndian.PutUint64(k[:8], i)
binary.BigEndian.PutUint64(k[8:], j)
b.Put(k, nil)
}
log.Println(i * j)
return nil
})
if err != nil {
panic(err)
}
}
// delete all of them in one large transaction
db.Update(func(tx *bolt.Tx) error {
b := tx.Bucket([]byte("0"))
c := b.Cursor()
i := 0
for k, _ := c.First(); k != nil; k, _ = c.Next() {
b.Delete(k)
if i % 1000 == 0 {
log.Println(i)
}
i++
}
return nil
})
/*
You should get something like this panic:
...
2014/06/05 20:52:23 9996000
2014/06/05 20:52:23 9997000
2014/06/05 20:52:23 9998000
2014/06/05 20:52:23 9999000
panic: tx 10002: page 79461 already freed in tx 10002
goroutine 1 [running]:
runtime.panic(0xa2b20, 0x24c9a12b0)
/usr/local/go/src/pkg/runtime/panic.c:266 +0xb6
github.com/boltdb/bolt.(*freelist).free(0x2102bd020, 0x2712, 0x2223b8b000)
/Users/jordan/Development/experiments/gopath/src/github.com/boltdb/bolt/freelist.go:85 +0x3a8
github.com/boltdb/bolt.(*node).spill(0x24d2b1b60, 0x24d2da5e0, 0x1dccb0)
/Users/jordan/Development/experiments/gopath/src/github.com/boltdb/bolt/node.go:307 +0x1d6
github.com/boltdb/bolt.(*node).spill(0x2103d9070, 0x24d2da5c0, 0x1dccb0)
/Users/jordan/Development/experiments/gopath/src/github.com/boltdb/bolt/node.go:293 +0xc2
github.com/boltdb/bolt.(*node).spill(0x2103d9000, 0x210395330, 0x22103e6b98)
/Users/jordan/Development/experiments/gopath/src/github.com/boltdb/bolt/node.go:293 +0xc2
github.com/boltdb/bolt.(*Bucket).spill(0x210395300, 0x210275f00, 0x1)
/Users/jordan/Development/experiments/gopath/src/github.com/boltdb/bolt/bucket.go:543 +0x182
github.com/boltdb/bolt.(*Bucket).spill(0x2102c5de8, 0x143833c2, 0x1dd220)
/Users/jordan/Development/experiments/gopath/src/github.com/boltdb/bolt/bucket.go:514 +0x7bb
github.com/boltdb/bolt.(*Tx).Commit(0x2102c5dd0, 0x0, 0x0)
/Users/jordan/Development/experiments/gopath/src/github.com/boltdb/bolt/tx.go:159 +0x1a9
github.com/boltdb/bolt.(*DB).Update(0x2102ad140, 0x22103e6f00, 0x0, 0x0)
/Users/jordan/Development/experiments/gopath/src/github.com/boltdb/bolt/db.go:464 +0xe7
main.main()
/Users/jordan/Development/experiments/try-to-crash.go:61 +0x1c1
exit status 2
*/
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment