mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-27 15:16:43 +00:00
core/rawdb: don't check different lenghts in freezer
This commit is contained in:
parent
f9f1172d59
commit
b22bb9869c
1 changed files with 81 additions and 34 deletions
|
|
@ -336,33 +336,68 @@ func (f *Freezer) Sync() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// splitTables splits tables in header and non-header tables
|
||||||
|
func splitTables(tables map[string]*freezerTable) (map[string]*freezerTable, map[string]*freezerTable) {
|
||||||
|
var (
|
||||||
|
headTables = make(map[string]*freezerTable)
|
||||||
|
otherTables = make(map[string]*freezerTable)
|
||||||
|
)
|
||||||
|
for kind, table := range tables {
|
||||||
|
if kind == ChainFreezerHeaderTable || kind == ChainFreezerHashTable {
|
||||||
|
headTables[kind] = table
|
||||||
|
} else {
|
||||||
|
otherTables[kind] = table
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return headTables, otherTables
|
||||||
|
}
|
||||||
|
|
||||||
// validate checks that every table has the same boundary.
|
// validate checks that every table has the same boundary.
|
||||||
// Used instead of `repair` in readonly mode.
|
// Used instead of `repair` in readonly mode.
|
||||||
func (f *Freezer) validate() error {
|
func (f *Freezer) validate() error {
|
||||||
if len(f.tables) == 0 {
|
if len(f.tables) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
check := func(tables map[string]*freezerTable) (uint64, uint64, error) {
|
||||||
var (
|
var (
|
||||||
head uint64
|
head uint64
|
||||||
tail uint64
|
tail uint64
|
||||||
name string
|
name string
|
||||||
)
|
)
|
||||||
// Hack to get boundary of any table
|
// Hack to get boundary of any table
|
||||||
for kind, table := range f.tables {
|
for kind, table := range tables {
|
||||||
head = table.items.Load()
|
head = table.items.Load()
|
||||||
tail = table.itemHidden.Load()
|
tail = table.itemHidden.Load()
|
||||||
name = kind
|
name = kind
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
// Now check every table against those boundaries.
|
// Now check every table against those boundaries.
|
||||||
for kind, table := range f.tables {
|
for kind, table := range tables {
|
||||||
if head != table.items.Load() {
|
if head != table.items.Load() {
|
||||||
return fmt.Errorf("freezer tables %s and %s have differing head: %d != %d", kind, name, table.items.Load(), head)
|
return 0, 0, fmt.Errorf("freezer tables %s and %s have differing head: %d != %d", kind, name, table.items.Load(), head)
|
||||||
}
|
}
|
||||||
if tail != table.itemHidden.Load() {
|
if tail != table.itemHidden.Load() {
|
||||||
return fmt.Errorf("freezer tables %s and %s have differing tail: %d != %d", kind, name, table.itemHidden.Load(), tail)
|
return 0, 0, fmt.Errorf("freezer tables %s and %s have differing tail: %d != %d", kind, name, table.itemHidden.Load(), tail)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return head, tail, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
headTables, otherTables := splitTables(f.tables)
|
||||||
|
// verify that all the non-header tables have the same size
|
||||||
|
head, tail, err := check(otherTables)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// verify that the header tables have the same size
|
||||||
|
if len(headTables) != 0 {
|
||||||
|
head, tail, err = check(headTables)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
f.frozen.Store(head)
|
f.frozen.Store(head)
|
||||||
f.tail.Store(tail)
|
f.tail.Store(tail)
|
||||||
return nil
|
return nil
|
||||||
|
|
@ -370,28 +405,40 @@ func (f *Freezer) validate() error {
|
||||||
|
|
||||||
// repair truncates all data tables to the same length.
|
// repair truncates all data tables to the same length.
|
||||||
func (f *Freezer) repair() error {
|
func (f *Freezer) repair() error {
|
||||||
|
repair := func(tables map[string]*freezerTable) (uint64, uint64, error) {
|
||||||
var (
|
var (
|
||||||
head = uint64(math.MaxUint64)
|
head = uint64(math.MaxUint64)
|
||||||
tail = uint64(0)
|
tail = uint64(0)
|
||||||
)
|
)
|
||||||
for _, table := range f.tables {
|
for _, table := range tables {
|
||||||
items := table.items.Load()
|
head = min(head, table.items.Load())
|
||||||
if head > items {
|
tail = max(tail, table.itemHidden.Load())
|
||||||
head = items
|
|
||||||
}
|
}
|
||||||
hidden := table.itemHidden.Load()
|
for _, table := range tables {
|
||||||
if hidden > tail {
|
|
||||||
tail = hidden
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for _, table := range f.tables {
|
|
||||||
if err := table.truncateHead(head); err != nil {
|
if err := table.truncateHead(head); err != nil {
|
||||||
return err
|
return 0, 0, err
|
||||||
}
|
}
|
||||||
if err := table.truncateTail(tail); err != nil {
|
if err := table.truncateTail(tail); err != nil {
|
||||||
|
return 0, 0, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return head, tail, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
headTables, otherTables := splitTables(f.tables)
|
||||||
|
// verify that all the non-header tables have the same size
|
||||||
|
head, tail, err := repair(otherTables)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// verify that the header tables have the same size
|
||||||
|
if len(headTables) != 0 {
|
||||||
|
head, tail, err = repair(headTables)
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
f.frozen.Store(head)
|
f.frozen.Store(head)
|
||||||
f.tail.Store(tail)
|
f.tail.Store(tail)
|
||||||
return nil
|
return nil
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue