刚接触WordPress博客/网站时,本人并没什么备份概念。博客不在了大不了重新搭建,反正既没什么人看,也没有多少东西。工作后遇到过网络攻击、运维失误、硬件故障等意外,安全和备份意识越来越强,对其重要性的认识上升到新的层面。
本文简要介绍一些可行的WordPress备份方案,并给出本站目前使用的备份方案和备份脚本,备份脚本稍加修改也可以应用到其他类型网站的备份。
WordPress备份方案
备份就是把数据复制一份或多份,防止出现意外时造成数据丢失、并能通过备份尽快恢复服务。要做好WordPress备份服务,需要从以下几个方面考虑:
备份位置
备份需要额外的存储空间存放冗余数据,备份位置有如下几种选择:
-
同一台服务器的不同分区。这种方式优点是备份特别快,当网站被挂木马时也能迅速恢复。缺点是如果服务器故障无法登录,那就没辙了;
-
同一数据中心的不同服务器上。优点是避免了单台服务器故障的问题、同步也快,缺点是需要一台额外服务器,机房网络故障时可能都无法正常访问;
-
同一地区的不同服务器上。优点是避免了单机房网络、电力故障的问题,缺点是同步速度较同机房稍慢;
-
异地服务器。异地备份的优点是避免某个地区可能出现的网络故障(例如施工挖断光缆),能提供最大的可用性,缺点是同步很慢;
-
备份到云盘/网盘。目前云备份也很成熟,可以将数据备份到网盘。
本站使用的是异地备份方案,用家里的 树莓派 作备份服务器,备份空间大且能省下一笔费用。
备份数据方案
备份数据方案有多种:
-
整盘备份。最简单粗暴的,也是最慢的备份方式,优点是恢复时省心,对拷过去就完事了。VPS商家提供的快照服务就是用的这种方式;
-
备份数据分区。网站的数据库、程序文件放在单独分区上,备份时复制这个分区就可以了。比整盘复制快,但同步数据量也大;
-
仅备份数据库和程序文件。备份数据量小,恢复时候麻烦点,要重新安装程序和运行环境,用docker能省心点。
因为是跨广域网备份,因此本站使用仅备份数据库和程序文件的方式,传输的数据量最小,能更快完成备份。
WordPress备份方式
具体到WordPress网站备份,有以下几种方式:
-
使用WordPress备份插件。有许多知名的WordPress备份插件,例如 UpdraftPlus 、BackWPup 、WP Time Capsule 等,支持将程序和数据备份到本地、ftp、dropbox、Google Drive等。这种方式适合于托管在虚拟主机的网站;
-
使用备份脚本。如果你的网站运行在自己的服务器上,可以自己写脚本或者用网络上的脚本备份。
本站使用自己写的备份脚本进行备份,详细脚本和功能请往下看。
WordPress备份脚本
本站使用本人自己写的备份脚本进行备份,备份脚本有以下特点:
-
网站程序文件使用 rsync 增量备份,同步速度快;
-
定期(默认每周)归档程序文件;
-
数据库全量备份;
-
自动删除过期的文件。
备份脚本使用方法
- 备份服务器上生成RSA公钥:
ssh-keygen -t rsa -b 4096 一直回车
然后将公钥传到网站服务器:
ssh-copy-id xxx.xxx.xxx.xxx 你服务器Ip
(如果已经进行过免密认证请跳过);
- 复制下文的脚本代码,保存到一个文件里,例如root家目录下的wp-backup.sh,按照提示将脚本里的IP、mysql数据库密码等改成你的;
安装crontab服务并设置开机自启 {#ud4b31d9b}
yum install crontabs (centos默认就会带,一般不需要安装)
systemctl enable crond (设为开机启动)
systemctl start crond(启动crond服务)
systemctl status crond (查看状态)
- 编辑 /etc/crontab 文件,按照需求定时备份。例如:
vi /etc/crontab
#每个月的1号的19点钟备份一次
0 19 1 * * root bash /root/wp-backup.sh
vim /etc/crontab
# 每天,每5分钟执行一次 myshell.sh脚本
*/5 * * * root /root/wp-backup.sh
每天凌晨二点,执行命令脚本,这里由于第一个的分钟没有设置,那么就会每天凌晨2点的每分钟都执行一次命令
* 2 * * * root `/root/wp-backup.sh`
每天凌晨二点整执行一次命令脚本
0 2 * * * root `/root/wp-backup.sh`
每天11点到13点之间,每10分钟执行一次命令脚本
*/10 11-13 * * * root `/root/wp-backup.sh`
每小时的10-30分钟,每分钟执行一次命令脚本,共执行20次
10-30 * * * * root `/root/wp-backup.sh`
每小时的10,30分钟,分别执行一次命令脚本,共执行2次
10,30 * * * * * root `/root/wp-backup.sh`
周一到周五每天的9点到14点,每5min执行一次python脚本
*/5 9-14 * * 1-5 `/root/wp-backup.`py
周一到周五的15点到15点35分,每5min执行一次python脚本
0-35/5 15 * * 1-5 `/root/wp-backup.`py
注意:
crond的计划任务并不会调用用户设置的环境变量,在执行计划任务时,用的时crond自己的环境变量,所以有些脚本手工执行是可以的,但是计划任务就不行,此时要么写脚本的绝对路径,要么将环境便俩个添加到/etc/crontab中;
遇到的问题:
# */5 9-14 * * 1-5 root /usr/local/python3/bin/python3 /root/gold.py
这种写法虽然脚本能执行成功,但是cron的执行日志中会有相关的报错,看着很不爽,于是就有了下面这种写法;
# */5 9-14 * * 1-5 /root/gold.py 这种写法有一个前提,需要指定执行脚本的解释器,也就是"#!/usr/local/python3/bin/python3";
不知道是不是我是root的缘故,当在cron中加入执行用户root时,脚本能执行成功,但是cron的执行日志中仍然会报错,于是就干脆取消了,不知道普通用户状态下会不会出现这种问题;(测试系统:CentOS 7.7)
保存生效
# 加载任务使其生效
crontab /etc/crontab (每一次的改动都需要执行,否则不生效)
# 查看任务
crontab -l
# 直接编辑
crontab -e (或者直接vim /etc/crontab)
注意:如果第一次写计划任务直接执行crontab -e,则计划任务文件是保存在/tmp目录下的,关机重启会失效;所以推荐"vim /etc/crontab";
对于个人博客,个人认为一天备份一次就行,毕竟平时都不变。
备份脚本代码
以下是备份脚本代码,请按照提示修改:
#!/bin/bash
# WordPress备份脚本,用法参考:https://qiquanji.com/wordpress-backup-plans-and-script
请修改这些变量的值
=========
IP=这里填写你网站服务器ip
WEBDIR=这里填写网站程序目录,例如/data/wwwroot/qiquanji
DBPASS=这里填写Mysql数据库的root密码,如果不需要密码请填123456等任意字符
DBNAME=这里填写数据库的名称
BACKUPDIR=这里填写本地备份目录,例如/root/backup
NGINX=这里填写nginx的网站配置目录,列如/usr/local/nginx/conf/vhost
EXPIRE_DAYS=14 #保留14天的备份,可以改成30天,200天等
好了,下面的内容一般无需改动
==============
准备备份目录
======
mkdir -p ${BACKUPDIR}/db
mkdir -p ${BACKUPDIR}/nginx
mkdir -p ${BACKUPDIR}/tar
mkdir -p ${BACKUPDIR}/files
if \[ ! -d ${BACKUPDIR}/db \]; then
echo "无法创建备份目录"
exit 1
fi
#判断nginx下的网站配置文件是否存在,如果不存在就备份一次
if \[ ! -d ${BACKUPDIR}/nginx/vhost \]; then
rsync -avP --delete-after root@${IP}:${NGINX} ${BACKUPDIR}/nginx/
fi
备份数据库
=====
DBFILE=${DBNAME}-`date +\%Y\%m\%d\%H\%M\%S`.sql.gz
ssh root@${IP} "mysqldump -uroot -p"${DBPASS}" ${DBNAME} \| gzip \> \~/${DBFILE}"
scp root@${IP}:\~/${DBFILE} ${BACKUPDIR}/db/
rm -rf root@${IP}:\~/${DBFILE}
备份程序文件
======
rsync -avP --delete-after root@${IP}:${WEBDIR} ${BACKUPDIR}/files/
归档程序
====
day=`date +\%u`
if \[ "$day" = "7" \]; then
tar -jcf ${BACKUPDIR}/tar/`date +\%Y\%m\%d`.tar.bz2 ${BACKUPDIR}/files
fi
删除过期备份
======
`find ${BACKUPDIR}/db -mtime +${EXPIRE_DAYS} -exec rm -rf {} ;
find ${BACKUPDIR}/tar -mtime +${EXPIRE_DAYS} -exec rm -rf {} ;
`
脚本注意事项
- IP可以是主机名或者域名;
- 如果ssh端口不是标准的22,在~/.ssh/config配置端口;
- 备份脚本分三个目录存放备份文件:db:存放数据库备份;tar:存放程序文件的归档,可使用 tar -jxf 文件名 解压;files:存放网站程序文件;
- 建议将网站服务器上的nginx配置文件、域名程序也下载到备份目录,恢复时拷贝过去即可。脚本已经自动备份一次,如果是https,记得备份证书