Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mvcc/backend: restore original bolt db options after defrag #13713

Merged
merged 1 commit into from
Feb 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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