2. 迁移升级前的资产盘点

迁移升级最怕的不是操作复杂,而是“不知道自己有什么”。很多团队在切换窗口才发现某个业务库没有纳入备份、某个分片键设计导致无法直接搬迁、某个应用账号权限依赖了旧版本的角色继承关系。资产盘点的目标,就是把 MongoDB 部署中所有会影响迁移决策的对象和关系,变成一份可核对、可评估、可执行的清单。

盘点不是简单执行几条命令,而是围绕“迁移单元”建立完整视图。一个迁移单元通常包括:数据库、集合、索引、用户与角色、副本集或分片集群拓扑、以及它们之间的依赖关系。下面按对象逐层展开,并给出可直接参考的盘点命令与记录字段。

一、数据库与集合:确定迁移粒度

首先列出所有数据库及其大小。在 mongosh 中执行:

db.adminCommand({ listDatabases: 1, nameOnly: false })

输出中要重点关注 name、sizeOnDisk、empty。对于非空库,继续进入每个库统计集合:

use appdb
db.getCollectionNames()
db.stats()

集合层面需要记录:集合名、文档数、平均文档大小、是否有上限集合(capped)、是否为时间序列集合(time series)、是否使用了通配符索引或加密字段。特别要注意 system.profile、system.views 等系统集合,它们通常不需要迁移,但视图定义需要单独导出。

对于大集合,还要评估是否包含分片键、是否有 TTL 索引、是否存在大量删除后留下的空洞。这些信息决定迁移时采用全量复制、增量同步还是按时间窗口分批搬迁。

二、索引:迁移后性能的关键

索引是迁移中最容易被忽略、却最影响上线后性能的资产。对每个集合执行:

db.getCollection("orders").getIndexes()

记录每个索引的 name、key、unique、sparse、partialFilterExpression、expireAfterSeconds 以及是否包含排序规则(collation)。迁移后如果只搬数据不建索引,查询会迅速退化为全表扫描;如果索引顺序或选项不一致,唯一性约束和 TTL 行为也会改变。

建议在清单中为每个索引标注“迁移后必须重建”或“可延迟重建”。对于唯一索引,还要确认目标版本是否支持相同的部分索引表达式。

三、用户与角色:权限不能靠猜

用户和角色决定了应用能否在目标环境正常连接。执行:

use admin
db.system.users.find({}, { user: 1, db: 1, roles: 1, mechanisms: 1 })
db.system.roles.find({}, { role: 1, db: 1, privileges: 1, roles: 1 })

需要记录:用户名、认证库、认证机制(SCRAM-SHA-1/SCRAM-SHA-256)、直接角色、继承角色、以及自定义角色中的 privileges。特别注意跨库角色和内置角色(如 readWriteAnyDatabase、clusterMonitor)的依赖。如果目标版本调整了角色权限模型,必须在清单中标记“需重新验证”。

四、副本集与分片集群拓扑:决定迁移路径

拓扑信息直接决定迁移方式。对副本集执行:

rs.status()
rs.conf()

记录成员主机、端口、优先级、隐藏节点、延迟节点、仲裁节点、投票配置以及当前主节点。对分片集群执行:

sh.status()
db.adminCommand({ listShards: 1 })
db.adminCommand({ getShardMap: 1 })

重点记录:分片数量、每个分片的副本集名称、分片键、块分布、均衡器状态、config server 的副本集配置。分片集群迁移时,分片键是否可变更、是否包含哈希前缀、是否存在孤立文档,都会影响搬迁方案。

MongoDB 迁移升级资产盘点视图 从数据库到集群拓扑,逐层记录迁移单元与依赖关系 ① 数据库层 listDatabases → 库名 / sizeOnDisk / empty 标记:业务库、系统库、待归档库、可废弃库 appdb · 48 GB logdb · 12 GB admin · 系统库 config · 分片配置 ② 集合层 getCollectionNames + stats → 文档数 / 平均大小 / capped / time series 标记:大集合、分片集合、TTL 集合、视图、加密集合 orders · 2.1 亿 users · 860 万 events · capped metrics · TS ③ 索引层 getIndexes → key / unique / sparse / partial / TTL / collation 标记:必须重建、可延迟重建、目标版本兼容性待验证 _id_ · 默认 uid_1 · unique ts_1 · TTL status_1 · partial ④ 用户与角色 system.users → 认证库 / 机制 / 角色 system.roles → 自定义权限 / 继承关系 标记:跨库角色、内置角色、需重新验证项 appUser · SCRAM-SHA-256 readWrite · appdb customRole · 继承 ⑤ 副本集 / 分片集群拓扑 rs.status / rs.conf → 成员 / 优先级 / 延迟 / 仲裁 sh.status / listShards → 分片数 / 分片键 / 块分布 标记:均衡器状态、config server、孤立文档风险 rs0 · 3 节点 shard01 · rs1 shard02 · rs2

五、形成迁移升级清单

把上述信息汇总成一张可执行的清单。清单不是简单罗列,而是为每个对象标注迁移策略和风险等级。建议字段如下:

对象类型 对象名称 关键属性 迁移策略 风险等级 验证方式
数据库 appdb 48 GB,含分片集合 全量 + 增量同步 高 文档数比对、抽样校验
集合 orders 2.1 亿,分片键 {uid: "hashed"} 按分片并行迁移 高 分片块分布检查
索引 uid_1 unique,目标版本兼容 迁移后重建 中 唯一性冲突检测
用户 appUser SCRAM-SHA-256,readWrite@appdb 目标环境重建 中 连接测试 + 权限验证
拓扑 shard01/rs1 3 节点,含延迟节点 逐分片滚动迁移 高 rs.status 一致性检查

清单完成后,还需要做一次交叉核对:每个业务库是否都有对应的用户和角色?每个分片集合的分片键是否在目标版本中仍然有效?每个唯一索引是否会在数据合并时产生冲突?这些问题的答案,决定了迁移窗口内是否需要额外的数据清洗或索引调整。

资产盘点的最佳实践是“先只读、后变更”。所有盘点命令都应在从节点或只读副本上执行,避免对生产主节点造成额外压力。盘点结果应版本化保存,作为迁移前后比对的基线。
不要忽略 config 数据库和 admin 数据库中的系统集合。分片集群的 config server 保存了块分布和分片元数据,迁移时如果丢失,整个集群将无法正确路由请求。

完成资产盘点后,你会得到一份包含数据库、集合、索引、用户、角色和拓扑的完整清单。这份清单是后续制定迁移方案、评估停机窗口、设计回滚策略的直接输入。没有它,迁移就只能靠运气;有了它,每一步操作都有据可依。