Files
lislgosms/docs/preprod-data-disk-stage2-20260831.md

7.4 KiB
Raw Permalink Blame History

预生产数据盘第二阶段(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.18PGDATA /var/lib/pgsql/data,不存在外部表空间或WAL符号链接;数据库postgrescmpp_platform随完整父目录迁移。
  • Redis目录/var/lib/redisRDB dump.rdbAOF关闭;未借迁盘改持久化策略。
  • 对象存储驱动为MinIO,目录/var/lib/minio,62个业务对象,总大小40846589字节。未切换到local备用驱动。
  • 下游连接4个、上游9/9,在途提交0。命令Stream长度75533但pending/lag均0,是已消费历史条目,不能据长度清队列;结果及协议日志Stream长度0、pending/lag均0。
  • Inbox completed 4613Submit Outbox published 867UpstreamReceiptInbox matched 140861 / unmatched 7;7条既有未匹配回执未作为迁盘问题删除或强制处理。

恢复资产与执行顺序

  • 本次恢复点:/data/cmpp-platform-backups/preprod-storage-stage2-20260831T142327Z(也可通过原固定备份入口访问)。旧版本4d526b8原恢复点继续保留。
  • 停写前已保存PostgreSQL custom dump、全局角色、当前运行目录、系统配置和fstab,SHA256SUMS.onlinepg_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配置RequiresMountsForAfterBindsTo,并以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 WorkerAPI启动后恢复供应商连接。启动健康轮询出现短暂端口未监听,随后全部通过;没有将启动瞬态当作已验收服务。
  • 封存冷备后的最终数据盘约4.0G使用、93G可用(5%);系统盘约24%、可用44G,其中仍保留约2.4GiB原数据冷副本。容量是本次观察值,后续以实际df为准。

后续部署与回退限制

  • 本地及服务器production-deploy.shproduction-bootstrap.sh增加已有数据盘安装的前置检查,失败发生在初始化/发布写入之前;原systemd drop-in不被这两个脚本覆盖。新增可复用检查源文件为tools/deploy/check-data-storage.sh
  • 两个脚本和检查器已通过bash语法检查,两个入口在隔离缺挂载环境中均拒绝继续。未执行完整部署、Git提交或推送;当前运行目录的运维脚本有本次明确记录的修改,业务产物部署标记不变,不能声称运行目录所有文件仍与该commit逐字节一致。
  • 新位置已恢复正常业务写入,禁止直接切回系统盘旧目录或冷备覆盖新数据。若需回迁,必须重新停写,将新位置的最新一致数据反向同步,核验后再修改挂载。
  • 暂保留的原副本是迁移恢复证据;后续清理需核对本次冷备及业务状态。备份和业务数据同在一块数据盘不能替代异机灾备。
  • 服务器执行资产:/etc/cmpp-platform/storage-stage2-20260831/;本地原始证据:outputs/data-disk-stage2-*.txtmigration.log、表行数、Stream/对象清单、文件校验清单、前后配置均位于本次恢复点。