Skip to content

Commit

Permalink
core/rawdb: fsync head data file before closing it (#26490)
Browse files Browse the repository at this point in the history
This PR fixes an issue which might result in data lost in freezer.

Whenever mutation happens in freezer, all data will be written into head data file
and it will be rotated with a new one in case the size of file reaches the threshold.

Theoretically, the rotated old data file should be fsync'd to prevent data loss.
In freezer.Sync function, we only fsync: (1) index file (2) meta file and (3) head
data file. So this PR forcibly fsync the head data file if mutation happens in the
boundary of data file.
  • Loading branch information
rjl493456442 authored Jan 13, 2023
1 parent a21e963 commit e04d63e
Show file tree
Hide file tree
Showing 3 changed files with 8 additions and 5 deletions.
4 changes: 2 additions & 2 deletions core/rawdb/chain_freezer.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,14 +86,14 @@ func (f *chainFreezer) Close() error {
// This functionality is deliberately broken off from block importing to avoid
// incurring additional data shuffling delays on block propagation.
func (f *chainFreezer) freeze(db ethdb.KeyValueStore) {
nfdb := &nofreezedb{KeyValueStore: db}

var (
backoff bool
triggered chan struct{} // Used in tests
nfdb = &nofreezedb{KeyValueStore: db}
)
timer := time.NewTimer(freezerRecheckInterval)
defer timer.Stop()

for {
select {
case <-f.quit:
Expand Down
7 changes: 5 additions & 2 deletions core/rawdb/freezer_table.go
Original file line number Diff line number Diff line change
Expand Up @@ -852,8 +852,11 @@ func (t *freezerTable) advanceHead() error {
if err != nil {
return err
}

// Close old file, and reopen in RDONLY mode.
// Commit the contents of the old file to stable storage and
// tear it down. It will be re-opened in read-only mode.
if err := t.head.Sync(); err != nil {
return err
}
t.releaseFile(t.headId)
t.openFile(t.headId, openFreezerFileForReadOnly)

Expand Down
2 changes: 1 addition & 1 deletion core/rawdb/freezer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ func TestFreezerConcurrentModifyTruncate(t *testing.T) {

var item = make([]byte, 256)

for i := 0; i < 1000; i++ {
for i := 0; i < 10; i++ {
// First reset and write 100 items.
if err := f.TruncateHead(0); err != nil {
t.Fatal("truncate failed:", err)
Expand Down

0 comments on commit e04d63e

Please sign in to comment.