PG数据库自动备份脚本及恢复

按照需求,需要每天凌晨自动备份数据库,并删除历史备份。

PostgreSQL 免密登录

设置免密登录,也可以不设置,不设置需要在脚本中加入密码

vim ~/.pgpass
localhost:5432:mydatabase:postgres:yourpassword
# 配置权限
chmod 600 ~/.pgpass

编写执行脚本

#!/bin/bash

# === 配置部分 ===
PGUSER="postgres"                      # PostgreSQL 用户名
PGDATABASE="hnfuel"               # 需要备份的数据库名
BACKUP_DIR="/data/pg_backup"          # 备份目录
RETENTION_DAYS=7                      # 保留最近 N 天的备份

# === 系统自动生成部分 ===
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="$BACKUP_DIR/backup_${PGDATABASE}_${TIMESTAMP}.sql.gz"

# 确保备份目录存在
mkdir -p "$BACKUP_DIR"

# === 开始备份 ===
echo "[$(date)] 开始备份数据库 $PGDATABASE ..."

# 如果path中有这个路径,可以直接pg_dump执行
/opt/postgresql/bin/pg_dump -U "$PGUSER" "$PGDATABASE" | gzip > "$BACKUP_FILE"

if [ $? -eq 0 ]; then
    echo "[$(date)] 备份成功:$BACKUP_FILE"
else
    echo "[$(date)] 备份失败!" >&2
    exit 1
fi

# === 删除旧备份 ===
echo "[$(date)] 清理 $RETENTION_DAYS 天前的备份文件..."
find "$BACKUP_DIR" -type f -name "backup_${PGDATABASE}_*.sql.gz" -mtime +$RETENTION_DAYS -exec rm -f {} \;

echo "[$(date)] 备份流程完成。"

添加执行权限

chmod +x /data/pg_backup/pg_backup.sh

定时执行

0 2 * * * /bin/bash /data/pg_backup/pg_backup.sh >> /data/pg_backup/backup.log 2>&1

恢复数据

psql -U postgres -d hnfuel_restore -f backup_hnfuel_20250418_143550.sql
# 输入密码的方式
PGPASSWORD=yourpassword psql -U postgres -d hnfuel_restore -f yourfile.sql

可能存在的问题

在执行脚本测试的时候报错,信息如下:

-bash: ./pg_backup.sh: /bin/bash^M: 坏的解释器: 没有那个文件或目录

原因是脚本文件是 Windows 格式的文本文件(CRLF 行尾),里面的第一行 #!/bin/bash 末尾带了一个 隐藏的 ^M(回车符),Linux 无法识别解释器路径 /bin/bash^M。

解决方式为:

  1. vim 打开文件
  2. : 输入命令set ff=unix
  3. 保存退出wq

双机备份脚本

之前备份的文件是sql版本的,只能恢复数据库,不能指定恢复某一部分,而且明文可查看,单机备份也不够安全。这里换成双机备份,而且输出dump文件。

#!/bin/bash

# === 配置部分 ===
PGUSER="postgres"
PGDATABASE="fueldb"
BACKUP_BASE="/home/appuser/pgsql_data_backups/pg_backup_schedule"
RETENTION_DAYS=7

# 远程服务器信息(可选)
REMOTE_USER="backupuser"
REMOTE_HOST="192.168.1.22"
REMOTE_PORT=2222
REMOTE_BASE_DIR="/data/pg_backup_schedule"

# === 生成变量 ===
TODAY=$(date "+%Y-%m-%d")
TARGET_DIR="$BACKUP_BASE"
BACKUP_FILE="${TARGET_DIR}/${TODAY}_${PGDATABASE}.dump"

# === 创建目录 ===
mkdir -p "$TARGET_DIR"

# === 执行备份 === 如果没有环境变量,找不到命令就写绝对路径
echo "[$(date)] 开始备份数据库 $PGDATABASE..."
pg_dump -U "$PGUSER" -v -Fc -d "$PGDATABASE" --no-owner -f "$BACKUP_FILE"

if [ $? -eq 0 ]; then
    echo "[$(date)] 备份成功:$BACKUP_FILE"
else
    echo "[$(date)] 备份失败!" >&2
    exit 1
fi

# === 删除本地旧备份 ===
echo "[$(date)] 清理本地 $RETENTION_DAYS 天前的备份..."
find "$BACKUP_BASE" -type f -name "*_${PGDATABASE}.dump" -mtime +$RETENTION_DAYS -exec rm -f {} \;

# === 传输并清理远程备份(可选)===
echo "[$(date)] 正在将备份传输到远程服务器 $REMOTE_HOST..."
ssh -p "$REMOTE_PORT" "$REMOTE_USER@$REMOTE_HOST" "mkdir -p $REMOTE_BASE_DIR/$TODAY"
scp -P "$REMOTE_PORT" "$BACKUP_FILE" "${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_BASE_DIR}/${TODAY}/"

echo "[$(date)] 清理远程旧备份..."
ssh -p "$REMOTE_PORT" "$REMOTE_USER@$REMOTE_HOST" \
    "find '${REMOTE_BASE_DIR}' -type f -name '*_${PGDATABASE}.dump' -mtime +${RETENTION_DAYS} -exec rm -f {} \;"

echo "[$(date)] 备份完成。"

dump文件恢复方式

恢复数据库

# 恢复到现有数据库
pg_restore -U postgres -d fueldb_restored -v /path/to/2025-05-19_fueldb.dump
# 恢复到新建数据库
createdb -U postgres fueldb_restored
pg_restore -U postgres -d fueldb_restored -v /path/to/2025-05-19_fueldb.dump

恢复特定对象(如单表)

# 恢复一个名为 user_logs 的表
pg_restore -U postgres -d fueldb_restored -t user_logs /path/to/2025-05-19_fueldb.dump

-t 指定表,-n 可以指定 schema,比如:

pg_restore -U postgres -d fueldb_restored -n public -t user_logs ...

查看 .dump 内容(先看再决定要恢复什么)

pg_restore -l /path/to/backup.dump
功能命令示例
全部还原pg_restore -d dbname backup.dump
指定表还原pg_restore -d dbname -t tablename backup.dump
指定 schemapg_restore -d dbname -n schema_name backup.dump
只导出 SQL(不执行)pg_restore -f out.sql backup.dump
只导入结构(无数据)pg_restore --schema-only ...

添加文件加密

环境变量中添加加密密码

echo 'export GPG_PASSPHRASE="your_strong_passphrase"' >> ~/.bash_profile
source ~/.bash_profile

脚本修改

GPG_PASSPHRASE="${GPG_PASSPHRASE}"
echo "$GPG_PASSPHRASE" | gpg --batch --yes --passphrase-fd 0 -c yourfile.dump
# === 删除原始压缩包 ===
rm -f "$BACKUP_FILE"
echo "[$(date)] 清理 $RETENTION_DAYS 天前的备份文件..."
find "$BACKUP_DIR" -type f -name "backup_${PGDATABASE}_*.sql.gz.gpg" -mtime +$RETENTION_DAYS -exec rm -f {} \;

文件解密

gpg --output backup.sql.tar.gz --decrypt backup.sql.tar.gz.gpg
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