6. 运维工具

6.1. 前言

ChainMaker Keeper 是长安链官方提供的命令行运维工具集,主要用于区块链数据的存储管理、数据完整性检查和数据重建等运维场景。当区块链数据出现损坏或需要重建历史数据时,可以使用该工具进行处理。

6.2. 工具简介

ChainMaker Keeper 是一个用于 ChainMaker 区块链的命令行工具集,提供以下核心功能:

  • 数据重建 - 从区块文件重建区块链数据库,支持选择性重建

  • 完整性检查 - 验证区块链数据的完整性和一致性

  • 多数据库支持 - 支持 LevelDB、BadgerDB 等多种存储后端

6.3. 系统要求

  • Go 1.18 或更高版本

  • Linux 操作系统

  • 足够的磁盘空间用于区块链数据操作

6.4. 安装部署

6.4.1. 从源码构建

# 克隆仓库
git clone https://git.chainmaker.org.cn/chainmaker/chainmaker-keeper.git
cd chainmaker-keeper

# 安装依赖
go mod download

# 构建
make build

# 移动到长安链bin目录
mv cmk /path/to/chainmaker/bin/

6.5. 快速开始

6.5.1. 基本使用

# 查看帮助
./cmk --help

# 查看版本信息
./cmk version

# 重建区块链数据
./cmk store rebuild --chain-id=chain1 --chainmaker-config=./chainmaker.yml

# 检查数据完整性
./cmk store check --chain-id=chain1 --chainmaker-config=./chainmaker.yml

6.6. 命令参考

6.6.1. store rebuild — 存储重建

从区块文件(bfdb)重建区块链数据库,当前支持重建 historyDB。

cmk store rebuild [flags]

主要参数:

选项 类型 说明 默认值
--chainmaker-config string Chainmaker 配置文件路径 ./chainmaker.yml
--config, -c string Keeper 日志配置文件路径 -
--chain-id string 链 ID chain1
--start-height uint 起始区块高度(不指定则从头开始) -
--end-height uint 结束区块高度(不指定则到最新区块) -
--log-level string 日志级别 (DEBUG/INFO/WARN/ERROR) INFO

使用示例:

# 完整重建(不指定高度范围 = 全量重建)
./cmk store rebuild \
  --chain-id=chain1 \
  --chainmaker-config=./chainmaker.yml

# 重建指定区块范围
./cmk store rebuild \
  --chain-id=chain1 \
  --chainmaker-config=./chainmaker.yml \
  --start-height=50000 \
  --end-height=100000

6.6.2. store check — 数据完整性检查

验证区块链数据的完整性和一致性。

cmk store check [flags]

主要参数:

选项 类型 说明 默认值
--chainmaker-config string Chainmaker 配置文件路径 ./chainmaker.yml
--config, -c string Keeper 日志配置文件路径 -
--chain-id string 链 ID chain1
--db-types strings 要检查的数据库类型 historyDB
--log-level string 日志级别 (DEBUG/INFO/WARN/ERROR) INFO

使用示例:

./cmk store check \
  --chain-id=chain1 \
  --chainmaker-config=./chainmaker.yml \
  --db-types=historyDB

6.7. 使用场景

6.7.1. 场景:重建历史数据

当需要重建 ChainMaker 的历史数据库时,按照以下步骤操作。

前提条件:cmk 必须放置在 ChainMaker 节点的 bin/ 目录下使用,因为工具依赖配置文件中的相对路径来定位数据目录。

6.7.1.1. 节点目录结构

chain1 为例,节点目录结构如下:

chainmaker-node/
├── bin/
│   ├── chainmaker
│   ├── cmk          # ← 放置在此处
│   ├── start.sh
│   ├── stop.sh
│   └── ...
├── config/
│   └── node1/
│       ├── chainmaker.yml
│       ├── log.yml
│       └── ...
├── data/                 # 数据目录(相对路径读取)
└── lib/

6.7.1.2. 操作步骤

1. 准备工作(无需停止服务)

将 cmk 放入 ChainMaker 的 bin 目录:

cp cmk /path/to/chainmaker-node/bin/
cd /path/to/chainmaker-node/bin/

复制配置文件(避免修改正在使用的配置文件):

cd ../config/node1
cp chainmaker.yml ./chainmaker.rebuild.yml

修改复制后的配置文件 chainmaker.rebuild.yml

