跳转至

第八章:备份与恢复

数据备份是数据库管理的关键环节。本章将介绍 PostgreSQL 的多种备份策略和恢复方法。

8.1 备份类型概述

备份类型 特点 适用场景
SQL 转储 逻辑备份,跨版本兼容 小型数据库、迁移
文件系统备份 物理备份,速度快 大型数据库
WAL 归档 持续备份,时间点恢复 生产环境
逻辑复制 表级同步 数据分发

8.2 pg_dump 逻辑备份

基本用法

# 备份单个数据库
pg_dump -U postgres -h localhost mydb > backup.sql

# 指定格式
pg_dump -U postgres -F c mydb > backup.dump      # 自定义格式(推荐)
pg_dump -U postgres -F d mydb -f backup_dir/     # 目录格式
pg_dump -U postgres -F t mydb > backup.tar       # tar 格式

# 压缩备份
pg_dump -U postgres -F c -Z 9 mydb > backup.dump

# 仅备份结构
pg_dump -U postgres --schema-only mydb > schema.sql

# 仅备份数据
pg_dump -U postgres --data-only mydb > data.sql

# 备份特定表
pg_dump -U postgres -t users -t orders mydb > tables.sql

# 备份特定模式
pg_dump -U postgres -n sales mydb > sales_schema.sql

# 排除表
pg_dump -U postgres -T logs -T temp_* mydb > backup.sql

恢复数据

# 从 SQL 文件恢复
psql -U postgres -h localhost mydb < backup.sql

# 从自定义格式恢复
pg_restore -U postgres -h localhost -d mydb backup.dump

# 恢复前创建数据库
pg_restore -U postgres -C -d postgres backup.dump

# 恢复特定表
pg_restore -U postgres -d mydb -t users backup.dump

# 并行恢复(加速)
pg_restore -U postgres -d mydb -j 4 backup.dump

# 仅恢复结构
pg_restore -U postgres -d mydb --schema-only backup.dump

# 生成 SQL 而不执行
pg_restore -U postgres --schema-only backup.dump > schema.sql

pg_dumpall 备份所有数据库

# 备份所有数据库和全局对象(角色、表空间)
pg_dumpall -U postgres > all_databases.sql

# 仅备份全局对象
pg_dumpall -U postgres --globals-only > globals.sql

# 恢复
psql -U postgres -f all_databases.sql

8.3 文件系统备份

冷备份

# 停止 PostgreSQL
systemctl stop postgresql

# 复制数据目录
cp -r /var/lib/postgresql/14/main /backup/pg_cold_backup/

# 启动 PostgreSQL
systemctl start postgresql

热备份(需要归档)

-- 开始备份
SELECT pg_start_backup('backup_label');

-- 在操作系统层面复制数据目录
-- cp -r /var/lib/postgresql/14/main /backup/

-- 结束备份
SELECT pg_stop_backup();

8.4 WAL 归档与时间点恢复

配置 WAL 归档

-- postgresql.conf
wal_level = replica
archive_mode = on
archive_command = 'cp %p /archive/%f'

-- 或使用更可靠的命令
archive_command = 'test ! -f /archive/%f && cp %p /archive/%f'

-- Windows
archive_command = 'copy "%p" "C:\\archive\\%f"'

基础备份

# 使用 pg_basebackup
pg_basebackup -U postgres -h localhost -D /backup/base -Ft -z -P

# 参数说明
# -D 目标目录
# -Ft tar 格式
# -z 压缩
# -P 显示进度
# -X stream 同时备份 WAL

时间点恢复(PITR)

# 1. 停止数据库
systemctl stop postgresql

