Skip to content

Commit 0a8b820

Browse files
authored
triedb/pathdb: make batch with pre-allocated size (#32914)
In this PR, the database batch for writing the history index data is pre-allocated. It's observed that database batch repeatedly grows the size of the mega-batch, causing significant memory allocation pressure. This approach can effectively mitigate the overhead.
1 parent 79b6a56 commit 0a8b820

File tree

2 files changed

+26
-5
lines changed

2 files changed

+26
-5
lines changed

triedb/pathdb/history_index_block.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@ import (
2525
)
2626

2727
const (
28-
indexBlockDescSize = 14 // The size of index block descriptor
29-
indexBlockEntriesCap = 4096 // The maximum number of entries can be grouped in a block
30-
indexBlockRestartLen = 256 // The restart interval length of index block
31-
historyIndexBatch = 1_000_000 // The number of state history indexes for constructing or deleting as batch
28+
indexBlockDescSize = 14 // The size of index block descriptor
29+
indexBlockEntriesCap = 4096 // The maximum number of entries can be grouped in a block
30+
indexBlockRestartLen = 256 // The restart interval length of index block
31+
historyIndexBatch = 512 * 1024 // The number of state history indexes for constructing or deleting as batch
3232
)
3333

3434
// indexBlockDesc represents a descriptor for an index block, which contains a

triedb/pathdb/history_indexer.go

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,11 @@ const (
4040
stateHistoryIndexVersion = stateHistoryIndexV0 // the current state index version
4141
trienodeHistoryIndexV0 = uint8(0) // initial version of trienode index structure
4242
trienodeHistoryIndexVersion = trienodeHistoryIndexV0 // the current trienode index version
43+
44+
// estimations for calculating the batch size for atomic database commit
45+
estimatedStateHistoryIndexSize = 3 // The average size of each state history index entry is approximately 2–3 bytes
46+
estimatedTrienodeHistoryIndexSize = 3 // The average size of each trienode history index entry is approximately 2-3 bytes
47+
estimatedIndexBatchSizeFactor = 32 // The factor counts for the write amplification for each entry
4348
)
4449

4550
// indexVersion returns the latest index version for the given history type.
@@ -150,6 +155,22 @@ func (b *batchIndexer) process(h history, id uint64) error {
150155
return b.finish(false)
151156
}
152157

158+
// makeBatch constructs a database batch based on the number of pending entries.
159+
// The batch size is roughly estimated to minimize repeated resizing rounds,
160+
// as accurately predicting the exact size is technically challenging.
161+
func (b *batchIndexer) makeBatch() ethdb.Batch {
162+
var size int
163+
switch b.typ {
164+
case typeStateHistory:
165+
size = estimatedStateHistoryIndexSize
166+
case typeTrienodeHistory:
167+
size = estimatedTrienodeHistoryIndexSize
168+
default:
169+
panic(fmt.Sprintf("unknown history type %d", b.typ))
170+
}
171+
return b.db.NewBatchWithSize(size * estimatedIndexBatchSizeFactor * b.pending)
172+
}
173+
153174
// finish writes the accumulated state indexes into the disk if either the
154175
// memory limitation is reached or it's requested forcibly.
155176
func (b *batchIndexer) finish(force bool) error {
@@ -160,7 +181,7 @@ func (b *batchIndexer) finish(force bool) error {
160181
return nil
161182
}
162183
var (
163-
batch = b.db.NewBatch()
184+
batch = b.makeBatch()
164185
batchMu sync.RWMutex
165186
start = time.Now()
166187
eg errgroup.Group

0 commit comments

Comments
 (0)