如何校验迁移后文档数量与哈希一致性?
解读
在国内金融、政务、医疗等对数据零丢失零容忍的场景里,**“迁移后文档数量与哈希一致性”**是上线评审的硬门槛。面试官想确认候选人能否:
- 用 CouchDB 原生工具低成本完成全量校验;
- 在不停机条件下解决“源端持续写入”带来的漂移;
- 给出可审计的量化报告,满足国内等保、银监、信创验收要求。
知识点
- CouchDB 序列号(update_seq):每个数据库单调递增,可快速判断“源库是否又写入”。
- _all_docs 与 _changes 的差异化:前者只能拿到最新修订,后者能拿到历史删除标记,必须组合使用才能算准“逻辑文档数”。
- MVCC 修订号(_rev):同一 id 下不同世代,不能直接用于跨库哈希,需先归一化。
- Erlang 视图 Server 的 reduce 溢出:国内 4 亿条记录规模下,若 reduce 阶段返回巨大数组,默认会触发“reduce_overflow_error”,必须改用 built-in _count 或 list 函数。
- 国内信创环境常见 ARM+麒麟组合,openssl 版本低,sha256sum 性能只有 x86 的 40%,需提前评估耗时。
答案
分五步落地,全部脚本用官方接口,无需第三方插件,可直接写进验收报告。
-
冻结写入窗口
若业务允许,在源库执行PUT /{db}/_security把写账号临时摘除;若不允许,则记录迁移开始时的update_seq作为“一致性锚点”,后续用_changes?since=锚点把增量补到目标库,再校验。 -
计算源库“逻辑文档数”
用POST /{db}/_all_docs?limit=1先取total_rows,再POST /{db}/_changes?descending=true&limit=1拿到最后一条删除标记的 seq,两者相减得到真实存活文档数,写入《迁移报告》第一行。 -
生成源库“内容哈希”
设计视图:map: function (doc) { emit(doc._id, doc._rev); } reduce: _count再建第二个视图:
map: function (doc) { emit(null, require('crypto').createHash('sha256').update(JSON.stringify(doc, Object.keys(doc).sort())).digest('hex')); } reduce: function (keys, values) { return values.sort().join(''); }对 4 亿条记录,用 ?group_level=0 直接取 reduce 结果,得到 64 位十六进制摘要,耗时约 3 分钟(16 核信创服务器)。把摘要写入报告第二行。
-
目标库执行完全相同的 2、3 步
拿到目标库的“逻辑文档数”与“内容哈希”,与源库逐字节比对。若一致,进入第 5 步;若不一致,用diff _changes法快速定位差异 id,再人工修复。 -
出具“双章”报告
报告里必须包含:- 源、目标库的 URL、节点 IP、CouchDB 版本、Erlang 版本;
- 校验时刻的
update_seq截图; - 两份哈希的十六进制字符串与执行耗时;
- DBA 与业务方双方签字,满足国内等保 2.0 对“数据迁移可追溯”条款。
拓展思考
- 增量漂移场景:若业务 7×24 写入,可在第 1 步后启动
_changes?feed=continuous&since=锚点把增量写入 Kafka,目标库消费完后再做一次“二次哈希”,实现热迁移零窗口。 - 分片集群:国内大型互联网用 CouchDB 3.x 做分片,校验时要逐分片执行上述流程,再把各分片哈希再做一次 Merkle Tree,防止“跨分片碰撞”。
- 合规加密:部分政务云要求哈希算法用国密 SM3,只需把视图里的
crypto.createHash('sha256')换成sm3(),Node 端提前安装@npm/sm-crypto即可,无需改 CouchDB 源码。 - 自动化回归:把五步脚本封装成 Jenkins 流水线,每次版本升级后自动跑一遍,10 分钟内给出“数据零丢失”报告,可成为团队 CI/CD 的强制门禁。