-
Notifications
You must be signed in to change notification settings - Fork 634
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #417 from ahrtr/surgery_clear_element_20230310
Add cobra style `surgery clear-page-elements` command
- Loading branch information
Showing
10 changed files
with
694 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package main | ||
|
||
import ( | ||
"github.com/spf13/cobra" | ||
) | ||
|
||
const ( | ||
cliName = "bbolt" | ||
cliDescription = "A simple command line tool for inspecting bbolt databases" | ||
) | ||
|
||
func NewRootCommand() *cobra.Command { | ||
rootCmd := &cobra.Command{ | ||
Use: cliName, | ||
Short: cliDescription, | ||
Version: "dev", | ||
} | ||
|
||
rootCmd.AddCommand( | ||
newSurgeryCobraCommand(), | ||
) | ||
|
||
return rootCmd | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
package main | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
"os" | ||
|
||
"github.com/spf13/cobra" | ||
|
||
"go.etcd.io/bbolt/internal/common" | ||
"go.etcd.io/bbolt/internal/surgeon" | ||
) | ||
|
||
var ( | ||
surgeryTargetDBFilePath string | ||
surgeryPageId uint64 | ||
surgeryStartElementIdx int | ||
surgeryEndElementIdx int | ||
) | ||
|
||
func newSurgeryCobraCommand() *cobra.Command { | ||
cmd := &cobra.Command{ | ||
Use: "surgery <subcommand>", | ||
Short: "surgery related commands", | ||
} | ||
|
||
cmd.AddCommand(newSurgeryClearPageElementsCommand()) | ||
|
||
return cmd | ||
} | ||
|
||
func newSurgeryClearPageElementsCommand() *cobra.Command { | ||
clearElementCmd := &cobra.Command{ | ||
Use: "clear-page-elements <bbolt-file> [options]", | ||
Short: "Clears elements from the given page, which can be a branch or leaf page", | ||
Args: func(cmd *cobra.Command, args []string) error { | ||
if len(args) == 0 { | ||
return errors.New("db file path not provided") | ||
} | ||
if len(args) > 1 { | ||
return errors.New("too many arguments") | ||
} | ||
return nil | ||
}, | ||
|
||
RunE: surgeryClearPageElementFunc, | ||
} | ||
|
||
clearElementCmd.Flags().StringVar(&surgeryTargetDBFilePath, "output", "", "path to the target db file") | ||
clearElementCmd.Flags().Uint64VarP(&surgeryPageId, "pageId", "", 0, "page id") | ||
clearElementCmd.Flags().IntVarP(&surgeryStartElementIdx, "from-index", "", 0, "start element index (included) to clear, starting from 0") | ||
clearElementCmd.Flags().IntVarP(&surgeryEndElementIdx, "to-index", "", 0, "end element index (excluded) to clear, starting from 0, -1 means to the end of page") | ||
|
||
return clearElementCmd | ||
} | ||
|
||
func surgeryClearPageElementFunc(cmd *cobra.Command, args []string) error { | ||
srcDBPath := args[0] | ||
|
||
if err := copyFile(srcDBPath, surgeryTargetDBFilePath); err != nil { | ||
return fmt.Errorf("[clear-page-element] copy file failed: %w", err) | ||
} | ||
|
||
if surgeryPageId < 2 { | ||
return fmt.Errorf("the pageId must be at least 2, but got %d", surgeryPageId) | ||
} | ||
|
||
needAbandonFreelist, err := surgeon.ClearPageElements(surgeryTargetDBFilePath, common.Pgid(surgeryPageId), surgeryStartElementIdx, surgeryEndElementIdx, false) | ||
if err != nil { | ||
return fmt.Errorf("clear-page-element command failed: %w", err) | ||
} | ||
|
||
if needAbandonFreelist { | ||
fmt.Fprintf(os.Stdout, "WARNING: The clearing has abandoned some pages that are not yet referenced from free list.\n") | ||
fmt.Fprintf(os.Stdout, "Please consider executing `./bbolt surgery abandon-freelist ...`\n") | ||
} | ||
|
||
fmt.Fprintf(os.Stdout, "All elements in [%d, %d) in page %d were cleared\n", surgeryStartElementIdx, surgeryEndElementIdx, surgeryPageId) | ||
return nil | ||
} |
Oops, something went wrong.