本文目录导读:

- 核心工具:
pg_dump和pg_dumpall - 方案一:Bash 脚本(Linux / macOS / WSL)
- 方案二:Windows 批处理脚本(.bat)
- 方案三:PowerShell 脚本(更现代)
- 关键建议与最佳实践
- 快速启动步骤总结
是的,脚本完全可以自动备份 PostgreSQL 数据库,这是运维中非常常见的需求,以下我会提供几种常见的脚本方案(Bash/Linux、Windows批处理/PowerShell),并解释关键点。
核心工具:pg_dump 和 pg_dumpall
pg_dump:备份单个数据库(最常用)。pg_dumpall:备份整个数据库集群(包括所有数据库、用户、表空间等)。
Bash 脚本(Linux / macOS / WSL)
这是最主流、最灵活的方式。
#!/bin/bash
# ======================================================
# PostgreSQL 自动备份脚本 (pg_dump)
# 用法: 将此脚本添加到 crontab 中定时执行
# ======================================================
# --- 配置区域 ---
DB_NAME="your_database_name" # 要备份的数据库名
DB_USER="your_username" # 数据库用户(需要有读权限)
DB_HOST="localhost" # 数据库主机地址
DB_PORT="5432" # 数据库端口
BACKUP_DIR="/path/to/your/backups" # 备份文件存储目录
RETENTION_DAYS=7 # 保留最近7天的备份(自动删除旧文件)
# --- 以下是脚本逻辑,一般不需要修改 ---
# 1. 生成带时间戳的文件名(mydb_20231027_143022.sql.gz)
TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
BACKUP_FILE="${BACKUP_DIR}/${DB_NAME}_${TIMESTAMP}.sql.gz"
# 2. 创建备份目录(如果不存在)
mkdir -p "${BACKUP_DIR}"
# 3. 执行备份,实时压缩(推荐,节省空间)
# - 使用 管道 (pipe) 把 pg_dump 输出直接传给 gzip
# - 注意密码处理:建议使用 .pgpass 文件或环境变量 PGPASSWORD
echo "开始备份数据库: ${DB_NAME} ..."
pg_dump -h ${DB_HOST} -p ${DB_PORT} -U ${DB_USER} -d ${DB_NAME} | gzip > ${BACKUP_FILE}
# 4. 检查备份是否成功
if [ $? -eq 0 ] && [ -s "${BACKUP_FILE}" ]; then
echo "备份成功!文件: ${BACKUP_FILE} ($(du -sh ${BACKUP_FILE} | cut -f1))"
else
echo "错误:备份失败!"
# 这里可以添加发送告警通知(邮件、短信)
exit 1
fi
# 5. 删除旧备份(保留策略)
echo "清理 ${RETENTION_DAYS} 天前的备份..."
find ${BACKUP_DIR} -name "${DB_NAME}_*.sql.gz" -type f -mtime +${RETENTION_DAYS} -delete
echo "备份流程结束。"
使用前注意事项:
- 密码安全:不要在脚本里写明文密码,推荐使用
~/.pgpass文件(权限需为 600 或 0600),格式为:hostname:port:database:username:password或者临时设置环境变量:export PGPASSWORD='your_password'(不太安全)。 - 给脚本执行权限:
chmod +x backup_pg.sh - 设置定时任务 (Crontab):
crontab -e,添加一行,例如每天凌晨2点执行:0 2 * * * /path/to/your/backup_pg.sh >> /var/log/pg_backup.log 2>&1
Windows 批处理脚本(.bat)
适用于 Windows 系统。
@echo off
setlocal enabledelayedexpansion
:: ============================================
:: PostgreSQL 自动备份脚本 (Windows)
:: ============================================
:: ----- 配置区域 -----
set DB_NAME=your_database_name
set DB_USER=your_username
set DB_HOST=localhost
set DB_PORT=5432
:: Windows 下 pg_dump 路径(请根据实际安装位置修改)
set PG_DUMP_PATH="C:\Program Files\PostgreSQL\15\bin\pg_dump.exe"
:: 备份存储目录
set BACKUP_DIR=C:\Backups\PostgreSQL
:: 保留天数
set RETENTION_DAYS=7
:: ----- 脚本逻辑 -----
:: 1. 创建备份目录
if not exist "%BACKUP_DIR%" mkdir "%BACKUP_DIR%"
:: 2. 生成时间戳文件名
set TIMESTAMP=%date:~0,4%%date:~5,2%%date:~8,2%_%time:~0,2%%time:~3,2%%time:~6,2%
:: 去除时间中的空格(如果小时小于10,前面会有空格导致文件名异常)
set TIMESTAMP=%TIMESTAMP: =0%
set BACKUP_FILE=%BACKUP_DIR%\%DB_NAME%_%TIMESTAMP%.sql
:: 3. 设置临时PGPASSWORD环境变量(方法1:使用.pgpass或设置环境变量)
:: 注意:这会短暂暴露密码,但比写在文件里好一点
:: set PGPASSWORD=your_password_here
:: 更推荐:使用 pgpass.conf 文件(路径:%APPDATA%\postgresql\pgpass.conf)
:: 4. 执行备份
echo 开始备份数据库 %DB_NAME% ...
%PG_DUMP_PATH% -h %DB_HOST% -p %DB_PORT% -U %DB_USER% -d %DB_NAME% > "%BACKUP_FILE%"
if %errorlevel% neq 0 (
echo 错误:备份失败!
pause
exit /b 1
) else (
echo 备份成功!文件: %BACKUP_FILE%
)
:: 5. 删除旧备份 (使用 forfiles,Windows 7+ 自带)
echo 清理 %RETENTION_DAYS% 天前的备份...
forfiles -p "%BACKUP_DIR%" -s -m *.sql -d -%RETENTION_DAYS% -c "cmd /c del @path" 2>nul
echo 备份流程结束。
PowerShell 脚本(更现代)
# ============================================
# PostgreSQL 自动备份脚本 (PowerShell)
# ============================================
# 配置参数
$DBName = "your_database_name"
$DBUser = "your_username"
$DBHost = "localhost"
$DBPort = "5432"
$BackupDir = "C:\Backups\PostgreSQL"
$RetentionDays = 7
# pg_dump 路径
$PgDumpPath = "C:\Program Files\PostgreSQL\15\bin\pg_dump.exe"
# 创建备份目录
if (-not (Test-Path $BackupDir)) {
New-Item -ItemType Directory -Path $BackupDir
}
# 生成时间戳文件名
$Timestamp = Get-Date -Format "yyyyMMdd_HHmmss"
$BackupFile = Join-Path $BackupDir "$($DBName)_$Timestamp.sql"
# 执行备份
Write-Host "开始备份数据库: $DBName"
# 推荐使用 .pgpass 文件,或通过 PGPASSWORD 环境变量传递密码
$env:PGPASSWORD = "your_password_here" # 注意安全
& $PgDumpPath -h $DBHost -p $DBPort -U $DBUser -d $DBName | Out-File $BackupFile
if ($LASTEXITCODE -eq 0) {
Write-Host "备份成功!文件: $BackupFile"
} else {
Write-Host "错误:备份失败!"
exit 1
}
# 清理旧备份
Write-Host "清理 $RetentionDays 天前的备份..."
Get-ChildItem $BackupDir -Filter "*.sql" | Where-Object {
$_.LastWriteTime -lt (Get-Date).AddDays(-$RetentionDays)
} | Remove-Item -Force
Write-Host "备份流程结束。"
关键建议与最佳实践
- 不要写死密码:始终使用
.pgpass文件或环境变量(如PGPASSWORD),在敏感环境中,可以考虑使用 HashiCorp Vault 等机密管理服务。 - 实时压缩:上面 Bash 脚本里使用的
| gzip方式(生成.sql.gz)是标准做法,能显著节省磁盘空间和 I/O。 - 备份策略:
- 保留周期:如上面的
RETENTION_DAYS变量,根据你的恢复点目标(RPO)和磁盘容量来定。 - 异地备份:备份文件生成后,用
rsync、scp或云存储 CLI(如aws s3 cp、rclone)将备份传到另一台机器或对象存储。
- 保留周期:如上面的
- 日志与告警:在脚本中加入失败后的通知(发送邮件到运维团队、调用 Webhook 等)。
- 测试恢复:定期的备份脚本运行成功,不代表恢复就一定成功,务必定期测试恢复(每月恢复一次到测试环境)。
- 权限:确保运行脚本的操作系统用户对备份目录有写权限,对 PostgreSQL 有读权限(通常通过
pg_hba.conf的trust或md5/scram-sha-256认证控制)。
快速启动步骤总结
- 配置
.pgpass(Linux) 或pgpass.conf(Windows)。 - 选择一个脚本(推荐 Linux Bash)。
- 填入你的数据库连接信息 和 备份目录。
- 本地测试运行一次。
- 设置定时任务(crontab / 任务计划程序)。
- 定期检查备份文件 和 定期做恢复演练。
如果需要处理非常大的数据库(比如几TB),建议考虑 pg_dump 的 --jobs 并行选项(需要 PG 9.3+)或使用 pg_basebackup 进行物理备份(配合 WAL 归档实现持续备份)。