前言
本文介绍一种使用 rsync 实现 VPS 间每日定时自动备份的方案。假设需要备份的网站所在服务器为 VPS A,用于备份的服务器为 VPS B,系统均为 CentOS。目标是让 VPS B 定时拉取 VPS A 上的网站文件和数据库备份。
一、VPS A(源服务器)部署
VPS A 作为 rsync 服务端,需要配置 rsync 守护进程,并设置 MySQL 自动备份脚本。
1. 安装 rsync
使用 yum 安装 rsync:
yum -y install rsync
将 rsync 加入开机启动(适用于使用 systemd 前的 CentOS 版本):
echo 'rsync --daemon' >> /etc/rc.d/rc.local
注意:现代 CentOS/RHEL 7+ 系统通常使用 systemd,更推荐使用 systemctl enable rsyncd 来启用服务(如果使用系统服务的话)。本文以传统 daemon 模式为例。
2. 设置 rsync 认证密码
创建密码文件,格式为“用户名:密码”:
echo '你的用户名:你的密码' > /etc/rsyncd.scrt
chmod 600 /etc/rsyncd.scrt
此处设置的用户名和密码将在 VPS B 上连接时使用。
3. 配置 rsync 服务
编辑配置文件 /etc/rsyncd.conf:
uid = root
gid = root
use chroot = no
read only = yes
max connections = 10
port = 873
pid file = /var/run/rsyncd.pid
lock file = /var/run/rsync.lock
#log file = /var/log/rsync.log # 可选,是否记录日志
log format = %t %a %m %f %b
syslog facility = local3
timeout = 300
[www]
path = /var/www/
comment = 网站数据
ignore errors
read only = yes
list = no
auth users = andy
secrets file = /etc/rsyncd.scrt
#exclude = cache/ # 不需要备份的目录,也可使用 exclude from 文件
# 使用 exclude from 文件来定义排除列表
exclude from = /etc/rsync_exclude.txt
hosts allow = 备份服务器的IP
hosts deny = *
配置说明:
[www]:模块名,客户端连接时指定。path:要同步的源目录。auth users:允许认证的用户名。hosts allow:务必替换为 VPS B 的真实 IP 地址,以增强安全性。
4. 定义排除列表
创建排除文件 /etc/rsync_exclude.txt,列出不需要备份的目录(相对 path 的路径),每行一个:
youquso.com/new/cache/
youquso.com/manual/
5. 创建 rsync 重启脚本
创建脚本 /root/rsyncd_restart.sh,用于重启 rsync 守护进程:
#!/bin/bash
kill -9 `cat /var/run/rsyncd.pid`
rm -f /var/run/rsyncd.pid
rm -f /var/run/rsync.lock
rsync --daemon
赋予执行权限:
chmod 600 /root/rsyncd_restart.sh
chmod +x /root/rsyncd_restart.sh
之后可通过 /root/rsyncd_restart.sh 重启服务。
6. 配置 MySQL 自动备份脚本
创建脚本 /root/mysql_backup.sh,用于备份多个数据库,并自动清理旧备份:
#!/bin/bash
# 以下配置信息请根据实际情况修改
mysql_user="USER" # MySQL备份用户
mysql_password="PASSWORD" # 对应用户的密码
mysql_host="localhost"
mysql_port="3306"
mysql_charset="utf8mb4" # 建议使用 utf8mb4
backup_db_arr=("db1" "db2") # 要备份的数据库,多个用空格隔开
backup_location=/var/www/mysql # 备份存放目录,末尾不要带"/"
expire_backup_delete="ON" # 是否开启过期备份删除 ON为开启 OFF为关闭
expire_days=3 # 过期天数,expire_backup_delete开启时有效
# 以下部分一般无需修改
backup_time=`date +%Y%m%d%H%M`
backup_Ymd=`date +%Y-%m-%d`
backup_3ago=`date -d '3 days ago' +%Y-%m-%d`
backup_dir=$backup_location/$backup_Ymd
welcome_msg="MySQL backup start."
# 判断MySQL是否运行
mysql_ps=`ps -ef |grep mysqld |grep -v grep |wc -l`
mysql_listen=`netstat -an |grep LISTEN |grep ":$mysql_port" |wc -l`
if [[ $mysql_ps -eq 0 ]] || [[ $mysql_listen -eq 0 ]]; then
echo "ERROR: MySQL is not running! Backup stopped."
exit 1
else
echo $welcome_msg
fi
# 测试数据库连接
mysql -h$mysql_host -P$mysql_port -u$mysql_user -p$mysql_password -e "SELECT 1" > /dev/null 2>&1
if [ $? -ne 0 ]; then
echo "ERROR: Can't connect to MySQL server! Backup stopped."
exit 1
else
echo "MySQL connection OK. Starting backup..."
fi
# 开始备份数据库
if [ "${#backup_db_arr[@]}" -gt 0 ]; then
mkdir -p $backup_dir
for dbname in "${backup_db_arr[@]}"
do
echo "Backing up database: $dbname"
mysqldump -h$mysql_host -P$mysql_port -u$mysql_user -p$mysql_password
--single-transaction --routines --triggers --default-character-set=$mysql_charset $dbname | gzip > $backup_dir/${dbname}-${backup_time}.sql.gz
if [ $? -eq 0 ]; then
echo "Database $dbname backed up to $backup_dir/${dbname}-${backup_time}.sql.gz"
else
echo "ERROR: Failed to backup database $dbname"
fi
done
else
echo "ERROR: No database specified for backup."
exit 1
fi
# 清理过期备份
if [ "$expire_backup_delete" == "ON" ] && [ -n "$backup_location" ]; then
find $backup_location -type d -mtime +$expire_days -exec rm -rf {} ; 2>/dev/null
echo "Expired backups older than $expire_days days have been deleted."
fi
echo "All databases backed up successfully."
赋予脚本执行权限:
chmod 600 /root/mysql_backup.sh
chmod +x /root/mysql_backup.sh
加入 crontab,每天 00:00 执行:
0 0 * * * /root/mysql_backup.sh
至此,VPS A 上的部署完成。网站文件将通过 rsync 模块提供,数据库备份文件将生成在 /var/www/mysql/ 目录下,该目录也在 rsync 同步路径内。
二、VPS B(备份服务器)部署
VPS B 作为 rsync 客户端,定时从 VPS A 拉取数据。
1. 安装 rsync
yum -y install rsync
客户端无需常驻服务,因此不需要加入开机启动。
2. 设置 rsync 密码文件
创建仅包含密码的文件(注意:不是“用户名:密码”,只有密码):
echo '你在A上设置的密码' > /etc/rsync.pass
chmod 400 /etc/rsync.pass
3. 测试同步
创建本地存储目录:
mkdir -p /var/rsync/
执行测试同步命令:
rsync -avzP --delete --password-file=/etc/rsync.pass 用户名@VPS_A_IP::www /var/rsync/website_backup/
命令参数说明:
-avzP: 归档模式、显示详情、压缩传输、显示进度。--delete: 让目标目录与源目录严格一致,源端删除的文件在目标端也会被删除。--password-file: 指定密码文件路径,避免交互输入。用户名@VPS_A_IP::www: 连接 VPS A 的 rsync 服务,使用www模块。用户名需与 VPS A 密码文件中定义的一致。- 最后参数是本地存储路径。
4. 加入定时任务
编辑 crontab,设定每天 00:30 执行同步(假设 MySQL 备份在 00:00 完成):
30 0 * * * rsync -avzP --delete --password-file=/etc/rsync.pass 用户名@VPS_A_IP::www /var/rsync/website_backup/ > /dev/null 2>&1
输出重定向到 /dev/null 可避免产生不必要的日志邮件。
总结与扩展
通过以上步骤,已经建立了一个从 VPS A 到 VPS B 的自动备份系统,涵盖了网站文件和数据库。
为了进一步提升数据安全性,可以考虑增加一个“VPS C”,让 C 从 B 再次同步,形成异地双重备份。其配置方法与 VPS B 从 A 拉取类似,只需将源地址改为 VPS B 的 IP 并配置相应的 rsync 服务端即可。
重要提示:
- 确保防火墙开放了 VPS A 的 873 端口(或自定义的 rsync 端口)。
- 密码文件需严格设置权限,防止泄露。
- 定期检查备份日志和备份文件的完整性。
- 对于现代 Linux 发行版,建议研究使用 systemd service 或 timer 来管理 rsync 服务与定时任务。