ITADN

High sustained MDBX COW writes at mainnet tip (110-140 MiB/block)

#23199Openmbg033 创建于 9 天前
performance
M
mbg033commented
#### System information Erigon version: ```text erigon version 3.5.4-28bc52d6 ``` The same behavior was also observed on Erigon `3.4.2`. OS & Version: ```text Guest: Ubuntu 24.04.4 LTS, Linux 6.8.0-137-generic, x86_64 Host: Proxmox VE 9.2.0, Linux 7.0.14-6-pve, x86_64 VM: 8 vCPU, 40 GiB RAM Disk: WD_BLACK SN850X 4 TB NVMe Host filesystem: ext4, noatime Guest data mount: virtiofs ``` There is no btrfs, ZFS, or autodefrag layer in the data path. SMART reports no media or data integrity errors. The node has very low JSON-RPC traffic during the measurements. Commit hash: `28bc52d6` Erigon command (addresses shortened; all other relevant flags are unchanged): ```text /usr/bin/erigon \ --chain=mainnet \ --datadir=/var/lib/eth/erigon \ --authrpc.addr=127.0.0.1 \ --authrpc.port=8551 \ --authrpc.jwtsecret=/var/lib/eth/jwt/jwt.hex \ --http \ --http.addr=<private-ip> \ --http.port=8545 \ --http.api=eth,net,web3,erigon,trace,ots \ --port=30303 \ --torrent.port=42069 \ --nat=stun \ --caplin.nat=stun \ --metrics \ --metrics.addr=<private-ip> \ --metrics.port=6060 \ --sync.loop.block.limit=10000 \ --batchSize=1g \ --caplin.max-peer-count=64 ``` Consensus Layer: embedded Caplin. I also reproduced the execution-layer write rate with Caplin disabled (`--externalcl`) and Lighthouse BN 8.2.1 connected to the Engine API. Consensus Layer command for the external-CL control: ```text lighthouse bn \ --network=mainnet \ --datadir=/var/lib/eth/lighthouse \ --execution-endpoint=http://127.0.0.1:8551 \ --execution-jwt=/var/lib/eth/jwt/jwt.hex \ --checkpoint-sync-url=https://mainnet.checkpoint.sigp.io ``` Chain/Network: Ethereum mainnet #### Expected behaviour I expected steady-state writes at chain tip to be substantially lower than `110-140 MiB` of MDBX copy-on-write pages and `160-180 MiB` of physical NVMe writes per execution block, especially while the MDBX file and total database size remain constant. If this write volume is expected for Erigon 3 at mainnet tip, please confirm it and consider documenting the expected steady-state write rate or write amplification. At the observed rate, the host writes approximately `1.2-1.4 TB/day` if the workload remains constant. #### Actual behaviour Erigon stays fully synced and healthy, but continuously writes approximately `13-15 MiB/s` to the physical NVMe at chain tip. The write activity continues without meaningful RPC load and stops when execution stops processing new blocks. The strongest 30-minute baseline on Erigon 3.5.4 processed 150 blocks with zero head lag and zero restarts: | Metric | Result | |---|---:| | Physical NVMe writes | `13.522 MiB/s` | | Physical NVMe writes per block | `162.26 MiB/block` | | MDBX COW writes | `9.166 MiB/s` | | MDBX COW writes per block | `109.99 MiB/block` | | MDBX page splits | `361.59/block` | | MDBX file size delta | `0` | The following controls were run on the same node and data directory: | Test | Duration | Blocks | Physical NVMe | MDBX COW | Notes | |---|---:|---:|---:|---:|---| | `--externalcl`, no CL input | `300s` | `0` | `0.369 MiB/s` | `0` | Execution head intentionally static | | Embedded Caplin | `300s` | `25` | `12.30 MiB/s` | `10.57 MiB/s` | Chain tip, lag `0` | | Caplin, parallel execution | `1800s` | `150` | `13.522 MiB/s` | `9.166 MiB/s` | Chain tip, lag `0` | | Caplin, `--exec.serial` | `1800s` | `149` | `13.358 MiB/s` | `10.180 MiB/s` | Chain tip, lag `0` | | External Lighthouse | `1812s` | `151` | `14.955 MiB/s` | `11.565 MiB/s` | Chain tip, lag `0`; Lighthouse was backfilling | Normalizing the two 30-minute Caplin execution modes by block: | Metric | Parallel | Serial | Serial change | |---|---:|---:|---:| | Physical NVMe write/block | `162.26 MiB` | `161.37 MiB` | `-0.55%` | | MDBX COW/block | `109.99 MiB` | `122.97 MiB` | `+11.81%` | | MDBX page splits/block | `361.59` | `415.05` | `+14.78%` | Therefore `--exec.serial` does not reduce the write amplification. Replacing Caplin with Lighthouse also does not reduce Erigon MDBX COW. The external Lighthouse physical-disk result includes its checkpoint backfill, but the MDBX COW metric is emitted by Erigon and remains high independently of that CL I/O. During longer observation periods: - `mdbx.dat` remained approximately `6.26 GiB`; - total `db_size{db="chaindata"}` remained constant; - `ReclaimableSpace`, `CommitmentVals`, and `ChangeSets3` changed in both directions instead of growing without bound; - `db_rotx_overloaded_total` remained `0`; - the execution head remained at the public head; - running Erigon with `--externalcl` and no CL input reduced physical writes to the host background level while the execution head remained static. This looks like sustained MDBX COW/page-split churn caused by per-block execution state and commitment updates rather than database growth, Caplin, pruning backlog, or RPC traffic. #### Steps to reproduce the behaviour 1. Sync Erigon 3.5.4 on Ethereum mainnet and wait for `eth_syncing=false` and zero public-head lag. 2. Wait at least five minutes after catch-up so catch-up execution is excluded. 3. Enable Erigon Prometheus metrics and scrape them every 15 seconds. 4. Measure an uninterrupted 30-minute chain-tip window. 5. Record the start and end execution block numbers and normalize all counters by the number of processed blocks. 6. Calculate MDBX COW bytes from the 16 KiB MDBX page counter: ```promql increase(db_pgops{db="chaindata",phase="cow"}[30m]) * 16384 ``` 7. Measure physical device writes using node-exporter or Linux diskstats: ```promql increase(node_disk_written_bytes_total{device="nvme0n1"}[30m]) ``` 8. Confirm that the physical write rate falls to the host background level when execution is intentionally held static with `--externalcl` and no CL. For a control that isolates consensus input, start Erigon with `--externalcl` and no CL. MDBX COW remains zero while the execution head is static. Then attach a synced external CL: MDBX COW returns as execution resumes at chain tip. #### Related work This report may be an operator-visible measurement of the work already tracked in: - #19801, which states that commitment dominates at tip and proposes delayed trie writes to reduce MDBX write amplification; - #21801, which attributes random MDBX page writes, splits, and overflow churn to large randomly keyed Commitment values and proposes a sequential value layout. Could you confirm whether `110-140 MiB` of MDBX COW per mainnet block is expected on 3.5.4 and whether these two changes are intended to address this steady-state write volume? I can provide raw Prometheus series, a longer test window, selected Erigon logs, or test a specific branch/build if useful. #### Backtrace There is no crash or backtrace. Erigon remains synced, has no automatic restarts, and logs no errors during the measurement windows.
29 条评论