Skip to content

postgresql 大型数据库 / 生产环境:使用 pg_basebackup(全量物理备份)+ WAL 归档(增量 / PITR),保证备份效率和灾备能力。 #24

Description

@ipme

这个肯定不能 多讲了吧!
pg_probackup:PostgreSQL 官方推荐的备份工具,支持增量备份、压缩、校验、时间点恢复。

1. pg_basebackup(全量物理备份)

pg_basebackup 基于 PostgreSQL 的流复制机制,生成数据库集群的完整物理副本,支持热备份(不中断业务)。

前置条件(必须配置):

修改postgresql.confpg_hba.conf,开启流复制:

# 1. 编辑postgresql.conf        ###     /data/pgsql-18/postgresql.conf {看你安装的pgsql 什么版本,对应版本号,这里演示是pgsql-18}
sudo vim postgresql.conf
# 添加/修改以下配置
wal_level = replica       # 开启WAL日志的复制级别
max_wal_senders = 10       # 允许的流复制连接数
wal_keep_size = 128MB      # 保留的WAL日志大小(按需调整)
listen_addresses = '*'    # 允许远程连接(若备份在远程执行)

2. 编辑pg_hba.conf,#允许备份用户的流复制连接

PS:本地主机,就不用管这个配置文件了

sudo vim pg_hba.conf

# 添加流复制授权规则(根据实际场景选择)

# 场景1:本地备份(备份机和数据库在同一台服务器)
local   replication     postgres                                peer 

# 场景2:远程备份(指定备份机IP,比如备份机IP是192.168.1.100)
host    replication     postgres        192.168.1.100/32        md5

# 说明:
# replication:表示流复制连接(pg_basebackup用此类型)
# postgres:备份使用的用户(建议用超级用户,如postgres)
# 192.168.1.100/32:允许的备份机IP段(/32表示单个IP)
# md5:认证方式(本地可使用peer,远程建议md5)

# 3. 重启PostgreSQL服务
bypanel restart postgresql 

测试一下 直接在宿主机 运行命令

docker exec -u postgres bypanel-postgresql-1 \
  pg_basebackup -U postgres -D /shared/backups/pgsql_18/pg_base_20260109 -F p -X s -P -c fast

正常成功显示

waiting for checkpoint
32472/32472 kB (100%), 0/1 tablespace
32472/32472 kB (100%), 1/1 tablespace
pg_basebackup: base backup completed

验证备份结果(宿主机端)

# 查看新备份文件夹
ls -l /data/backups/pgsql_18/

# 预期输出(会看到pg_base_20260109,所有者为999:999/999:systemd-journal):
total 8
drwx------ 19 999 systemd-journal 4096 Jan  8 01:44 pg_base_20260108
drwx------ 19 999 systemd-journal 4096 Jan  8 XX:XX pg_base_20260109

# 检查核心备份文件(确认完整性)
ls -l /data/backups/pgsql_18/pg_base_20260109/ | grep backup_label
# 能看到backup_label文件即代表备份完整:
-rw------- 1 999 systemd-journal   207 Jan  8 XX:XX backup_label

新建一个 备份脚本(解决目录非空问题+只保存15天数据,超期删除)

/data/scripts/pgsql_backup.sh 添加「备份前检查并删除当天备份目录」的逻辑,避免冲突:

#!/bin/bash
# PostgreSQL容器物理备份脚本(修复目录非空问题)
# 解决pg_basebackup要求目录为空的问题:先删除已存在的当天备份目录

# 添加系统环境变量(避免crontab找不到docker命令)
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

# 核心配置
BACKUP_DIR="/data/backups/pgsql_18"          # 宿主机备份目录
CONTAINER_BACKUP_DIR="/shared/backups/pgsql_18"  # 容器内备份目录
CONTAINER_NAME="bypanel-postgresql-1"        # 容器名
BACKUP_NAME="pg_base_$(date +%Y%m%d)"        # 当天备份目录名

# 步骤1:删除容器内已存在的当天备份目录(避免非空报错)
echo "[$(date +'%Y-%m-%d %H:%M:%S')] 检查并删除已存在的备份目录: ${CONTAINER_BACKUP_DIR}/${BACKUP_NAME}"
docker exec -u postgres ${CONTAINER_NAME} rm -rf ${CONTAINER_BACKUP_DIR}/${BACKUP_NAME}

# 步骤2:执行物理备份(此时目录为空,不会报错)
echo "[$(date +'%Y-%m-%d %H:%M:%S')] 开始执行PostgreSQL物理备份..."
docker exec -u postgres ${CONTAINER_NAME} \
  pg_basebackup -U postgres -D ${CONTAINER_BACKUP_DIR}/${BACKUP_NAME} -F p -X s -P -c fast

# 步骤3:清理15天前的备份(仅删除pg_base_开头的目录)
echo "[$(date +'%Y-%m-%d %H:%M:%S')] 清理15天前的备份文件..."
find ${BACKUP_DIR} -name "pg_base_*" -type d -mtime +15 -exec rm -rf {} \;

# 步骤4:输出备份完成日志
echo "[$(date +'%Y-%m-%d %H:%M:%S')] 备份+清理完成!当前保留的备份目录:"
ls -l ${BACKUP_DIR} | grep pg_base_

执行脚本

# 1. 确保脚本执行权限
chmod +x /data/scripts/pgsql_backup.sh

# 2. 手动执行脚本测试(验证无报错)
./data/scripts/pgsql_backup.sh

预期正常输出(无目录非空报错)

[2026-01-08 10:00:00] 检查并删除已存在的备份目录: /shared/backups/pgsql_18/pg_base_20260108
[2026-01-08 10:00:00] 开始执行PostgreSQL物理备份...
32472/32472 kB (100%), 1/1 tablespace
[2026-01-08 10:00:10] 清理15天前的备份文件...
[2026-01-08 10:00:10] 备份+清理完成!当前保留的备份目录:
drwx------ 19 70 70 4096 Jan  8 10:00 pg_base_20260108

配置 crontab 定时任务

crontab -e

每天凌晨2:00执行PostgreSQL备份+清理(保留15天)

0 2 * * * /data/scripts/pgsql_backup.sh >> /data/scripts/pgsql_backup.log 2>&1

日志排查:若仍有报错,查看脚本日志定位问题

tail -f /data/scripts/pgsql_backup.log

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions