Merge pull request #6967 from filecoin-project/tools/shed-splitstore-clear

lotus-shed splitstore clear command
This commit is contained in:
Jiaying Wang 2021-08-03 18:49:30 -04:00 committed by GitHub
commit faf8a47684
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 99 additions and 1 deletions

View File

@ -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.

View File

@ -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 {