⚠️ 核心原则:重建时必须指定新的存储路径,禁止使用原路径,否则会覆盖原数据造成不可逆损失!

根据您使用的存储后端类型修改对应配置项:

# LevelDB:将 `leveldb_config.store_path` 改为新目录

historydb_config:
  provider: leveldb
  leveldb_config:
    store_path: ../data/ledgerData1/rebuild_history   # ← 改为新目录

# BadgerDB:将 `badgerdb_config.store_path` 改为新目录

historydb_config:
  provider: badgerdb
  badgerdb_config:
    store_path: ../data/ledgerData1/rebuild_history   # ← 改为新目录

# SQL:在 `sqldb_config.db_prefix` 添加前缀

historydb_config:
  provider: sqlkv
  sqldb_config:
    sqldb_type: mysql
    dsn: root:password@tcp(127.0.0.1:3306)/
    db_prefix: rebuild_                         # ← 添加前缀

2. 执行重建

执行 rebuild 命令完整重建数据:

./cmk store rebuild \
  --chain-id=chain1 \
  --chainmaker-config=../config/node1/chainmaker.rebuild.yml

执行过程中会逐块读取并写入,看到以下日志表示重建完成:

Starting rebuild from height 0 to 604
...
async read block [height: 604] done, cost: 150.24µs
async write batch [height: 604, dbType: historyDB] done, cost: 2.468657ms
Rebuild operation completed successfully, cost 639.970436ms

3. 执行检查

执行 check 命令检查数据完整性:

./cmk store check \
  --chain-id=chain1 \
  --chainmaker-config=../config/node1/chainmaker.rebuild.yml \
  --db-types=historyDB

看到以下日志表示检查通过:

Successfully initialized historyDB checker
Checker 1/1 completed successfully
Blockchain data integrity check completed successfully in 393.336µs

4. 应用重建数据

停止服务,备份原数据,替换为新数据:

# 停止 ChainMaker 服务
./stop.sh

# 备份原有 historydb(用于快速恢复)
mv ../data/node1/history/chain1 ../data/node1/history/chain1.old

# 重命名重建的 rebuild_history/chain1 为 history/chain1
mv ../data/node1/rebuild_history/chain1 ../data/node1/history/chain1

# 重启 ChainMaker 服务
./start.sh

快速恢复方案(如果替换后服务异常):

# 停止服务
./stop.sh
# 恢复原数据
rm -rf ../data/node1/history/chain1
mv ../data/node1/history/chain1.old ../data/node1/history/chain1
# 重启服务
./start.sh

6.7.1.3. 注意事项

  • ✅ 重建过程可以在服务运行时执行,不影响正常业务

  • 复制配置文件后再修改,避免影响正在运行的服务

  • ⚠️ 应用新数据时需要短暂停止服务,建议在维护窗口执行

  • ⚠️ 确保有足够的磁盘空间(重建期间新旧数据并存,通常需要 2 倍以上空间)

  • 🔄 保留原数据备份,直到确认新数据库稳定运行

  • ⚠️ provider 类型(leveldb / badgerdb / sqlkv)必须与原配置保持一致,否则重建后的数据格式与服务不兼容

  • 💡 disable_key_historydisable_contract_historydisable_account_history 等开关建议与原配置保持一致,确保重建的数据范围与原数据一致

6.8. 日志配置

通过 --config-c)参数指定 Keeper 日志配置文件,支持灵活控制日志输出策略。不指定时使用硬编码默认配置。

配置文件格式(YAML):

log:
  log_level_default: INFO       # 日志级别:DEBUG / INFO / WARN / ERROR
  file_path: ./log/cmk.log     # 日志文件路径
  max_age: 365                  # 日志文件最大保留天数
  rotation_time: 1              # 日志文件滚动周期(天)
  log_in_console: true          # 是否输出到控制台
  show_color: true              # 控制台输出是否启用颜色

使用示例:

# 使用配置文件控制日志
./cmk store rebuild \
  --chain-id=chain1 \
  --chainmaker-config=./chainmaker.yml \
  --config=./config/config.yml

# --log-level 可覆盖配置文件中的日志级别
./cmk store rebuild \
  --chain-id=chain1 \
  --chainmaker-config=./chainmaker.yml \
  --config=./config/config.yml \
  --log-level=DEBUG

优先级:硬编码默认值 < 配置文件值 < 命令行 --log-level