mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-17 09:23:48 +00:00
core/rawdb: clean up freezer index truncation logic
Couple modifications here: - Use switch instead of a condition chain. It seems better to me since the idea is comparing the file size with flushOffset and performing different actions when it's larger, smaller, equal. - Rephrase some messages to add context. Users should be able to infer it's about the freezer from the message. - Rename 'offset' to 'size'.
This commit is contained in:
parent
a33bba4773
commit
791988fd32
1 changed files with 35 additions and 30 deletions
|
|
@ -393,52 +393,57 @@ func (t *freezerTable) repairIndex() error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
offset := stat.Size()
|
size := stat.Size()
|
||||||
|
|
||||||
// Validate the items in the index file to ensure the data integrity.
|
// Validate the items in the index file to ensure the data integrity.
|
||||||
// It's possible some garbage data is retained in the index file after
|
// It's possible some garbage data is retained in the index file after
|
||||||
// the power failures and should be truncated first.
|
// the power failures and should be truncated first.
|
||||||
offset, err = t.checkIndex(offset)
|
size, err = t.checkIndex(size)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// If legacy metadata is detected, attempt to recover the offset from the
|
// If legacy metadata is detected, attempt to recover the offset from the
|
||||||
// index file to avoid clearing the entire table.
|
// index file to avoid clearing the entire table.
|
||||||
if t.metadata.version == freezerTableV1 {
|
if t.metadata.version == freezerTableV1 {
|
||||||
t.logger.Info("Recover the flush offset for legacy table", "offset", offset)
|
t.logger.Info("Recovering freezer flushOffset for legacy table", "offset", size)
|
||||||
return t.metadata.setFlushOffset(uint64(offset), true)
|
return t.metadata.setFlushOffset(uint64(size), true)
|
||||||
}
|
}
|
||||||
// Move the flush offset to the end of the file for fresh new freezer table
|
|
||||||
if offset == indexEntrySize && t.metadata.flushOffset == 0 {
|
switch {
|
||||||
return t.metadata.setFlushOffset(uint64(offset), true)
|
case size == indexEntrySize && t.metadata.flushOffset == 0:
|
||||||
}
|
// It's a new freezer table with no content.
|
||||||
// Short circuit if the offset is aligned with the index file
|
// Move the flush offset to the end of the file.
|
||||||
if offset == int64(t.metadata.flushOffset) {
|
return t.metadata.setFlushOffset(uint64(size), true)
|
||||||
|
|
||||||
|
case size == int64(t.metadata.flushOffset):
|
||||||
|
// flushOffset is aligned with the index file, all is well.
|
||||||
return nil
|
return nil
|
||||||
}
|
|
||||||
// Extra index items have been detected beyond the flush offset. Since these
|
case size > int64(t.metadata.flushOffset):
|
||||||
// entries correspond to data that has not been fully flushed to disk in the
|
// Extra index items have been detected beyond the flush offset. Since these
|
||||||
// last run (because of unclean shutdown), their integrity cannot be guaranteed.
|
// entries correspond to data that has not been fully flushed to disk in the
|
||||||
// To ensure consistency, these index items will be truncated, as there is no
|
// last run (because of unclean shutdown), their integrity cannot be guaranteed.
|
||||||
// reliable way to validate or recover their associated data.
|
// To ensure consistency, these index items will be truncated, as there is no
|
||||||
if offset > int64(t.metadata.flushOffset) {
|
// reliable way to validate or recover their associated data.
|
||||||
size := offset - int64(t.metadata.flushOffset)
|
extraSize := size - int64(t.metadata.flushOffset)
|
||||||
if t.readonly {
|
if t.readonly {
|
||||||
return fmt.Errorf("index file(path: %s, name: %s) contains garbage data %d", t.path, t.name, size)
|
return fmt.Errorf("index file(path: %s, name: %s) contains %d garbage data bytes", t.path, t.name, extraSize)
|
||||||
}
|
}
|
||||||
t.logger.Info("Truncate excessive items", "size", size)
|
t.logger.Warn("Truncating freezer items after flushOffset", "size", extraSize)
|
||||||
return truncateFreezerFile(t.index, int64(t.metadata.flushOffset))
|
return truncateFreezerFile(t.index, int64(t.metadata.flushOffset))
|
||||||
|
|
||||||
|
default: // size < flushOffset
|
||||||
|
// Flush offset refers to a position larger than index file. The only
|
||||||
|
// possible scenario for this is: a power failure or system crash has occurred after
|
||||||
|
// truncating the segment in index file from head or tail, but without updating
|
||||||
|
// the flush offset. In this case, automatically reset the flush offset with
|
||||||
|
// the file size which implies the entire index file is complete.
|
||||||
|
if t.readonly {
|
||||||
|
return nil // do nothing in read only mode
|
||||||
|
}
|
||||||
|
t.logger.Warn("Rewinding freezer flushOffset", "old", t.metadata.flushOffset, "new", size)
|
||||||
|
return t.metadata.setFlushOffset(uint64(size), true)
|
||||||
}
|
}
|
||||||
// Flush offset refers to the position which exceeds the index file. The only
|
|
||||||
// possible scenario for this is: power failure or system crash occurs after
|
|
||||||
// truncating the segment in index file from head or tail, but without updating
|
|
||||||
// the flush offset. In this case, automatically reset the flush offset with
|
|
||||||
// the file size which implies the entire index file is complete.
|
|
||||||
if t.readonly {
|
|
||||||
return nil // do nothing in read only mode
|
|
||||||
}
|
|
||||||
t.logger.Info("Rewind the flush offset", "old", t.metadata.flushOffset, "new", offset)
|
|
||||||
return t.metadata.setFlushOffset(uint64(offset), true)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// checkIndex validates the integrity of the index file. According to the design,
|
// checkIndex validates the integrity of the index file. According to the design,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue