1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
|
package main
import (
"fmt"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
bolt "go.etcd.io/bbolt"
"go.etcd.io/bbolt/internal/guts_cli"
)
type checkOptions struct {
fromPageID uint64
}
func (o *checkOptions) AddFlags(fs *pflag.FlagSet) {
fs.Uint64VarP(&o.fromPageID, "from-page", "", o.fromPageID, "check db integrity starting from the given page ID")
}
func newCheckCommand() *cobra.Command {
var o checkOptions
checkCmd := &cobra.Command{
Use: "check <bbolt-file>",
Short: "verify integrity of bbolt database data",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
return checkFunc(cmd, args[0], o)
},
}
o.AddFlags(checkCmd.Flags())
return checkCmd
}
func checkFunc(cmd *cobra.Command, dbPath string, cfg checkOptions) error {
if _, err := checkSourceDBPath(dbPath); err != nil {
return err
}
// Open database.
db, err := bolt.Open(dbPath, 0600, &bolt.Options{
ReadOnly: true,
PreLoadFreelist: true,
})
if err != nil {
return err
}
defer db.Close()
opts := []bolt.CheckOption{bolt.WithKVStringer(CmdKvStringer())}
if cfg.fromPageID != 0 {
opts = append(opts, bolt.WithPageId(cfg.fromPageID))
}
// Perform consistency check.
return db.View(func(tx *bolt.Tx) error {
var count int
for err := range tx.Check(opts...) {
fmt.Fprintln(cmd.OutOrStdout(), err)
count++
}
// Print summary of errors.
if count > 0 {
fmt.Fprintf(cmd.OutOrStdout(), "%d errors found\n", count)
return guts_cli.ErrCorrupt
}
// Notify user that database is valid.
fmt.Fprintln(cmd.OutOrStdout(), "OK")
return nil
})
}
|