接上一篇,将能迁移的服务都迁移到PostgreSQL后,再配置上自动备份脚本,基本上就可以高枕无忧了,本来想备份到阿里云OSS的,想了想本站几乎是ALL IN Cloudflare,那就直接备份到CloudFlare R2吧,正好也快一点。下面就记录下备份的方法。
创建CloudFlare R2桶
在面板首页->存储和数据库 -> R2对象存储中,创建一个桶,我起的名字就是backup。

创建完成后发,返回桶列表,点击右下角的Account Deatails下面的Manage,按钮,创建一个Token。

1、权限必须是管理员读和写,选对象读和写执行rclone命令会报权限错误。
2、因为1,所以最好将客户端IP限制一下,反正VPS都是静态的IP地址,不然要是被泄露了那就完犊子了~
创建好后,给你三个信息,分别是访问密钥 ID(access_key_id)、机密访问密钥(secret_access_key)、为 S3 客户端使用管辖权地特定的终结点(endpoint)。暂时记录下来,下一步要用。
安装Rclone
要备份到CloudFlare R2,那就需要Rclone,执行下面的命令安装即可。
安装完成后,执行rclone config就可以配置了,不过控制台看着乱糟糟的,我直接选创建配置文件的方式了。
1
| touch ~/.config/rclone/rclone.conf
|
然后在里面填写如下信息:
1 2 3 4 5 6 7 8
| [r2-remote] type = s3 provider = Cloudflare access_key_id = <你的访问密钥> secret_access_key = <你的机密访问密钥>
endpoint = https://<Account_ID>.r2.cloudflarestorage.com no_check_bucket = true
|
配置完成后,执行如下命令进行测试:
1 2 3 4 5 6 7 8 9
| rclone listremotes
r2-remote:
rclone lsd r2-remote: -vv
|
配置脚本
PostgreSQL
在/data/script/中创建pgsql-to-r2.sh文件,内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| #!/bin/bash
CONTAINER_NAME="postgresql" DB_USER="postgres" BACKUP_DIR="/data/backups/pgsql" DATE=$(date +%Y%m%d_%H%M%S) FILE_NAME="pg_all_backup_$DATE.sql.gz" R2_BUCKET="r2-remote:backup" RETENTION_DAYS=7
mkdir -p $BACKUP_DIR
echo "开始导出 ..." docker exec -t $CONTAINER_NAME pg_dumpall -c -U $DB_USER | gzip > $BACKUP_DIR/$FILE_NAME
echo "正在上传 $FILE_NAME 到 Cloudflare R2..." rclone copy $BACKUP_DIR/$FILE_NAME $R2_BUCKET/pgsql_daily/
echo "清理 $RETENTION_DAYS 天前的本地备份..." find $BACKUP_DIR -mtime +$RETENTION_DAYS -exec rm {} \;
echo "备份任务完成!"
|
测试
MySQL
在/data/script/中创建mysql-to-r2.sh文件,内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| #!/bin/bash
CONTAINER_NAME="db" DB_USER="root" DB_PASSWORD="password" BACKUP_DIR="/data/backups/mysql" DATE=$(date +%Y%m%d_%H%M) R2_REMOTE="r2-remote:backup" RETENTION_DAYS=7
DATABASES=("db1" "db2")
mkdir -p $BACKUP_DIR echo "[$DATE] 开始执行 MySQL 分库备份..."
for DB in "${DATABASES[@]}"; do FILE_NAME="${DB}_${DATE}.sql.gz" echo "正在备份 MySQL 数据库: $DB..." docker exec $CONTAINER_NAME mysqldump -u$DB_USER -p$DB_PASSWORD \ --single-transaction --routines --databases $DB | gzip > $BACKUP_DIR/$FILE_NAME if [ ${PIPESTATUS[0]} -eq 0 ]; then echo "上传 $FILE_NAME 到 R2..." rclone copy $BACKUP_DIR/$FILE_NAME $R2_REMOTE/mysql_daily/ else echo "错误: $DB 备份失败!" fi done
find $BACKUP_DIR -mtime +$RETENTION_DAYS -exec rm {} \; echo "MySQL 备份任务完成。"
|
执行测试
配置定时计划
填写如下内容:
1 2 3 4 5
| 0 2 * * * /bin/bash /data/script/pgsql-to-r2.sh >> /var/log/pg_backup.log 2>&1
0 3 * * * /bin/bash /data/script/mysql-to-r2.sh >> /var/log/mysql_backup.log 2>&1
|
配置对象生命周期规则
数据库文件比较小,乐意放几天放几天。我的习惯,30天肯定至少要访问一次的,所以就30天了。
