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 篇清理,并检查保留备份。跨区域副本提升和整区灾备是后续专项,本实验不声称验证了区域故障恢复。

搜索文档

输入关键词,搜索所有文档。

↑ ↓ 选择 · Enter 打开 · Esc 关闭