Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lotus-shed splitstore clear command #6967

Merged
merged 4 commits into from
Aug 3, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions blockstore/splitstore/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
and automatically rewrite the lotus config to disable splitstore (with the `--rewrite-config` flag).
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.
The results are appended to `<lotus-repo>/datastore/splitstore/check.txt`.
- `info` -- prints some basic information about the splitstore.
99 changes: 98 additions & 1 deletion cmd/lotus-shed/splitstore.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (

"github.com/dgraph-io/badger/v2"
"github.com/urfave/cli/v2"
"go.uber.org/multierr"
"golang.org/x/sync/errgroup"
"golang.org/x/xerrors"

Expand All @@ -29,6 +30,7 @@ var splitstoreCmd = &cli.Command{
Description: "splitstore utilities",
Subcommands: []*cli.Command{
splitstoreRollbackCmd,
splitstoreClearCmd,
splitstoreCheckCmd,
splitstoreInfoCmd,
},
Expand Down Expand Up @@ -91,10 +93,16 @@ var splitstoreRollbackCmd = &cli.Command{
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...")
err = deleteSplitstoreDir(lr)
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...")
Expand All @@ -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 {
repoPath := lr.Path()
dataPath := filepath.Join(repoPath, "datastore")
Expand Down Expand Up @@ -224,6 +297,30 @@ func deleteSplitstoreDir(lr repo.LockedRepo) error {
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 {
ds, err := lr.Datastore(context.TODO(), "/metadata")
if err != nil {
Expand Down