Linux PostgreSQL 自动备份脚本:pg_dump 实战与定时任务配置
在前面的文章中,我们详细讲解了 MySQL 自动备份的完整方案,从全量、增量备份到自动清理、有效性验证,覆盖了生产环境的核心需求。但在实际运维工作中,PostgreSQL(简称 PG)同样是高频使用的数据库,尤其在政企、金融、大数据等场景中应用广泛。
很多运维新手从 MySQL 转向 PG 时,会习惯性沿用 mysqldump 的思路使用 pg_dump,却忽略了两者的核心差异,最终导致备份失败、数据无法恢复、权限报错等问题。其实 PG 在一致性备份方面(MVCC)具有天然优势,但安全性仍取决于权限配置与备份策略,细节上的坑同样不少——比如 pg_dump 的默认备份行为、权限配置、加密方式,都和 mysqldump 有明显区别。
这篇文章,我们从初学者视角出发,结合生产环境实战,手把手教你搞定 PostgreSQL 自动备份:从 pg_dump 核心用法、与 mysqldump 的区别,到全量/单库/单表备份脚本、压缩加密、定时任务配置、自动清理,再到备份恢复验证,每一步都有完整可复制的代码,再也不用为 PG 备份发愁。
适用场景:本文基于 Linux 环境(CentOS/Ubuntu 通用),适配 PostgreSQL 10+ 版本,脚本可直接用于中小规模 PG 实例(数据量<100GB);大规模高并发场景,推荐结合 pg_basebackup 物理备份工具使用。
一、核心前置:pg_dump 与 mysqldump 核心区别
很多运维人员刚接触 PG 备份时,会把 mysqldump 的使用习惯套在 pg_dump 上,导致各种异常。这里用一张表格,清晰对比两者的核心差异,帮你快速避开“思维定势”坑:
| | |
|---|
| PG 官方逻辑备份工具,默认基于 MVCC 提供一致性快照,大多数场景下无需额外参数即可实现逻辑一致备份(高频DDL场景需验证) | MySQL 官方逻辑备份工具,InnoDB 需加 --single-transaction 实现热备 |
| 默认不锁表(MVCC 机制),备份期间不阻塞业务读写 | 默认锁表(MyISAM),InnoDB 需显式加参数避免锁表 |
| 仅支持单个数据库、单表、指定schema备份;整个实例备份需用 pg_dumpall | 支持全库、指定多库、单表,schema 备份需额外处理 |
| 需 CONNECT、SELECT、USAGE 权限,不强制要求 SUPERUSER,具备所有对象访问权限即可 | 需 SELECT、RELOAD 等权限,可创建专用备份账号(最小权限) |
| 默认不压缩,需结合 gzip 压缩;加密需用 openssl(推荐安全参数)或 GPG,支持多种加密方式 | 默认不压缩,可管道压缩;加密逻辑与 PG 一致,需额外工具 |
| 用 psql 导入,需先创建数据库(除非备份时包含创建语句) | 用 mysql 导入,可自动创建数据库(加 --databases 参数) |
⚠️ 避坑提示:pg_dump 默认基于 MVCC 提供一致性快照,大多数场景下无需额外参数即可实现逻辑一致备份,备份期间业务可正常读写,这是 PG 备份的一大优势;但在高频 DDL 或复杂场景下,仍需结合实际验证一致性。另外注意:pg_dump 只能备份单个数据库,无法直接备份整个 PG 实例,全实例备份需使用 pg_dumpall 工具;如果你的需求是“整机备份 + 快速恢复”,建议优先考虑物理备份(pg_basebackup)。
二、前置准备:备份前必须做好的2件事(避免权限踩坑)
PG 备份的权限管控比 MySQL 更严格,提前做好这两步,后续脚本执行不会出现权限报错,避免反复排查。
1. 检查 pg_dump 工具是否安装
pg_dump 是 PostgreSQL 自带的工具,安装 PG 时会自动安装,可通过以下命令检查:
# 检查 pg_dump 版本(确认与 PG 版本一致)
pg_dump --version
# 若提示“command not found”,说明未安装或未配置环境变量
# CentOS 安装:yum install postgresql-server -y
# Ubuntu 安装:apt install postgresql-client -y
# 配置环境变量(若未自动配置):export PATH=$PATH:/usr/pgsql-14/bin(替换为你的 PG 安装路径)
2. 创建 PG 专用备份账号(最小权限原则)
生产环境严禁使用 postgres 超级用户执行备份,建议创建专用备份账号,仅授予备份所需的最小权限,降低安全风险。
-- 1. 切换到 postgres 系统用户(PG 默认管理员用户)
su - postgres
-- 2. 登录 PG 数据库
psql
-- 3. 创建备份账号(替换为你的密码,建议用强密码)
CREATEUSER backup_user WITH PASSWORD '你的强密码';
-- 4. 授予备份所需最小权限(分场景授权,生产级完整配置)
-- 说明:PostgreSQL 不存在专门的 BACKUP 权限,备份权限主要依赖 CONNECT、SELECT、USAGE
-- 核心注意:ON ALL TABLES 仅对当前已存在的表生效,需补充默认权限确保新表继承
-- 场景1:备份全实例(需用 pg_dumpall,备份全局对象时通常需要 SUPERUSER 权限,谨慎授予)
ALTERUSER backup_user SUPERUSER;
-- 场景2:备份指定数据库(推荐,最小权限)
-- 授予指定数据库的连接权限
GRANTCONNECTON DATABASE test_db TO backup_user;
-- 授予当前已存在表的查询权限
GRANTSELECTONALL TABLES IN SCHEMA public TO backup_user;
-- 授予新创建表的自动查询权限(关键,避免后续新表备份报错)
ALTERDEFAULT PRIVILEGES IN SCHEMA public
GRANTSELECTON TABLES TO backup_user;
-- 授予当前已存在序列的使用权限
GRANT USAGE ONALL SEQUENCES IN SCHEMA public TO backup_user;
-- 授予新创建序列的自动使用权限(关键,避免后续新序列备份报错)
ALTERDEFAULT PRIVILEGES IN SCHEMA public
GRANT USAGE ON SEQUENCES TO backup_user;
-- 5. 退出 PG
\q
💡 实用技巧:如果仅备份单个业务库,优先选择“场景2”,无需授予超级用户权限(pg_dump 不强制要求 SUPERUSER,具备所有对象访问权限即可);若需备份整个 PG 实例(所有数据库、角色、权限等全局对象),需用 pg_dumpall 工具,pg_dumpall 在备份全局对象(角色、权限等)时通常需要 SUPERUSER 权限,遵循“最小权限”原则。
三、pg_dump 核心参数详解
pg_dump 的参数比 mysqldump 更简洁,核心常用参数只有10个左右,我们按“备份范围、备份格式、实用优化”分类讲解,结合实例说明,新手一看就会。
1. 备份范围参数(最常用)
| | |
|---|
| | |
| 指定要备份的单个数据库(必选,pg_dump 仅支持单库备份) | pg_dump -U backup_user -d test_db |
| | pg_dump -U backup_user -d test_db -t user_info |
| | pg_dump -U backup_user -d test_db -n public |
| 会尝试连接默认数据库(通常是 postgres)并备份该库,并非全实例备份 | pg_dump -U backup_user(仅备份默认数据库) |
2. 备份格式与优化参数
| | |
|---|
| 自定义格式备份(压缩率高,支持并行恢复、选择性恢复) | 生产环境首选,备份体积小,恢复灵活(不支持断点续传) |
| | |
| | 结合 -F c 使用,推荐级别6(平衡速度与压缩率) |
| | pg_dump -U backup_user -d test_db -f /backup/test_db.sql |
| | |
⚠️ 避坑提示:pg_dump 的自定义格式(-F c)必须用 pg_restore 工具恢复,不能直接用 psql 导入;明文格式(默认)可直接用 psql 导入,新手可先从明文格式入手,熟悉后再用自定义格式。注意:pg_restore 支持并行恢复(-j 参数)和选择性恢复(指定表/ schema),但不支持严格意义上的断点续传恢复。
四、实战1:PG 单库全量备份脚本(压缩+日志+防重复,可直接用)
单库全量备份是 PG 备份的基础(pg_dump 仅支持单库备份),脚本实现:单库全量备份、自定义格式压缩、按日期命名、完整日志记录、防重复执行、异常处理,适配生产环境,可直接复制修改配置使用;若需备份整个 PG 实例,见下方扩展说明。
全量备份是 PG 备份的基础,脚本实现:全量备份、自定义格式压缩、按日期命名、完整日志记录、防重复执行、异常处理,适配生产环境,可直接复制修改配置使用。
1. 完整全量备份脚本
#!/bin/bash
##########################################################
# PostgreSQL 单库全量备份脚本(Linux 通用)
# 功能:单库全量备份、自定义格式压缩、日志记录、防重复、异常处理
# 适用:PostgreSQL 10+ 中小规模实例
# 说明:pg_dump 仅支持单库备份,全实例备份需用 pg_dumpall(见扩展)
##########################################################
######################## 配置项(按需修改) ########################
# PG 备份账号信息
PG_USER="backup_user"
PG_PASSWORD="你的强密码"
PG_HOST="localhost"
PG_PORT="5432"
# 要备份的单个数据库(必选,pg_dump 仅支持单库备份)
PG_DB="test_db"# 不可留空,否则报错
# 备份目录配置
BACKUP_ROOT="/data/backup/postgresql"
FULL_BACKUP_DIR="${BACKUP_ROOT}/full"
LOG_DIR="${BACKUP_ROOT}/logs"
# 备份保留天数(推荐30天)
RETENTION_DAYS=30
# 日期格式(用于文件命名)
DATE=$(date +%Y%m%d_%H%M%S)
# 备份文件名(自定义格式,压缩级别6)
BACKUP_FILE_NAME="pg_full_backup_${PG_DB}_${DATE}.dump"
BACKUP_FILE_PATH="${FULL_BACKUP_DIR}/${BACKUP_FILE_NAME}"
LOG_FILE="${LOG_DIR}/pg_full_backup_${DATE}.log"
# 防重复执行锁文件
LOCK_FILE="/var/lock/pg_full_backup.lock"
###################################################################
# 初始化目录(不存在则创建)
init_dir() {
mkdir -p ${FULL_BACKUP_DIR}
mkdir -p ${LOG_DIR}
}
# 日志输出函数(便于排查问题)
log() {
echo"[$(date +'%Y-%m-%d %H:%M:%S')] $1" >> ${LOG_FILE}
echo"[$(date +'%Y-%m-%d %H:%M:%S')] $1"
}
# 加排他锁,防止脚本重复执行(避免占用过多资源)
flock -xn ${LOCK_FILE} -c "
# 初始化目录
init_dir
log '==================== PostgreSQL 单库全量备份开始 ===================='
log '备份文件路径:${BACKUP_FILE_PATH}'
log '日志文件路径:${LOG_FILE}'
# 检查 PG_DB 是否配置(必选)
if [ -z "${PG_DB}" ]; then
log 'ERROR: 必须指定 PG_DB,pg_dump 不支持全实例备份,全实例请用 pg_dumpall'
exit 1
fi
# 检查 pg_dump 命令是否存在
if ! command -v pg_dump &> /dev/null; then
log 'ERROR: pg_dump 命令不存在,请安装 PostgreSQL 客户端或配置环境变量'
exit 1
fi
# 配置 PG 密码环境变量(避免交互输入密码)
export PGPASSWORD=${PG_PASSWORD}
# 执行单库全量备份(自定义格式+压缩)
log '开始执行单库全量备份...'
pg_dump -U ${PG_USER} -h ${PG_HOST} -p ${PG_PORT} -d ${PG_DB} -F c -Z 6 -f ${BACKUP_FILE_PATH}
# 判断备份是否成功
if [ $? -eq 0 ]; then
# 查看备份文件大小
BACKUP_FILE_SIZE=$(du -h ${BACKUP_FILE_PATH} | awk '{print $1}')
log '✅ 单库全量备份执行成功!'
log "备份文件大小:${BACKUP_FILE_SIZE}"
else
log '❌ 单库全量备份执行失败!'
# 删除无效备份文件,避免占用磁盘
rm -f ${BACKUP_FILE_PATH}
exit 1
fi
# 备份完成,日志结束
log '==================== PostgreSQL 单库全量备份完成 ===================='
# 扩展:全实例备份(pg_dumpall)命令示例
log '全实例备份命令参考:pg_dumpall -U ${PG_USER} -h ${PG_HOST} -p ${PG_PORT} > ${FULL_BACKUP_DIR}/pg_full_instance_${DATE}.sql'
log '注意:pg_dumpall 不支持 -F c 格式,不支持并行恢复,文件体积较大'
"
# 脚本执行结束
exit 0
2. 单库全量备份脚本使用步骤
# 1. 创建单库全量备份脚本文件
vim /usr/local/scripts/pg_full_backup.sh
# 2. 粘贴上面的脚本,修改【配置项】中的账号、密码、备份目录、PG_DB(必选)等信息
# 注意:PG_DB 不可留空,pg_dump 仅支持单库备份;全实例备份见脚本内扩展命令
# 3. 给脚本添加可执行权限
chmod +x /usr/local/scripts/pg_full_backup.sh
# 4. 手动执行测试,验证脚本是否正常运行
/usr/local/scripts/pg_full_backup.sh
# 5. 查看备份文件和日志,确认备份成功
ls /data/backup/postgresql/full
cat /data/backup/postgresql/logs/对应的日志文件
# 扩展:手动执行全实例备份(pg_dumpall)
pg_dumpall -U backup_user -h localhost -p 5432 > /data/backup/postgresql/full/pg_full_instance_20260411.sql
五、实战2:PG 单库/单表备份脚本
生产环境中,很多时候不需要全库备份(比如只需要备份核心业务表),单库/单表备份可以节省磁盘空间、提高备份效率,下面分别给出两种场景的脚本,可直接套用。
1. 单库备份脚本(简化版)
#!/bin/bash
##########################################################
# PostgreSQL 单库备份脚本
# 功能:指定单库备份、压缩、日志记录
##########################################################
# 配置项(按需修改)
PG_USER="backup_user"
PG_PASSWORD="你的强密码"
PG_HOST="localhost"
PG_PORT="5432"
PG_DB="test_db"# 要备份的单库名称
BACKUP_ROOT="/data/backup/postgresql/single_db"
LOG_DIR="${BACKUP_ROOT}/logs"
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="${BACKUP_ROOT}/pg_single_${PG_DB}_${DATE}.dump"
LOG_FILE="${LOG_DIR}/pg_single_backup_${DATE}.log"
# 初始化目录
mkdir -p ${BACKUP_ROOT}
mkdir -p ${LOG_DIR}
log() {
echo"[$(date +'%Y-%m-%d %H:%M:%S')] $1" >> ${LOG_FILE}
echo"[$(date +'%Y-%m-%d %H:%M:%S')] $1"
}
log'==================== 单库备份开始 ===================='
export PGPASSWORD=${PG_PASSWORD}
# 执行单库备份(自定义格式+压缩)
pg_dump -U ${PG_USER} -h ${PG_HOST} -p ${PG_PORT} -d ${PG_DB} -F c -Z 6 -f ${BACKUP_FILE}
if [ $? -eq 0 ]; then
log"✅ 单库(${PG_DB})备份成功,文件路径:${BACKUP_FILE}"
else
log"❌ 单库(${PG_DB})备份失败"
rm -f ${BACKUP_FILE}
exit 1
fi
log'==================== 单库备份完成 ===================='
exit 0
2. 单库备份脚本使用步骤
# 1. 创建单库备份脚本文件(路径与脚本名对应,避免混淆)
vim /usr/local/scripts/pg_single_backup.sh
# 2. 粘贴上面的单库备份脚本,修改【配置项】
# 重点修改:PG_USER、PG_PASSWORD、PG_DB、BACKUP_ROOT 等信息
# 3. 给脚本添加可执行权限
chmod +x /usr/local/scripts/pg_single_backup.sh
# 4. 手动执行测试,验证脚本是否正常运行
/usr/local/scripts/pg_single_backup.sh
# 5. 查看备份文件和日志,确认备份成功
ls /data/backup/postgresql/single_db
cat /data/backup/postgresql/single_db/logs/对应的日志文件
3. 单表备份脚本(精准备份核心表)
#!/bin/bash
##########################################################
# PostgreSQL 单表备份脚本
# 功能:指定单库单表备份、压缩、日志记录
##########################################################
# 配置项(按需修改)
PG_USER="backup_user"
PG_PASSWORD="你的强密码"
PG_HOST="localhost"
PG_PORT="5432"
PG_DB="test_db"# 表所在的数据库
PG_TABLE="user_info"# 要备份的单表名称
BACKUP_ROOT="/data/backup/postgresql/single_table"
LOG_DIR="${BACKUP_ROOT}/logs"
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="${BACKUP_ROOT}/pg_table_${PG_DB}_${PG_TABLE}_${DATE}.dump"
LOG_FILE="${LOG_DIR}/pg_table_backup_${DATE}.log"
# 初始化目录
mkdir -p ${BACKUP_ROOT}
mkdir -p ${LOG_DIR}
log() {
echo"[$(date +'%Y-%m-%d %H:%M:%S')] $1" >> ${LOG_FILE}
echo"[$(date +'%Y-%m-%d %H:%M:%S')] $1"
}
log'==================== 单表备份开始 ===================='
export PGPASSWORD=${PG_PASSWORD}
# 执行单表备份(-t 指定表名)
pg_dump -U ${PG_USER} -h ${PG_HOST} -p ${PG_PORT} -d ${PG_DB} -t ${PG_TABLE} -F c -Z 6 -f ${BACKUP_FILE}
if [ $? -eq 0 ]; then
log"✅ 单表(${PG_DB}.${PG_TABLE})备份成功,文件路径:${BACKUP_FILE}"
else
log"❌ 单表(${PG_DB}.${PG_TABLE})备份失败"
rm -f ${BACKUP_FILE}
exit 1
fi
log'==================== 单表备份完成 ===================='
exit 0
4. 单表备份脚本使用步骤
# 1. 创建单表备份脚本文件
vim /usr/local/scripts/pg_table_backup.sh
# 2. 粘贴上面的单表备份脚本,修改【配置项】
# 重点修改:PG_USER、PG_PASSWORD、PG_DB、PG_TABLE、BACKUP_ROOT 等信息
# 3. 给脚本添加可执行权限
chmod +x /usr/local/scripts/pg_table_backup.sh
# 4. 手动执行测试,验证脚本是否正常运行
/usr/local/scripts/pg_table_backup.sh
# 5. 查看备份文件和日志,确认备份成功
ls /data/backup/postgresql/single_table
cat /data/backup/postgresql/single_table/logs/对应的日志文件
💡 实用技巧:如果需要备份多个表,可在 -t 参数后添加多个表名,用空格分隔,例如:-t user_info -t order_info。
六、实战3:备份压缩与加密(生产环境必备,防止数据泄露)
PG 备份文件可能包含敏感数据(如用户信息、交易数据),仅压缩远远不够,建议对包含敏感数据的备份进行加密处理;同时,合理的压缩方式可以大幅减小备份文件体积,节省磁盘空间。
1. 备份压缩(两种方式,按需选择)
我们在前面的脚本中已经使用了 pg_dump 自带的压缩(-Z 6),除此之外,还可以结合 gzip 进行二次压缩(适合明文格式备份),两种方式对比如下:
# 方式1:pg_dump 自带压缩(推荐,自定义格式,压缩率高)
pg_dump -U backup_user -d test_db -F c -Z 6 -f test_db.dump
# 方式2:gzip 二次压缩(适合明文格式备份)
pg_dump -U backup_user -d test_db -f test_db.sql | gzip -9 > test_db.sql.gz
# 说明:gzip -9 表示最高压缩级别,速度较慢,适合夜间低峰期备份
2. 备份加密(openssl 加密,安全可靠)
# 1. 备份+压缩+加密(一步完成,推荐安全参数)
pg_dump -U backup_user -d test_db -F c -Z 6 | openssl enc -e -aes-256-cbc -pbkdf2 -iter 100000 -k "你的加密密码" -out test_db.dump.enc
# 2. 解密备份文件(恢复前必须先解密,参数与加密时保持一致)
openssl enc -d -aes-256-cbc -pbkdf2 -iter 100000 -k "你的加密密码" -in test_db.dump.enc -out test_db.dump
# 3. 加密脚本整合(修改全量备份脚本核心部分)
# 替换原备份命令为以下内容:
pg_dump -U ${PG_USER} -h ${PG_HOST} -p ${PG_PORT} -F c -Z 6 | openssl enc -e -aes-256-cbc -pbkdf2 -iter 100000 -k "你的加密密码" -out ${BACKUP_FILE_PATH}.enc
# 注意1:备份文件名后缀改为 .enc,便于区分加密文件
# 注意2:更推荐使用 GPG 加密,安全性更高;openssl 需使用 -pbkdf2 提升安全性(避免 -k 弱KDF风险)
⚠️ 避坑提示:加密后的备份文件,必须先解密才能恢复;建议将加密密码记录在安全的密码管理工具中,避免丢失;涉及敏感数据的生产环境建议进行加密,非敏感数据可根据需求选择是否加密。
七、实战4:定时任务配置与过期备份自动清理
备份脚本编写完成后,需要配置定时任务(crontab)实现自动执行,同时定时清理过期备份文件,避免磁盘被占满,这两步结合才能实现真正的“自动备份”。
1. 定时任务配置(crontab,与 PG 备份适配)
推荐备份时间:全量备份在每日凌晨3点(业务低峰期),单库/单表备份可在每日凌晨4点,避免与全量备份冲突。
2. 过期备份自动清理脚本(安全版,防误删)
清理脚本实现:清理指定天数前的全量、单库、单表备份文件,限制目录深度,避免变量异常导致误删,同时记录清理日志,便于追溯。
3. 清理脚本定时配置
# 1. 编辑 crontab 定时任务
crontab -e
# 2. 添加定时任务(按需选择,可同时添加多个)
# 每日凌晨3点执行单库全量备份
0 3 * * * /usr/local/scripts/pg_full_backup.sh >> /var/log/cron/pg_full_backup.log 2>&1
# 每日凌晨4点执行单库备份
0 4 * * * /usr/local/scripts/pg_single_backup.sh >> /var/log/cron/pg_single_backup.log 2>&1
# 3. 注意:crontab 修改后会自动生效,无需重启 crond/cron 服务
# 4. 查看定时任务是否添加成功
crontab -l
# 添加定时任务,每日凌晨5点执行(备份完成后)
crontab -e
0 5 * * * /usr/local/scripts/pg_backup_clean.sh >> /var/log/cron/pg_clean.log 2>&1
八、实战5:备份恢复验证(关键步骤,避免备份无效)
和 MySQL 备份一样,PG 备份的核心价值是“可恢复”,很多新手只关注备份是否执行,却忽略了备份文件是否有效,等到故障发生时才发现备份无法恢复,追悔莫及。下面给出完整的恢复验证方法,适配不同备份格式和场景。
#!/bin/bash
##########################################################
# PostgreSQL 过期备份自动清理脚本(安全版)
# 功能:清理过期备份、日志,防误删,可追溯
# 适配:单库备份、全实例备份文件清理
##########################################################
# 配置项
BACKUP_ROOT="/data/backup/postgresql"
# 备份保留天数(与备份脚本一致,推荐30天)
RETENTION_DAYS=30
# 日志保留天数(7天)
LOG_RETENTION=7
LOG_FILE="${BACKUP_ROOT}/logs/backup_clean_$(date +%Y%m%d).log"
# 日志输出函数
log() {
echo"[$(date +'%Y-%m-%d %H:%M:%S')] $1" >> ${LOG_FILE}
echo"[$(date +'%Y-%m-%d %H:%M:%S')] $1"
}
log'==================== 过期备份清理开始 ===================='
# 清理单库全量备份(限制目录深度,防误删)
log"清理${RETENTION_DAYS}天前的单库全量备份..."
find ${BACKUP_ROOT}/full -mindepth 1 -maxdepth 1 -type f -name "pg_full_backup_*.dump*" -mtime +${RETENTION_DAYS} -print -delete >> ${LOG_FILE}
# 清理全实例备份(pg_dumpall 生成的 sql 文件)
log"清理${RETENTION_DAYS}天前的全实例备份..."
find ${BACKUP_ROOT}/full -mindepth 1 -maxdepth 1 -type f -name "pg_full_instance_*.sql*" -mtime +${RETENTION_DAYS} -print -delete >> ${LOG_FILE}
# 清理单库备份
log"清理${RETENTION_DAYS}天前的单库备份..."
find ${BACKUP_ROOT}/single_db -mindepth 1 -maxdepth 1 -type f -name "pg_single_*.dump*" -mtime +${RETENTION_DAYS} -print -delete >> ${LOG_FILE}
# 清理单表备份
log"清理${RETENTION_DAYS}天前的单表备份..."
find ${BACKUP_ROOT}/single_table -mindepth 1 -maxdepth 1 -type f -name "pg_table_*.dump*" -mtime +${RETENTION_DAYS} -print -delete >> ${LOG_FILE}
# 清理过期日志
log"清理${LOG_RETENTION}天前的备份日志..."
find ${BACKUP_ROOT}/logs -type f -name "*.log" -mtime +${LOG_RETENTION} -print -delete >> ${LOG_FILE}
log'✅ 过期备份清理完成'
log'==================== 清理结束 ===================='
exit 0
1. 明文格式备份恢复(.sql 文件)
# 1. 恢复前先创建数据库(若备份时未包含创建语句)
su - postgres
psql
CREATE DATABASE test_db_restore; # 新数据库名称,可自定义
\q
# 2. 执行恢复(用 psql 导入)
psql -U backup_user -d test_db_restore -f /data/backup/postgresql/full/pg_full_backup_xxx.sql
# 3. 验证恢复结果(登录数据库查看表和数据)
psql -U backup_user -d test_db_restore
\dt # 查看所有表
select count(*) from user_info; # 查看核心表数据量
\q
2. 自定义格式备份恢复(.dump 文件)
自定义格式备份(-F c)必须用 pg_restore 工具恢复,支持并行恢复(-j 参数)和选择性恢复(指定表/ schema),灵活性更高,但不支持严格意义上的断点续传恢复。
# 1. 方式1:完整恢复(覆盖整个数据库)
pg_restore -U backup_user -h localhost -p 5432 -d test_db_restore -F c /data/backup/postgresql/full/pg_full_backup_xxx.dump
# 2. 方式2:选择性恢复(仅恢复指定表)
pg_restore -U backup_user -d test_db_restore -F c -t user_info /data/backup/postgresql/full/pg_full_backup_xxx.dump
# 3. 验证恢复结果(同上,登录数据库查看)
3. 加密备份恢复(先解密,再恢复)
# 1. 先解密备份文件(参数与加密时保持一致,避免解密失败)
openssl enc -d -aes-256-cbc -pbkdf2 -iter 100000 -k "你的加密密码" -in pg_full_backup_xxx.dump.enc -out pg_full_backup_xxx.dump
# 2. 再执行恢复(自定义格式,用 pg_restore)
pg_restore -U backup_user -d test_db_restore -F c pg_full_backup_xxx.dump
4. 自动验证脚本
可参考 MySQL 备份验证逻辑,编写自动验证脚本,备份完成后自动创建临时库、导入备份,验证成功后删除临时库,异常则发送告警,确保备份始终有效。
九、常见问题与避坑指南
1. 执行 pg_dump 提示“权限不足”?
原因1:备份账号没有对应权限(比如全库备份没有 SUPERUSER 权限);原因2:备份账号没有连接数据库的权限。
解决:重新授予权限(参考前置准备中的权限配置,删除无效的 GRANT BACKUP 语句);若为单库备份,确保账号有该数据库的 CONNECT、SELECT 权限;pg_dump 不强制要求 SUPERUSER,具备所有对象访问权限即可。
2. 备份时提示“could not connect to server”?
原因1:PG 服务未启动;原因2:PG_HOST、PG_PORT 配置错误;原因3:PG 监听地址限制(未监听 localhost)。
解决:启动 PG 服务(systemctl start postgresql);检查配置项中的主机和端口;修改 pg_hba.conf 文件,允许 localhost 连接。
3. 恢复时提示“relation already exists”(表已存在)?
原因:恢复的数据库中已存在同名表,未清理就执行恢复。
解决:恢复前删除同名表,或在备份时添加 --clean 参数(备份文件中包含删除语句),谨慎使用 --clean(避免误删数据)。
4. 加密备份解密时提示“bad decrypt”?
原因:加密密码错误,或备份文件损坏。
解决:核对加密密码(区分大小写);若备份文件损坏,重新执行备份。
5. 备份文件过大,磁盘占满?
解决:使用自定义格式(-F c)+ 压缩(-Z 6);定期清理过期备份;排除无备份价值的大表(用 -T 参数排除表)。
十、总结
本文从 PG 备份的核心痛点出发,完整讲解了 PostgreSQL 自动备份的全流程:从 pg_dump 与 mysqldump 的区别、前置权限配置,到单库全量/单库/单表备份脚本、压缩加密、定时任务、自动清理,再到备份恢复验证,每一步都有可复制的实战代码,兼顾专业性和易懂性,修正了关键技术错误,新手也能快速落地。
如果你觉得本文对你有帮助,欢迎点赞、推荐、转发,关注我,后续会分享更多Linux入门干货!
文 / 零距技术仓
记录每一次真实的折腾 (#^.^#)
🚀 想看到更多实用折腾技巧?
👉 先关注
💬 评论区说说你的经历或想看的内容
👍 点赞表示支持
🔁 顺手分享给也在折腾的人,让大家都少踩坑 😎