6.6 KiB
聊天历史用户修复工具
按会员 ID 修正 IM 身份,保留同昵称会员的各自账号与历史关系。支持 MySQL 5.7、8.0 和 Node.js 20.19 及以上版本。工具可以在能连接两库的运维电脑运行。
准备连接
cd repair-im-users
npm ci --omit=dev
cp config.example.json config.local.json
chmod 600 config.local.json
在 config.local.json 分别填写业务库和 IM 库的地址、端口、库名、账号。passwordEnv 指向密码环境变量。按现有数据库要求设置可选的 ssl 参数。
下面的密码输入示例使用 Bash。
read -r -s -p '业务数据库密码 ' CHAT_REPAIR_BUSINESS_PASSWORD
printf '\n'
read -r -s -p 'IM 数据库密码 ' CHAT_REPAIR_IM_PASSWORD
printf '\n'
export CHAT_REPAIR_BUSINESS_PASSWORD CHAT_REPAIR_IM_PASSWORD
umask 077
plan、verify 使用只读事务。apply、rollback 需要相应表的查询、更新、插入权限,apply 还需要业务会员表的 ALTER 权限。结构迁移通过独立 SQL 文件执行。
四个命令
# 提前只读检查,允许新结构尚未安装
node repair-im-users.mjs plan --config config.local.json --out runs/preflight.plan.json
# 维护窗口内,执行结构迁移后,重新生成正式清单
node repair-im-users.mjs plan --config config.local.json --out runs/maintenance.plan.json
# 保持两库写入、旧服务和同步任务暂停
node repair-im-users.mjs apply --config config.local.json --plan runs/maintenance.plan.json --maintenance
# 服务启动前核验资料、关系、消息数量和编号水位
node repair-im-users.mjs verify --config config.local.json --plan runs/maintenance.plan.json
# 启动新版服务并完成后台补偿后,开放流量前再次核验
node repair-im-users.mjs verify --config config.local.json --plan runs/maintenance.plan.json --ready
# 需要回滚时,重新进入维护窗口并暂停服务
node repair-im-users.mjs rollback --config config.local.json --plan runs/maintenance.plan.json --maintenance
每条命令成功退出码为 0,异常退出码为 1。--maintenance 表示操作者已经完成停写,工具依据数据库快照再次检查数据。
清单和执行记录
| 文件 | 用途 |
|---|---|
*.plan.json |
原字段值、目标字段值、数据库身份、批次号和 SHA256 |
*.plan.json.summary.json |
状态数量、缺失用户、同昵称清单、结构预检查 |
*.plan.json.journal.json |
IM 提交、业务任务提交、自增起点调整和回滚断点 |
*.plan.json.verification.json |
最近一次成功核验结果 |
清单包含会员手机号、头像地址等资料,以及用于核验密码未变化的哈希指纹。请与两库完整备份一起保存至受控目录。生成文件采用私有权限和原子替换。清单、记录、配置文件须保持成套保存。
处理规则
| 数据分类 | 用户名 | 会员状态 |
|---|---|---|
| 正常业务会员 | u<ID> |
0 |
| 禁用业务会员 | u<ID> |
1 |
| 逻辑删除会员 | u<ID> |
2 |
| IM 独有正数用户 | u<ID> |
3 |
| 业务会员缺少 IM 用户 | 创建同步任务,启动新版接口后补建 | 按业务当前状态 |
| 系统账号 -100、-200 | 保留专用初始化规则 | 保留并核验 |
工具使用精确十进制字符串和 BigInt 处理 ID、同步版本和撤销版本。头像、昵称同步至用户、好友和群成员的资料副本。群备注沿用原值。
正式执行前检查唯一索引、字段容量、InnoDB 引擎、异常 ID、保留账号占用,并通过数据库实际排序规则检查用户名冲突。两库身份包含库名、服务器 UUID、服务器名称和版本。
提交和重跑
- 对原始业务资料和 IM 快照重新核对。
- 在一个 IM 事务内,将所有待迁移用户改为批次临时用户名,再统一改为
u<ID>,更新资料副本和账号状态。 - 核对用户、关系和消息快照后提交 IM 事务。
- 在业务事务内写入同步任务和持久化编号水位。
- 单独校正会员表 AUTO_INCREMENT,保存完成断点。
编号水位覆盖业务用户、IM 用户,以及好友、群和历史消息中的用户编号。新版业务注册使用持久化水位分配 ID,可覆盖 MySQL 5.7 重启后重建自增值的情况。
进程中断或提交响应丢失后,保持停写,使用同一份清单重新运行 apply。工具识别已提交快照并补齐后续阶段。完成后的重复执行保持幂等。imApplying、imCommitted、businessCommitted 是执行过程中的正常断点名称。
核验边界
verify 用于服务启动前,要求原有消息数量与快照完全一致。verify --ready 允许补建账号、默认好友和欢迎消息,要求原有关系仍存在、消息总量未减少、任务已确认且正常会员已完成初始化。
核验期间继续暂停用户业务写入。若已经开放流量,会员改资料、新消息或群变动会影响快照核验,应依据新清单及业务记录检查。
--ready 同时要求系统账号存在且可用。该步骤在业务服务运行专用系统账号初始化后执行。
回滚规则
回滚前再次备份当前两库,暂停同步、写入和所有 IM 服务。
工具先检查迁移后字段、好友、群成员和消息是否发生后续变化。发现差异会打印字段路径及原值、现值并终止覆盖。回滚采用两阶段改名,恢复原用户名、昵称和头像副本。
会员停用状态、人工封禁、登录撤销版本和持久化编号水位继续保持当前有效约束。同步版本和登录撤销版本递增,业务任务重新排入补偿队列。数据回滚完成后应保持维护状态,再生成正式清单执行修复,或依据差异进行人工处理。新版同步任务随后执行时会再次采用 u<ID>。
服务启动产生的新好友、欢迎消息,以及恢复流量后的资料和消息变化,都可能触发回滚保护。此时依据完整数据库备份和差异记录制定定向恢复步骤。
回滚命令只负责本批次资料字段及同步任务,表结构与历史账号继续保留。恢复后启动新版 IM 接口重建 Redis 状态,再启动连接节点和业务服务,按当前账号状态重新领取凭证。
本地测试
# 算法和清单测试
npm test
# 指向本机隔离 MySQL 测试端口,每个测试创建并清理独立库
CHAT_REPAIR_TEST_PORTS=33907,33909 npm test
MySQL 测试夹具使用本地专用凭据,限制为显式指定的 127.0.0.1 端口。HTTP、WebSocket 测试依赖完整源码树和独立本地服务,运行方式见发布核验报告。