-
Notifications
You must be signed in to change notification settings - Fork 20.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
core, eth, trie: streaming GC for the trie cache #16810
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -674,7 +674,7 @@ func (bc *BlockChain) Stop() { | |
for !bc.triegc.Empty() { | ||
triedb.Dereference(bc.triegc.PopItem().(common.Hash), common.Hash{}) | ||
} | ||
if size := triedb.Size(); size != 0 { | ||
if size, _ := triedb.Size(); size != 0 { | ||
log.Error("Dangling trie nodes after full cleanup") | ||
} | ||
} | ||
|
@@ -916,33 +916,29 @@ func (bc *BlockChain) WriteBlockWithState(block *types.Block, receipts []*types. | |
bc.triegc.Push(root, -float32(block.NumberU64())) | ||
|
||
if current := block.NumberU64(); current > triesInMemory { | ||
// If we exceeded our memory allowance, flush matured singleton nodes to disk | ||
var ( | ||
nodes, imgs = triedb.Size() | ||
limit = common.StorageSize(bc.cacheConfig.TrieNodeLimit) * 1024 * 1024 | ||
) | ||
if nodes > limit || imgs > 4*1024*1024 { | ||
triedb.Cap(limit - ethdb.IdealBatchSize) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This will tell the triedb to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hysteresis. If we cap it as the limit, we will keep writing out 32 byte blobs. This way when we go over the limit, we push out 100KB, and then we have a bit of buffer to accumulate data before flushing. At least that's the theory. In practice, it might be interesting to see how much we overflow the limit. |
||
} | ||
// Find the next state trie we need to commit | ||
header := bc.GetHeaderByNumber(current - triesInMemory) | ||
chosen := header.Number.Uint64() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hi @karalabe, sorry to dig this out. I'm reading geth source code and just come across this part. May I know why do we choose the Otherwise There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is to support fast / snap sync. I need the latest 128 blocks' state available in the network. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yeah, well I mean the chosen trie to commit to disk on exceeding the |
||
|
||
// Only write to disk if we exceeded our memory allowance *and* also have at | ||
// least a given number of tries gapped. | ||
var ( | ||
size = triedb.Size() | ||
limit = common.StorageSize(bc.cacheConfig.TrieNodeLimit) * 1024 * 1024 | ||
) | ||
if size > limit || bc.gcproc > bc.cacheConfig.TrieTimeLimit { | ||
// If we exceeded out time allowance, flush an entire trie to disk | ||
if bc.gcproc > bc.cacheConfig.TrieTimeLimit { | ||
// If we're exceeding limits but haven't reached a large enough memory gap, | ||
// warn the user that the system is becoming unstable. | ||
if chosen < lastWrite+triesInMemory { | ||
switch { | ||
case size >= 2*limit: | ||
log.Warn("State memory usage too high, committing", "size", size, "limit", limit, "optimum", float64(chosen-lastWrite)/triesInMemory) | ||
case bc.gcproc >= 2*bc.cacheConfig.TrieTimeLimit: | ||
log.Info("State in memory for too long, committing", "time", bc.gcproc, "allowance", bc.cacheConfig.TrieTimeLimit, "optimum", float64(chosen-lastWrite)/triesInMemory) | ||
} | ||
} | ||
// If optimum or critical limits reached, write to disk | ||
if chosen >= lastWrite+triesInMemory || size >= 2*limit || bc.gcproc >= 2*bc.cacheConfig.TrieTimeLimit { | ||
triedb.Commit(header.Root, true) | ||
lastWrite = chosen | ||
bc.gcproc = 0 | ||
if chosen < lastWrite+triesInMemory && bc.gcproc >= 2*bc.cacheConfig.TrieTimeLimit { | ||
log.Info("State in memory for too long, committing", "time", bc.gcproc, "allowance", bc.cacheConfig.TrieTimeLimit, "optimum", float64(chosen-lastWrite)/triesInMemory) | ||
} | ||
// Flush an entire trie and restart the counters | ||
triedb.Commit(header.Root, true) | ||
lastWrite = chosen | ||
bc.gcproc = 0 | ||
} | ||
// Garbage collect anything below our required write retention | ||
for !bc.triegc.Empty() { | ||
|
@@ -1181,7 +1177,9 @@ func (bc *BlockChain) insertChain(chain types.Blocks) (int, []interface{}, []*ty | |
} | ||
stats.processed++ | ||
stats.usedGas += usedGas | ||
stats.report(chain, i, bc.stateCache.TrieDB().Size()) | ||
|
||
cache, _ := bc.stateCache.TrieDB().Size() | ||
stats.report(chain, i, cache) | ||
} | ||
// Append a single chain head event if we've progressed the chain | ||
if lastCanon != nil && bc.CurrentBlock().Hash() == lastCanon.Hash() { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -47,7 +47,7 @@ var DefaultConfig = Config{ | |
LightPeers: 100, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
DatabaseCache: 768, | ||
TrieCache: 256, | ||
TrieTimeout: 5 * time.Minute, | ||
TrieTimeout: 60 * time.Minute, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In blockchain.go There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmmm, I thought there would be used. |
||
GasPrice: big.NewInt(18 * params.Shannon), | ||
|
||
TxPool: core.DefaultTxPoolConfig, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the
4*1024*1024
limit forimgs
, and why is that not a named parameter like the other settings?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a random number really, just needs to be small enough not to be bothersome, large enough to dedup data. It's arbitrary really.