Merge pull request #6967 from filecoin-project/tools/shed-splitstore-clear
lotus-shed splitstore clear command
This commit is contained in:
commit
faf8a47684
@ -119,6 +119,7 @@ TBD -- see [#6577](https://github.com/filecoin-project/lotus/issues/6577)
|
|||||||
It can also optionally compact/gc the coldstore after the copy (with the `--gc-coldstore` flag)
|
It can also optionally compact/gc the coldstore after the copy (with the `--gc-coldstore` flag)
|
||||||
and automatically rewrite the lotus config to disable splitstore (with the `--rewrite-config` flag).
|
and automatically rewrite the lotus config to disable splitstore (with the `--rewrite-config` flag).
|
||||||
Note: the node *must be stopped* before running this command.
|
Note: the node *must be stopped* before running this command.
|
||||||
|
- `clear` -- clears a splitstore installation for restart from snapshot.
|
||||||
- `check` -- asynchronously runs a basic healthcheck on the splitstore.
|
- `check` -- asynchronously runs a basic healthcheck on the splitstore.
|
||||||
The results are appended to `<lotus-repo>/datastore/splitstore/check.txt`.
|
The results are appended to `<lotus-repo>/datastore/splitstore/check.txt`.
|
||||||
- `info` -- prints some basic information about the splitstore.
|
- `info` -- prints some basic information about the splitstore.
|
||||||
|
@ -11,6 +11,7 @@ import (
|
|||||||
|
|
||||||
"github.com/dgraph-io/badger/v2"
|
"github.com/dgraph-io/badger/v2"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
|
"go.uber.org/multierr"
|
||||||
"golang.org/x/sync/errgroup"
|
"golang.org/x/sync/errgroup"
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
@ -29,6 +30,7 @@ var splitstoreCmd = &cli.Command{
|
|||||||
Description: "splitstore utilities",
|
Description: "splitstore utilities",
|
||||||
Subcommands: []*cli.Command{
|
Subcommands: []*cli.Command{
|
||||||
splitstoreRollbackCmd,
|
splitstoreRollbackCmd,
|
||||||
|
splitstoreClearCmd,
|
||||||
splitstoreCheckCmd,
|
splitstoreCheckCmd,
|
||||||
splitstoreInfoCmd,
|
splitstoreInfoCmd,
|
||||||
},
|
},
|
||||||
@ -91,10 +93,16 @@ var splitstoreRollbackCmd = &cli.Command{
|
|||||||
return xerrors.Errorf("error copying hotstore to coldstore: %w", err)
|
return xerrors.Errorf("error copying hotstore to coldstore: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fmt.Println("clearing splitstore directory...")
|
||||||
|
err = clearSplitstoreDir(lr)
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("error clearing splitstore directory: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
fmt.Println("deleting splitstore directory...")
|
fmt.Println("deleting splitstore directory...")
|
||||||
err = deleteSplitstoreDir(lr)
|
err = deleteSplitstoreDir(lr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return xerrors.Errorf("error deleting splitstore directory: %w", err)
|
log.Warnf("error deleting splitstore directory: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println("deleting splitstore keys from metadata datastore...")
|
fmt.Println("deleting splitstore keys from metadata datastore...")
|
||||||
@ -118,6 +126,71 @@ var splitstoreRollbackCmd = &cli.Command{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var splitstoreClearCmd = &cli.Command{
|
||||||
|
Name: "clear",
|
||||||
|
Description: "clears a splitstore installation for restart from snapshot",
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "repo",
|
||||||
|
Value: "~/.lotus",
|
||||||
|
},
|
||||||
|
&cli.BoolFlag{
|
||||||
|
Name: "keys-only",
|
||||||
|
Usage: "only delete splitstore keys",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Action: func(cctx *cli.Context) error {
|
||||||
|
r, err := repo.NewFS(cctx.String("repo"))
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("error opening fs repo: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
exists, err := r.Exists()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !exists {
|
||||||
|
return xerrors.Errorf("lotus repo doesn't exist")
|
||||||
|
}
|
||||||
|
|
||||||
|
lr, err := r.Lock(repo.FullNode)
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("error locking repo: %w", err)
|
||||||
|
}
|
||||||
|
defer lr.Close() //nolint:errcheck
|
||||||
|
|
||||||
|
cfg, err := lr.Config()
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("error getting config: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fncfg, ok := cfg.(*config.FullNode)
|
||||||
|
if !ok {
|
||||||
|
return xerrors.Errorf("wrong config type: %T", cfg)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !fncfg.Chainstore.EnableSplitstore {
|
||||||
|
return xerrors.Errorf("splitstore is not enabled")
|
||||||
|
}
|
||||||
|
|
||||||
|
if !cctx.Bool("keys-only") {
|
||||||
|
fmt.Println("clearing splitstore directory...")
|
||||||
|
err = clearSplitstoreDir(lr)
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("error clearing splitstore directory: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("deleting splitstore keys from metadata datastore...")
|
||||||
|
err = deleteSplitstoreKeys(lr)
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("error deleting splitstore keys: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
func copyHotstoreToColdstore(lr repo.LockedRepo, gcColdstore bool) error {
|
func copyHotstoreToColdstore(lr repo.LockedRepo, gcColdstore bool) error {
|
||||||
repoPath := lr.Path()
|
repoPath := lr.Path()
|
||||||
dataPath := filepath.Join(repoPath, "datastore")
|
dataPath := filepath.Join(repoPath, "datastore")
|
||||||
@ -224,6 +297,30 @@ func deleteSplitstoreDir(lr repo.LockedRepo) error {
|
|||||||
return os.RemoveAll(path)
|
return os.RemoveAll(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func clearSplitstoreDir(lr repo.LockedRepo) error {
|
||||||
|
path, err := lr.SplitstorePath()
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("error getting splitstore path: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
entries, err := os.ReadDir(path)
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("error reading splitstore directory %s: %W", path, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var result error
|
||||||
|
for _, e := range entries {
|
||||||
|
target := filepath.Join(path, e.Name())
|
||||||
|
err = os.RemoveAll(target)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("error removing %s: %s", target, err)
|
||||||
|
result = multierr.Append(result, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
func deleteSplitstoreKeys(lr repo.LockedRepo) error {
|
func deleteSplitstoreKeys(lr repo.LockedRepo) error {
|
||||||
ds, err := lr.Datastore(context.TODO(), "/metadata")
|
ds, err := lr.Datastore(context.TODO(), "/metadata")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
Loading…
Reference in New Issue
Block a user