142 lines
4.9 KiB
Bash
Executable File
142 lines
4.9 KiB
Bash
Executable File
#!/bin/bash
|
||
|
||
# 获取脚本所在目录的绝对路径
|
||
SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)
|
||
|
||
# 切换工作目录到脚本所在目录
|
||
cd $SCRIPT_DIR
|
||
|
||
# 加载环境变量
|
||
load_env_variables() {
|
||
if [ -f ".envrc" ]; then
|
||
# 使用direnv加载环境变量
|
||
if command -v direnv &> /dev/null; then
|
||
eval "$(direnv export bash)"
|
||
# 检查POSTGRES_PASSWORD是否已设置,如果没有设置,尝试执行direnv allow
|
||
if [ -z "$POSTGRES_PASSWORD" ]; then
|
||
echo "检测到POSTGRES_PASSWORD未设置,尝试执行direnv allow..."
|
||
direnv allow
|
||
# 再次加载环境变量
|
||
eval "$(direnv export bash)"
|
||
|
||
# 再次检查POSTGRES_PASSWORD
|
||
if [ -z "$POSTGRES_PASSWORD" ]; then
|
||
echo "错误: 密码验证失败,无法继续操作"
|
||
return 1
|
||
fi
|
||
fi
|
||
else
|
||
echo "错误: 未安装direnv,请先安装direnv"
|
||
return 1
|
||
fi
|
||
else
|
||
echo "错误: 找不到.envrc文件"
|
||
return 1
|
||
fi
|
||
return 0
|
||
}
|
||
|
||
# 调用函数加载环境变量
|
||
if ! load_env_variables; then
|
||
echo "无法加载环境变量,脚本退出"
|
||
exit 1
|
||
fi
|
||
|
||
# 声明变量
|
||
container_name=${POSTGRES_CONTAINER_NAME:-postgres}
|
||
pg_user=${POSTGRES_USER:-postgres}
|
||
backup_dir="./data/backup/"
|
||
|
||
# 获取宿主机上的绝对备份路径
|
||
HOST_BACKUP_DIR="$(pwd)/${backup_dir}"
|
||
|
||
# 清除几天前的备份
|
||
days=${2:-15}
|
||
|
||
# 备份单个数据库的函数
|
||
backup_database() {
|
||
local db_name=$1
|
||
local datetime=$(date +"%Y%m%d_%H%M%S")
|
||
local filename="${db_name}_full_${datetime}"
|
||
local backup_path="${backup_dir}${filename}"
|
||
local host_backup_path="${HOST_BACKUP_DIR}${filename}"
|
||
|
||
echo "开始备份数据库 $db_name..."
|
||
# 创建新备份
|
||
docker exec -i "$container_name" pg_dump -U postgres -Fd "$db_name" -f "$backup_path" -j 4
|
||
|
||
# 检查备份是否成功
|
||
if [ $? -eq 0 ]; then
|
||
echo "备份完成!"
|
||
echo "宿主机上的备份文件路径: ${host_backup_path}"
|
||
echo "备份目录名: ${filename}"
|
||
echo "注意:PostgreSQL目录格式备份包含多个文件,其中toc.dat是目录文件,包含备份内容的表目录信息"
|
||
# 显示宿主机上备份文件大小信息
|
||
du -sh "${host_backup_path}" 2>/dev/null || echo "无法获取备份大小信息"
|
||
# 显示备份目录中的文件数量
|
||
find "${host_backup_path}" -type f | wc -l | xargs echo "备份目录中的文件数量:"
|
||
echo ""
|
||
return 0
|
||
else
|
||
echo "备份失败!"
|
||
return 1
|
||
fi
|
||
}
|
||
|
||
# 主逻辑
|
||
if [ -n "$1" ]; then
|
||
# 如果指定了数据库名称,则只备份该数据库
|
||
pg_database=$1
|
||
echo "将备份指定的数据库: $pg_database"
|
||
|
||
# 清除该数据库几天前的备份
|
||
echo "清理 $pg_database 数据库 $days 天前的备份..."
|
||
find $backup_dir -maxdepth 1 -name "${pg_database}*" -mtime +$days -exec sh -c 'echo "$(date): $1" >> cleardump.log; rm -rf $1' sh {} \;
|
||
|
||
# 备份指定数据库
|
||
backup_database "$pg_database"
|
||
else
|
||
# 如果未指定数据库名称,则备份所有用户数据库(排除系统数据库)
|
||
echo "未指定数据库名称,将备份所有用户数据库"
|
||
|
||
# 获取所有用户数据库(排除postgres, template0, template1系统数据库)
|
||
echo "正在获取数据库列表..."
|
||
databases=$(docker exec -i "$container_name" psql -U postgres -t -c "SELECT datname FROM pg_database WHERE datistemplate = false AND datname NOT IN ('postgres', 'template0', 'template1');")
|
||
|
||
# 检查是否成功获取数据库列表
|
||
if [ -z "$databases" ]; then
|
||
echo "警告: 未找到用户数据库,将备份默认的postgres数据库"
|
||
# 清理postgres数据库几天前的备份
|
||
echo "清理 postgres 数据库 $days 天前的备份..."
|
||
find $backup_dir -maxdepth 1 -name "postgres*" -mtime +$days -exec sh -c 'echo "$(date): $1" >> cleardump.log; rm -rf $1' sh {} \;
|
||
# 备份postgres数据库
|
||
backup_database "postgres"
|
||
else
|
||
echo "找到以下用户数据库:"
|
||
echo "$databases"
|
||
echo ""
|
||
|
||
# 清理所有数据库几天前的备份
|
||
echo "清理所有数据库 $days 天前的备份..."
|
||
find $backup_dir -maxdepth 1 -name "*_full_*" -mtime +$days -exec sh -c 'echo "$(date): $1" >> cleardump.log; rm -rf $1' sh {} \;
|
||
|
||
# 备份每个用户数据库
|
||
for db in $databases; do
|
||
# 去除可能的空格和换行符
|
||
db=$(echo "$db" | tr -d ' \n\r')
|
||
if [ -n "$db" ]; then
|
||
backup_database "$db"
|
||
fi
|
||
done
|
||
fi
|
||
fi
|
||
|
||
# 检查是否有备份成功完成
|
||
if [ $? -eq 0 ]; then
|
||
echo "所有指定的数据库备份完成!"
|
||
exit 0
|
||
else
|
||
echo "备份过程中出现错误,请检查日志"
|
||
exit 1
|
||
fi
|