core, ethdb: polish code

This commit is contained in:
Gary Rong 2025-04-25 17:01:06 +08:00
parent a64a85cf9a
commit 892113345f
4 changed files with 22 additions and 10 deletions

View file

@ -620,7 +620,8 @@ func (hc *HeaderChain) setHead(headBlock uint64, headTime uint64, updateFn Updat
// This step must be performed after synchronizing the key-value store; // This step must be performed after synchronizing the key-value store;
// otherwise, in the event of a panic, it's theoretically possible to // otherwise, in the event of a panic, it's theoretically possible to
// lose recent key-value store writes while the ancient store deletions // lose recent key-value store writes while the ancient store deletions
// remain, leading to data inconsistency. // remain, leading to data inconsistency, e.g., the gap between the key
// value store and ancient can be created due to unclean shutdown.
if delFn != nil { if delFn != nil {
// Ignore the error here since light client won't hit this path // Ignore the error here since light client won't hit this path
frozen, _ := hc.chainDb.Ancients() frozen, _ := hc.chainDb.Ancients()

View file

@ -329,7 +329,8 @@ func (db *Database) Path() string {
func (db *Database) Sync() error { func (db *Database) Sync() error {
// In theory, the WAL (Write-Ahead Log) can be explicitly synchronized using // In theory, the WAL (Write-Ahead Log) can be explicitly synchronized using
// a write operation with SYNC=true. However, there is no dedicated key reserved // a write operation with SYNC=true. However, there is no dedicated key reserved
// for this purpose, and even a nil key (key=nil) is considered a valid database entry. // for this purpose, and even a nil key (key=nil) is considered a valid
// database entry.
// //
// In LevelDB, writes are blocked until the data is written to the WAL, meaning // In LevelDB, writes are blocked until the data is written to the WAL, meaning
// recent writes won't be lost unless a power failure or system crash occurs. // recent writes won't be lost unless a power failure or system crash occurs.

View file

@ -182,10 +182,18 @@ func New(file string, cache int, handles int, namespace string, readonly bool) (
memTableSize = maxMemTableSize - 1 memTableSize = maxMemTableSize - 1
} }
db := &Database{ db := &Database{
fn: file, fn: file,
log: logger, log: logger,
quitChan: make(chan chan error), quitChan: make(chan chan error),
writeOptions: &pebble.WriteOptions{Sync: false},
// Use asynchronous write mode by default. Otherwise, the overhead of frequent fsync
// operations can be significant, especially on platforms with slow fsync performance
// (e.g., macOS) or less capable SSDs.
//
// Note that enabling async writes means recent data may be lost in the event of an
// application-level panic (writes will also be lost on a machine-level failure,
// of course). Geth is expected to handle recovery from an unclean shutdown.
writeOptions: pebble.NoSync,
} }
opt := &pebble.Options{ opt := &pebble.Options{
// Pebble has a single combined cache area and the write // Pebble has a single combined cache area and the write
@ -426,12 +434,11 @@ func (d *Database) Path() string {
// Sync flushes all pending writes in the write-ahead-log to disk, ensuring // Sync flushes all pending writes in the write-ahead-log to disk, ensuring
// data durability up to that point. // data durability up to that point.
func (d *Database) Sync() error { func (d *Database) Sync() error {
b := d.db.NewBatch()
// The entry (value=nil) is not written to the database; it is only // The entry (value=nil) is not written to the database; it is only
// added to the WAL. Writing this special log entry in sync mode // added to the WAL. Writing this special log entry in sync mode
// automatically flushes all previous writes, ensuring database // automatically flushes all previous writes, ensuring database
// durability up to this point. // durability up to this point.
b := d.db.NewBatch()
b.LogData(nil, nil) b.LogData(nil, nil)
return d.db.Apply(b, pebble.Sync) return d.db.Apply(b, pebble.Sync)
} }

View file

@ -135,8 +135,11 @@ func (b *buffer) flush(db ethdb.KeyValueStore, freezer ethdb.AncientWriter, node
start = time.Now() start = time.Now()
batch = db.NewBatchWithSize(b.nodes.dbsize() * 11 / 10) // extra 10% for potential pebble internal stuff batch = db.NewBatchWithSize(b.nodes.dbsize() * 11 / 10) // extra 10% for potential pebble internal stuff
) )
// Explicitly sync the state freezer, ensuring that all written // Explicitly sync the state freezer to ensure all written data is persisted to disk
// data is transferred to disk before updating the key-value store. // before updating the key-value store.
//
// This step is crucial to guarantee that the corresponding state history remains
// available for state rollback.
if freezer != nil { if freezer != nil {
if err := freezer.SyncAncient(); err != nil { if err := freezer.SyncAncient(); err != nil {
return err return err