Files
Friendship-and-chat-api/script/repair-im-users/README.md
T

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、服务器名称和版本。

提交和重跑

  1. 对原始业务资料和 IM 快照重新核对。
  2. 在一个 IM 事务内,将所有待迁移用户改为批次临时用户名,再统一改为 u<ID>,更新资料副本和账号状态。
  3. 核对用户、关系和消息快照后提交 IM 事务。
  4. 在业务事务内写入同步任务和持久化编号水位。
  5. 单独校正会员表 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 测试依赖完整源码树和独立本地服务,运行方式见发布核验报告。