Cloud SQL PITR:恢复点、切换与对账
验证:未记录
- 适用版本
- 未记录
- 验证范围
- 尚未登记验证记录。
恢复先确定 RPO/RTO、可恢复窗口和业务写入隔离。
推荐做法#
- 恢复到独立实例,核对数据与应用权限后再切连接。
- 切换前暂停写入/消费并记录水位;SQL、对象与消息按业务 ID 对账。
- 恢复实例接受新写入后,回切须考虑增量同步和冲突。
常用操作#
替换为实际资源;本段不依赖 lab.env。
PROJECT_ID='REPLACE_PROJECT_ID'
INSTANCE='REPLACE_SOURCE_INSTANCE'
gcloud sql instances describe "$INSTANCE" --project="$PROJECT_ID"
gcloud sql backups list --instance="$INSTANCE" --project="$PROJECT_ID"
gcloud sql operations list --instance="$INSTANCE" --project="$PROJECT_ID"容易踩的坑#
- HA 不等于 PITR;日志未预先保留就没有对应恢复点。
SQL 恢复不会同步回退 Storage,也不会重投已 ACK 的消息。 恢复消费者前按业务 ID 对账、补放事件,避免恢复后数据再次错位。
配置说明与完整示例(按需展开)
前置:Cloud SQL 实验的独立 lab-pg、app 数据库与 lab_items 表;不要对活跃订单实例做破坏性练习。需要创建/克隆实例权限,克隆实例会增加费用。
HA、备份与灾备的区别#
| 能力 | 解决的问题 | 不解决的问题 |
|---|---|---|
| 区域 HA | 部分实例/可用区故障切换 | 误删会同步,不代替备份 |
| 备份恢复 | 恢复某个备份状态 | 不自动包含备份后的写入 |
| PITR | 恢复到可恢复窗口内的时间点 | 必须事先启用并有可用日志 |
| 跨区域副本/恢复 | 应对区域级故障 | 需要确认复制延迟、提升与应用切换 |
RPO 是容忍丢失多少数据,RTO 是容忍恢复多久;以演练结果计,不凭产品名称推断。
执行边界与停止线#
使用 变更执行记录 固定项目、源实例、恢复实例、恢复点、允许损失与恢复时限。先验证备份/日志可用、克隆配额、私网与密钥权限;恢复实例必须保持业务写入隔离。
本篇的单行误删用于验证 PITR 机制,不构成企业灾备验收;生产需对实际业务数据和外部依赖完成后文对账。以下 retained-transaction-log-days=1 仅用于独立实验实例,不能照搬到已有生产实例缩短恢复窗口。
| 状态 | 停止/恢复动作 |
|---|---|
| 恢复点不在可恢复窗口、日志未就绪或权限/配额不足 | 不执行 DELETE;先解决恢复前置条件 |
| 克隆失败或客户端超时 | 查询本次实例操作和错误;确认真实状态后再决定是否重试,保留源实例 |
| 恢复数据不符、外部对象/消息无法对齐 | 不切应用;选择有效恢复点或补偿方案,不能直接恢复消费者 |
| 恢复实例开始接受写入 | 原实例不再是直接回退目标;停写对账后制定反向同步/补偿方案 |
启用并准备恢复点#
source lab.env
gcloud sql instances patch lab-pg --enable-point-in-time-recovery --retained-transaction-log-days=1
gcloud sql instances describe lab-pg --format='yaml(settings.backupConfiguration)'
gcloud sql backups create --instance=lab-pg等待备份成功,并在 Console 确认 PITR 可恢复时间窗口已包含实验写入。用 psql 连到原实例,执行以下步骤;确保 autocommit 开启、没有未提交事务:
INSERT INTO lab_items VALUES (9001, 'recover-me');
-- 复制下面结果,作为后续 RECOVERY_TIME;它在 INSERT 提交之后。
SELECT to_char(clock_timestamp() AT TIME ZONE 'UTC', 'YYYY-MM-DD"T"HH24:MI:SS.US"Z"');稍后再执行 DELETE FROM lab_items WHERE id=9001;,确认原实例已查不到该行。两步不能放在同一个尚未提交的事务里。
恢复到新实例#
export RECOVERY_TIME='替换为上面记录的UTC时间'
gcloud sql instances clone lab-pg lab-pg-recovered --point-in-time="$RECOVERY_TIME"
gcloud sql operations list --instance=lab-pg-recovered --limit=10
gcloud sql instances describe lab-pg-recovered --format='yaml(name,state,connectionName,region,settings.ipConfiguration)'确认本次操作 DONE 且无 error、实例 RUNNABLE 后再启动代理;失败时不要继续。私网实例还需从可达网络运行代理并使用 --private-ip。
export RECOVERED_CONNECTION=$(gcloud sql instances describe lab-pg-recovered --format='value(connectionName)')
cloud-sql-proxy "$RECOVERED_CONNECTION" --address=127.0.0.1 --port=5434另一个终端 psql -h 127.0.0.1 -p 5434 -U appuser -d app -W,查询 ID 9001 应存在;原实例仍不存在。PITR 不是在原实例上“撤销 SQL”,而是先创建可验证的恢复实例。PITR
在原实例和恢复实例分别执行:
SELECT current_database(), current_user;
SELECT id, name FROM lab_items WHERE id=9001;预期:原实例 0 行,恢复实例 1 行且内容为 recover-me。若列名与原实验不同,先核对表结构;连接身份与数据库必须符合预期。记录恢复请求到查询可用的耗时和恢复点;这只是数据库技术恢复耗时,完整业务恢复时间还要包含连接切换、验收和积压处理。
接入应用时的恢复步骤#
停止/暂停写入与消费者 → 确定恢复点 → 恢复新实例 → 核对数据 → 更新连接配置/Secret → 发布新 revision → 验证 → 恢复消费。
订单项目还要对账 SQL、Storage 与消息:SQL 回到旧时间点时,归档桶不会自动回到相同时间,已经 ACK 的事件也不会自动再次出现。按订单 ID 比对并从可靠源补放;不能直接恢复消费者就声称一致性已完成。
企业验收按停写水位核对关键表行数、主键集合、金额/状态汇总及确定性摘要;再验证应用最小权限、幂等读写、消息重放与归档对象。沿用 企业订单项目 的业务门禁,并记录缺失/重复/无法确认的订单,而非只验证实验行存在。
只有该恢复实例仍是可丢弃实验资源、未接入业务且证据已保存时,停止代理后清理:
gcloud sql instances delete lab-pg-recovered原 lab-pg 按 SQL 篇清理,并检查保留备份。跨区域副本提升和整区灾备是后续专项,本实验不声称验证了区域故障恢复。