forked from cerc-io/plugeth
cmd/geth: add db-command to inspect freezer index (#22633)
This PR makes it easier to inspect the freezer index, which could be useful to investigate things like #22111
This commit is contained in:
parent
6c27d8f996
commit
271e5b7fc9
@ -20,6 +20,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -60,6 +61,7 @@ Remove blockchain and state databases`,
|
|||||||
dbDeleteCmd,
|
dbDeleteCmd,
|
||||||
dbPutCmd,
|
dbPutCmd,
|
||||||
dbGetSlotsCmd,
|
dbGetSlotsCmd,
|
||||||
|
dbDumpFreezerIndex,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
dbInspectCmd = cli.Command{
|
dbInspectCmd = cli.Command{
|
||||||
@ -177,6 +179,22 @@ WARNING: This is a low-level operation which may cause database corruption!`,
|
|||||||
},
|
},
|
||||||
Description: "This command looks up the specified database key from the database.",
|
Description: "This command looks up the specified database key from the database.",
|
||||||
}
|
}
|
||||||
|
dbDumpFreezerIndex = cli.Command{
|
||||||
|
Action: utils.MigrateFlags(freezerInspect),
|
||||||
|
Name: "freezer-index",
|
||||||
|
Usage: "Dump out the index of a given freezer type",
|
||||||
|
ArgsUsage: "<type> <start (int)> <end (int)>",
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
utils.DataDirFlag,
|
||||||
|
utils.SyncModeFlag,
|
||||||
|
utils.MainnetFlag,
|
||||||
|
utils.RopstenFlag,
|
||||||
|
utils.RinkebyFlag,
|
||||||
|
utils.GoerliFlag,
|
||||||
|
utils.YoloV3Flag,
|
||||||
|
},
|
||||||
|
Description: "This command displays information about the freezer index.",
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
func removeDB(ctx *cli.Context) error {
|
func removeDB(ctx *cli.Context) error {
|
||||||
@ -449,3 +467,43 @@ func dbDumpTrie(ctx *cli.Context) error {
|
|||||||
}
|
}
|
||||||
return it.Err
|
return it.Err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func freezerInspect(ctx *cli.Context) error {
|
||||||
|
var (
|
||||||
|
start, end int64
|
||||||
|
disableSnappy bool
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
if ctx.NArg() < 3 {
|
||||||
|
return fmt.Errorf("required arguments: %v", ctx.Command.ArgsUsage)
|
||||||
|
}
|
||||||
|
kind := ctx.Args().Get(0)
|
||||||
|
if noSnap, ok := rawdb.FreezerNoSnappy[kind]; !ok {
|
||||||
|
var options []string
|
||||||
|
for opt := range rawdb.FreezerNoSnappy {
|
||||||
|
options = append(options, opt)
|
||||||
|
}
|
||||||
|
sort.Strings(options)
|
||||||
|
return fmt.Errorf("Could read freezer-type '%v'. Available options: %v", kind, options)
|
||||||
|
} else {
|
||||||
|
disableSnappy = noSnap
|
||||||
|
}
|
||||||
|
if start, err = strconv.ParseInt(ctx.Args().Get(1), 10, 64); err != nil {
|
||||||
|
log.Info("Could read start-param", "error", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if end, err = strconv.ParseInt(ctx.Args().Get(2), 10, 64); err != nil {
|
||||||
|
log.Info("Could read count param", "error", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
stack, _ := makeConfigNode(ctx)
|
||||||
|
defer stack.Close()
|
||||||
|
path := filepath.Join(stack.ResolvePath("chaindata"), "ancient")
|
||||||
|
log.Info("Opening freezer", "location", path, "name", kind)
|
||||||
|
if f, err := rawdb.NewFreezerTable(path, kind, disableSnappy); err != nil {
|
||||||
|
return err
|
||||||
|
} else {
|
||||||
|
f.DumpIndex(start, end)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@ -118,7 +118,7 @@ func newFreezer(datadir string, namespace string, readonly bool) (*freezer, erro
|
|||||||
trigger: make(chan chan struct{}),
|
trigger: make(chan chan struct{}),
|
||||||
quit: make(chan struct{}),
|
quit: make(chan struct{}),
|
||||||
}
|
}
|
||||||
for name, disableSnappy := range freezerNoSnappy {
|
for name, disableSnappy := range FreezerNoSnappy {
|
||||||
table, err := newTable(datadir, name, readMeter, writeMeter, sizeGauge, disableSnappy)
|
table, err := newTable(datadir, name, readMeter, writeMeter, sizeGauge, disableSnappy)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
for _, table := range freezer.tables {
|
for _, table := range freezer.tables {
|
||||||
|
@ -636,25 +636,24 @@ func (t *freezerTable) Sync() error {
|
|||||||
return t.head.Sync()
|
return t.head.Sync()
|
||||||
}
|
}
|
||||||
|
|
||||||
// printIndex is a debug print utility function for testing
|
// DumpIndex is a debug print utility function, mainly for testing. It can also
|
||||||
func (t *freezerTable) printIndex() {
|
// be used to analyse a live freezer table index.
|
||||||
|
func (t *freezerTable) DumpIndex(start, stop int64) {
|
||||||
buf := make([]byte, indexEntrySize)
|
buf := make([]byte, indexEntrySize)
|
||||||
|
|
||||||
fmt.Printf("|-----------------|\n")
|
fmt.Printf("| number | fileno | offset |\n")
|
||||||
fmt.Printf("| fileno | offset |\n")
|
fmt.Printf("|--------|--------|--------|\n")
|
||||||
fmt.Printf("|--------+--------|\n")
|
|
||||||
|
|
||||||
for i := uint64(0); ; i++ {
|
for i := uint64(start); ; i++ {
|
||||||
if _, err := t.index.ReadAt(buf, int64(i*indexEntrySize)); err != nil {
|
if _, err := t.index.ReadAt(buf, int64(i*indexEntrySize)); err != nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
var entry indexEntry
|
var entry indexEntry
|
||||||
entry.unmarshalBinary(buf)
|
entry.unmarshalBinary(buf)
|
||||||
fmt.Printf("| %03d | %03d | \n", entry.filenum, entry.offset)
|
fmt.Printf("| %03d | %03d | %03d | \n", i, entry.filenum, entry.offset)
|
||||||
if i > 100 {
|
if stop > 0 && i >= uint64(stop) {
|
||||||
fmt.Printf(" ... \n")
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fmt.Printf("|-----------------|\n")
|
fmt.Printf("|--------------------------|\n")
|
||||||
}
|
}
|
||||||
|
@ -525,7 +525,7 @@ func TestOffset(t *testing.T) {
|
|||||||
|
|
||||||
f.Append(4, getChunk(20, 0xbb))
|
f.Append(4, getChunk(20, 0xbb))
|
||||||
f.Append(5, getChunk(20, 0xaa))
|
f.Append(5, getChunk(20, 0xaa))
|
||||||
f.printIndex()
|
f.DumpIndex(0, 100)
|
||||||
f.Close()
|
f.Close()
|
||||||
}
|
}
|
||||||
// Now crop it.
|
// Now crop it.
|
||||||
@ -572,7 +572,7 @@ func TestOffset(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
f.printIndex()
|
f.DumpIndex(0, 100)
|
||||||
// It should allow writing item 6
|
// It should allow writing item 6
|
||||||
f.Append(numDeleted+2, getChunk(20, 0x99))
|
f.Append(numDeleted+2, getChunk(20, 0x99))
|
||||||
|
|
||||||
|
@ -114,9 +114,9 @@ const (
|
|||||||
freezerDifficultyTable = "diffs"
|
freezerDifficultyTable = "diffs"
|
||||||
)
|
)
|
||||||
|
|
||||||
// freezerNoSnappy configures whether compression is disabled for the ancient-tables.
|
// FreezerNoSnappy configures whether compression is disabled for the ancient-tables.
|
||||||
// Hashes and difficulties don't compress well.
|
// Hashes and difficulties don't compress well.
|
||||||
var freezerNoSnappy = map[string]bool{
|
var FreezerNoSnappy = map[string]bool{
|
||||||
freezerHeaderTable: false,
|
freezerHeaderTable: false,
|
||||||
freezerHashTable: true,
|
freezerHashTable: true,
|
||||||
freezerBodiesTable: false,
|
freezerBodiesTable: false,
|
||||||
|
Loading…
Reference in New Issue
Block a user