Skip to content

Commit

Permalink
Merge pull request #13713 from lavacat/defrag-bopts-fix-3.4
Browse files Browse the repository at this point in the history
mvcc/backend: restore original bolt db options after defrag
  • Loading branch information
serathius authored Feb 18, 2022
2 parents a905430 + d30a4fb commit c50b726
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 9 deletions.
24 changes: 16 additions & 8 deletions mvcc/backend/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,9 @@ type backend struct {
// openReadTxN is the number of currently open read transactions in the backend
openReadTxN int64

mu sync.RWMutex
db *bolt.DB
mu sync.RWMutex
bopts *bolt.Options
db *bolt.DB

batchInterval time.Duration
batchLimit int
Expand Down Expand Up @@ -167,7 +168,8 @@ func newBackend(bcfg BackendConfig) *backend {
// In future, may want to make buffering optional for low-concurrency systems
// or dynamically swap between buffered/non-buffered depending on workload.
b := &backend{
db: db,
bopts: bopts,
db: db,

batchInterval: bcfg.BatchInterval,
batchLimit: bcfg.BatchLimit,
Expand Down Expand Up @@ -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 b.lg != nil {
b.lg.Fatal("failed to open database", zap.String("path", dbp), zap.Error(err))
Expand Down Expand Up @@ -568,18 +570,24 @@ func (b *backend) OpenReadTxN() int64 {
return atomic.LoadInt64(&b.openReadTxN)
}

// NewTmpBackend creates a backend implementation for testing.
func NewTmpBackend(batchInterval time.Duration, batchLimit int) (*backend, string) {
// NewTmpBackendFromCfg creates a backend implementation for testing with custom BackendConfig.
func NewTmpBackendFromCfg(bcfg BackendConfig) (*backend, string) {
dir, err := ioutil.TempDir(os.TempDir(), "etcd_backend_test")
if err != nil {
panic(err)
}
tmpPath := filepath.Join(dir, "database")
bcfg := DefaultBackendConfig()
bcfg.Path, bcfg.BatchInterval, bcfg.BatchLimit = tmpPath, batchInterval, batchLimit
bcfg.Path = 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) {
return NewTmpBackend(defaultBatchInterval, defaultBatchLimit)
}
Expand Down
15 changes: 14 additions & 1 deletion mvcc/backend/backend_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,16 @@ func TestBackendBatchIntervalCommit(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)

tx := b.BatchTx()
Expand Down Expand Up @@ -167,6 +176,10 @@ func TestBackendDefrag(t *testing.T) {
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.
tx = b.BatchTx()
tx.Lock()
Expand Down

0 comments on commit c50b726

Please sign in to comment.