跳到主要内容

pg_basebackup

前言

pg_basebackup是postgresql在9.1版本开始提供的基础热备份工具,其备份是在不影响数据库的其它客户端的情况下进行的,并且备份产生的文件可以用于时间点恢复和作为日志传输或流复制的起点。

使用pg_basebackup需要数据库开启归档模式。

命令行选项

以15.3版本为例

$  pg_basebackup --help

pg_basebackup takes a base backup of a running PostgreSQL server.

Usage:
pg_basebackup [OPTION]...

Options controlling the output: # 控制输出的选项
-D, --pgdata=DIRECTORY receive base backup into directory # 基本备份保存到指定目录下
-F, --format=p|t output format (plain (default), tar) # 输出格式,默认为plain,可选 tar
-r, --max-rate=RATE maximum transfer rate to transfer data directory # 传输数据目录的最大速率
(in kB/s, or use suffix "k" or "M") # 使用 kB/s 为单位,或者使用后缀 k 或 M
-R, --write-recovery-conf
write configuration for replication # 用于复制的写入配置
-t, --target=TARGET[:DETAIL]
backup target (if other than client) # 备份目标
-T, --tablespace-mapping=OLDDIR=NEWDIR
relocate tablespace in OLDDIR to NEWDIR # 重定位表空间位置
--waldir=WALDIR location for the write-ahead log directory # 预写日志目录路径
-X, --wal-method=none|fetch|stream # 包含指定方法所需的预写日志文件
include required WAL files with specified method
-z, --gzip compress tar output # 压缩 tar 输出
-Z, --compress=[{client|server}-]METHOD[:DETAIL]
compress on client or server as specified
-Z, --compress=none do not compress tar output

General options: # 常规选项
-c, --checkpoint=fast|spread
set fast or spread checkpointing # 设置快速或扩展检查点
-C, --create-slot create replication slot # 创建复制槽
-l, --label=LABEL set backup label # 设置备份标签
-n, --no-clean do not clean up after errors # 出错后不清理
-N, --no-sync do not wait for changes to be written safely to disk # 不等待更改安全性就写入硬盘
-P, --progress show progress information # 显示进度信息
-S, --slot=SLOTNAME replication slot to use # 指定复制槽
-v, --verbose output verbose messages # 输出详细信息
-V, --version output version information, then exit # 显示版本号
--manifest-checksums=SHA{224,256,384,512}|CRC32C|NONE
use algorithm for manifest checksums
--manifest-force-encode
hex encode all file names in manifest
--no-estimate-size do not estimate backup size in server side
--no-manifest suppress generation of backup manifest
--no-slot prevent creation of temporary replication slot # 防止创建临时复制槽
--no-verify-checksums
do not verify checksums # 不验证校验和
-?, --help show this help, then exit

Connection options: # 连接选项
-d, --dbname=CONNSTR connection string
-h, --host=HOSTNAME database server host or socket directory
-p, --port=PORT database server port number
-s, --status-interval=INTERVAL # 状态包发送到数据库服务器的间隔时间, 单位为秒
time between status packets sent to server (in seconds)
-U, --username=NAME connect as specified database user
-w, --no-password never prompt for password
-W, --password force password prompt (should happen automatically)

Report bugs to <pgsql-bugs@lists.postgresql.org>.
PostgreSQL home page: <https://www.postgresql.org/>

在主库使用pg_basebackup

  1. 创建热备份目录
mkdir -p /home/postgres/backup/hot/$(date +%F)
  1. 执行热备份。-F t指定格式tar格式输出。-X表示备份开始后,启动另一个流复制连接从数据库接收预写日志文件。接收到的预写日志文件会被写入一个单独的名称为pg_wal.tar的文件。
pg_basebackup -F t -D /home/postgres/backup/hot/$(date +%F) -v -Xs
  1. 查看生成的备份文件
$ tree /home/postgres/backup/hot

/home/postgres/backup/hot
└── 2024-01-27
├── backup_manifest
├── base.tar
└── pg_wal.tar

2 directories, 3 files

在从库使用pg_basebackup

  1. 在主库创建具有复制权限的用户
create user backup_user replication login password 'bakupwd';
  1. 修改主库的pg_hba.conf文件, 允许backup_user从任意地址通过加密密码访问replication数据库
host replication backup_user 0.0.0.0/0 scram-sha-256
  1. 重加载pg_hba.conf配置
pg_ctl reload -D /home/postgres/apps/pgsql/data/
  1. 在从库创建热备份目录
mkdir -p /home/postgres/backup/hot/$(date +%F)
  1. 在从库执行热备份。按提示填写backup_user用户密码
pg_basebackup -h 192.168.1.112 -p 5432 -U backup_user -F t -D /home/postgres/backup/hot/$(date +%F) -v -Xs

使用pg_basebackup的备份进行恢复

不管是在主库,还是在从库上,在使用pg_basebackup执行备份操作后,便可以使用备份产生的备份文件来进行恢复。

  1. 停止pg,并删除其数据目录,模拟数据库运行错误
pg_ctl stop -D /home/postgres/apps/pgsql/data
rm -rf /home/postgres/apps/pgsql/data
  1. 查看pg_basebackup产生的备份文件
/home/postgres/backup/hot
└── 2024-01-27
├── backup_manifest
├── base.tar
└── pg_wal.tar
  1. 将数据文件base.tar解压到数据目录
mkdir /home/postgres/apps/pgsql/data
tar xf base.tar -C /home/postgres/apps/pgsql/data
  1. 修改data目录的权限
chmod -R 700 /home/postgres/apps/pgsql/data
  1. 将pg_wal.tar解压到指定位置,具体位置可自定义,恢复时会用到
mkdir -p /home/postgres/backup/restore
tar xf pg_wal.tar -C /home/postgres/backup/restore/
  1. 修改postgresql.conf文件,指定参数restore_commandrecovery_target
restore_command = 'cp /home/postgres/backup/restore/%f %p'
recovery_target = 'immediate'
  1. 在data目录下新建空文件recovery.signal
touch /home/postgres/apps/pgsql/data/recovery.signal
  1. 启动pg执行恢复
pg_ctl -D /home/postgres/apps/pgsql/data -l logfile start
  1. 验证数据是否恢复成功。正常情况下,原始数据都还在,不过刚恢复时数据库处于只读状态,写入数据将报错。
postgres=# insert into public.user(username,age) values('lisi', 19);
ERROR: cannot execute INSERT in a read-only transaction
  1. 查看pg状态。Database cluster state的值为in archive recovery表示pg正在执行归档恢复操作。
pg_controldata -D /home/postgres/apps/pgsql/data/

...
Database cluster state: in archive recovery
...
  1. 将pg切换为正常运行状态
pg_ctl promote -D /home/postgres/apps/pgsql/data/
  1. insert测试写入是否正常

参考

  • 赵渝强《PostgreSQL数据库实战派》