mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-23 13:16:42 +00:00
soft truncate
This commit is contained in:
parent
1c431f6f95
commit
96963e75ad
4 changed files with 22 additions and 59 deletions
|
|
@ -1003,13 +1003,6 @@ func (bc *BlockChain) setHeadBeyondRoot(head uint64, time uint64, root common.Ha
|
|||
newHeadBlock, rootNumber = bc.rewindHead(header, root)
|
||||
rawdb.WriteHeadBlockHash(db, newHeadBlock.Hash())
|
||||
|
||||
// Use soft truncate for fast rewind - actual truncation happens at the end
|
||||
if bc.triedb.Scheme() == rawdb.PathScheme {
|
||||
if err := bc.triedb.SoftTruncateHead(); err != nil {
|
||||
log.Warn("Failed to soft truncate trie database", "err", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Degrade the chain markers if they are explicitly reverted.
|
||||
// In theory we should update all in-memory markers in the
|
||||
// last step, however the direction of SetHead is from high
|
||||
|
|
@ -1103,11 +1096,9 @@ func (bc *BlockChain) setHeadBeyondRoot(head uint64, time uint64, root common.Ha
|
|||
bc.blockCache.Purge()
|
||||
bc.txLookupCache.Purge()
|
||||
|
||||
// Commit all soft truncations to align the state histories with the current state.
|
||||
if bc.triedb.Scheme() == rawdb.PathScheme {
|
||||
if err := bc.triedb.CommitTruncation(); err != nil {
|
||||
log.Crit("Failed to commit trie database truncation", "err", err)
|
||||
}
|
||||
// Commit all recovery operations to finalize state freezer truncation.
|
||||
if err := bc.triedb.RecoverDone(); err != nil {
|
||||
log.Crit("Failed to finalize trie database recovery", "err", err)
|
||||
}
|
||||
|
||||
// Clear safe block, finalized block if needed
|
||||
|
|
|
|||
|
|
@ -280,35 +280,15 @@ func (db *Database) Recover(target common.Hash) error {
|
|||
return pdb.Recover(target)
|
||||
}
|
||||
|
||||
// TruncateHead truncates all state histories in the freezer above the bottom state layer.
|
||||
// This operation is only supported by path-based database. It's typically used during
|
||||
// state recovery to align the state histories with the current state.
|
||||
func (db *Database) TruncateHead() error {
|
||||
// RecoverDone commits all pending soft truncations after a series of recovery operations.
|
||||
// This should be called after all recover operations are complete to finalize the state
|
||||
// freezer truncation in one efficient batch operation.
|
||||
func (db *Database) RecoverDone() error {
|
||||
pdb, ok := db.backend.(*pathdb.Database)
|
||||
if !ok {
|
||||
return errors.New("not supported")
|
||||
}
|
||||
return pdb.TruncateHead()
|
||||
}
|
||||
|
||||
// SoftTruncateHead marks state histories above the bottom state layer as logically deleted
|
||||
// without physical truncation. This is much faster than TruncateHead.
|
||||
func (db *Database) SoftTruncateHead() error {
|
||||
pdb, ok := db.backend.(*pathdb.Database)
|
||||
if !ok {
|
||||
return errors.New("not supported")
|
||||
}
|
||||
return pdb.SoftTruncateHead()
|
||||
}
|
||||
|
||||
// CommitTruncation performs the actual file truncation to match any soft truncations.
|
||||
// This should be called after all soft truncations are complete.
|
||||
func (db *Database) CommitTruncation() error {
|
||||
pdb, ok := db.backend.(*pathdb.Database)
|
||||
if !ok {
|
||||
return errors.New("not supported")
|
||||
}
|
||||
return pdb.CommitTruncation()
|
||||
return pdb.RecoverDone()
|
||||
}
|
||||
|
||||
// Recoverable returns the indicator if the specified state is enabled to be
|
||||
|
|
|
|||
|
|
@ -502,26 +502,20 @@ func (db *Database) Recover(root common.Hash) error {
|
|||
if err := db.diskdb.SyncKeyValue(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Soft truncate the state freezer to the recovered state
|
||||
if _, err := db.stateFreezer.SoftTruncateHead(dl.stateID()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Debug("Recovered state", "root", root, "elapsed", common.PrettyDuration(time.Since(start)))
|
||||
return nil
|
||||
}
|
||||
|
||||
// TruncateHead truncates all state histories in the freezer above the bottom state layer.
|
||||
func (db *Database) TruncateHead() error {
|
||||
_, err := truncateFromHead(db.stateFreezer, db.tree.bottom().stateID())
|
||||
return err
|
||||
}
|
||||
|
||||
// SoftTruncateHead marks state histories above the bottom state layer as logically deleted
|
||||
// without physical truncation. This is much faster than TruncateHead.
|
||||
func (db *Database) SoftTruncateHead() error {
|
||||
_, err := db.stateFreezer.SoftTruncateHead(db.tree.bottom().stateID())
|
||||
return err
|
||||
}
|
||||
|
||||
// CommitTruncation performs the actual file truncation to match any soft truncations.
|
||||
// This should be called after all soft truncations are complete.
|
||||
func (db *Database) CommitTruncation() error {
|
||||
// RecoverDone commits all pending soft truncations after a series of recovery operations.
|
||||
// This should be called after all recover operations are complete to finalize the state
|
||||
// freezer truncation in one efficient batch operation.
|
||||
func (db *Database) RecoverDone() error {
|
||||
return db.stateFreezer.CommitTruncation()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -600,18 +600,16 @@ func TestDatabaseRollback(t *testing.T) {
|
|||
if err := tester.db.Recover(parent); err != nil {
|
||||
t.Fatalf("Failed to revert db, err: %v", err)
|
||||
}
|
||||
if err := tester.db.SoftTruncateHead(); err != nil {
|
||||
t.Fatalf("Failed to soft truncate head, err: %v", err)
|
||||
}
|
||||
if err := tester.db.CommitTruncation(); err != nil {
|
||||
t.Fatalf("Failed to commit truncation, err: %v", err)
|
||||
}
|
||||
if i > 0 {
|
||||
if err := tester.verifyState(parent); err != nil {
|
||||
t.Fatalf("Failed to verify state, err: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
// Finalize all recovery operations
|
||||
if err := tester.db.RecoverDone(); err != nil {
|
||||
t.Fatalf("Failed to finalize recovery, err: %v", err)
|
||||
}
|
||||
if tester.db.tree.len() != 1 {
|
||||
t.Fatal("Only disk layer is expected")
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue