简要方案概述
昨天用 GPT 写了一个方案,测试了一晚上,通过 GPT 分析了日志情况,暂未发现什么毛病。
方案简要:
网站目录使用 rsync
同步增量更新,数据库使用 mysqldump
进行增量备份。
目前这个方案只适合做备份,“主机宕机,备用机马上接管业务”这种情况还是不太适合(后续会有关于这个的想法,欢迎各位大佬指点)。
我的做法
准备两台设备,分别安装 rsync
工具:
apt install rsync # Debian/Ubuntu 系统
或者
yum install rsync # CentOS/RHEL 系统
设备A 为主用机,设备B 为备用机。
1. 设备A创建SSH公钥
命令:
ssh-keygen -t rsa -b 2048
默认按回车即可生成密钥。
然后通过设备A将公钥传到设备B上:
ssh-copy-id -i /root/.ssh/id_rsa.pub -p 设备A的SSH端口 root@设备B的IP
测试是否配置成功:
ssh -p 设备B的SSH端口 root@设备B的IP
如果成功,进入设备B的SSH时不需要输入密码,说明公钥上传成功。
2. 使用rsync同步目录
同步网站目录的命令如下:
rsync -avz --delete -e "ssh -p 设备B的SSH端口" /www/wwwroot/ root@设备B的IP:/www/wwwroot/backup/
可以尝试在设备A上执行测试命令:
rsync -avz --delete -e "ssh -p 22" /root/test/ root@设备B的IP:/root/test2/
执行后,若提示报错,通常是设备B没有安装 rsync
,只需在设备B上安装即可。
安装命令:
apt install rsync # Debian/Ubuntu 系统
或者
yum install rsync # CentOS/RHEL 系统
执行成功后的效果如下:
3. 设置定期自动执行
在宝塔面板中设置定时任务,定期执行 rsync
同步命令。
例如,命令:
rsync -avz --delete -e "ssh -p 22" /www/wwwroot/ [email protected]:/www/wwwroot/
该命令将设备A中 /www/wwwroot/
目录中的所有文件同步到设备B的 /www/wwwroot/
目录。
提醒:
设备B的 /www/wwwroot/
中不应包含与设备A不同的文件,避免同步时被删除。
数据库增量备份方案
数据库备份脚本:
创建一个新的脚本文件 mysqlback_shanghai.sh
,放在 /www
目录中。
给脚本执行权限:
chmod +x /www/mysqlback_shanghai.sh
脚本内容如下:
#!/bin/bash
# 源数据库连接信息
SOURCE_HOST="127.0.0.1"
SOURCE_USER="root"
SOURCE_PASSWORD="root"
# 目标数据库连接信息
TARGET_HOST="设备B的IP"
TARGET_USER="同root权限的mysql账号"
TARGET_PASSWORD="密码"
# 要排除的系统数据库列表
EXCLUDED_DATABASES="information_schema|performance_schema|mysql|sys"
# 1. 获取源数据库和目标数据库的数据库列表
get_databases() {
echo "Fetching database lists from source and target servers..."
# 获取源服务器的数据库列表并排除系统数据库
SOURCE_DATABASES=$(mysql --host=$SOURCE_HOST --user=$SOURCE_USER --password=$SOURCE_PASSWORD -e "SHOW DATABASES;" | tail -n +2 | grep -Ev "$EXCLUDED_DATABASES")
# 获取目标服务器的数据库列表并排除系统数据库
TARGET_DATABASES=$(mysql --host=$TARGET_HOST --user=$TARGET_USER --password=$TARGET_PASSWORD -e "SHOW DATABASES;" | tail -n +2 | grep -Ev "$EXCLUDED_DATABASES")
}
# 2. 同步新数据库
sync_new_databases() {
echo "Syncing new databases..."
for DB in $SOURCE_DATABASES; do
if ! echo "$TARGET_DATABASES" | grep -q "$DB"; then
echo "New database detected: $DB. Synchronizing..."
mysqldump --host=$SOURCE_HOST --user=$SOURCE_USER --password=$SOURCE_PASSWORD --single-transaction --databases $DB --skip-lock-tables | \
mysql --host=$TARGET_HOST --user=$TARGET_USER --password=$TARGET_PASSWORD
if [ $? -eq 0 ]; then
echo "Database $DB synchronized successfully."
else
echo "Error occurred while synchronizing database $DB."
fi
fi
done
}
# 3. 同步更新的数据库(如果数据发生变化)
sync_updated_databases() {
echo "Syncing updated databases..."
for DB in $SOURCE_DATABASES; do
if echo "$TARGET_DATABASES" | grep -q "$DB"; then
echo "Syncing updated database: $DB..."
mysqldump --host=$SOURCE_HOST --user=$SOURCE_USER --password=$SOURCE_PASSWORD --single-transaction --databases $DB --skip-lock-tables | \
mysql --host=$TARGET_HOST --user=$TARGET_USER --password=$TARGET_PASSWORD
if [ $? -eq 0 ]; then
echo "Database $DB synchronized successfully."
else
echo "Error occurred while synchronizing database $DB."
fi
fi
done
}
# 4. 主程序
echo "Starting automatic database synchronization..."
# 获取数据库列表
get_databases
# 同步新创建的数据库
sync_new_databases
# 同步已经更新的数据库
sync_updated_databases
echo "Automatic database synchronization completed."
创建目标数据库用户
在设备B的宝塔面板中,创建一个与 root
同权的 MySQL 用户。
操作步骤:
- 在宝塔数据库管理中,新增一个用户,填写设备A的IP地址,并设置访问权限。
- 配置 MySQL 的 3306 端口,并允许设备A的IP访问。
修改脚本中的目标数据库连接信息:
TARGET_HOST="设备B的IP"
TARGET_USER="同root权限的mysql账号"
TARGET_PASSWORD="密码"
执行备份脚本
在设备A上执行脚本:
bash /www/mysqlback_shanghai.sh
GPT日志分析结果:
从日志来看,数据库和用户权限的同步成功,所有相关的数据库已正确同步到目标服务器。
需要关注的地方:
- 密码暴露警告:
虽然不会直接影响同步操作,但为了安全,建议使用 MySQL 配置文件(如~/.my.cnf
)或环境变量来隐藏密码,而不是直接在命令行中使用。 - 没有显示错误:
日志中没有错误信息,意味着操作完成得很顺利。
后续建议:
- 如果数据库同步过程中没有权限问题且数据已经正确同步,可以忽略这些警告。
- 为了进一步提升安全性,建议通过配置文件管理密码,避免在命令行中暴露密码。
完成设置
在设备A的宝塔面板中,设置同步命令定时执行,确保备份任务自动化。
GPT排的版,应该会好看点
这个内容目前只能实现:网站目录和数据库增量同步,
我自己能想到后期要优化的话,希望能做到:直接和主服务器相同配置,连nginx中的网站配置都同步起来,宝塔板面上能显示数据库密码,服务器能同时向多台设备发起同步请求(感觉数据库很麻烦),然后emmm以后再说。
目前还是主打能用就用,后面有需求了再去折腾