Skip to content

ckmanctl 命令行工具 ​

ckmanctl 是与 ckman 一起发行的命令行运维工具,用于完成 Web 界面之外的低频但关键操作:持久层迁移、ZooKeeper 维护、Schema 升级、直连 SQL 查询等。

仅给运维 / DBA 使用

ckmanctl 直接读写 ckman 的持久层和被管控集群的 ZooKeeper。操作前请先备份,并优先在测试环境演练。

安装位置 ​

安装方式ckmanctl 路径
tar.gz<工作目录>/bin/ckmanctl
rpm/usr/local/bin/ckmanctl
源码cmd/ckmanctl/ckmanctl(make backend 自动构建)

日志默认写到 /var/log/ckmanctl.log。如果当前用户无权写入该路径,ckmanctl 会输出告警并自动将日志写到标准错误,不会因此终止命令。

全局帮助 ​

bash
ckmanctl --help

子命令列表:

子命令作用
migrate在不同持久层之间迁移集群配置
dump-to-json把本地 SQLite 导出为 legacy clusters.json
sql持久层 SQL shell(交互或单次执行)
get znodes统计 ZooKeeper znode 数量
cleanup znodes suball删除指定集群在 ZK 上的全部子节点
cleanup znodes queue清理副本表的复制队列
set metacache重建集群的 metacache
upgrade backup升级旧 Backup 表到新 BackupPolicy / BackupRun schema
upgrade encryption把集群配置中的密码重写为 SM4 密文
keygen sm4生成 16 字节 SM4 密钥并输出 .env 格式

每个子命令都支持 --help:

bash
ckmanctl migrate --help
ckmanctl cleanup znodes suball --help

migrate ​

在不同持久层之间迁移 ckman 的集群配置。典型场景:

  • 从 local 切到 mysql / postgres / dm8
  • 从 mysql 切到 postgres
  • 一份本地配置文件复制到另一份
bash
ckmanctl migrate -c /etc/ckman/conf/migrate.hjson

配置文件 ​

源 / 目标在一个独立的 migrate.hjson 中描述,与 ckman.hjson 解耦:

hjson
{
  "source": "local2",     // 引用下面 persistent_config 中的某个 key
  "target": "mysql",
  "persistent_config": {
    "local1": {
      "policy": "local",
      "config": {
        "format": "yaml",
        "config_dir": "/etc/ckman/conf",
        "config_file": "ckman"
      }
    },
    "local2": {
      "policy": "local",
      "config": {
        "format": "json",
        "config_dir": "/etc/ckman/conf",
        "config_file": "clusters"
      }
    },
    "mysql": {
      "policy": "mysql",
      "config": {
        "host": "127.0.0.1",
        "port": 3306,
        "user": "root",
        "password": "1qaz@WSX",
        "database": "ckman_migrate"
      }
    }
  }
}
字段含义
source数据从哪里读,键名引用 persistent_config 中的条目
target数据写到哪里,同上

关于 local 条目

新版本 CKMAN 的 local 策略已经是 SQLite(<config_dir>/<config_file>.db)。在 migrate.hjson 中:

  • 不写 format → 自动识别新 SQLite 或老 clusters.json / clusters.yaml
  • format: "json" / format: "yaml" → 显式从老格式读取,方便从历史数据迁出

target 端若为 local,总是写入 SQLite,无视 format。

| persistent_config.<key>.policy | 该条目的持久化类型:local / mysql / postgres / dm8 | | persistent_config.<key>.config | 该类型对应的连接参数 |

执行流程 ​

  1. 解析配置文件
  2. 同时连上 source 与 target
  3. 读取 source 全部集群数据
  4. 逐条写入 target
  5. 任一步失败立即中断(不会写入半数据)

安全建议

  • 迁移前停掉 ckman 服务,避免源数据在迁移途中被改
  • target 数据库最好是空库,避免与已有数据冲突
  • 迁移成功后再启动 ckman,并把 ckman.hjson 的 persistent_policy 切到新后端

dump-to-json ​

