refactor: rename FlushStateMode::ALWAYS to FORCE_FLUSH
This prepares the addition of `FORCE_SYNC`. `empty_cache` in `FlushStateToDisk` was moved up to be reusable and `FlushStateMode::FORCE_FLUSH` was used as a placeholder before we properly split the two new states. `log_utxocache_flush.py` was regenerated and the alignment adjusted for the wider `FlushStateMode` values. Co-authored-by: Pieter Wuille <pieter@wuille.net> Co-authored-by: optout <13562139+optout21@users.noreply.github.com>
This commit is contained in:
7 files changed
+22
-22
No files matched your search
@@ -246,10 +246,10 @@ $ python3 contrib/tracing/log_utxocache_flush.py $(pidof bitcoind)
|
|||||||
|
|
||||||
```
|
```
|
||||||
Logging utxocache flushes. Ctrl-C to end...
|
Logging utxocache flushes. Ctrl-C to end...
|
||||||
Duration (µs) Mode Coins Count Memory Usage Prune
|
Duration (µs) Mode Coins Count Memory Usage Flush for Prune
|
||||||
730451 IF_NEEDED 22990 3323.54 kB True
|
2556340 IF_NEEDED 2899141 394844.34 kB False
|
||||||
637657 ALWAYS 122320 17124.80 kB False
|
2005788 FORCE_FLUSH 2238117 310189.68 kB False
|
||||||
81349 ALWAYS 0 1383.49 kB False
|
2685 FORCE_FLUSH 0 262.24 kB False
|
||||||
```
|
```
|
||||||
|
|
||||||
### log_utxos.bt
|
### log_utxos.bt
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ from bcc import BPF, USDT
|
|||||||
"""Example logging Bitcoin Core utxo set cache flushes utilizing
|
"""Example logging Bitcoin Core utxo set cache flushes utilizing
|
||||||
the utxocache:flush tracepoint."""
|
the utxocache:flush tracepoint."""
|
||||||
|
|
||||||
# USAGE: ./contrib/tracing/log_utxocache_flush.py path/to/bitcoind
|
# USAGE: ./contrib/tracing/log_utxocache_flush.py <pid of bitcoind>
|
||||||
|
|
||||||
# BCC: The C program to be compiled to an eBPF program (by BCC) and loaded into
|
# BCC: The C program to be compiled to an eBPF program (by BCC) and loaded into
|
||||||
# a sandboxed Linux kernel VM.
|
# a sandboxed Linux kernel VM.
|
||||||
@@ -45,7 +45,7 @@ FLUSH_MODES = [
|
|||||||
'NONE',
|
'NONE',
|
||||||
'IF_NEEDED',
|
'IF_NEEDED',
|
||||||
'PERIODIC',
|
'PERIODIC',
|
||||||
'ALWAYS'
|
'FORCE_FLUSH',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@@ -61,7 +61,7 @@ class Data(ctypes.Structure):
|
|||||||
|
|
||||||
|
|
||||||
def print_event(event):
|
def print_event(event):
|
||||||
print("%-15d %-10s %-15d %-15s %-8s" % (
|
print("%-15d %-12s %-15d %-15s %-8s" % (
|
||||||
event.duration,
|
event.duration,
|
||||||
FLUSH_MODES[event.mode],
|
FLUSH_MODES[event.mode],
|
||||||
event.coins_count,
|
event.coins_count,
|
||||||
@@ -88,7 +88,7 @@ def main(pid):
|
|||||||
|
|
||||||
b["flush"].open_perf_buffer(handle_flush)
|
b["flush"].open_perf_buffer(handle_flush)
|
||||||
print("Logging utxocache flushes. Ctrl-C to end...")
|
print("Logging utxocache flushes. Ctrl-C to end...")
|
||||||
print("%-15s %-10s %-15s %-15s %-8s" % ("Duration (µs)", "Mode",
|
print("%-15s %-12s %-15s %-15s %-8s" % ("Duration (µs)", "Mode",
|
||||||
"Coins Count", "Memory Usage",
|
"Coins Count", "Memory Usage",
|
||||||
"Flush for Prune"))
|
"Flush for Prune"))
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -185,8 +185,8 @@ Is called *after* the in-memory UTXO cache is flushed.
|
|||||||
|
|
||||||
Arguments passed:
|
Arguments passed:
|
||||||
1. Time it took to flush the cache microseconds as `int64`
|
1. Time it took to flush the cache microseconds as `int64`
|
||||||
2. Flush state mode as `uint32`. It's an enumerator class with values `0`
|
2. Flush state mode as `uint32`. It's an enumerator class with values
|
||||||
(`NONE`), `1` (`IF_NEEDED`), `2` (`PERIODIC`), `3` (`ALWAYS`)
|
`0` (`NONE`), `1` (`IF_NEEDED`), `2` (`PERIODIC`), `3` (`FORCE_FLUSH`),
|
||||||
3. Cache size (number of coins) before the flush as `uint64`
|
3. Cache size (number of coins) before the flush as `uint64`
|
||||||
4. Cache memory usage in bytes as `uint64`
|
4. Cache memory usage in bytes as `uint64`
|
||||||
5. If pruning caused the flush as `bool`
|
5. If pruning caused the flush as `bool`
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ BOOST_FIXTURE_TEST_CASE(write_during_multiblock_activation, TestChain100Setup)
|
|||||||
BOOST_CHECK_EQUAL(second_from_tip->pprev, chainstate.m_chain.Tip());
|
BOOST_CHECK_EQUAL(second_from_tip->pprev, chainstate.m_chain.Tip());
|
||||||
|
|
||||||
// Set m_next_write to current time
|
// Set m_next_write to current time
|
||||||
chainstate.FlushStateToDisk(state_dummy, FlushStateMode::ALWAYS);
|
chainstate.FlushStateToDisk(state_dummy, FlushStateMode::FORCE_FLUSH);
|
||||||
m_node.validation_signals->SyncWithValidationInterfaceQueue();
|
m_node.validation_signals->SyncWithValidationInterfaceQueue();
|
||||||
// The periodic flush interval is between 50 and 70 minutes (inclusive)
|
// The periodic flush interval is between 50 and 70 minutes (inclusive)
|
||||||
// The next call to a PERIODIC write will flush
|
// The next call to a PERIODIC write will flush
|
||||||
|
|||||||
+5
-5
@@ -2795,8 +2795,9 @@ bool Chainstate::FlushStateToDisk(
|
|||||||
bool fCacheCritical = mode == FlushStateMode::IF_NEEDED && cache_state >= CoinsCacheSizeState::CRITICAL;
|
bool fCacheCritical = mode == FlushStateMode::IF_NEEDED && cache_state >= CoinsCacheSizeState::CRITICAL;
|
||||||
// It's been a while since we wrote the block index and chain state to disk. Do this frequently, so we don't need to redownload or reindex after a crash.
|
// It's been a while since we wrote the block index and chain state to disk. Do this frequently, so we don't need to redownload or reindex after a crash.
|
||||||
bool fPeriodicWrite = mode == FlushStateMode::PERIODIC && nNow >= m_next_write;
|
bool fPeriodicWrite = mode == FlushStateMode::PERIODIC && nNow >= m_next_write;
|
||||||
|
const auto empty_cache{(mode == FlushStateMode::FORCE_FLUSH) || fCacheLarge || fCacheCritical};
|
||||||
// Combine all conditions that result in a write to disk.
|
// Combine all conditions that result in a write to disk.
|
||||||
bool should_write = (mode == FlushStateMode::ALWAYS) || fCacheLarge || fCacheCritical || fPeriodicWrite || fFlushForPrune;
|
bool should_write = empty_cache || fPeriodicWrite || fFlushForPrune;
|
||||||
// Write blocks, block index and best chain related state to disk.
|
// Write blocks, block index and best chain related state to disk.
|
||||||
if (should_write) {
|
if (should_write) {
|
||||||
LogDebug(BCLog::COINDB, "Writing chainstate to disk: flush mode=%s, prune=%d, large=%d, critical=%d, periodic=%d",
|
LogDebug(BCLog::COINDB, "Writing chainstate to disk: flush mode=%s, prune=%d, large=%d, critical=%d, periodic=%d",
|
||||||
@@ -2844,7 +2845,6 @@ bool Chainstate::FlushStateToDisk(
|
|||||||
return FatalError(m_chainman.GetNotifications(), state, _("Disk space is too low!"));
|
return FatalError(m_chainman.GetNotifications(), state, _("Disk space is too low!"));
|
||||||
}
|
}
|
||||||
// Flush the chainstate (which may refer to block index entries).
|
// Flush the chainstate (which may refer to block index entries).
|
||||||
const auto empty_cache{(mode == FlushStateMode::ALWAYS) || fCacheLarge || fCacheCritical};
|
|
||||||
empty_cache ? CoinsTip().Flush() : CoinsTip().Sync();
|
empty_cache ? CoinsTip().Flush() : CoinsTip().Sync();
|
||||||
full_flush_completed = true;
|
full_flush_completed = true;
|
||||||
TRACEPOINT(utxocache, flush,
|
TRACEPOINT(utxocache, flush,
|
||||||
@@ -2874,7 +2874,7 @@ bool Chainstate::FlushStateToDisk(
|
|||||||
void Chainstate::ForceFlushStateToDisk()
|
void Chainstate::ForceFlushStateToDisk()
|
||||||
{
|
{
|
||||||
BlockValidationState state;
|
BlockValidationState state;
|
||||||
if (!this->FlushStateToDisk(state, FlushStateMode::ALWAYS)) {
|
if (!this->FlushStateToDisk(state, FlushStateMode::FORCE_FLUSH)) {
|
||||||
LogWarning("Failed to force flush state (%s)", state.ToString());
|
LogWarning("Failed to force flush state (%s)", state.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5546,7 +5546,7 @@ bool Chainstate::ResizeCoinsCaches(size_t coinstip_size, size_t coinsdb_size)
|
|||||||
ret = FlushStateToDisk(state, FlushStateMode::IF_NEEDED);
|
ret = FlushStateToDisk(state, FlushStateMode::IF_NEEDED);
|
||||||
} else {
|
} else {
|
||||||
// Otherwise, flush state to disk and deallocate the in-memory coins map.
|
// Otherwise, flush state to disk and deallocate the in-memory coins map.
|
||||||
ret = FlushStateToDisk(state, FlushStateMode::ALWAYS);
|
ret = FlushStateToDisk(state, FlushStateMode::FORCE_FLUSH);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -5992,7 +5992,7 @@ util::Result<void> ChainstateManager::PopulateAndValidateSnapshot(
|
|||||||
// returns in `ActivateSnapshot()`, when `MaybeRebalanceCaches()` is
|
// returns in `ActivateSnapshot()`, when `MaybeRebalanceCaches()` is
|
||||||
// called, since we've added a snapshot chainstate and therefore will
|
// called, since we've added a snapshot chainstate and therefore will
|
||||||
// have to downsize the IBD chainstate, which will result in a call to
|
// have to downsize the IBD chainstate, which will result in a call to
|
||||||
// `FlushStateToDisk(ALWAYS)`.
|
// `FlushStateToDisk(FORCE_FLUSH)`.
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(index);
|
assert(index);
|
||||||
|
|||||||
+3
-3
@@ -457,12 +457,12 @@ enum DisconnectResult
|
|||||||
class ConnectTrace;
|
class ConnectTrace;
|
||||||
|
|
||||||
/** @see Chainstate::FlushStateToDisk */
|
/** @see Chainstate::FlushStateToDisk */
|
||||||
inline constexpr std::array FlushStateModeNames{"NONE", "IF_NEEDED", "PERIODIC", "ALWAYS"};
|
inline constexpr std::array FlushStateModeNames{"NONE", "IF_NEEDED", "PERIODIC", "FORCE_FLUSH"};
|
||||||
enum class FlushStateMode: uint8_t {
|
enum class FlushStateMode: uint8_t {
|
||||||
NONE,
|
NONE,
|
||||||
IF_NEEDED,
|
IF_NEEDED,
|
||||||
PERIODIC,
|
PERIODIC,
|
||||||
ALWAYS
|
FORCE_FLUSH,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -735,7 +735,7 @@ public:
|
|||||||
FlushStateMode mode,
|
FlushStateMode mode,
|
||||||
int nManualPruneHeight = 0);
|
int nManualPruneHeight = 0);
|
||||||
|
|
||||||
//! Unconditionally flush all changes to disk.
|
//! Flush all changes to disk.
|
||||||
void ForceFlushStateToDisk();
|
void ForceFlushStateToDisk();
|
||||||
|
|
||||||
//! Prune blockfiles from the disk if necessary and then flush chainstate changes
|
//! Prune blockfiles from the disk if necessary and then flush chainstate changes
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ FLUSHMODE_NAME = {
|
|||||||
0: "NONE",
|
0: "NONE",
|
||||||
1: "IF_NEEDED",
|
1: "IF_NEEDED",
|
||||||
2: "PERIODIC",
|
2: "PERIODIC",
|
||||||
3: "ALWAYS",
|
3: "FORCE_FLUSH",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -389,8 +389,8 @@ class UTXOCacheTracepointTest(BitcoinTestFramework):
|
|||||||
# A node shutdown causes two flushes. One that flushes UTXOS_IN_CACHE
|
# A node shutdown causes two flushes. One that flushes UTXOS_IN_CACHE
|
||||||
# UTXOs and one that flushes 0 UTXOs. Normally the 0-UTXO-flush is the
|
# UTXOs and one that flushes 0 UTXOs. Normally the 0-UTXO-flush is the
|
||||||
# second flush, however it can happen that the order changes.
|
# second flush, however it can happen that the order changes.
|
||||||
expected_flushes.append({"mode": "ALWAYS", "for_prune": False, "size": UTXOS_IN_CACHE})
|
expected_flushes.append({"mode": "FORCE_FLUSH", "for_prune": False, "size": UTXOS_IN_CACHE})
|
||||||
expected_flushes.append({"mode": "ALWAYS", "for_prune": False, "size": 0})
|
expected_flushes.append({"mode": "FORCE_FLUSH", "for_prune": False, "size": 0})
|
||||||
self.stop_node(0)
|
self.stop_node(0)
|
||||||
|
|
||||||
bpf.perf_buffer_poll(timeout=200)
|
bpf.perf_buffer_poll(timeout=200)
|
||||||
|
|||||||
Reference in new issue
Block a user