备份到七牛云

chmod +x backup_pg_to_qiniu.sh

#!/bin/bash

# === 配置项 ===
DATE=$(date +\%Y-\%m-\%d_\%H-\%M-\%S)
BACKUP_DIR="changeit 备份路径"
REMOTE_HOST="changeit 如果是远程数据库则填写"
REMOTE_PORT="changeit 如果是远程数据库则填写"
REMOTE_USER="changeit 如果是远程数据库则填写"
SSH_PASS="changeit 如果是远程数据库则填写"
DB_NAME="changeit 数据库名称"
DB_USER="changeit 数据库用户"
ENCRYPT_PASS="changeit 7z密码"
QINIU_BUCKET="changeit 七牛存储桶名称"
QINIU_REMOTE_DIR="db_backup/orgid"  #固定格式db_backup/机构名称
TMP_LIST="/tmp/qiniu_file_list.txt"
DAYS=3 #3天过期
NOW=$(date +%s)
EXPIRE=$((NOW - DAYS * 86400))

# === 文件路径 ===
LOCAL_BACKUP_GZFILE="$BACKUP_DIR/${DB_NAME}_${DATE}.sql.gz"
LOCAL_BACKUP_FILE="$BACKUP_DIR/${DB_NAME}_${DATE}.sql"
ARCHIVE_FILE="$LOCAL_BACKUP_FILE.7z"

log() {
    echo "[$(date '+%F %T')] [$1] $2"
}

# === 创建备份目录 ===
mkdir -p "$BACKUP_DIR"

log "INFO" "开始备份 PostgreSQL 数据库:$DB_NAME"

# === 0.使用 touch 测试生成 sql 文件 ===
# touch "$LOCAL_BACKUP_FILE"


# === 1.如果是远程机器 使用 sshpass 执行 pg_dump 并压缩为 .gz 文件 ===
sshpass -p "$SSH_PASS" ssh -p "$REMOTE_PORT" -o StrictHostKeyChecking=no "$REMOTE_USER@$REMOTE_HOST" "pg_dump -U $DB_USER $DB_NAME | gzip -c" > "$LOCAL_BACKUP_GZFILE"
# === 1.如果是远程机器-且是 docker 使用 sshpass 执行 docker pg_dump 并压缩为 .gz 文件 ===
# sshpass -p "$SSH_PASS" ssh -p "$REMOTE_PORT" -o StrictHostKeyChecking=no "$REMOTE_USER@$REMOTE_HOST" "sudo docker exec -t postgres pg_dump -U \"$DB_USER\" \"$DB_NAME\" | gzip -c" > "$LOCAL_BACKUP_GZFILE"
# === 1.解压 .gz 文件为 .sql 文件 ===
log "INFO" "解压 $LOCAL_BACKUP_GZFILE 为 $LOCAL_BACKUP_FILE"
gunzip -c "$LOCAL_BACKUP_GZFILE" > "$LOCAL_BACKUP_FILE"
rm -f "$LOCAL_BACKUP_GZFILE"
log "INFO" "已删除原始 GZ 文件:$LOCAL_BACKUP_GZFILE"

	
# === 2.如果是本地机器 使用 pg_dump 导出为 .sql 文件 ===
# pg_dump -U $DB_USER $DB_NAME > "$LOCAL_BACKUP_FILE"


# === 3.如果是本地docker 使用 docker 导出为 .sql 文件 ===
# docker exec -t postgres pg_dump -U $DB_USER $DB_NAME > "$LOCAL_BACKUP_FILE"


# === 使用 7z 加密压缩 SQL 文件 ===
log "INFO" "压缩并加密文件 $LOCAL_BACKUP_FILE"
7z a -t7z -mx=9 -p"$ENCRYPT_PASS" -mhe=on "$ARCHIVE_FILE" "$LOCAL_BACKUP_FILE"

# === 上传到七牛云(需先配置好 qshell)===
log "INFO" "上传到七牛云 $ARCHIVE_FILE"
if qshell rput "$QINIU_BUCKET" "$QINIU_REMOTE_DIR/$(basename "$ARCHIVE_FILE")" "$ARCHIVE_FILE"; then
    log "INFO" "✅ 上传成功:$ARCHIVE_FILE"
else
    log "ERROR" "❌ 上传失败:$ARCHIVE_FILE"
    exit 1
fi

# === 删除本地文件 ===
rm -f "$LOCAL_BACKUP_FILE" "$ARCHIVE_FILE"
log "INFO" "已删除原始 SQL 文件:$LOCAL_BACKUP_FILE"
log "INFO" "已删除原始 7z 文件:$ARCHIVE_FILE"

# === 七牛云端备份清理(超过 DAYS 天) ===
log "INFO" "开始清理七牛云超过 $DAYS 天的备份..."

# 获取文件列表并存入临时文件
log "INFO" "获取七牛云存储文件列表..."
qshell listbucket "$QINIU_BUCKET" "$TMP_LIST" --prefix="$QINIU_REMOTE_DIR/" > "$TMP_LIST"

# 遍历七牛云存储文件列表 
while IFS= read -r line; do
    # 如果文件名以 "db_backup" 开头
    if [[ "$line" =~ ^db_backup/ ]]; then
        # 从文件名中提取日期部分 (例如:orgid_2025-04-15_...)
        filename=$(echo "$line" | awk '{print $1}' | awk -F'/' '{print $NF}')
        filedate=$(echo "$filename" | sed -E "s/^${DB_NAME}_([0-9]{4}-[0-9]{2}-[0-9]{2})_.*/\1/")
        # 将日期转换为 Unix 时间戳
        timestamp=$(date -d "$filedate" +%s)
        log "INFO" "获取到文件: $filename - 文件日期: $timestamp - 过期日期: $EXPIRE"
        
        # 如果文件的日期小于 30 天前,则删除
        if [[ "$timestamp" -lt "$EXPIRE" ]]; then
            log "WARN" "删除文件: $filename"
            qshell delete "$QINIU_BUCKET" "$QINIU_REMOTE_DIR/$filename"
        fi
    fi
done < "$TMP_LIST"

log "INFO" "所有任务完成。"

定时执行

crontab -e
# 写入-每天2点执行
0 2 * * * /xxx/backup_pg_to_qiniu.sh >> /xxx/pg_backups/backup.log 2>&1

执行效果

文章作者: Captain
版权声明: 本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 One piece
喜欢就支持一下吧