Commit 60facaea authored by acud's avatar acud Committed by GitHub

statestore: try to recover leveldb on corrupted db (#1253)

parent 73b765da
...@@ -39,7 +39,7 @@ func TestDBStore(t *testing.T) { ...@@ -39,7 +39,7 @@ func TestDBStore(t *testing.T) {
} }
defer os.RemoveAll(dir) defer os.RemoveAll(dir)
store, err := leveldb.NewStateStore(dir) store, err := leveldb.NewStateStore(dir, nil)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
......
...@@ -136,7 +136,7 @@ func NewBee(addr string, swarmAddress swarm.Address, publicKey ecdsa.PublicKey, ...@@ -136,7 +136,7 @@ func NewBee(addr string, swarmAddress swarm.Address, publicKey ecdsa.PublicKey,
stateStore = mockinmem.NewStateStore() stateStore = mockinmem.NewStateStore()
logger.Warning("using in-mem state store. no node state will be persisted") logger.Warning("using in-mem state store. no node state will be persisted")
} else { } else {
stateStore, err = leveldb.NewStateStore(filepath.Join(o.DataDir, "statestore")) stateStore, err = leveldb.NewStateStore(filepath.Join(o.DataDir, "statestore"), logger)
if err != nil { if err != nil {
return nil, fmt.Errorf("statestore: %w", err) return nil, fmt.Errorf("statestore: %w", err)
} }
......
...@@ -8,9 +8,12 @@ import ( ...@@ -8,9 +8,12 @@ import (
"encoding" "encoding"
"encoding/json" "encoding/json"
"errors" "errors"
"fmt"
"github.com/ethersphere/bee/pkg/logging"
"github.com/ethersphere/bee/pkg/storage" "github.com/ethersphere/bee/pkg/storage"
"github.com/syndtr/goleveldb/leveldb" "github.com/syndtr/goleveldb/leveldb"
ldberr "github.com/syndtr/goleveldb/leveldb/errors"
"github.com/syndtr/goleveldb/leveldb/util" "github.com/syndtr/goleveldb/leveldb/util"
) )
...@@ -19,16 +22,27 @@ var _ storage.StateStorer = (*store)(nil) ...@@ -19,16 +22,27 @@ var _ storage.StateStorer = (*store)(nil)
// Store uses LevelDB to store values. // Store uses LevelDB to store values.
type store struct { type store struct {
db *leveldb.DB db *leveldb.DB
logger logging.Logger
} }
// New creates a new persistent state storage. // New creates a new persistent state storage.
func NewStateStore(path string) (storage.StateStorer, error) { func NewStateStore(path string, l logging.Logger) (storage.StateStorer, error) {
db, err := leveldb.OpenFile(path, nil) db, err := leveldb.OpenFile(path, nil)
if err != nil { if err != nil {
if !ldberr.IsCorrupted(err) {
return nil, err return nil, err
} }
l.Warningf("statestore open failed: %v. attempting recovery", err)
db, err = leveldb.RecoverFile(path, nil)
if err != nil {
return nil, fmt.Errorf("statestore recovery: %w", err)
}
l.Warning("statestore recovery ok! you are kindly request to inform us about the steps that preceded the last Bee shutdown.")
}
return &store{ return &store{
db: db, db: db,
logger: l,
}, nil }, nil
} }
......
...@@ -26,7 +26,7 @@ func TestPersistentStateStore(t *testing.T) { ...@@ -26,7 +26,7 @@ func TestPersistentStateStore(t *testing.T) {
} }
}) })
store, err := leveldb.NewStateStore(dir) store, err := leveldb.NewStateStore(dir, nil)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
...@@ -40,7 +40,7 @@ func TestPersistentStateStore(t *testing.T) { ...@@ -40,7 +40,7 @@ func TestPersistentStateStore(t *testing.T) {
}) })
test.RunPersist(t, func(t *testing.T, dir string) storage.StateStorer { test.RunPersist(t, func(t *testing.T, dir string) storage.StateStorer {
store, err := leveldb.NewStateStore(dir) store, err := leveldb.NewStateStore(dir, nil)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment