From 869518be0afaf8c717513a634dc8cd2228c466e6 Mon Sep 17 00:00:00 2001 From: Dmitrii Stepanov Date: Mon, 30 Oct 2023 17:11:04 +0300 Subject: [PATCH] [#728] writecache: Fix Badger writecache race. Signed-off-by: Dmitrii Stepanov --- .../writecachebadger/cachebadger.go | 6 ++++ .../writecache/writecachebadger/gc.go | 31 +++++++++++-------- 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/pkg/local_object_storage/writecache/writecachebadger/cachebadger.go b/pkg/local_object_storage/writecache/writecachebadger/cachebadger.go index be7046d05..484f01815 100644 --- a/pkg/local_object_storage/writecache/writecachebadger/cachebadger.go +++ b/pkg/local_object_storage/writecache/writecachebadger/cachebadger.go @@ -85,6 +85,9 @@ func (c *cache) DumpInfo() writecache.Info { // Open opens and initializes database. Reads object counters from the ObjectCounters instance. func (c *cache) Open(_ context.Context, readOnly bool) error { + c.modeMtx.Lock() + defer c.modeMtx.Unlock() + err := c.openStore(readOnly) if err != nil { return metaerr.Wrap(err) @@ -94,6 +97,9 @@ func (c *cache) Open(_ context.Context, readOnly bool) error { // Init runs necessary services. func (c *cache) Init() error { + c.modeMtx.Lock() + defer c.modeMtx.Unlock() + c.log.Info(logs.WritecacheBadgerInitExperimental) c.metrics.SetMode(c.mode) ctx, cancel := context.WithCancel(context.Background()) diff --git a/pkg/local_object_storage/writecache/writecachebadger/gc.go b/pkg/local_object_storage/writecache/writecachebadger/gc.go index b856efc3d..8937ff295 100644 --- a/pkg/local_object_storage/writecache/writecachebadger/gc.go +++ b/pkg/local_object_storage/writecache/writecachebadger/gc.go @@ -21,20 +21,25 @@ func (c *cache) runGCLoop(ctx context.Context) { case <-ctx.Done(): return case <-t.C: - // This serves to synchronize the c.db field when changing mode as well. - c.modeMtx.RLock() - ro := c.readOnly() - c.modeMtx.RUnlock() - if ro { - continue - } - - // 0.5 is the recommended value so that write amplification of the value log is 2. - // See https://pkg.go.dev/github.com/dgraph-io/badger/v4#DB.RunValueLogGC for more info. - for c.db.RunValueLogGC(0.5) == nil { - c.log.Debug(logs.WritecacheDBValueLogGCRunCompleted) - } + c.runGC() } } }() } + +func (c *cache) runGC() { + // This serves to synchronize the c.db field when changing mode as well. + c.modeMtx.RLock() + defer c.modeMtx.RUnlock() + + ro := c.readOnly() + if ro { + return + } + + // 0.5 is the recommended value so that write amplification of the value log is 2. + // See https://pkg.go.dev/github.com/dgraph-io/badger/v4#DB.RunValueLogGC for more info. + for c.db.RunValueLogGC(0.5) == nil { + c.log.Debug(logs.WritecacheDBValueLogGCRunCompleted) + } +}