You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This was found while I was investigating moby/libnetwork#1950 (although granted that uses the original boltdb). However the issue is still in the latest maintained version here.
Here's a simple test program which simulates the issue - all it does is have a number of goroutines attempt to open a database simultaneously.
package main
import (
"fmt"
"os"
"sync"
bolt "github.com/etcd-io/bbolt"
)
func main() {
const instances = 30
var wg sync.WaitGroup
for instance := 0; instance < instances; instance++ {
wg.Add(1)
go opener(instance, &wg)
}
wg.Wait()
fmt.Println("Success :)")
}
func opener(instance int, wg *sync.WaitGroup) {
defer wg.Done()
db, err := bolt.Open(`c:\bolt\test.db`, 0600, nil)
if err != nil {
panic(fmt.Sprintf("instance %d failed to open: %s", instance, err))
os.Exit(-1)
}
db.Close()
}
Now run it a few times - due it being a race condition, it may succeed, as it does the first time below. Note this is run with $env:GOTRACEBACK=2 set. The important part is at the top of the output: panic: instance 0 failed to open: open c:\bolt\test.db.lock: Access is denied, although occasionally you will see The process cannot access the file cause it is being used by another process
The root cause of the issue is the way in which the database is locked, and there being a race condition between flock() and funlock() in bolt_windows.go. However, as I discovered, synchronising those two isn't quite sufficient to guarantee thread-safe access. There is a potentially better fix which removes the .lock file, being closer in implementation to the *NIX LOCK_EX/LOCK_SH. I'm validating it before submitting a PR.
The text was updated successfully, but these errors were encountered:
(I have a fix, PR soon).
This was found while I was investigating moby/libnetwork#1950 (although granted that uses the original boltdb). However the issue is still in the latest maintained version here.
Here's a simple test program which simulates the issue - all it does is have a number of goroutines attempt to open a database simultaneously.
Now run it a few times - due it being a race condition, it may succeed, as it does the first time below. Note this is run with
$env:GOTRACEBACK=2
set. The important part is at the top of the output:panic: instance 0 failed to open: open c:\bolt\test.db.lock: Access is denied
, although occasionally you will seeThe process cannot access the file cause it is being used by another process
The root cause of the issue is the way in which the database is locked, and there being a race condition between
flock()
andfunlock()
inbolt_windows.go
. However, as I discovered, synchronising those two isn't quite sufficient to guarantee thread-safe access. There is a potentially better fix which removes the.lock
file, being closer in implementation to the *NIX LOCK_EX/LOCK_SH. I'm validating it before submitting a PR.The text was updated successfully, but these errors were encountered: