7.4 KiB
7.4 KiB
预生产数据盘第二阶段(2026-08-31晚间)
授权、范围与结果
- 用户明确要求“开始执行第二阶段”;主机
8.160.169.106:12022,仅迁移PostgreSQL、Redis、MinIO三项持久化存储。 - 实际业务停写窗口:
2026-08-31 22:31:57—22:33:14 +08:00,约77秒。API在窗口内不可用,CMPP上下游连接经历断开与重连,不能表述为零中断。 - 当前业务程序、应用日志、Prometheus和系统日志未迁移,Nginx及Security Agent未重启;未发送、补发或手工重投短信,未手工ACK/XDEL或清理业务队列。
- 22:36复核11项服务active,供应商连接9/9,客户端连接恢复4个(刚恢复时短暂为2个),API/Callback/Gateway/MinIO健康、PostgreSQL接受连接、Redis PONG,外部API健康通过。
迁移前真实状态
- 部署标记
1a5063a7c635280b912021c42c33a07c99f4c5dd;第二阶段未发布新的业务产物。 - 数据盘UUID
ef4ee3bb-a19b-4aeb-b00c-aa2b995611c2,第一阶段挂载和备份保护正常。 - PostgreSQL 15.18,PGDATA
/var/lib/pgsql/data,不存在外部表空间或WAL符号链接;数据库postgres及cmpp_platform随完整父目录迁移。 - Redis目录
/var/lib/redis,RDBdump.rdb,AOF关闭;未借迁盘改持久化策略。 - 对象存储驱动为MinIO,目录
/var/lib/minio,62个业务对象,总大小40846589字节。未切换到local备用驱动。 - 下游连接4个、上游9/9,在途提交0。命令Stream长度75533但pending/lag均0,是已消费历史条目,不能据长度清队列;结果及协议日志Stream长度0、pending/lag均0。
- Inbox completed 4613,Submit Outbox published 867,UpstreamReceiptInbox matched 140861 / unmatched 7;7条既有未匹配回执未作为迁盘问题删除或强制处理。
恢复资产与执行顺序
- 本次恢复点:
/data/cmpp-platform-backups/preprod-storage-stage2-20260831T142327Z(也可通过原固定备份入口访问)。旧版本4d526b8原恢复点继续保留。 - 停写前已保存PostgreSQL custom dump、全局角色、当前运行目录、系统配置和fstab,
SHA256SUMS.online、pg_restore --list及两份tar可读性通过。配置备份第一次遇到不存在的/etc/sysconfig/pgsql而中止;去除错误输入、重新生成并校验后才进入停写窗口。 - 停Send Worker、Outbox和API,确认Gateway在途及结果Outbox为0,再停Gateway;核对Stream无待处理后停Callback和Protocol Log Worker。
- 在冻结状态保存110张public表的精确行数、MinIO对象清单及三条Stream的长度/组状态;执行Redis SAVE,再停止MinIO、Redis、PostgreSQL。
- 确认九个写入相关服务MainPID均为0,
pg_controldata显示shut down后,以40MiB/s限速做完整冷复制。不是把普通在线目录复制当作一致备份。 - PostgreSQL 2225个文件/目录条目、2373269966文件字节;Redis 2条目、184085437字节;MinIO 249条目、40914208字节。三组全部文件SHA-256、类型、属主、权限、mtime和扩展属性与源目录一致。
- 原目录改名为以下冷副本,再建立绑定挂载;它们未删除,也不再是服务使用的数据目录:
/var/lib/pgsql.systemdisk-stage2-20260831/var/lib/redis.systemdisk-stage2-20260831/var/lib/minio.systemdisk-stage2-20260831
- 恢复点中的
cold-storage.tar.gz包含上述三项同一停写窗口的原数据副本,约611MiB;压缩包可读性及tar --compare源文件内容比对通过。SHA256SUMS.final覆盖36项恢复文件并全部校验通过,完整恢复点约1006MiB。在线逻辑dump与独立Redis文件不能替代这套一致冷备。
当前路径与启动保护
| 服务 | 原访问路径 | 实际数据盘目录 | systemd挂载单元 |
|---|---|---|---|
| PostgreSQL | /var/lib/pgsql |
/data/postgresql |
var-lib-pgsql.mount |
| Redis | /var/lib/redis |
/data/redis |
var-lib-redis.mount |
| MinIO | /var/lib/minio |
/data/minio |
var-lib-minio.mount |
- 原服务参数、账号、业务路径不变。fstab绑定挂载使用
bind,nofail,x-systemd.requires=data.mount,x-systemd.after=data.mount。 - 每个服务的
/etc/systemd/system/<unit>.service.d/50-cmpp-data-disk.conf配置RequiresMountsFor、After及BindsTo,并以root权限在ExecStartPre调用存储检查;数据盘缺失不能因nofail启动空库。 /etc/cmpp-platform/data-disk.uuid保存预期UUID。/usr/local/sbin/cmpp-data-storage-check核验数据盘、对应绑定挂载、源/目标设备号及inode一致、读写挂载选项、PG_VERSION/RDB/MinIO格式标记。- 三个系统盘底层空挂载点均设置immutable;第一阶段底层
/data的保护保持不变。 - 在隔离mount namespace内实测:缺少绑定挂载、缺少数据盘、错绑同盘其他目录、只读绑定挂载均被拒绝;底层系统盘写入失败。宿主机挂载及三个服务PID在这些测试中未改变。
findmnt --verify --verbose无错误或警告。此次未重启整机,开机过程尚未通过真实重启验收;未通过真实拔盘触发线上停机测试。
恢复前后数据核对
- 新位置启动三项存储后、恢复业务前,110张public表精确行数逐项一致;其中短信记录74457、提交记录75532、回执记录148281、上游回执Inbox 140868。
- 三条Redis Stream在冻结前后长度、consumer group、pending、lag、last-delivered-id及entries-read完整一致。恢复Worker后协议日志组consumer数从2变3是新进程注册,pending/lag仍0,未删除旧consumer。
- MinIO 62个业务对象的key/size/etag清单一致,并完成独立随机对象的上传、下载内容比对与删除;未操作已有业务对象。
- PostgreSQL以临时表事务执行真实写读并ROLLBACK;Redis使用随机诊断key写读删除,附带60秒TTL;无短信发送探针。
- 依次启动Callback/Protocol Log Worker/Outbox、Gateway、API、Send Worker,API启动后恢复供应商连接。启动健康轮询出现短暂端口未监听,随后全部通过;没有将启动瞬态当作已验收服务。
- 封存冷备后的最终数据盘约4.0G使用、93G可用(5%);系统盘约24%、可用44G,其中仍保留约2.4GiB原数据冷副本。容量是本次观察值,后续以实际df为准。
后续部署与回退限制
- 本地及服务器
production-deploy.sh、production-bootstrap.sh增加已有数据盘安装的前置检查,失败发生在初始化/发布写入之前;原systemd drop-in不被这两个脚本覆盖。新增可复用检查源文件为tools/deploy/check-data-storage.sh。 - 两个脚本和检查器已通过bash语法检查,两个入口在隔离缺挂载环境中均拒绝继续。未执行完整部署、Git提交或推送;当前运行目录的运维脚本有本次明确记录的修改,业务产物部署标记不变,不能声称运行目录所有文件仍与该commit逐字节一致。
- 新位置已恢复正常业务写入,禁止直接切回系统盘旧目录或冷备覆盖新数据。若需回迁,必须重新停写,将新位置的最新一致数据反向同步,核验后再修改挂载。
- 暂保留的原副本是迁移恢复证据;后续清理需核对本次冷备及业务状态。备份和业务数据同在一块数据盘不能替代异机灾备。
- 服务器执行资产:
/etc/cmpp-platform/storage-stage2-20260831/;本地原始证据:outputs/data-disk-stage2-*.txt。migration.log、表行数、Stream/对象清单、文件校验清单、前后配置均位于本次恢复点。