# 聊天历史用户修复工具 按会员 ID 修正 IM 身份,保留同昵称会员的各自账号与历史关系。支持 MySQL 5.7、8.0 和 Node.js 20.19 及以上版本。工具可以在能连接两库的运维电脑运行。 ## 准备连接 ```bash 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。 ```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 文件执行。 ## 四个命令 ```bash # 提前只读检查,允许新结构尚未安装 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` | 0 | | 禁用业务会员 | `u` | 1 | | 逻辑删除会员 | `u` | 2 | | IM 独有正数用户 | `u` | 3 | | 业务会员缺少 IM 用户 | 创建同步任务,启动新版接口后补建 | 按业务当前状态 | | 系统账号 -100、-200 | 保留专用初始化规则 | 保留并核验 | 工具使用精确十进制字符串和 BigInt 处理 ID、同步版本和撤销版本。头像、昵称同步至用户、好友和群成员的资料副本。群备注沿用原值。 正式执行前检查唯一索引、字段容量、InnoDB 引擎、异常 ID、保留账号占用,并通过数据库实际排序规则检查用户名冲突。两库身份包含库名、服务器 UUID、服务器名称和版本。 ## 提交和重跑 1. 对原始业务资料和 IM 快照重新核对。 2. 在一个 IM 事务内,将所有待迁移用户改为批次临时用户名,再统一改为 `u`,更新资料副本和账号状态。 3. 核对用户、关系和消息快照后提交 IM 事务。 4. 在业务事务内写入同步任务和持久化编号水位。 5. 单独校正会员表 AUTO_INCREMENT,保存完成断点。 编号水位覆盖业务用户、IM 用户,以及好友、群和历史消息中的用户编号。新版业务注册使用持久化水位分配 ID,可覆盖 MySQL 5.7 重启后重建自增值的情况。 进程中断或提交响应丢失后,保持停写,使用同一份清单重新运行 `apply`。工具识别已提交快照并补齐后续阶段。完成后的重复执行保持幂等。`imApplying`、`imCommitted`、`businessCommitted` 是执行过程中的正常断点名称。 ## 核验边界 `verify` 用于服务启动前,要求原有消息数量与快照完全一致。`verify --ready` 允许补建账号、默认好友和欢迎消息,要求原有关系仍存在、消息总量未减少、任务已确认且正常会员已完成初始化。 核验期间继续暂停用户业务写入。若已经开放流量,会员改资料、新消息或群变动会影响快照核验,应依据新清单及业务记录检查。 `--ready` 同时要求系统账号存在且可用。该步骤在业务服务运行专用系统账号初始化后执行。 ## 回滚规则 回滚前再次备份当前两库,暂停同步、写入和所有 IM 服务。 工具先检查迁移后字段、好友、群成员和消息是否发生后续变化。发现差异会打印字段路径及原值、现值并终止覆盖。回滚采用两阶段改名,恢复原用户名、昵称和头像副本。 会员停用状态、人工封禁、登录撤销版本和持久化编号水位继续保持当前有效约束。同步版本和登录撤销版本递增,业务任务重新排入补偿队列。数据回滚完成后应保持维护状态,再生成正式清单执行修复,或依据差异进行人工处理。新版同步任务随后执行时会再次采用 `u`。 服务启动产生的新好友、欢迎消息,以及恢复流量后的资料和消息变化,都可能触发回滚保护。此时依据完整数据库备份和差异记录制定定向恢复步骤。 回滚命令只负责本批次资料字段及同步任务,表结构与历史账号继续保留。恢复后启动新版 IM 接口重建 Redis 状态,再启动连接节点和业务服务,按当前账号状态重新领取凭证。 ## 本地测试 ```bash # 算法和清单测试 npm test # 指向本机隔离 MySQL 测试端口,每个测试创建并清理独立库 CHAT_REPAIR_TEST_PORTS=33907,33909 npm test ``` MySQL 测试夹具使用本地专用凭据,限制为显式指定的 `127.0.0.1` 端口。HTTP、WebSocket 测试依赖完整源码树和独立本地服务,运行方式见发布核验报告。