把当前 SQLite(local 策略下的 conf/clusters.db)导出为兼容旧版的 clusters.json 文件。

bash
ckmanctl dump-to-json -c /etc/ckman/conf/ckman.hjson -o conf/clusters.json
参数默认说明
-c, --conf/etc/ckman/conf/ckman.hjsonckman 配置文件
-o, --outputconf/clusters.json输出 JSON 路径

应用场景

  • 跨版本回退:新版本 CKMAN 的 local 策略落到 SQLite,旧版本只认 clusters.json;导出后即可在旧版上加载
  • 调试 / 离线分析:把 SQLite 内容快速读成结构化 JSON

不是常规备份方式

日常备份直接复制 conf/clusters.db 即可(SQLite WAL 模式下也能安全在线复制)。dump-to-json 主要服务于版本兼容场景。


sql ​

直接对 ckman 持久层执行 SQL,支持交互式 shell 和单次执行。

交互模式 ​

bash
ckmanctl sql -c /etc/ckman/conf/ckman.hjson

进入提示符后可直接输入 SQL,支持历史回滚、\q 退出。

单次执行 ​

bash
ckmanctl sql \
  -c /etc/ckman/conf/ckman.hjson \
  -q "SELECT cluster_name, mode FROM tbl_cluster"

输出格式 ​

参数默认说明
--formattabletable / json / csv
-E, --verticalfalse行竖排(类似 mysql \G),列数多时更易读
-N, --no-truncatefalse不截断长字段

示例:

bash
# 导出为 csv
ckmanctl sql -q "SELECT * FROM tbl_task" --format csv > tasks.csv

# 列多时用竖排查看单行
ckmanctl sql -q "SELECT * FROM tbl_cluster LIMIT 1" -E

谨慎执行写操作

sql 子命令具有完整读写权限。请避免直接 UPDATE / DELETE ckman 表,可能破坏后台运行逻辑。生产排查建议只用 SELECT。


get znodes ​

统计 ZooKeeper 上指定路径的 znode 数量,便于评估 ZK 数据规模。

bash
ckmanctl get znodes /clickhouse/tables/test_cluster -r -s 20 -h 127.0.0.1:2181
参数默认说明
<path> (位置参数)/clickhouse起始路径
-h, --host127.0.0.1:2181ZK 地址
-r, --recursivefalse递归统计子节点
-s, --sort—按子节点数量排序,输出前 N 个

示例输出(按数量排序,仅看 top 20):

/clickhouse/tables/test/01/cdc_log_local           1234567
/clickhouse/tables/test/02/cdc_log_local           1234500
...

适用场景:ZK 数据膨胀排查——找出哪个表/集群占用最多 znode。


cleanup znodes suball ​

删除指定集群在 ZK 上的全部子节点。

不可逆操作

该操作会清掉该集群相关的复制元数据、分布式 DDL 记录、任务标记等。集群必须先停服,否则会导致数据状态混乱。

务必先用 --dryrun 演练一次。

bash
# dryrun:只打印会删什么,不真删
ckmanctl cleanup znodes suball test_cluster -c /etc/ckman/conf/ckman.hjson -d

# 真正执行
ckmanctl cleanup znodes suball test_cluster -c /etc/ckman/conf/ckman.hjson
参数默认说明
<cluster> (位置参数)—集群名
-c, --conf/etc/ckman/conf/ckman.hjsonckman 配置(用于读取该集群的 ZK 地址)
-p, --path—自定义 znode 根路径(默认根据集群信息推断)
-d, --dryrunfalse演练模式,不真删

适用场景:

  • 彻底销毁集群后清理残留 ZK 数据
  • 重建集群前清空旧的副本元信息

cleanup znodes queue ​

清理副本表的复制队列(/clickhouse/tables/.../replicas/<host>/queue)。

复制队列长期堆积会导致副本同步停滞、磁盘占用上涨。在确认队列项已经过期或失效时可以清理。

bash
# dryrun
ckmanctl cleanup znodes queue test_cluster -c /etc/ckman/conf/ckman.hjson -d

