mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-03 18:43:46 +00:00
Merge branch 'ethereum:master' into master
This commit is contained in:
commit
19f718f6e9
5 changed files with 94 additions and 61 deletions
|
|
@ -198,60 +198,73 @@ WARNING: This is a low-level operation which may cause database corruption!`,
|
|||
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
|
||||
// Resolve folder paths.
|
||||
var (
|
||||
rootDir = stack.ResolvePath("chaindata")
|
||||
ancientDir = 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)
|
||||
case ancientDir == "":
|
||||
ancientDir = filepath.Join(stack.ResolvePath("chaindata"), "ancient")
|
||||
case !filepath.IsAbs(ancientDir):
|
||||
ancientDir = config.Node.ResolvePath(ancientDir)
|
||||
}
|
||||
// Delete state data
|
||||
statePaths := []string{rootDir, filepath.Join(ancientDir, rawdb.StateFreezerName)}
|
||||
confirmAndRemoveDB(statePaths, "state data")
|
||||
|
||||
// Delete ancient chain
|
||||
chainPaths := []string{filepath.Join(ancientDir, rawdb.ChainFreezerName)}
|
||||
confirmAndRemoveDB(chainPaths, "ancient chain")
|
||||
return nil
|
||||
}
|
||||
|
||||
// removeFolder deletes all files (not folders) inside the directory 'dir' (but
|
||||
// not files in subfolders).
|
||||
func removeFolder(dir string) {
|
||||
filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
|
||||
// If we're at the top level folder, recurse into
|
||||
if path == dir {
|
||||
return nil
|
||||
}
|
||||
// Delete all the files, but not subfolders
|
||||
if !info.IsDir() {
|
||||
os.Remove(path)
|
||||
return nil
|
||||
}
|
||||
return filepath.SkipDir
|
||||
})
|
||||
}
|
||||
|
||||
// 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))
|
||||
// list of folders if accepted.
|
||||
func confirmAndRemoveDB(paths []string, kind string) {
|
||||
msg := fmt.Sprintf("Location(s) of '%s': \n", kind)
|
||||
for _, path := range paths {
|
||||
msg += fmt.Sprintf("\t- %s\n", path)
|
||||
}
|
||||
fmt.Println(msg)
|
||||
|
||||
confirm, err := prompt.Stdin.PromptConfirm(fmt.Sprintf("Remove '%s'?", kind))
|
||||
switch {
|
||||
case err != nil:
|
||||
utils.Fatalf("%v", err)
|
||||
case !confirm:
|
||||
log.Info("Database deletion skipped", "path", database)
|
||||
log.Info("Database deletion skipped", "kind", kind, "paths", paths)
|
||||
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
|
||||
var (
|
||||
deleted []string
|
||||
start = time.Now()
|
||||
)
|
||||
for _, path := range paths {
|
||||
if common.FileExist(path) {
|
||||
removeFolder(path)
|
||||
deleted = append(deleted, path)
|
||||
} else {
|
||||
log.Info("Folder is not existent", "path", path)
|
||||
}
|
||||
// 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)))
|
||||
}
|
||||
log.Info("Database successfully deleted", "kind", kind, "paths", deleted, "elapsed", common.PrettyDuration(time.Since(start)))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -68,14 +68,14 @@ var stateFreezerNoSnappy = map[string]bool{
|
|||
|
||||
// The list of identifiers of ancient stores.
|
||||
var (
|
||||
chainFreezerName = "chain" // the folder name of chain segment ancient store.
|
||||
stateFreezerName = "state" // the folder name of reverse diff ancient store.
|
||||
ChainFreezerName = "chain" // the folder name of chain segment ancient store.
|
||||
StateFreezerName = "state" // the folder name of reverse diff ancient store.
|
||||
)
|
||||
|
||||
// freezers the collections of all builtin freezers.
|
||||
var freezers = []string{chainFreezerName, stateFreezerName}
|
||||
var freezers = []string{ChainFreezerName, StateFreezerName}
|
||||
|
||||
// NewStateFreezer initializes the freezer for state history.
|
||||
func NewStateFreezer(ancientDir string, readOnly bool) (*ResettableFreezer, error) {
|
||||
return NewResettableFreezer(filepath.Join(ancientDir, stateFreezerName), "eth/db/state", readOnly, stateHistoryTableSize, stateFreezerNoSnappy)
|
||||
return NewResettableFreezer(filepath.Join(ancientDir, StateFreezerName), "eth/db/state", readOnly, stateHistoryTableSize, stateFreezerNoSnappy)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -81,14 +81,14 @@ func inspectFreezers(db ethdb.Database) ([]freezerInfo, error) {
|
|||
var infos []freezerInfo
|
||||
for _, freezer := range freezers {
|
||||
switch freezer {
|
||||
case chainFreezerName:
|
||||
info, err := inspect(chainFreezerName, chainFreezerNoSnappy, db)
|
||||
case ChainFreezerName:
|
||||
info, err := inspect(ChainFreezerName, chainFreezerNoSnappy, db)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
infos = append(infos, info)
|
||||
|
||||
case stateFreezerName:
|
||||
case StateFreezerName:
|
||||
if ReadStateScheme(db) != PathScheme {
|
||||
continue
|
||||
}
|
||||
|
|
@ -102,7 +102,7 @@ func inspectFreezers(db ethdb.Database) ([]freezerInfo, error) {
|
|||
}
|
||||
defer f.Close()
|
||||
|
||||
info, err := inspect(stateFreezerName, stateFreezerNoSnappy, f)
|
||||
info, err := inspect(StateFreezerName, stateFreezerNoSnappy, f)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -125,9 +125,9 @@ func InspectFreezerTable(ancient string, freezerName string, tableName string, s
|
|||
tables map[string]bool
|
||||
)
|
||||
switch freezerName {
|
||||
case chainFreezerName:
|
||||
case ChainFreezerName:
|
||||
path, tables = resolveChainFreezerDir(ancient), chainFreezerNoSnappy
|
||||
case stateFreezerName:
|
||||
case StateFreezerName:
|
||||
path, tables = filepath.Join(ancient, freezerName), stateFreezerNoSnappy
|
||||
default:
|
||||
return fmt.Errorf("unknown freezer, supported ones: %v", freezers)
|
||||
|
|
|
|||
|
|
@ -178,7 +178,7 @@ func resolveChainFreezerDir(ancient string) string {
|
|||
// sub folder, if not then two possibilities:
|
||||
// - chain freezer is not initialized
|
||||
// - chain freezer exists in legacy location (root ancient folder)
|
||||
freezer := path.Join(ancient, chainFreezerName)
|
||||
freezer := path.Join(ancient, ChainFreezerName)
|
||||
if !common.FileExist(freezer) {
|
||||
if !common.FileExist(ancient) {
|
||||
// The entire ancient store is not initialized, still use the sub
|
||||
|
|
|
|||
|
|
@ -170,14 +170,31 @@ func New(diskdb ethdb.Database, config *Config) *Database {
|
|||
}
|
||||
db.freezer = freezer
|
||||
|
||||
// Truncate the extra state histories above in freezer in case
|
||||
// it's not aligned with the disk layer.
|
||||
pruned, err := truncateFromHead(db.diskdb, freezer, db.tree.bottom().stateID())
|
||||
if err != nil {
|
||||
log.Crit("Failed to truncate extra state histories", "err", err)
|
||||
}
|
||||
if pruned != 0 {
|
||||
log.Warn("Truncated extra state histories", "number", pruned)
|
||||
diskLayerID := db.tree.bottom().stateID()
|
||||
if diskLayerID == 0 {
|
||||
// Reset the entire state histories in case the trie database is
|
||||
// not initialized yet, as these state histories are not expected.
|
||||
frozen, err := db.freezer.Ancients()
|
||||
if err != nil {
|
||||
log.Crit("Failed to retrieve head of state history", "err", err)
|
||||
}
|
||||
if frozen != 0 {
|
||||
err := db.freezer.Reset()
|
||||
if err != nil {
|
||||
log.Crit("Failed to reset state histories", "err", err)
|
||||
}
|
||||
log.Info("Truncated extraneous state history")
|
||||
}
|
||||
} else {
|
||||
// Truncate the extra state histories above in freezer in case
|
||||
// it's not aligned with the disk layer.
|
||||
pruned, err := truncateFromHead(db.diskdb, freezer, diskLayerID)
|
||||
if err != nil {
|
||||
log.Crit("Failed to truncate extra state histories", "err", err)
|
||||
}
|
||||
if pruned != 0 {
|
||||
log.Warn("Truncated extra state histories", "number", pruned)
|
||||
}
|
||||
}
|
||||
}
|
||||
// Disable database in case node is still in the initial state sync stage.
|
||||
|
|
@ -431,6 +448,9 @@ func (db *Database) Initialized(genesisRoot common.Hash) bool {
|
|||
inited = true
|
||||
}
|
||||
})
|
||||
if !inited {
|
||||
inited = rawdb.ReadSnapSyncStatusFlag(db.diskdb) != rawdb.StateSyncUnknown
|
||||
}
|
||||
return inited
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue