zippoxer / bow

Bow - Minimal embedded database powered by Badger
MIT License
224 stars 15 forks source link

SIGSEGV When Trying to Read from Read-Only DB already opened in a Different Thread #8

Closed cbalano closed 5 years ago

cbalano commented 5 years ago

I was under the impression that read-only mode allows one to read from databases already open elsewhere. But that is not true, as illustrated by the code below. Opening the DB in read-only mode succeeds, but as soon as I try a Get, process crashes with SIGSEGV. Any idea why this might be?

package main

import ( "github.com/zippoxer/bow" "fmt" "time" "github.com/dgraph-io/badger" "encoding/json" )

type TS struct { Key string bow:"key" Value string }

func main () { fmt.Println("START MAIN") dbDir := "./testdb"

r := TS{"key1", "value1"} db, _ := bow.Open(dbDir) defer db.Close() fmt.Println("Putting ", r, " in bucket test") db.Bucket("test").Put(&r) time.Sleep(1 * time.Second)

go func () { fmt.Println("--------START ROUTINE-------------") opts := badger.DefaultOptions opts.ReadOnly = true t := time.Now().Unix() + 8 db, = bow.Open(dbDir, bow.SetBadgerOptions(opts)) for time.Now().Unix() < t { fmt.Println("DOT") eo := db.Bucket("test2").Get("key", &r) if eo != nil { fmt.Println(eo.Error()) } else { txt, := json.Marshal(r) fmt.Println(string(txt)) } time.Sleep(100 * time.Millisecond) } fmt.Println("----------END OF ROUTINE------------") }()

time.Sleep(1 time.Second) r = TS{"key2", "value2"} fmt.Println("Putting ", r, " in bucket test2") db.Bucket("test2").Put(&r) r2 := TS{} fmt.Println("Getting r2 from bucket test2") db.Bucket("test2").Get("key", &r2) fmt.Println(r2) time.Sleep(8 time.Second) fmt.Println("END of MAIN") }

dbro-put2 START MAIN badger 2019/05/26 14:42:52 INFO: All 1 tables opened in 0s badger 2019/05/26 14:42:52 DEBUG: Value Log Discard stats: map[] badger 2019/05/26 14:42:52 INFO: Replaying file id: 0 at offset: 2691 badger 2019/05/26 14:42:52 INFO: Replay took: 104.161µs Putting {key1 value1} in bucket test --------START ROUTINE------------- DOT panic: runtime error: invalid memory address or nil pointer dereference [signal SIGSEGV: segmentation violation code=0x1 addr=0x28 pc=0x7cf78c]

goroutine 53 [running]: sync.(RWMutex).RLock(...) /usr/local/go/src/sync/rwmutex.go:48 github.com/zippoxer/bow.(DB).bucket(0x0, 0x8b28d1, 0x5, 0x0, 0x0) /opt/test/vendor/src/github.com/zippoxer/bow/db.go:276 +0x2c github.com/zippoxer/bow.(*DB).Bucket(0x0, 0x8b28d1, 0x5, 0x1) /opt/test/vendor/src/github.com/zippoxer/bow/db.go:232 +0x43 main.main.func1(0x8b4998, 0x8, 0xc00000e0b8, 0xc00000cf60) /opt/test/dbro/dbro-put2.go:37 +0x29a created by main.main /opt/test/dbro/dbro-put2.go:29 +0x2fe

cbalano commented 5 years ago

Hold on, I will rebuild my example, as I found why this one does not work. The issue is still there though.

cbalano commented 5 years ago

Alright, I see what is going on. You get: "Cannot acquire directory lock on "./testdb". Another process is using this Badger database.: resource temporarily unavailable" even if you try to open read-only. I was hoping that was not the case.