mvcc/backend: restore original bolt db options after defrag
Problem: Defrag was implemented before custom bolt options were added. Currently defrag doesn't restore backend options. For example BackendFreelistType will be unset after defrag. Solution: save bolt db options and use them in defrag.
This commit is contained in:
@ -95,8 +95,9 @@ type backend struct {
|
|||||||
// openReadTxN is the number of currently open read transactions in the backend
|
// openReadTxN is the number of currently open read transactions in the backend
|
||||||
openReadTxN int64
|
openReadTxN int64
|
||||||
|
|
||||||
mu sync.RWMutex
|
mu sync.RWMutex
|
||||||
db *bolt.DB
|
bopts *bolt.Options
|
||||||
|
db *bolt.DB
|
||||||
|
|
||||||
batchInterval time.Duration
|
batchInterval time.Duration
|
||||||
batchLimit int
|
batchLimit int
|
||||||
@ -167,7 +168,8 @@ func newBackend(bcfg BackendConfig) *backend {
|
|||||||
// In future, may want to make buffering optional for low-concurrency systems
|
// In future, may want to make buffering optional for low-concurrency systems
|
||||||
// or dynamically swap between buffered/non-buffered depending on workload.
|
// or dynamically swap between buffered/non-buffered depending on workload.
|
||||||
b := &backend{
|
b := &backend{
|
||||||
db: db,
|
bopts: bopts,
|
||||||
|
db: db,
|
||||||
|
|
||||||
batchInterval: bcfg.BatchInterval,
|
batchInterval: bcfg.BatchInterval,
|
||||||
batchLimit: bcfg.BatchLimit,
|
batchLimit: bcfg.BatchLimit,
|
||||||
@ -447,7 +449,7 @@ func (b *backend) defrag() error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
b.db, err = bolt.Open(dbp, 0600, boltOpenOptions)
|
b.db, err = bolt.Open(dbp, 0600, b.bopts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if b.lg != nil {
|
if b.lg != nil {
|
||||||
b.lg.Fatal("failed to open database", zap.String("path", dbp), zap.Error(err))
|
b.lg.Fatal("failed to open database", zap.String("path", dbp), zap.Error(err))
|
||||||
@ -568,18 +570,24 @@ func (b *backend) OpenReadTxN() int64 {
|
|||||||
return atomic.LoadInt64(&b.openReadTxN)
|
return atomic.LoadInt64(&b.openReadTxN)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewTmpBackend creates a backend implementation for testing.
|
// NewTmpBackendFromCfg creates a backend implementation for testing with custom BackendConfig.
|
||||||
func NewTmpBackend(batchInterval time.Duration, batchLimit int) (*backend, string) {
|
func NewTmpBackendFromCfg(bcfg BackendConfig) (*backend, string) {
|
||||||
dir, err := ioutil.TempDir(os.TempDir(), "etcd_backend_test")
|
dir, err := ioutil.TempDir(os.TempDir(), "etcd_backend_test")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
tmpPath := filepath.Join(dir, "database")
|
tmpPath := filepath.Join(dir, "database")
|
||||||
bcfg := DefaultBackendConfig()
|
bcfg.Path = tmpPath
|
||||||
bcfg.Path, bcfg.BatchInterval, bcfg.BatchLimit = tmpPath, batchInterval, batchLimit
|
|
||||||
return newBackend(bcfg), tmpPath
|
return newBackend(bcfg), tmpPath
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewTmpBackend creates a backend implementation for testing.
|
||||||
|
func NewTmpBackend(batchInterval time.Duration, batchLimit int) (*backend, string) {
|
||||||
|
bcfg := DefaultBackendConfig()
|
||||||
|
bcfg.BatchInterval, bcfg.BatchLimit = batchInterval, batchLimit
|
||||||
|
return NewTmpBackendFromCfg(bcfg)
|
||||||
|
}
|
||||||
|
|
||||||
func NewDefaultTmpBackend() (*backend, string) {
|
func NewDefaultTmpBackend() (*backend, string) {
|
||||||
return NewTmpBackend(defaultBatchInterval, defaultBatchLimit)
|
return NewTmpBackend(defaultBatchInterval, defaultBatchLimit)
|
||||||
}
|
}
|
||||||
|
@ -120,7 +120,16 @@ func TestBackendBatchIntervalCommit(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestBackendDefrag(t *testing.T) {
|
func TestBackendDefrag(t *testing.T) {
|
||||||
b, tmpPath := NewDefaultTmpBackend()
|
bcfg := DefaultBackendConfig()
|
||||||
|
// Make sure we change BackendFreelistType
|
||||||
|
// The goal is to verify that we restore config option after defrag.
|
||||||
|
if bcfg.BackendFreelistType == bolt.FreelistMapType {
|
||||||
|
bcfg.BackendFreelistType = bolt.FreelistArrayType
|
||||||
|
} else {
|
||||||
|
bcfg.BackendFreelistType = bolt.FreelistMapType
|
||||||
|
}
|
||||||
|
|
||||||
|
b, tmpPath := NewTmpBackendFromCfg(bcfg)
|
||||||
defer cleanup(b, tmpPath)
|
defer cleanup(b, tmpPath)
|
||||||
|
|
||||||
tx := b.BatchTx()
|
tx := b.BatchTx()
|
||||||
@ -167,6 +176,10 @@ func TestBackendDefrag(t *testing.T) {
|
|||||||
t.Errorf("new size = %v, want < %d", nsize, size)
|
t.Errorf("new size = %v, want < %d", nsize, size)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if b.db.FreelistType != bcfg.BackendFreelistType {
|
||||||
|
t.Errorf("db FreelistType = [%v], want [%v]", b.db.FreelistType, bcfg.BackendFreelistType)
|
||||||
|
}
|
||||||
|
|
||||||
// try put more keys after shrink.
|
// try put more keys after shrink.
|
||||||
tx = b.BatchTx()
|
tx = b.BatchTx()
|
||||||
tx.Lock()
|
tx.Lock()
|
||||||
|
Reference in New Issue
Block a user