Skip to content

共享内存

VIZ 节点的所有区块链状态存储在由 chainbase 库管理的单一内存映射文件(shared_memory.bin)中。没有该文件节点无法运行。


架构

vizd 进程
├── block_log / dlt_block_log  — 原始区块字节(磁盘)
└── shared_memory.bin (mmap)   — 所有链状态(chainbase)
    ├── account_index
    ├── witness_index
    ├── transaction_index
    └── ... (所有其他对象索引)

API 线程(Web 服务器线程池)获取共享读锁;区块应用持有独占写锁。多个读者可以共存;写入时阻塞所有读者。


配置

所有选项在 config.ini 中设置。

大小选项

选项默认值描述
shared-file-dirstateshared_memory.bin 的目录(相对于数据目录或绝对路径)
shared-file-size2G初始分配大小。若文件已存在且此值更大,文件将增长,不触发重放。
inc-shared-file-size2G空闲空间低于阈值时的自动增长步长
min-free-shared-file-size500M触发自动增长的空闲空间阈值

规则: min-free-shared-file-size 必须小于 inc-shared-file-size,否则会发生级联大小调整。

锁超时选项

选项默认值描述
read-wait-micro500000(500 毫秒)每次读锁尝试的超时时间
max-read-wait-retries3出错前最大读取尝试次数
write-wait-micro500000(500 毫秒)每次写锁尝试的超时时间
max-write-wait-retries3出错前最大写入尝试次数

性能选项

选项默认值描述
single-write-threadfalse序列化所有区块/交易推送。生产环境推荐。
block-num-check-free-size1000每 N 个区块检查一次空闲空间
flush-state-interval每 N 个区块将共享内存刷新到磁盘
clear-votes-before-block0丢弃早于此区块的投票(0 = 保留全部)。减少内存使用。
skip-virtual-opsfalse跳过虚拟操作通知。重放时节省 CPU。

推荐配置

验证者节点(生产环境):

ini
shared-file-size = 4G
inc-shared-file-size = 2G
min-free-shared-file-size = 500M
single-write-thread = true

API 节点(高读取吞吐量):

ini
shared-file-size = 8G
inc-shared-file-size = 2G
min-free-shared-file-size = 500M
single-write-thread = true
read-wait-micro = 1000000
max-read-wait-retries = 10
webserver-thread-pool-size = 256

重放 / 初始同步:

ini
shared-file-size = 8G
inc-shared-file-size = 4G
min-free-shared-file-size = 500M
block-num-check-free-size = 10
skip-virtual-ops = true

自动调整大小

当空闲空间降至 min-free-shared-file-size 以下时,数据库自动增长。每次调整大小时:

  1. 暂停所有操作(包括区块生产和 API 请求)。
  2. 销毁当前内存映射。
  3. inc-shared-file-size 扩展文件。
  4. 重新映射文件并重建所有索引指针。

预先充裕地分配 shared-file-size 以最小化调整大小频率。每次调整大小都会导致延迟峰值。


大小规划

VIZ 主网全节点的大致使用量:

组件估计大小
账户索引(约 14K 个账户)~50 MB
验证者索引~5 MB
操作历史(operation_history 插件)200–500 MB
账户历史(account_history 插件)100–300 MB
其他索引100–200 MB
推荐起始大小4–8 GB

启动序列

1. 打开 shared_memory.bin(若 shared-file-size 更大则扩展)
2. 获取独占文件锁
3. 初始化索引
4. 若缺少 genesis → init_genesis()
5. 打开 block_log 或 dlt_block_log
6. undo_all() → 回滚到最后一个不可逆区块
7. 验证头区块与区块日志匹配

恢复

症状操作
CRITICAL: validator X account object MISSING损坏 — 使用 --replay-from-snapshot --snapshot-auto-latest
Could not modify object, uniqueness constraint violated损坏 — 使用 --replay-from-snapshot --snapshot-auto-latest
Unable to acquire READ lock锁竞争 — 增大 read-wait-micro / 启用 single-write-thread
节点启动时循环崩溃文件损坏 — --replay-from-snapshot --snapshot-auto-latest

恢复选项:

  • --replay-from-snapshot --snapshot-auto-latest — 删除共享内存,导入最新快照,重放 dlt_block_log。
  • --resync-blockchain — 删除共享内存和区块日志,从对等节点同步。
  • --snapshot <path> — 从指定快照加载,在其之上重放 dlt_block_log。

参见:Chain 插件Snapshot 插件区块日志