cmd/geth: add db commands stats, compact, put, get, delete (#22014)
This PR introduces: - db.put to put a value into the database - db.get to read a value from the database - db.delete to delete a value from the database - db.stats to check compaction info from the database - db.compact to trigger a db compaction It also moves inspectdb to db.inspect.
This commit is contained in:
committed by
GitHub
parent
3ecfdccd9a
commit
c4a2b682ff
@ -20,7 +20,6 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"sync/atomic"
|
||||
@ -28,7 +27,6 @@ import (
|
||||
|
||||
"github.com/ethereum/go-ethereum/cmd/utils"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/console/prompt"
|
||||
"github.com/ethereum/go-ethereum/core"
|
||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||
"github.com/ethereum/go-ethereum/core/state"
|
||||
@ -170,18 +168,6 @@ The export-preimages command export hash preimages to an RLP encoded stream`,
|
||||
Category: "BLOCKCHAIN COMMANDS",
|
||||
Description: `
|
||||
The first argument must be the directory containing the blockchain to download from`,
|
||||
}
|
||||
removedbCommand = cli.Command{
|
||||
Action: utils.MigrateFlags(removeDB),
|
||||
Name: "removedb",
|
||||
Usage: "Remove blockchain and state databases",
|
||||
ArgsUsage: " ",
|
||||
Flags: []cli.Flag{
|
||||
utils.DataDirFlag,
|
||||
},
|
||||
Category: "BLOCKCHAIN COMMANDS",
|
||||
Description: `
|
||||
Remove blockchain and state databases`,
|
||||
}
|
||||
dumpCommand = cli.Command{
|
||||
Action: utils.MigrateFlags(dump),
|
||||
@ -202,25 +188,6 @@ Remove blockchain and state databases`,
|
||||
The arguments are interpreted as block numbers or hashes.
|
||||
Use "ethereum dump 0" to dump the genesis block.`,
|
||||
}
|
||||
inspectCommand = cli.Command{
|
||||
Action: utils.MigrateFlags(inspect),
|
||||
Name: "inspect",
|
||||
Usage: "Inspect the storage size for each type of data in the database",
|
||||
ArgsUsage: " ",
|
||||
Flags: []cli.Flag{
|
||||
utils.DataDirFlag,
|
||||
utils.AncientFlag,
|
||||
utils.CacheFlag,
|
||||
utils.MainnetFlag,
|
||||
utils.RopstenFlag,
|
||||
utils.RinkebyFlag,
|
||||
utils.GoerliFlag,
|
||||
utils.YoloV3Flag,
|
||||
utils.LegacyTestnetFlag,
|
||||
utils.SyncModeFlag,
|
||||
},
|
||||
Category: "BLOCKCHAIN COMMANDS",
|
||||
}
|
||||
)
|
||||
|
||||
// initGenesis will initialise the given JSON format genesis file and writes it as
|
||||
@ -323,17 +290,7 @@ func importChain(ctx *cli.Context) error {
|
||||
fmt.Printf("Import done in %v.\n\n", time.Since(start))
|
||||
|
||||
// Output pre-compaction stats mostly to see the import trashing
|
||||
stats, err := db.Stat("leveldb.stats")
|
||||
if err != nil {
|
||||
utils.Fatalf("Failed to read database stats: %v", err)
|
||||
}
|
||||
fmt.Println(stats)
|
||||
|
||||
ioStats, err := db.Stat("leveldb.iostats")
|
||||
if err != nil {
|
||||
utils.Fatalf("Failed to read database iostats: %v", err)
|
||||
}
|
||||
fmt.Println(ioStats)
|
||||
showLeveldbStats(db)
|
||||
|
||||
// Print the memory statistics used by the importing
|
||||
mem := new(runtime.MemStats)
|
||||
@ -351,22 +308,12 @@ func importChain(ctx *cli.Context) error {
|
||||
// Compact the entire database to more accurately measure disk io and print the stats
|
||||
start = time.Now()
|
||||
fmt.Println("Compacting entire database...")
|
||||
if err = db.Compact(nil, nil); err != nil {
|
||||
if err := db.Compact(nil, nil); err != nil {
|
||||
utils.Fatalf("Compaction failed: %v", err)
|
||||
}
|
||||
fmt.Printf("Compaction done in %v.\n\n", time.Since(start))
|
||||
|
||||
stats, err = db.Stat("leveldb.stats")
|
||||
if err != nil {
|
||||
utils.Fatalf("Failed to read database stats: %v", err)
|
||||
}
|
||||
fmt.Println(stats)
|
||||
|
||||
ioStats, err = db.Stat("leveldb.iostats")
|
||||
if err != nil {
|
||||
utils.Fatalf("Failed to read database iostats: %v", err)
|
||||
}
|
||||
fmt.Println(ioStats)
|
||||
showLeveldbStats(db)
|
||||
return importErr
|
||||
}
|
||||
|
||||
@ -499,66 +446,6 @@ func copyDb(ctx *cli.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func removeDB(ctx *cli.Context) error {
|
||||
stack, config := makeConfigNode(ctx)
|
||||
|
||||
// Remove the full node state database
|
||||
path := stack.ResolvePath("chaindata")
|
||||
if common.FileExist(path) {
|
||||
confirmAndRemoveDB(path, "full node state database")
|
||||
} else {
|
||||
log.Info("Full node state database missing", "path", path)
|
||||
}
|
||||
// Remove the full node ancient database
|
||||
path = config.Eth.DatabaseFreezer
|
||||
switch {
|
||||
case path == "":
|
||||
path = filepath.Join(stack.ResolvePath("chaindata"), "ancient")
|
||||
case !filepath.IsAbs(path):
|
||||
path = config.Node.ResolvePath(path)
|
||||
}
|
||||
if common.FileExist(path) {
|
||||
confirmAndRemoveDB(path, "full node ancient database")
|
||||
} else {
|
||||
log.Info("Full node ancient database missing", "path", path)
|
||||
}
|
||||
// Remove the light node database
|
||||
path = stack.ResolvePath("lightchaindata")
|
||||
if common.FileExist(path) {
|
||||
confirmAndRemoveDB(path, "light node database")
|
||||
} else {
|
||||
log.Info("Light node database missing", "path", path)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// confirmAndRemoveDB prompts the user for a last confirmation and removes the
|
||||
// folder if accepted.
|
||||
func confirmAndRemoveDB(database string, kind string) {
|
||||
confirm, err := prompt.Stdin.PromptConfirm(fmt.Sprintf("Remove %s (%s)?", kind, database))
|
||||
switch {
|
||||
case err != nil:
|
||||
utils.Fatalf("%v", err)
|
||||
case !confirm:
|
||||
log.Info("Database deletion skipped", "path", database)
|
||||
default:
|
||||
start := time.Now()
|
||||
filepath.Walk(database, func(path string, info os.FileInfo, err error) error {
|
||||
// If we're at the top level folder, recurse into
|
||||
if path == database {
|
||||
return nil
|
||||
}
|
||||
// Delete all the files, but not subfolders
|
||||
if !info.IsDir() {
|
||||
os.Remove(path)
|
||||
return nil
|
||||
}
|
||||
return filepath.SkipDir
|
||||
})
|
||||
log.Info("Database successfully deleted", "path", database, "elapsed", common.PrettyDuration(time.Since(start)))
|
||||
}
|
||||
}
|
||||
|
||||
func dump(ctx *cli.Context) error {
|
||||
stack, _ := makeConfigNode(ctx)
|
||||
defer stack.Close()
|
||||
@ -598,16 +485,6 @@ func dump(ctx *cli.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func inspect(ctx *cli.Context) error {
|
||||
node, _ := makeConfigNode(ctx)
|
||||
defer node.Close()
|
||||
|
||||
_, chainDb := utils.MakeChain(ctx, node, true)
|
||||
defer chainDb.Close()
|
||||
|
||||
return rawdb.InspectDatabase(chainDb)
|
||||
}
|
||||
|
||||
// hashish returns true for strings that look like hashes.
|
||||
func hashish(x string) bool {
|
||||
_, err := strconv.Atoi(x)
|
||||
|
Reference in New Issue
Block a user