# 2. 清空数据目录
rm -rf /var/lib/postgresql/14/main/*

# 3. 恢复基础备份
tar -xf /backup/base/base.tar.gz -C /var/lib/postgresql/14/main/

# 4. 创建恢复配置
cat > /var/lib/postgresql/14/main/postgresql.auto.conf << EOF
restore_command = 'cp /archive/%f %p'
recovery_target_time = '2024-03-15 10:30:00'
recovery_target_action = 'promote'
EOF

# 5. 创建恢复信号文件
touch /var/lib/postgresql/14/main/recovery.signal

# 6. 启动数据库
systemctl start postgresql

# 数据库将恢复到指定时间点

恢复目标选项

-- 恢复到指定时间
recovery_target_time = '2024-03-15 10:30:00'

-- 恢复到指定事务 ID
recovery_target_xid = '12345'

-- 恢复到指定 WAL 位置
recovery_target_lsn = '0/5000028'

-- 恢复到最早一致点
recovery_target = 'immediate'

-- 恢复后的动作
recovery_target_action = 'promote'  -- 提升为主库
recovery_target_action = 'pause'    -- 暂停等待
recovery_target_action = 'shutdown' -- 关闭

8.5 pgBackRest

pgBackRest 是企业级备份工具:

安装配置

# Ubuntu/Debian
apt-get install pgbackrest

# 创建配置
cat > /etc/pgbackrest/pgbackrest.conf << EOF
[global]
repo1-path=/backup/pgbackrest
repo1-retention-full=2
process-max=4
compress-type=lz4

[main]
pg1-path=/var/lib/postgresql/14/main
EOF

# 创建存储库
mkdir -p /backup/pgbackrest
chown postgres:postgres /backup/pgbackrest

备份操作

# 创建 stanza(备份配置)
pgbackrest --stanza=main stanza-create

# 全量备份
pgbackrest --stanza=main --type=full backup

# 增量备份
pgbackrest --stanza=main --type=incr backup

# 差异备份
pgbackrest --stanza=main --type=diff backup

# 查看备份
pgbackrest --stanza=main info

恢复操作

# 恢复到最新
pgbackrest --stanza=main --delta restore

# 恢复到指定时间
pgbackrest --stanza=main --delta --target="2024-03-15 10:30:00" restore

# 恢复到指定备份
pgbackrest --stanza=main --delta --set=20240315-100000F restore

8.6 自动化备份脚本

#!/bin/bash
# backup_postgres.sh

set -e

# 配置
DB_NAME="mydb"
BACKUP_DIR="/backup/postgres"
DATE=$(date +%Y%m%d_%H%M%S)
RETENTION_DAYS=7

# 创建备份目录
mkdir -p $BACKUP_DIR

# 备份
echo "开始备份 $DB_NAME..."
pg_dump -U postgres -F c -f "$BACKUP_DIR/${DB_NAME}_${DATE}.dump" $DB_NAME

# 检查备份
if [ -f "$BACKUP_DIR/${DB_NAME}_${DATE}.dump" ]; then
    echo "备份成功: ${DB_NAME}_${DATE}.dump"

    # 发送通知
    # curl -X POST webhook_url -d "备份成功"
else
    echo "备份失败!"
    exit 1
fi

# 清理旧备份
find $BACKUP_DIR -name "*.dump" -mtime +$RETENTION_DAYS -delete
echo "清理完成"

# 验证备份
echo "验证备份..."
pg_restore -l "$BACKUP_DIR/${DB_NAME}_${DATE}.dump" > /dev/null
if [ $? -eq 0 ]; then
    echo "备份验证通过"
fi

Cron 定时任务

# 编辑 crontab
crontab -e

# 每天凌晨 2 点备份
0 2 * * * /usr/local/bin/backup_postgres.sh >> /var/log/pg_backup.log 2>&1

# 每周日凌晨 3 点全量备份
0 3 * * 0 /usr/local/bin/backup_postgres.sh --full >> /var/log/pg_backup.log 2>&1

8.7 小结

本章学习了 PostgreSQL 的备份与恢复:

  1. 逻辑备份:pg_dump、pg_dumpall,适合小型数据库
  2. 物理备份:文件系统复制,速度快
  3. WAL 归档:持续备份,支持时间点恢复
  4. pgBackRest:企业级备份工具
  5. 自动化:脚本和定时任务

下一章将学习高可用与复制。