🧬 核心宏替换:内核与 Shell 的变量交接
当你写下 restore_command = 'cp /arch/%f %p' 时,PG 内核在执行它之前,会进行极其精准的字符串宏替换(String Substitution):
1. %f:死亡录像带的“纯净编号”
- 物理真相:它仅仅是一个 24 字节长的纯字符串(由时间线 ID + 逻辑 LSN 组成)。
- 替换结果:例如
00000001000000000000002A。 - 注意:它不带任何路径,没有任何目录前缀,它就是你要找的那个 16MB 文件的“学名”。
2. %p:内核指定的“物理空投坐标”
- 物理真相:这是 PG 内核在自己主数据目录下,为你画好的一个绝对物理路径(包含临时文件名)。
- 替换结果:它通常会被替换成类似
$PGDATA/pg_wal/RECOVERYXLOG。 - 底层的狡猾:内核非常谨慎!它不会让你直接把文件恢复成
0000...2A。它要求你先把文件拷过来,命名为RECOVERYXLOG。内核自己校验完这 16MB 文件没有损坏后,内核才会亲手把它重命名为真正的日志编号。这叫“防原子写撕裂”。
3. %%:转义符
如果你自己写的 Shell 脚本里刚好需要用到 % 这个符号(比如按日期格式化),你必须写成 %%,内核才不会把它当成宏变量解析。
⚖️ 绝对生死契约:Exit Code(退出状态码)
这是最关键的一环!PG 内核把替换好的字符串(比如 cp /arch/00...2A pg_wal/RECOVERYXLOG)通过 C 语言的 system() 函数扔给 Linux Bash 去执行后,它就闭上眼睛,只等 Linux 返回一个数字。
- 契约 1(生):如果你的命令返回
Exit Code 0内核立刻睁开眼,去读取RECOVERYXLOG文件。如果文件完好,继续重放恢复。 - 契约 2(死):如果你的命令返回
非 0(如1,文件不存在) 内核立刻判定:“归档通道已枯竭,这个文件世界上不存在了”。它会彻底停止调用restore_command,并开始准备结束恢复(或切换到流复制)。 - 【致命灾难】契约破坏者: 如果你写了一个极其糟糕的自定义脚本:脚本明明没找到文件,但最后不小心执行了
exit 0;或者拷了一个 0 字节的空文件过来返回了0。PG 内核会满心欢喜地去读,结果一读发现是坏文件,内核会当场触发PANIC(内核恐慌),数据库直接暴毙!
🛠️ 战术军火库:海量数据下的真实 restore_command
明白了底层的“宏替换”和“Exit Code 契约”,你就会发现,在这个单引号里,你可以塞进任何武器:
级别 1:朴素的本地拷贝(单机测试)
restore_command = 'cp /data/archive/%f %p'
- 动作:最简单的 Linux
cp,找不到文件自带返回1。
级别 2:异地机房的物理强拉(跨网络灾备)
restore_command = 'scp -q [email protected]:/remote_arch/%f %p'
- 动作:利用 SSH 通道,跨越几百公里的光缆,把远端主机的内存数据强行拉到本地硬盘的
%p坐标。
级别 3:云原生时代的百 TB 级吞吐(S3 对象存储)
restore_command = 'aws s3 cp s3://my-db-bucket/wal/%f %p'
- 动作:向 AWS 或阿里云的 API 服务器发送 HTTP GET 请求。网络流直接转化为本地的 16MB 文件。
级别 4:大厂极限压榨版的“终极包装”(自研 Shell)
restore_command = '/usr/local/bin/my_smart_restore.sh %f %p'
- 动作:在千万级并发下,简单的
cp已经不够了。DBA 会自己写一个my_smart_restore.sh脚本。 - 脚本内部逻辑:
- 先去高速 NVMe 缓存盘里找
%f。 - 找不到,再去 S3 冷存储里下载
%f。 - 下载下来后,校验 md5sum。
- 如果校验失败,重试 3 次。
- 最终如果真的没有,严格执行
exit 1;如果成功,严格执行exit 0。
- 先去高速 NVMe 缓存盘里找
PostgreSQL 内核对你说:“我把我要的文件名(%f)和接收坐标(%p)交给你。你用什么手段我不管,去哪拿我也不管。你拿到了,给我回个 0;你实在拿不到,给我回个 1。千万别骗我!”
这就是这段字符串背后最冷酷的物理执行逻辑。
了解 www.876873.xyz 的更多信息
订阅后即可通过电子邮件收到最新文章。
restore_command 里面的内容 详解:等您坐沙发呢!