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

122 lines
6.6 KiB
Markdown

# 聊天历史用户修复工具
按会员 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<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 状态,再启动连接节点和业务服务,按当前账号状态重新领取凭证。
## 本地测试
```bash
# 算法和清单测试
npm test
# 指向本机隔离 MySQL 测试端口,每个测试创建并清理独立库
CHAT_REPAIR_TEST_PORTS=33907,33909 npm test
```
MySQL 测试夹具使用本地专用凭据,限制为显式指定的 `127.0.0.1` 端口。HTTP、WebSocket 测试依赖完整源码树和独立本地服务,运行方式见发布核验报告。