docker-postgres/fulldump
2025-11-12 14:03:29 +08:00

142 lines
4.9 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/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