本文目录导读:

我来介绍几种PostgreSQL数据库备份的Shell脚本方法。
基础备份脚本
单数据库备份
#!/bin/bash
# 数据库配置
DB_NAME="mydb"
DB_USER="postgres"
DB_HOST="localhost"
DB_PORT="5432"
# 备份目录
BACKUP_DIR="/backup/postgres"
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="${BACKUP_DIR}/${DB_NAME}_${DATE}.sql"
# 创建备份目录
mkdir -p $BACKUP_DIR
# 执行备份
pg_dump -h $DB_HOST -p $DB_PORT -U $DB_USER -d $DB_NAME > $BACKUP_FILE
# 检查备份是否成功
if [ $? -eq 0 ]; then
echo "备份成功: $BACKUP_FILE"
# 压缩备份文件
gzip $BACKUP_FILE
echo "压缩完成: ${BACKUP_FILE}.gz"
else
echo "备份失败!"
exit 1
fi
全库备份
#!/bin/bash
# 配置
BACKUP_DIR="/backup/postgres"
DATE=$(date +%Y%m%d)
BACKUP_FILE="${BACKUP_DIR}/full_backup_${DATE}.sql"
# 全库备份
pg_dumpall -h localhost -U postgres > $BACKUP_FILE
# 压缩
gzip $BACKUP_FILE
增强版备份脚本(带错误处理和日志)
#!/bin/bash
# ============= 配置 =============
DB_NAME="your_database"
DB_USER="postgres"
DB_HOST="localhost"
DB_PORT="5432"
BACKUP_DIR="/var/backups/postgresql"
LOG_FILE="/var/log/pg_backup.log"
RETENTION_DAYS=7
# ============= 函数定义 =============
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a $LOG_FILE
}
cleanup_old_backups() {
log "清理 ${RETENTION_DAYS} 天前的备份..."
find $BACKUP_DIR -name "*.sql.gz" -mtime +$RETENTION_DAYS -delete
find $BACKUP_DIR -name "*.sql" -mtime +$RETENTION_DAYS -delete
}
# ============= 主程序 =============
# 创建备份目录
mkdir -p $BACKUP_DIR
# 备份文件名
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="${BACKUP_DIR}/${DB_NAME}_${DATE}.sql"
COMPRESSED_FILE="${BACKUP_FILE}.gz"
log "开始备份数据库: ${DB_NAME}"
# 执行备份
if pg_dump -h $DB_HOST -p $DB_PORT -U $DB_USER -d $DB_NAME \
--no-owner \
--no-acl \
--verbose \
> $BACKUP_FILE 2>> $LOG_FILE; then
log "备份完成: ${BACKUP_FILE}"
# 压缩
if gzip -f $BACKUP_FILE; then
log "压缩完成: ${COMPRESSED_FILE}"
BACKUP_SIZE=$(du -h $COMPRESSED_FILE | cut -f1)
log "备份文件大小: ${BACKUP_SIZE}"
else
log "压缩失败!"
exit 1
fi
else
log "备份失败!"
exit 1
fi
# 清理旧备份
cleanup_old_backups
log "备份过程完成"
多数据库备份脚本
#!/bin/bash
# 配置
BACKUP_DIR="/backup/postgres"
PG_USER="postgres"
LOG_FILE="/var/log/pg_backup.log"
EXCLUDE_DBS=("template0" "template1" "postgres")
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a $LOG_FILE
}
# 获取所有数据库列表
DATABASES=$(psql -U $PG_USER -t -c "SELECT datname FROM pg_database WHERE datistemplate = false;" | grep -v -E "^($(IFS=\|; echo "${EXCLUDE_DBS[*]}"))$")
for DB in $DATABASES; do
log "开始备份数据库: $DB"
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="${BACKUP_DIR}/${DB}_${DATE}.sql.gz"
# 备份并直接压缩
pg_dump -U $PG_USER $DB | gzip > $BACKUP_FILE
if [ $? -eq 0 ]; then
log "数据库 ${DB} 备份成功: ${BACKUP_FILE}"
else
log "数据库 ${DB} 备份失败!"
fi
done
带密码处理的脚本
#!/bin/bash
# 方法1: 使用 .pgpass 文件
# 创建 ~/.pgpass 文件:
# hostname:port:database:username:password
# localhost:5432:mydb:postgres:password123
# 方法2: 环境变量(不推荐,安全性低)
# export PGPASSWORD="your_password"
# 方法3: 使用 PGPASSFILE 环境变量
export PGPASSFILE="/path/to/.pgpass"
# 配置
DB_NAME="mydb"
BACKUP_DIR="/backup/postgres"
DATE=$(date +%Y%m%d_%H%M%S)
# 备份命令
pg_dump -h localhost -U postgres -d $DB_NAME \
--format=custom \
--file="${BACKUP_DIR}/${DB_NAME}_${DATE}.dump"
高级备份脚本(带多种备份策略)
#!/bin/bash
# ============= 配置 =============
DB_NAME="mydb"
DB_USER="postgres"
BACKUP_DIR="/backup/postgres"
LOG_FILE="/var/log/pg_backup.log"
BACKUP_TYPE="${1:-full}" # full, schema, data, tablespace
case $BACKUP_TYPE in
"full")
log "执行全量备份..."
pg_dump -h localhost -U $DB_USER -d $DB_NAME \
--format=custom \
--compress=9 \
--file="${BACKUP_DIR}/${DB_NAME}_full_${DATE}.dump"
;;
"schema")
log "执行结构备份..."
pg_dump -h localhost -U $DB_USER -d $DB_NAME \
--schema-only \
--file="${BACKUP_DIR}/${DB_NAME}_schema_${DATE}.sql"
;;
"data")
log "执行数据备份..."
pg_dump -h localhost -U $DB_USER -d $DB_NAME \
--data-only \
--format=custom \
--compress=9 \
--file="${BACKUP_DIR}/${DB_NAME}_data_${DATE}.dump"
;;
"tablespace")
log "执行表空间备份..."
pg_dump -h localhost -U $DB_USER -d $DB_NAME \
--tablespaces-only \
--file="${BACKUP_DIR}/${DB_NAME}_tablespace_${DATE}.sql"
;;
esac
备份验证脚本
#!/bin/bash
# 备份验证函数
verify_backup() {
local BACKUP_FILE=$1
echo "验证备份文件: $BACKUP_FILE"
# 检查文件是否存在
if [ ! -f "$BACKUP_FILE" ]; then
echo "错误: 备份文件不存在"
return 1
fi
# 检查文件大小
FILE_SIZE=$(stat -f%z "$BACKUP_FILE" 2>/dev/null || stat -c%s "$BACKUP_FILE")
if [ "$FILE_SIZE" -eq 0 ]; then
echo "错误: 备份文件为空"
return 1
fi
# 对于自定义格式的备份,可以尝试读取
if [[ "$BACKUP_FILE" == *.dump ]]; then
if pg_restore -l "$BACKUP_FILE" > /dev/null 2>&1; then
echo "备份文件验证成功"
return 0
else
echo "备份文件验证失败"
return 1
fi
fi
return 0
}
定时备份配置(crontab)
# 编辑 crontab # crontab -e # 每天凌晨2点执行备份 0 2 * * * /path/to/backup_script.sh # 每周日晚上11点执行全量备份 0 23 * * 0 /path/to/full_backup_script.sh # 每6小时执行一次增量备份(如果配置了 WAL 归档) 0 */6 * * * /path/to/incremental_backup.sh
注意事项
-
安全性:
- 使用
.pgpass文件管理密码 - 设置备份文件的权限(chmod 600)
- 考虑加密备份文件
- 使用
-
性能考虑:
- 在低负载时段执行备份
- 使用压缩减少存储空间
- 考虑并行备份(pg_dump 的 -j 参数)
-
存储管理:
- 实施备份轮转策略
- 远程备份到另一台服务器
- 定期测试备份恢复
-
监控告警:
- 设置备份失败的告警
- 监控备份大小变化
- 检查备份日志
这些脚本可以根据你的具体需求进行调整和组合使用。