Shell脚本如何备份PostgreSQL数据

wen 实用脚本 2

本文目录导读:

Shell脚本如何备份PostgreSQL数据

  1. 基础备份脚本
  2. 增强版备份脚本(带错误处理和日志)
  3. 多数据库备份脚本
  4. 带密码处理的脚本
  5. 高级备份脚本(带多种备份策略)
  6. 备份验证脚本
  7. 定时备份配置(crontab)
  8. 注意事项

我来介绍几种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

注意事项

  1. 安全性

    • 使用 .pgpass 文件管理密码
    • 设置备份文件的权限(chmod 600)
    • 考虑加密备份文件
  2. 性能考虑

    • 在低负载时段执行备份
    • 使用压缩减少存储空间
    • 考虑并行备份(pg_dump 的 -j 参数)
  3. 存储管理

    • 实施备份轮转策略
    • 远程备份到另一台服务器
    • 定期测试备份恢复
  4. 监控告警

    • 设置备份失败的告警
    • 监控备份大小变化
    • 检查备份日志

这些脚本可以根据你的具体需求进行调整和组合使用。

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