Skip to content

Commit

Permalink
DB: improve recreation behavior
Browse files Browse the repository at this point in the history
  • Loading branch information
strokovok committed Jul 29, 2024
1 parent a1711bb commit 457f056
Show file tree
Hide file tree
Showing 6 changed files with 39 additions and 21 deletions.
10 changes: 6 additions & 4 deletions cmd/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,9 @@ func FlattenDB() *cobra.Command {

log.Printf("Opening database at %s...", dbPath)
config := core.Config{
BadgerConfig: badger.DefaultOptions(dbPath),
GcIntervalSeconds: 60 * 60 * 24 * 365, // We don't want GC to be running during the flattening
RecreateOnCorruption: false,
BadgerConfig: badger.DefaultOptions(dbPath),
GcIntervalSeconds: 60 * 60 * 24 * 365, // We don't want GC to be running during the flattening
}
db, err := core.NewDB(config, codec.NewTinypackCodec())
if err != nil {
Expand Down Expand Up @@ -150,8 +151,9 @@ func FlattenDB() *cobra.Command {
// dbView opens db in read-only mode and calls fn with ViewTxn
func dbView(dbPath string, fn func(txn *core.ViewTxn) error) error {
config := core.Config{
BadgerConfig: badger.DefaultOptions(dbPath).WithLogger(nil).WithReadOnly(true),
GcIntervalSeconds: 10,
RecreateOnCorruption: false,
BadgerConfig: badger.DefaultOptions(dbPath).WithLogger(nil).WithReadOnly(true),
GcIntervalSeconds: 10,
}
db, err := core.NewDB(config, codec.NewTinypackCodec())
if err != nil {
Expand Down
11 changes: 6 additions & 5 deletions db/badger/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,12 @@ func defaultConfig() *Config {
badgerOptions.Logger = NewBadgerLogger(log.Log())
return &Config{
Core: core.Config{
MaxScanIterators: defaultLogMaxScanIterators,
ScanRangeThreshold: defaultLogScanRangeThreshold,
FilterTtlMinutes: defaultLogFilterTtlMinutes,
GcIntervalSeconds: defaultGcIntervalSeconds,
BadgerConfig: badgerOptions,
MaxScanIterators: defaultLogMaxScanIterators,
ScanRangeThreshold: defaultLogScanRangeThreshold,
FilterTtlMinutes: defaultLogFilterTtlMinutes,
GcIntervalSeconds: defaultGcIntervalSeconds,
RecreateOnCorruption: true,
BadgerConfig: badgerOptions,
},
}
}
Expand Down
11 changes: 6 additions & 5 deletions db/badger/core/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ package core
import "github.com/dgraph-io/badger/v3"

type Config struct {
MaxScanIterators uint `mapstructure:"maxScanIterators"`
ScanRangeThreshold uint `mapstructure:"scanRangeThreshold"`
FilterTtlMinutes int `mapstructure:"filterTtlMinutes"`
GcIntervalSeconds int `mapstructure:"gcIntervalSeconds"`
BadgerConfig badger.Options `mapstructure:"options"`
MaxScanIterators uint `mapstructure:"maxScanIterators"`
ScanRangeThreshold uint `mapstructure:"scanRangeThreshold"`
FilterTtlMinutes int `mapstructure:"filterTtlMinutes"`
GcIntervalSeconds int `mapstructure:"gcIntervalSeconds"`
RecreateOnCorruption bool `mapstructure:"recreateOnCorruption"`
BadgerConfig badger.Options `mapstructure:"options"`
}
24 changes: 19 additions & 5 deletions db/badger/core/core.go
Original file line number Diff line number Diff line change
@@ -1,23 +1,26 @@
package core

import (
"github.com/aurora-is-near/relayer2-base/log"
"github.com/aurora-is-near/relayer2-base/syncutils"
"fmt"
"os"
"path"
"strings"
"time"

"github.com/aurora-is-near/relayer2-base/log"
"github.com/aurora-is-near/relayer2-base/syncutils"

"github.com/dgraph-io/badger/v3"
)

var bdbPtr syncutils.LockablePtr[badger.DB]
var gcStop chan bool

func Open(options badger.Options, gcIntervalSeconds int) (*badger.DB, error) {
func Open(options badger.Options, gcIntervalSeconds int, recreateOnCorruption bool) (*badger.DB, error) {
var err error
bdb, unlock := bdbPtr.LockIfNil()
if unlock != nil {
bdb, err = tryOpen(options, gcIntervalSeconds)
bdb, err = tryOpen(options, gcIntervalSeconds, recreateOnCorruption)
unlock(bdb)
}
return bdb, err
Expand All @@ -37,7 +40,7 @@ func Close() error {
return nil
}

func tryOpen(options badger.Options, gcIntervalSeconds int) (*badger.DB, error) {
func tryOpen(options badger.Options, gcIntervalSeconds int, recreateOnCorruption bool) (*badger.DB, error) {
var err error
logger := log.Log()

Expand All @@ -51,6 +54,17 @@ func tryOpen(options badger.Options, gcIntervalSeconds int) (*badger.DB, error)
bdb, err := badger.Open(options)
if err != nil {
logger.Error().Err(err).Msg("failed to tryOpen database")

// No proper error class for that:
// https://github.com/dgraph-io/badger/blob/c08da0b80769f86aa44366e2da77b5c662810eca/dir_unix.go#L67
if strings.Contains(err.Error(), "Cannot acquire directory lock") {
return nil, fmt.Errorf("db is busy: %w", err)
}

if !recreateOnCorruption {
return nil, err
}

snapshotBaseName := path.Base(options.Dir) + "_" + time.Now().Format("2006-01-02T15-04-05.000000000")
snapshotPath := path.Join(path.Dir(options.Dir), snapshotBaseName)
logger.Warn().Err(err).Msgf("saving old database snapshot at [%s]", snapshotPath)
Expand Down
2 changes: 1 addition & 1 deletion db/badger/core/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ type DB struct {
}

func NewDB(config Config, codec codec.Codec) (*DB, error) {
core, err := Open(config.BadgerConfig, config.GcIntervalSeconds)
core, err := Open(config.BadgerConfig, config.GcIntervalSeconds, config.RecreateOnCorruption)
if err != nil {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion db/badger/core/db_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,7 @@ func initTestDb(t *testing.T) (*DB, *testLogger) {

opts := badger.DefaultOptions("")
opts.InMemory = true
core, err := Open(opts, 10)
core, err := Open(opts, 10, false)
require.NoError(t, err, "DB must tryOpen")

logger := testLogger{}
Expand Down

0 comments on commit 457f056

Please sign in to comment.