# 执行(默认会话超时 300 秒)
ckmanctl cleanup znodes queue test_cluster -c /etc/ckman/conf/ckman.hjson -t 600
参数默认说明
<cluster> (位置参数)—集群名
-c, --conf/etc/ckman/conf/ckman.hjsonckman 配置
-t, --session_timeout300ZK 会话超时(秒)
-d, --dryrunfalse演练模式

优先用 ClickHouse 内置命令

如果只是个别表的复制队列异常,建议先尝试 ClickHouse 的:

sql
SYSTEM RESTART REPLICA <db>.<table>;
SYSTEM RESTORE REPLICA <db>.<table>;

ckmanctl cleanup znodes queue 适用于整集群批量场景。


set metacache ​

为指定集群重建 metacache(ckman 持久层中缓存的集群元数据,如表结构)。

bash
ckmanctl set metacache test_cluster -c /etc/ckman/conf/ckman.hjson

# dryrun
ckmanctl set metacache test_cluster -d
参数默认说明
<cluster> (位置参数)—集群名
-c, --conf/etc/ckman/conf/ckman.hjsonckman 配置
-d, --dryrunfalse演练模式,只打印计划

适用场景:

  • 大量后台改动 ClickHouse 表结构后,ckman 缓存仍是旧版本
  • metacache 损坏导致 Web 界面表信息错乱

keygen sm4 ​

用 Go 的安全随机数生成器生成 16 字节 SM4 密钥,输出一行 CKMAN_SM4_KEY=<Base64字符串>,无需 OpenSSL。只在首次配置时运行;已有 SM4 密文时,应继续使用原密钥。RPM 安装写入文件的完整命令见配置总览。

bash
ckmanctl keygen sm4

upgrade encryption ​

将集群配置中的密码、SSH 密码、用户密码、S3 密钥和 TLS 私钥统一重写为 SM4-GCM 密文。旧 AES 密文没有前缀,新密文使用 sm4:gcm:v1: 前缀;读取时按密文识别算法。此命令不修改 ckman.hjson 中的 ENC(...) 值,需要时用 ckman --encrypt-algorithm SM4 --encrypt '密码' 生成并替换。

迁移步骤 ​

以下以 RPM 安装、local(SQLite)持久层为例。其他持久层使用各自数据库的备份方式;多实例部署要停止所有 ckman 写入实例。local 的数据库路径默认是 /etc/ckman/conf/clusters.db,如改过 persistent_config.local,请相应调整备份路径。

  1. 确认已安装支持 SM4 的 ckman 和 ckmanctl。在主配置文件顶层设置 encrypt_algorithm: SM4,并在配置文件同目录的 .ckman.env 中设置现有的 CKMAN_SM4_KEY。例如 /etc/ckman/conf/ckman.hjson 对应 /etc/ckman/conf/.ckman.env。密钥生成、已有密钥格式和文件权限见配置总览。已有 SM4 数据时不要重新生成密钥。

  2. 保持服务运行,先演练解密和集群数量;演练不重写集群记录:

bash
ckmanctl upgrade encryption -c /etc/ckman/conf/ckman.hjson --dry-run
  1. 演练通过后,先确认备份示例所需的 python3 可用,再停止 ckman,备份数据库、主配置和密钥文件。SQLite 可能还有未合并到 .db 的 WAL 数据,因此用 SQLite 备份接口生成一致快照,不要只复制正在使用的 .db 文件:
bash
command -v python3
systemctl stop ckman
ckman_backup_dir=/var/backups/ckman/sm4-$(date +%Y%m%d%H%M%S)
install -d -m 700 "$ckman_backup_dir"
cp -p /etc/ckman/conf/ckman.hjson "$ckman_backup_dir/ckman.hjson"
cp -p /etc/ckman/conf/.ckman.env "$ckman_backup_dir/.ckman.env"
python3 - "$ckman_backup_dir/clusters.db" <<'PY'
import os, sqlite3, sys
src = sqlite3.connect('file:/etc/ckman/conf/clusters.db?mode=ro', uri=True)
dst = sqlite3.connect(sys.argv[1])
src.backup(dst)
assert dst.execute('PRAGMA quick_check').fetchone()[0] == 'ok'
dst.close()
src.close()
os.chmod(sys.argv[1], 0o600)
PY

