# 第 14 章 配套代码 · 备份与恢复

## 准备工作

1. 跑 `psql -h 127.0.0.1 -U postgres -d learn_pg -f ../init.sql` 初始化 `ch14_users / ch14_orders` 等业务表
2. 确认 `pg_dump / pg_restore / pg_basebackup` 在 `PATH` 中（一般和 `psql` 同一个包）
3. （可选）安装依赖：`pip install "psycopg[binary]>=3.1"`（仅 `04_dump_with_python.py` 需要）
4. （可选）通过环境变量覆盖默认连接：`export PGHOST=... PGPORT=... PGUSER=... PGDATABASE=...`

## 脚本一览（推荐运行顺序）

| 脚本 | 一句话说明 | 关键 PG 特性 |
|------|------------|--------------|
| `01_pg_dump_examples.sh` | 同一个库分别用 plain / custom / dir / tar 四种格式各导出一份，对比体积 | `pg_dump -F{p,c,d,t}`、`-j`、`--schema-only / --data-only` |
| `02_pg_restore_demo.sh` | 把 `learn.dump` 恢复到临时库；演示按表恢复、`-L toc.list` 精细化恢复 | `pg_restore -j`、`-t`、`-l/-L` |
| `03_basebackup_pitr.sh` | 走一遍 `pg_basebackup` + WAL 归档 + `recovery_target_time` 的 PITR | `archive_command`、`pg_basebackup`、`recovery.signal` |
| `04_dump_with_python.py` | 「生产级备份脚本」：自动按日期分目录、并行 dump、写 `ch14_backup_history` 审计表、清理旧备份 | `subprocess` 调度、`pg_dumpall -g` |

## 运行方式

```bash
bash 01_pg_dump_examples.sh
bash 02_pg_restore_demo.sh
sudo bash 03_basebackup_pitr.sh                # 涉及 PGDATA 操作，需要 postgres 用户权限
python 04_dump_with_python.py --dest /tmp/pg_backup --jobs 4 --keep 7
```

## 预期输出

`01_pg_dump_examples.sh` 末尾会打印四种格式的体积对比：

```
-rw-r--r--  ... learn.tar
-rw-r--r--  ... learn.sql
-rw-r--r--  ... learn.dump
drwx------  ... learn_dir/
```

`04_dump_with_python.py` 每次运行后会在数据库里追加一行 `ch14_backup_history`，并打印最近 5 次备份历史。

## 常见报错与依赖

- `connection refused` → PG 未启动，或 `pg_hba.conf` 没放行
- `relation "ch14_orders" does not exist` → 没有先跑 `init.sql`
- `pg_basebackup: FATAL: number of requested standby connections exceeds max_wal_senders` → 调高 `max_wal_senders`
- `recovery_target_time` 不生效 → 检查归档目录是否被 PG 进程读到、`restore_command` 路径是否正确
- 03 / PITR 演示对 `PGDATA` 路径写入，**必须以 OS 上的 postgres 用户运行**，且备份目录要有写权限
- `04_dump_with_python.py` 需要 `psycopg[binary]`，并且数据库账号有建表权限（用于 `ch14_backup_history`）
