⛓️ PITR 绝对因果逻辑推演链
- [状态 0:刚解压的 5TB 备份]
- 【因(致命缺陷)】:数据由长时间顺序拷贝而来,物理页块处于撕裂(Torn Page)和时空不一致的模糊状态(Fuzzy)。若直接对外开放,必定发生物理级数据损坏。
- 【动作】:人为创建空文件
recovery.signal。 - 【果(状态跃迁)】:内核
Startup进程触发物理硬锁,封锁 5432 端口,强制进入“归档恢复(Archive Recovery)”状态机。 -> 进入 [状态 1]
- [状态 1:被锁死的恢复模式]
- 【因(致命缺陷)】:内核不知道这 5TB 数据的“时空基准点”在哪里,面对成千上万的 WAL 日志,无从下手。
- 【动作】:内核强行读取根目录下的
backup_label文件。 - 【果(状态跃迁)】:提取到精确的
START WAL LOCATION(REDO LSN)。获得了具有绝对物理意义的时空锚点。 -> 进入 [状态 2]
- [状态 2:获得了锚点,但弹药匮乏]
- 【因(致命缺陷)】:本地
pg_wal目录为空,没有用来治愈物理撕裂和推进时空的 WAL 日志(解药)。 - 【动作】:内核死循环调用操作系统执行
restore_command抓取日志,并解析重放。 - 【果(状态跃迁)】:通过全页镜像(FPI)物理覆盖治愈撕裂页;通过重放 DML 推进数据状态;阅后即焚防止磁盘爆满。 -> 进入 [状态 3]
- 【因(致命缺陷)】:本地
- [状态 3:高速运转的时空快车]
- 【因(致命缺陷)】:如果无限重放下去,必然会把“删库跑路”那条灾难级 SQL 也重新执行一遍,导致前功尽弃。
- 【动作】:内核在重放每一条日志前,严格比对
recovery_target_time。 - 【果(状态跃迁)】:一旦日志时间戳 ≥ 目标时间,触发微秒级硬中断。停止拉取,冻结当前数据块的物理状态。 -> 进入 [状态 4]
- [状态 4:时空冻结,准备重启]
- 【因(致命缺陷)】:如果直接就地重新营业,新生数据的 WAL 日志编号将与原有灾难发生前产生的旧 WAL 日志发生物理重名,导致归档系统逻辑崩溃(脑裂)。
- 【动作】:内核执行 Promote,强制 Timeline ID + 1(例如 TLI 1 -> 2),生成
.history记录文件。 - 【果(状态跃迁)】:彻底切割旧宇宙,开辟独立的新时间线命名空间。删除
recovery.signal,解锁 5432 端口,满血复活! -> 进入 [最终状态:正常主库]
📡 补充副线一:黑暗中的战术雷达(PITR 进度监控)
- 前因痛点:你拉起了一个 5TB 的恢复任务。它可能需要跑 3 个小时。但这 3 个小时里,数据库是不能对外服务的。如果你老板站在你背后问:“还有多久恢复完?现在重放到几点了?” 你总不能盯着 Linux 的
top命令跟老板说“CPU 还在转”吧? - 工作流程中的监控微操: 在 PITR 恢复期间,虽然数据库不能进行业务写入,但高级 DBA 会立刻用
psql连入数据库(因为此时它处于特殊的接收连接但不允许写状态),并疯狂敲击以下三个内核探针函数:SELECT pg_is_in_recovery();:确认探针。如果返回t(true),说明还在吃力地重放日志;如果返回f(false),说明刹车已经踩下,恢复彻底结束!SELECT pg_last_wal_replay_lsn();:物理探针。告诉你当前底层的磁头精确重放到了哪个 LSN 坐标。SELECT pg_last_xact_replay_timestamp();:最救命的业务探针! 它会返回一个人类可读的时间戳(比如2026-03-20 14:35:12)。你指着这个时间告诉老板:“报告!目前已经恢复到了两点半的数据,距离被删库的下午三点,还剩最后 25 分钟的进度!”
🧹 补充副线二:战后废墟的终极清道夫(archive_cleanup_command)
- 前因痛点:还记得我们在时间线跃迁时说过的吗?当你恢复完成,Timeline 从 1 变成了 2。这意味着原来 Timeline 1 后面跟着的那些几百 GB 的旧 WAL 日志(删库之后的日志)已经变成了彻底的**“平行宇宙垃圾”**。如果你不管它们,你的异地归档服务器很快就会被撑爆。
- 工作流程中的收尾动作:
- 顶级的灾备架构师会在
postgresql.conf里偷偷埋下一颗地雷:archive_cleanup_command = 'pg_archivecleanup /mnt/archive %r'。 - 逻辑咬合:当 PITR 完美结束,时间戳踩下刹车,内核在执行重启并切换时间线的那一瞬间,它会触发这个清道夫命令!
- 物理定性:内核会把当前刹车点的日志名字传给
%r。pg_archivecleanup这个冷酷的杀手会顺着网线爬到你的归档服务器上,把刹车点之前所有已经没用的旧日志,像割韭菜一样全部物理rm删除掉! 做到滴水不漏,寸草不生!
- 顶级的灾备架构师会在
🗺️ 终极暗雷一:物理空间的异次元折叠(表空间映射 tablespace_map)
- 前因痛点:在真实的生产环境中,5TB 的主库不可能全放在一个硬盘上。它可能把热表放在 SSD(挂载点
/data/ssd_fast),把冷历史表放在 HDD(挂载点/data/hdd_slow),这在 PG 里叫“表空间(Tablespace)”。 但是!你用于救灾的那台新服务器,可能只有一个巨大的/new_data目录。当Startup进程重放日志,试图去/data/ssd_fast里寻找文件时,会直接报No such file or directory,整个 PITR 当场崩溃! - 内核微操:
- 在启动恢复前,高级 DBA 会在
$PGDATA目录下手工建一个极其隐秘的文件:tablespace_map。 - 内容格式:
/data/ssd_fast /new_data/tbs1 - 物理定性:这叫**“底层 I/O 路径的欺骗与重定向”**!当重放进程试图访问旧路径时,内核会在底层将路径强行映射到新服务器的可用目录上。这是异构硬件灾备恢复的救命稻草!
- 在启动恢复前,高级 DBA 会在
🚀 终极暗雷二:双引擎混合驱动(restore_command + primary_conninfo)
- 前因痛点:我们一直说用
restore_command去拉取归档日志。但归档通常有 1 到 5 分钟的延迟!如果主库挂了,你用归档恢复,永远会丢失最后那几分钟的数据。 - 内核微操(混合模式):
- 谁规定 PITR 只能用归档文件?
- 顶级架构师会在配置中同时写上
restore_command(指向 S3 对象存储)和primary_conninfo(指向一个存活的灾备 WAL Hub 节点)。 - 物理定性:
Startup进程会像一辆混合动力汽车!它先用restore_command把 S3 上的历史大文件疯狂拉取重放;当把 S3 吸干后,它不会立刻结束,而是瞬间拉起后台的walreceiver进程,顺着primary_conninfo的网线,把最后那缺失的几分钟、甚至几秒钟的 WAL 内存流直接“吸”过来!这叫归档与流复制的无缝接力重放!
🎆 终极暗雷三:战胜死亡的胜利信号弹(recovery_end_command)
- 前因痛点:我们在上一轮讲过用
archive_cleanup_command打扫战场。但作为指挥官,恢复跑了 5 个小时,当它在凌晨 3 点终于完成、时间线切换、正式开门迎客的那一秒,你怎么知道?总不能一直人工盯着屏幕吧? - 内核微操:
- 设置
recovery_end_command = '/opt/scripts/send_slack_alert.sh'。 - 物理定性:这是整个 PITR 状态机跃迁到“正常(Normal)”状态前的最后一个也是唯一一个回调函数(Webhook)。
- 只有在时间线已经加 1,
recovery.signal已经被删除,数据库准备好接受业务连接的绝对安全时刻,内核才会触发这个脚本。你的手机会收到一条清脆的通知:“指挥官,PITR 完美收官,主库已满血复活!”
- 设置
☢️ 终极清场一:无情抹杀(UNLOGGED 表的物理重置)
- 前因痛点:数据库里除了正常表,还有一种为了追求极致速度而不写 WAL 日志的表(
UNLOGGED TABLE)。既然它不写日志,那么在 PITR 这场“依靠回放日志来复活”的仪式中,这些表里的数据是绝对不可能找回来的。 - 内核的暴力清场(工作流程中的隐藏步骤):
- 当
Startup进程踩下刹车、完成时间线跃迁后,在打开 5432 端口之前,它会去巡视整个$PGDATA目录。 - 物理动作:只要它看到这些
UNLOGGED表对应的数据文件,它会极其无情地调用底层文件操作,用极其微小的初始化空文件(_initfork)直接将它们物理覆盖! - 物理定性:这叫“宁缺毋滥的绝对一致性”!内核的逻辑是:既然你的数据不可靠了,为了防止业务读到半截子乱码,我干脆把这些表全部瞬间清空(Truncate)。你必须接受它们变成空表的现实,然后才能开机!
- 当
🛡️ 终极清场二:新宇宙的第一次地质加固(强制 Checkpoint)
- 前因痛点:我们通过重放了几百 GB 的日志,终于把数据恢复到了下午 3 点。但请注意,这些恢复出来的数据,此刻有很多还漂浮在主库的**共享内存(Shared Buffers)**里(也就是脏页)。如果在开机的第一秒,服务器突然又断电了怎么办?!难道还要再花 3 个小时重新做一次 PITR 吗?
- 内核的加固动作(工作流程的绝对终点):
- 在
recovery.signal被删除、马上要宣告恢复成功的前一微秒,Startup进程会向系统发出最后一道指令:“执行一次全局强制检查点(Forced Checkpoint)!” - 物理定性:所有的后台刷脏进程(bgwriter/checkpointer)瞬间暴起,把刚才重放产生的所有脏页,极其粗暴地全部砸死在物理硬盘上!并且在最新的
pg_control文件里,刻下这个全新的、属于新时间线的时空坐标! - 后果:只有当这个 Checkpoint 落盘成功,内核才会真正松口说:“新宇宙的地壳已经彻底稳定,开门接客!”
- 在
了解 www.876873.xyz 的更多信息
订阅后即可通过电子邮件收到最新文章。
时间点恢复到了 3点,此时的lsn 换算到 归档wal日志以前的wal日志要删除,那3-4点之间的wal日志在 s3归档服务器里面这么处理??:等您坐沙发呢!