forked from DevOps/deploy.stack
feat(backup): 添加PostgreSQL数据库备份脚本
添加两个备份脚本,pg_backup.sh和pgDump.sh,用于定期备份PostgreSQL数据库。pg_backup.sh支持自动备份所有数据库并保留最近7天的备份,pgDump.sh支持备份单个数据库或表,并生成日志文件。这些脚本通过Docker容器执行备份操作,确保环境一致性。
This commit is contained in:
130
crontab/posrgres/pgDump.sh
Normal file
130
crontab/posrgres/pgDump.sh
Normal file
@@ -0,0 +1,130 @@
|
||||
#!/usr/bin/env bash
|
||||
# @author: cnphpbb@hotmail.com
|
||||
# @date: 2025-04-27
|
||||
# @desc: PostgreSQL数据库备份脚本
|
||||
|
||||
## 基础配置
|
||||
TOYEAR=$(date "+%Y")
|
||||
TOMONTH=$(date "+%Y%m")
|
||||
TODATE=$(date "+%Y%m%d")
|
||||
NOWDATE=$(date "+%Y%m%d-%H%M%S")
|
||||
BACKDIR=/data/backups/pg_backs # 备份目录
|
||||
TARLOGDIR=/data/backups/pg_tar_logs # 日志目录
|
||||
DAYDIR=${BACKDIR}/${TOMONTH}/${TODATE}
|
||||
BACKLOGSDIR=${TARLOGDIR}/${TOMONTH}/logs/${TODATE}
|
||||
BACKTARDIR=${TARLOGDIR}/${TOMONTH}/db_tars
|
||||
LOGFILE=${BACKLOGSDIR}/pg-Dump.${NOWDATE}.log
|
||||
BACKSQLFILE=""
|
||||
FileSize=0
|
||||
|
||||
## PostgreSQL配置
|
||||
USERNAME=${PGSQL_USER}
|
||||
PASSWORD=${PGSQL_PASS}
|
||||
HOST=${PGSQL_HOST}
|
||||
PORT=${PGSQL_PORT}
|
||||
DOCKER_IMAGE="postgres:latest"
|
||||
|
||||
## 创建目录
|
||||
if [ ! -d "${BACKLOGSDIR}" ]; then
|
||||
mkdir -p ${BACKLOGSDIR}
|
||||
fi
|
||||
|
||||
if [ ! -d "${BACKTARDIR}" ]; then
|
||||
mkdir -p ${BACKTARDIR}
|
||||
fi
|
||||
|
||||
cd ${BACKDIR}
|
||||
if [ ! -d "${DAYDIR}" ]; then
|
||||
mkdir -vp "$DAYDIR" >> ${LOGFILE}
|
||||
fi
|
||||
|
||||
## 工具函数
|
||||
curTime() {
|
||||
NOWDATE=$(date "+%Y%m%d-%H%M%S")
|
||||
}
|
||||
|
||||
getLogFile(){
|
||||
curTime
|
||||
LOGFILE=${BACKLOGSDIR}/pg-Dump.${NOWDATE}.log
|
||||
}
|
||||
|
||||
# 备份整个数据库
|
||||
db_full_backup() {
|
||||
curTime
|
||||
BACKSQLFILE=${DAYDIR}/$1-${NOWDATE}.sql
|
||||
docker run --rm \
|
||||
-e PGPASSWORD="${PASSWORD}" \
|
||||
-v "${DAYDIR}:/backups" \
|
||||
"${DOCKER_IMAGE}" \
|
||||
pg_dump -h "${HOST}" -p "${PORT}" -U "${USERNAME}" -d "$1" \
|
||||
--no-password \
|
||||
--clean \
|
||||
--if-exists \
|
||||
-f "/backups/$1-${NOWDATE}.sql"
|
||||
|
||||
gzip ${BACKSQLFILE}
|
||||
getLogFile
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "$NOWDATE PostgreSQL数据库 $1 备份失败!" >> ${LOGFILE}
|
||||
else
|
||||
echo "$NOWDATE PostgreSQL数据库 $1 备份成功!" >> ${LOGFILE}
|
||||
fi
|
||||
}
|
||||
|
||||
# 备份单个表
|
||||
sigle_table_backup(){
|
||||
curTime
|
||||
BACKSQLFILE=${DAYDIR}/$1_$2-${NOWDATE}.sql
|
||||
docker run --rm \
|
||||
-e PGPASSWORD="${PASSWORD}" \
|
||||
-v "${DAYDIR}:/backups" \
|
||||
"${DOCKER_IMAGE}" \
|
||||
pg_dump -h "${HOST}" -p "${PORT}" -U "${USERNAME}" -d "$1" \
|
||||
--no-password \
|
||||
--clean \
|
||||
--if-exists \
|
||||
-t "$2" \
|
||||
-f "/backups/$1_$2-${NOWDATE}.sql"
|
||||
|
||||
gzip ${BACKSQLFILE}
|
||||
getLogFile
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "$NOWDATE PostgreSQL表 $1.$2 备份失败!" >> ${LOGFILE}
|
||||
else
|
||||
echo "$NOWDATE PostgreSQL表 $1.$2 备份成功!" >> ${LOGFILE}
|
||||
fi
|
||||
}
|
||||
|
||||
selfHelp() {
|
||||
echo "pgDump.sh 帮助文档"
|
||||
echo "-----------------------------------"
|
||||
echo "-h --help 显示帮助信息"
|
||||
echo
|
||||
echo "\$1 数据库名 (备份整个数据库)"
|
||||
echo "示例: pgDump.sh memos_db"
|
||||
echo
|
||||
echo "\$2 表名 (备份单个表)"
|
||||
echo "示例: pgDump.sh memos_db users"
|
||||
}
|
||||
|
||||
## 主逻辑
|
||||
case $1 in
|
||||
-h|--help|help )
|
||||
selfHelp
|
||||
;;
|
||||
*)
|
||||
if [ $# -eq 1 ]; then
|
||||
echo "开始备份PostgreSQL数据库 $1..."
|
||||
db_full_backup $1
|
||||
FileSize=$(stat -c %s ${BACKSQLFILE})
|
||||
echo "备份文件: ${BACKSQLFILE} ${FileSize} bytes"
|
||||
echo "完成备份PostgreSQL数据库 $1"
|
||||
else
|
||||
echo "开始备份PostgreSQL表 $1.$2..."
|
||||
sigle_table_backup $1 $2
|
||||
FileSize=$(stat -c %s ${BACKSQLFILE})
|
||||
echo "备份文件: ${BACKSQLFILE} ${FileSize} bytes"
|
||||
echo "完成备份PostgreSQL表 $1.$2"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
74
crontab/posrgres/pg_backup.sh
Normal file
74
crontab/posrgres/pg_backup.sh
Normal file
@@ -0,0 +1,74 @@
|
||||
#!/bin/bash
|
||||
|
||||
# PostgreSQL 备份脚本
|
||||
# 配置参数
|
||||
DB_HOST=${PGSQL_HOST}
|
||||
DB_PORT=${PGSQL_PORT}
|
||||
DB_USER=${PGSQL_USER}
|
||||
DB_PASSWORD=${PGSQL_PASSWORD}
|
||||
DOCKER_IMAGE="postgres:latest"
|
||||
|
||||
# 备份目录设置
|
||||
BACKUP_DIR="/data/backups/posrgres/$(date +%Y)/$(date +%Y%m)"
|
||||
DATE=$(date +%Y%m%d_%H%M%S)
|
||||
|
||||
# 创建备份目录
|
||||
mkdir -p "$BACKUP_DIR"
|
||||
|
||||
# 获取用户可以访问的所有数据库列表
|
||||
echo "获取可访问数据库列表..."
|
||||
DB_LIST=$(docker run --rm \
|
||||
-e PGPASSWORD="${DB_PASSWORD}" \
|
||||
"${DOCKER_IMAGE}" \
|
||||
psql -h "${DB_HOST}" -p "${DB_PORT}" -U "${DB_USER}" -d postgres -t -c "SELECT datname FROM pg_database WHERE datname NOT IN ('template0', 'template1', 'postgres') AND datistemplate = false;")
|
||||
|
||||
# 检查数据库列表
|
||||
if [ -z "$DB_LIST" ]; then
|
||||
echo "没有找到可备份的数据库"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 备份每个数据库
|
||||
for DB_NAME in $DB_LIST; do
|
||||
echo "开始备份数据库 ${DB_NAME}..."
|
||||
BACKUP_FILE="${BACKUP_DIR}/${DB_NAME}_${DATE}.sql"
|
||||
|
||||
docker run --rm \
|
||||
-e PGPASSWORD="${DB_PASSWORD}" \
|
||||
-v "${BACKUP_DIR}:/backups" \
|
||||
"${DOCKER_IMAGE}" \
|
||||
pg_dump -h "${DB_HOST}" -p "${DB_PORT}" -U "${DB_USER}" -d "${DB_NAME}" \
|
||||
--no-password \
|
||||
--clean \
|
||||
--if-exists \
|
||||
-f "/backups/${DB_NAME}_${DATE}.sql"
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "备份成功: ${BACKUP_FILE}"
|
||||
else
|
||||
echo "备份失败: ${DB_NAME}"
|
||||
fi
|
||||
done
|
||||
|
||||
# 保留本月的最近7天备份
|
||||
find "$BACKUP_DIR" -name "*_*.sql" -mtime +7 -type f -exec rm -f {} \;
|
||||
# 删除非本年&本月的备份目录(仅在每月2号执行)
|
||||
if [ $(date +%d) -eq 2 ]; then
|
||||
CURRENT_YEAR=$(date +%Y)
|
||||
CURRENT_MONTH=$(date +%m)
|
||||
find "/data/backups/posrgres/" -maxdepth 1 -type d -name "20*" | while read -r year_dir; do
|
||||
year=$(basename "$year_dir")
|
||||
if [ "$year" != "$CURRENT_YEAR" ]; then
|
||||
echo "删除非本年目录: $year_dir"
|
||||
rm -rf "$year_dir"
|
||||
else
|
||||
find "$year_dir" -maxdepth 1 -type d -name "20*" | while read -r month_dir; do
|
||||
month=$(basename "$month_dir" | cut -c5-6)
|
||||
if [ "$month" != "$CURRENT_MONTH" ]; then
|
||||
echo "删除非本月目录: $month_dir"
|
||||
rm -rf "$month_dir"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
done
|
||||
fi
|
||||
Reference in New Issue
Block a user