上例假设使用 .ckman.env;如果密钥来自 CKMAN_SM4_KEY_FILE 或 systemd 环境配置,也要备份相应文件。备份目录应只允许管理员访问。

  1. 执行正式迁移。工具先解密所有集群,再在一个持久层事务中重写;任何集群失败会回滚本次写入。它会重写全部集群记录,已经是 SM4 的密文也会重新生成:
bash
ckmanctl upgrade encryption -c /etc/ckman/conf/ckman.hjson
  1. 启动服务并验证。再次运行 --dry-run 会检查迁移后的密文能否解密;再确认服务可访问,以及集群连接等功能正常:
bash
systemctl start ckman
systemctl is-active ckman
ckmanctl upgrade encryption -c /etc/ckman/conf/ckman.hjson --dry-run
curl --noproxy '*' -fsS -o /dev/null http://127.0.0.1:8808/

验收时应确认演练前后的集群数量一致、数据库中的新密文带 sm4:gcm:v1: 前缀,并在测试环境对比迁移前后的解密结果及集群连接功能。上述流程验证的是 CKMAN 自身的 AES → SM4-GCM 迁移;其他程序生成的 SM4 密文还需要确认工作模式、IV 和密文格式是否兼容。

upgrade backup ​

把旧版 Backup 表升级到新的 BackupPolicy / BackupRun 双表 schema。

bash
# 演练
ckmanctl upgrade backup -c /etc/ckman/conf/ckman.hjson --dry-run

# 正式迁移
ckmanctl upgrade backup -c /etc/ckman/conf/ckman.hjson

# 详细日志 + 完成后清理旧表数据
ckmanctl upgrade backup -c /etc/ckman/conf/ckman.hjson -v --cleanup

# 新表非空时强制写入(默认会拒绝)
ckmanctl upgrade backup -c /etc/ckman/conf/ckman.hjson --force
参数默认说明
-c, --conf/etc/ckman/conf/ckman.hjsonckman 配置
--dry-runfalse演练,只打印映射计划,不写入
-v, --verbosefalse每行详细日志
--forcefalse允许在新表已有数据时继续写入
--cleanupfalse迁移成功后删除旧 Backup 表中已迁移的行

跨版本升级时需要

当你从带有旧 Backup schema 的 ckman 升级到新版本后,必须跑一次 ckmanctl upgrade backup,否则历史备份记录看不到。

操作顺序:

  1. 停 ckman
  2. 升级 ckman 包
  3. ckmanctl upgrade backup --dry-run 看映射对不对
  4. ckmanctl upgrade backup 正式迁移
  5. 验证 ckman 界面备份历史正常显示
  6. (可选)再跑一次 --cleanup 清理旧表

退出码 ​

退出码含义
0成功
1参数错误或运行时错误(具体看 stderr)

排错 ​

parse config failed ​

  • 检查 -c 指定的 ckman.hjson 路径是否存在且可读
  • 注意 HJSON 语法(允许注释、宽松逗号),但仍要求基本 JSON 结构正确

persistent_policy not set ​

  • ckman.hjson 中 server.persistent_policy 为空
  • sql / upgrade backup 等子命令需要读取 ckman 持久层,必须有该字段

ZK 连接失败 ​

  • 防火墙 / 网络
  • 检查 ckman.hjson 里集群的 ZK 节点配置是否准确
  • 用 -h 显式指定 ZK 地址绕过配置

迁移到 mysql 时表创建失败 ​

  • 确认目标数据库编码为 UTF-8
  • 用户具备 CREATE TABLE 权限
  • 数据库本身已存在(migrate 不会自动建库)

基于 Apache 2.0 协议发布