脚本能自动备份PostgreSQL吗?

wen 实用脚本 2

本文目录导读:

脚本能自动备份PostgreSQL吗?

  1. 核心工具:pg_dumppg_dumpall
  2. 方案一:Bash 脚本(Linux / macOS / WSL)
  3. 方案二:Windows 批处理脚本(.bat)
  4. 方案三:PowerShell 脚本(更现代)
  5. 关键建议与最佳实践
  6. 快速启动步骤总结

是的,脚本完全可以自动备份 PostgreSQL 数据库,这是运维中非常常见的需求,以下我会提供几种常见的脚本方案(Bash/Linux、Windows批处理/PowerShell),并解释关键点。

核心工具:pg_dumppg_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 "备份流程结束。"

使用前注意事项:

  1. 密码安全:不要在脚本里写明文密码,推荐使用 ~/.pgpass 文件(权限需为 600 或 0600),格式为: hostname:port:database:username:password 或者临时设置环境变量:export PGPASSWORD='your_password'(不太安全)。
  2. 给脚本执行权限chmod +x backup_pg.sh
  3. 设置定时任务 (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 "备份流程结束。"

关键建议与最佳实践

  1. 不要写死密码:始终使用 .pgpass 文件或环境变量(如 PGPASSWORD),在敏感环境中,可以考虑使用 HashiCorp Vault 等机密管理服务。
  2. 实时压缩:上面 Bash 脚本里使用的 | gzip 方式(生成 .sql.gz)是标准做法,能显著节省磁盘空间和 I/O。
  3. 备份策略
    • 保留周期:如上面的 RETENTION_DAYS 变量,根据你的恢复点目标(RPO)和磁盘容量来定。
    • 异地备份:备份文件生成后,用 rsyncscp 或云存储 CLI(如 aws s3 cprclone)将备份传到另一台机器或对象存储。
  4. 日志与告警:在脚本中加入失败后的通知(发送邮件到运维团队、调用 Webhook 等)。
  5. 测试恢复:定期的备份脚本运行成功,不代表恢复就一定成功,务必定期测试恢复(每月恢复一次到测试环境)。
  6. 权限:确保运行脚本的操作系统用户对备份目录有写权限,对 PostgreSQL 有读权限(通常通过 pg_hba.conftrustmd5 / scram-sha-256 认证控制)。

快速启动步骤总结

  1. 配置 .pgpass(Linux)pgpass.conf(Windows)。
  2. 选择一个脚本(推荐 Linux Bash)。
  3. 填入你的数据库连接信息备份目录
  4. 本地测试运行一次
  5. 设置定时任务(crontab / 任务计划程序)。
  6. 定期检查备份文件定期做恢复演练

如果需要处理非常大的数据库(比如几TB),建议考虑 pg_dump--jobs 并行选项(需要 PG 9.3+)或使用 pg_basebackup 进行物理备份(配合 WAL 归档实现持续备份)。

抱歉,评论功能暂时关闭!