Skip to content

Commit bf78e7c

Browse files
committed
lexi: Move old db if bad version.
1 parent 3e3deab commit bf78e7c

4 files changed

Lines changed: 81 additions & 4 deletions

File tree

client/asset/btc/txdb.go

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,14 @@ import (
1414
"fmt"
1515
"math"
1616
"math/rand"
17+
"os"
1718
"sync"
1819
"sync/atomic"
1920
"time"
2021

2122
"decred.org/dcrdex/client/asset"
2223
"decred.org/dcrdex/dex"
24+
"decred.org/dcrdex/dex/lexi"
2325
"github.com/dgraph-io/badger/v4"
2426
)
2527

@@ -123,7 +125,22 @@ func (db *BadgerTxDB) Connect(ctx context.Context) (*sync.WaitGroup, error) {
123125
var err error
124126
db.DB, err = badger.Open(opts)
125127
if err != nil {
126-
return nil, err
128+
if lexi.IsBadgerVersionError(err) {
129+
db.log.Warnf("Detected incompatible database version at %s. "+
130+
"Backing up old database and creating new one.", db.filePath)
131+
backupPath := db.filePath + ".v1.bak"
132+
if err := os.Rename(db.filePath, backupPath); err != nil {
133+
return nil, fmt.Errorf("failed to backup old database: %w", err)
134+
}
135+
db.log.Infof("Old database backed up to %s", backupPath)
136+
// Try opening again with a fresh directory
137+
db.DB, err = badger.Open(opts)
138+
if err != nil {
139+
return nil, err
140+
}
141+
} else {
142+
return nil, err
143+
}
127144
}
128145
db.ctx = ctx
129146
db.seq, err = db.GetSequence([]byte("seq"), 10)

client/asset/eth/txdb_legacy.go

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@ import (
77
"errors"
88
"fmt"
99
"math"
10+
"os"
1011
"sync"
1112
"time"
1213

1314
"decred.org/dcrdex/dex"
15+
"decred.org/dcrdex/dex/lexi"
1416
"github.com/dgraph-io/badger/v4"
1517
"github.com/ethereum/go-ethereum/common"
1618
)
@@ -100,7 +102,22 @@ func newBadgerTxDB(filePath string, log dex.Logger) (*badgerTxDB, error) {
100102
var err error
101103
bdb, err := badger.Open(opts)
102104
if err != nil {
103-
return nil, err
105+
if lexi.IsBadgerVersionError(err) {
106+
log.Warnf("Detected incompatible database version at %s. "+
107+
"Backing up old database and creating new one.", filePath)
108+
backupPath := filePath + ".v1.bak"
109+
if err := os.Rename(filePath, backupPath); err != nil {
110+
return nil, fmt.Errorf("failed to backup old database: %w", err)
111+
}
112+
log.Infof("Old database backed up to %s", backupPath)
113+
// Try opening again with a fresh directory
114+
bdb, err = badger.Open(opts)
115+
if err != nil {
116+
return nil, err
117+
}
118+
} else {
119+
return nil, err
120+
}
104121
}
105122

106123
db := &badgerTxDB{

client/asset/kvdb/kvdb.go

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,12 @@ import (
77
"context"
88
"encoding"
99
"errors"
10+
"fmt"
11+
"os"
1012
"time"
1113

1214
"decred.org/dcrdex/dex"
15+
"decred.org/dcrdex/dex/lexi"
1316
"github.com/dgraph-io/badger/v4"
1417
)
1518

@@ -34,7 +37,22 @@ func NewFileDB(filePath string, log dex.Logger) (KeyValueDB, error) {
3437
opts := badger.DefaultOptions(filePath).WithLogger(&badgerLoggerWrapper{log})
3538
db, err := badger.Open(opts)
3639
if err != nil {
37-
return nil, err
40+
if lexi.IsBadgerVersionError(err) {
41+
log.Warnf("Detected incompatible database version at %s. "+
42+
"Backing up old database and creating new one.", filePath)
43+
backupPath := filePath + ".v1.bak"
44+
if err := os.Rename(filePath, backupPath); err != nil {
45+
return nil, fmt.Errorf("failed to backup old database: %w", err)
46+
}
47+
log.Infof("Old database backed up to %s", backupPath)
48+
// Try opening again with a fresh directory
49+
db, err = badger.Open(opts)
50+
if err != nil {
51+
return nil, err
52+
}
53+
} else {
54+
return nil, err
55+
}
3856
}
3957

4058
return &kvDB{db, log}, nil

dex/lexi/lexi.go

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import (
99
"encoding/binary"
1010
"errors"
1111
"fmt"
12+
"os"
13+
"strings"
1214
"sync"
1315
"time"
1416

@@ -46,12 +48,35 @@ type Config struct {
4648
Log dex.Logger
4749
}
4850

51+
// IsBadgerVersionError checks if the error is due to an incompatible badger
52+
// database version (e.g., trying to open a v1 database with v4).
53+
func IsBadgerVersionError(err error) bool {
54+
errStr := err.Error()
55+
return strings.Contains(errStr, "manifest has unsupported version") ||
56+
strings.Contains(errStr, "external magic number doesn't match")
57+
}
58+
4959
// New constructs a new Lexi DB.
5060
func New(cfg *Config) (*DB, error) {
5161
opts := badger.DefaultOptions(cfg.Path).WithLogger(&badgerLoggerWrapper{cfg.Log.SubLogger("BADG")})
5262
bdb, err := badger.Open(opts)
5363
if err != nil {
54-
return nil, err
64+
if IsBadgerVersionError(err) {
65+
cfg.Log.Warnf("Detected incompatible database version at %s. "+
66+
"Backing up old database and creating new one.", cfg.Path)
67+
backupPath := cfg.Path + ".v1.bak"
68+
if err := os.Rename(cfg.Path, backupPath); err != nil {
69+
return nil, fmt.Errorf("failed to backup old database: %w", err)
70+
}
71+
cfg.Log.Infof("Old database backed up to %s", backupPath)
72+
// Try opening again with a fresh directory
73+
bdb, err = badger.Open(opts)
74+
if err != nil {
75+
return nil, err
76+
}
77+
} else {
78+
return nil, err
79+
}
5580
}
5681
idSeq, err := bdb.GetSequence(prefixedKey(primarySequencePrefix, []byte{0x00}), 1000)
5782
if err != nil {

0 commit comments

Comments
 (0)