|
@@ -247,7 +247,11 @@ func (b *backend) defrag() error {
|
|
|
b.mu.Lock()
|
|
b.mu.Lock()
|
|
|
defer b.mu.Unlock()
|
|
defer b.mu.Unlock()
|
|
|
|
|
|
|
|
- b.batchTx.commit(true)
|
|
|
|
|
|
|
+ // block concurrent read requests while resetting tx
|
|
|
|
|
+ b.readTx.mu.Lock()
|
|
|
|
|
+ defer b.readTx.mu.Unlock()
|
|
|
|
|
+
|
|
|
|
|
+ b.batchTx.unsafeCommit(true)
|
|
|
b.batchTx.tx = nil
|
|
b.batchTx.tx = nil
|
|
|
|
|
|
|
|
tmpdb, err := bolt.Open(b.db.Path()+".tmp", 0600, boltOpenOptions)
|
|
tmpdb, err := bolt.Open(b.db.Path()+".tmp", 0600, boltOpenOptions)
|
|
@@ -288,6 +292,10 @@ func (b *backend) defrag() error {
|
|
|
plog.Fatalf("cannot begin tx (%s)", err)
|
|
plog.Fatalf("cannot begin tx (%s)", err)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ b.readTx.buf.reset()
|
|
|
|
|
+ b.readTx.tx = b.unsafeBegin(false)
|
|
|
|
|
+ atomic.StoreInt64(&b.size, b.readTx.tx.Size())
|
|
|
|
|
+
|
|
|
return nil
|
|
return nil
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -345,12 +353,17 @@ func defragdb(odb, tmpdb *bolt.DB, limit int) error {
|
|
|
|
|
|
|
|
func (b *backend) begin(write bool) *bolt.Tx {
|
|
func (b *backend) begin(write bool) *bolt.Tx {
|
|
|
b.mu.RLock()
|
|
b.mu.RLock()
|
|
|
|
|
+ tx := b.unsafeBegin(write)
|
|
|
|
|
+ b.mu.RUnlock()
|
|
|
|
|
+ atomic.StoreInt64(&b.size, tx.Size())
|
|
|
|
|
+ return tx
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func (b *backend) unsafeBegin(write bool) *bolt.Tx {
|
|
|
tx, err := b.db.Begin(write)
|
|
tx, err := b.db.Begin(write)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
plog.Fatalf("cannot begin tx (%s)", err)
|
|
plog.Fatalf("cannot begin tx (%s)", err)
|
|
|
}
|
|
}
|
|
|
- b.mu.RUnlock()
|
|
|
|
|
- atomic.StoreInt64(&b.size, tx.Size())
|
|
|
|
|
return tx
|
|
return tx
|
|
|
}
|
|
}
|
|
|
|
|
|