Skip to content

Commit 36a283e

Browse files
rjl493456442MatusKysel
authored andcommitted
core/rawdb: fsync the index file after each freezer write (ethereum#28483)
* core/rawdb: fsync the index and data file after each freezer write * core/rawdb: fsync the data file in freezer after write
1 parent 78d1cad commit 36a283e

File tree

4 files changed

+27
-10
lines changed

4 files changed

+27
-10
lines changed

core/rawdb/ancient_utils.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,8 @@ func InspectFreezerTable(ancient string, freezerName string, tableName string, s
129129
switch freezerName {
130130
case chainFreezerName:
131131
path, tables = resolveChainFreezerDir(ancient), chainFreezerNoSnappy
132+
case stateFreezerName:
133+
path, tables = filepath.Join(ancient, freezerName), stateFreezerNoSnappy
132134
default:
133135
return fmt.Errorf("unknown freezer, supported ones: %v", freezers)
134136
}

core/rawdb/freezer_batch.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -188,19 +188,27 @@ func (batch *freezerTableBatch) maybeCommit() error {
188188

189189
// commit writes the batched items to the backing freezerTable.
190190
func (batch *freezerTableBatch) commit() error {
191-
// Write data.
191+
// Write data. The head file is fsync'd after write to ensure the
192+
// data is truly transferred to disk.
192193
_, err := batch.t.head.Write(batch.dataBuffer)
193194
if err != nil {
194195
return err
195196
}
197+
if err := batch.t.head.Sync(); err != nil {
198+
return err
199+
}
196200
dataSize := int64(len(batch.dataBuffer))
197201
batch.dataBuffer = batch.dataBuffer[:0]
198202

199-
// Write indices.
203+
// Write indices. The index file is fsync'd after write to ensure the
204+
// data indexes are truly transferred to disk.
200205
_, err = batch.t.index.Write(batch.indexBuffer)
201206
if err != nil {
202207
return err
203208
}
209+
if err := batch.t.index.Sync(); err != nil {
210+
return err
211+
}
204212
indexSize := int64(len(batch.indexBuffer))
205213
batch.indexBuffer = batch.indexBuffer[:0]
206214

core/rawdb/freezer_table.go

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,9 @@ func (t *freezerTable) repair() error {
223223
if t.readonly {
224224
return fmt.Errorf("index file(path: %s, name: %s) size is not a multiple of %d", t.path, t.name, indexEntrySize)
225225
}
226-
truncateFreezerFile(t.index, stat.Size()-overflow) // New file can't trigger this path
226+
if err := truncateFreezerFile(t.index, stat.Size()-overflow); err != nil {
227+
return err
228+
} // New file can't trigger this path
227229
}
228230
// Retrieve the file sizes and prepare for truncation
229231
if stat, err = t.index.Stat(); err != nil {
@@ -268,8 +270,8 @@ func (t *freezerTable) repair() error {
268270
// Print an error log if the index is corrupted due to an incorrect
269271
// last index item. While it is theoretically possible to have a zero offset
270272
// by storing all zero-size items, it is highly unlikely to occur in practice.
271-
if lastIndex.offset == 0 && offsetsSize%indexEntrySize > 1 {
272-
log.Error("Corrupted index file detected", "lastOffset", lastIndex.offset, "items", offsetsSize%indexEntrySize-1)
273+
if lastIndex.offset == 0 && offsetsSize/indexEntrySize > 1 {
274+
log.Error("Corrupted index file detected", "lastOffset", lastIndex.offset, "indexes", offsetsSize/indexEntrySize)
273275
}
274276
if t.readonly {
275277
t.head, err = t.openFile(lastIndex.filenum, openFreezerFileForReadOnly)
@@ -424,6 +426,9 @@ func (t *freezerTable) truncateHead(items uint64) error {
424426
if err := truncateFreezerFile(t.index, int64(length+1)*indexEntrySize); err != nil {
425427
return err
426428
}
429+
if err := t.index.Sync(); err != nil {
430+
return err
431+
}
427432
// Calculate the new expected size of the data file and truncate it
428433
var expected indexEntry
429434
if length == 0 {
@@ -446,13 +451,17 @@ func (t *freezerTable) truncateHead(items uint64) error {
446451
// Release any files _after the current head -- both the previous head
447452
// and any files which may have been opened for reading
448453
t.releaseFilesAfter(expected.filenum, true)
454+
449455
// Set back the historic head
450456
t.head = newHead
451457
t.headId = expected.filenum
452458
}
453459
if err := truncateFreezerFile(t.head, int64(expected.offset)); err != nil {
454460
return err
455461
}
462+
if err := t.head.Sync(); err != nil {
463+
return err
464+
}
456465
// All data files truncated, set internal counters and return
457466
t.headBytes = int64(expected.offset)
458467
t.items.Store(items)
@@ -597,10 +606,12 @@ func (t *freezerTable) Close() error {
597606
// error on Windows.
598607
doClose(t.index, true, true)
599608
doClose(t.meta, true, true)
609+
600610
// The preopened non-head data-files are all opened in readonly.
601611
// The head is opened in rw-mode, so we sync it here - but since it's also
602612
// part of t.files, it will be closed in the loop below.
603613
doClose(t.head, true, false) // sync but do not close
614+
604615
for _, f := range t.files {
605616
doClose(f, false, true) // close but do not sync
606617
}

core/rawdb/freezer_utils.go

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -73,11 +73,7 @@ func copyFrom(srcPath, destPath string, offset uint64, before func(f *os.File) e
7373
return err
7474
}
7575
f = nil
76-
77-
if err := os.Rename(fname, destPath); err != nil {
78-
return err
79-
}
80-
return nil
76+
return os.Rename(fname, destPath)
8177
}
8278

8379
// openFreezerFileForAppend opens a freezer table file and seeks to the end

0 commit comments

Comments
 (0)