From 13d454796fb00b91705586e51d8cb4b1e9f187ff Mon Sep 17 00:00:00 2001 From: Chris Li Date: Tue, 16 Jul 2024 22:36:18 +0800 Subject: [PATCH] fix: pruneancient freeze from the previous position when the first time (#2542) --- core/rawdb/freezer_table.go | 5 +++++ core/rawdb/prunedfreezer.go | 43 ++++++++++++++++++++++++++++--------- 2 files changed, 38 insertions(+), 10 deletions(-) diff --git a/core/rawdb/freezer_table.go b/core/rawdb/freezer_table.go index 2158bc4b0..74152ee7b 100644 --- a/core/rawdb/freezer_table.go +++ b/core/rawdb/freezer_table.go @@ -127,6 +127,11 @@ func newFreezerTable(path, name string, disableSnappy, readonly bool) (*freezerT return newTable(path, name, metrics.NilMeter{}, metrics.NilMeter{}, metrics.NilGauge{}, freezerTableSize, disableSnappy, readonly) } +// newAdditionTable opens the given path as a addition table. +func newAdditionTable(path, name string, disableSnappy, readonly bool) (*freezerTable, error) { + return openAdditionTable(path, name, metrics.NilMeter{}, metrics.NilMeter{}, metrics.NilGauge{}, freezerTableSize, disableSnappy, readonly) +} + // newTable opens a freezer table, creating the data and index files if they are // non-existent. Both files are truncated to the shortest common length to ensure // they don't go out of sync. diff --git a/core/rawdb/prunedfreezer.go b/core/rawdb/prunedfreezer.go index 212d51735..b9c18ac2a 100644 --- a/core/rawdb/prunedfreezer.go +++ b/core/rawdb/prunedfreezer.go @@ -8,6 +8,8 @@ import ( "sync/atomic" "time" + "golang.org/x/exp/slices" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/log" @@ -66,28 +68,49 @@ func newPrunedFreezer(datadir string, db ethdb.KeyValueStore, offset uint64) (*p // repair init frozen , compatible disk-ancientdb and pruner-block-tool. func (f *prunedfreezer) repair(datadir string) error { - offset := atomic.LoadUint64(&f.frozen) // compatible freezer - min := uint64(math.MaxUint64) + minItems := uint64(math.MaxUint64) for name, disableSnappy := range chainFreezerNoSnappy { - table, err := newFreezerTable(datadir, name, disableSnappy, false) + var ( + table *freezerTable + err error + ) + if slices.Contains(additionTables, name) { + table, err = newAdditionTable(datadir, name, disableSnappy, false) + } else { + table, err = newFreezerTable(datadir, name, disableSnappy, false) + } if err != nil { return err } + // addition tables only align head + if slices.Contains(additionTables, name) { + if EmptyTable(table) { + continue + } + } items := table.items.Load() - if min > items { - min = items + if minItems > items { + minItems = items } table.Close() } - log.Info("Read ancientdb item counts", "items", min) - offset += min - if frozen := ReadFrozenOfAncientFreezer(f.db); frozen > offset { - offset = frozen + // If minItems is non-zero, it indicates that the chain freezer was previously enabled, and we should use minItems as the current frozen value. + // If minItems is zero, it indicates that the pruneAncient was previously enabled, and we should continue using frozen + // (retrieved from CurrentAncientFreezer) as the current frozen value. + offset := minItems + if offset == 0 { + // no item in ancientDB, init `offset` to the `f.frozen` + offset = atomic.LoadUint64(&f.frozen) } + log.Info("Read ancientdb item counts", "items", minItems, "offset", offset) - atomic.StoreUint64(&f.frozen, offset) + // FrozenOfAncientFreezer is the progress of the last prune-freezer freeze. + frozenInDB := ReadFrozenOfAncientFreezer(f.db) + maxOffset := max(offset, frozenInDB) + + atomic.StoreUint64(&f.frozen, maxOffset) if err := f.Sync(); err != nil { return nil }