刚接触WordPress博客/网站时,本人并没什么备份概念。博客不在了大不了重新搭建,反正既没什么人看,也没有多少东西。工作后遇到过网络攻击、运维失误、硬件故障等意外,安全和备份意识越来越强,对其重要性的认识上升到新的层面。

本文简要介绍一些可行的WordPress备份方案,并给出本站目前使用的备份方案和备份脚本,备份脚本稍加修改也可以应用到其他类型网站的备份。

WordPress备份方案

备份就是把数据复制一份或多份,防止出现意外时造成数据丢失、并能通过备份尽快恢复服务。要做好WordPress备份服务,需要从以下几个方面考虑:

备份位置

备份需要额外的存储空间存放冗余数据,备份位置有如下几种选择:

  1. 同一台服务器的不同分区。这种方式优点是备份特别快,当网站被挂木马时也能迅速恢复。缺点是如果服务器故障无法登录,那就没辙了;
  2. 同一数据中心的不同服务器上。优点是避免了单台服务器故障的问题、同步也快,缺点是需要一台额外服务器,机房网络故障时可能都无法正常访问;
  3. 同一地区的不同服务器上。优点是避免了单机房网络、电力故障的问题,缺点是同步速度较同机房稍慢;
  4. 异地服务器。异地备份的优点是避免某个地区可能出现的网络故障(例如施工挖断光缆),能提供最大的可用性,缺点是同步很慢;
  5. 备份到云盘/网盘。目前云备份也很成熟,可以将数据备份到网盘。

本站使用的是异地备份方案,用家里的 树莓派 作备份服务器,备份空间大且能省下一笔费用。

备份数据方案

备份数据方案有多种:

  1. 整盘备份。最简单粗暴的,也是最慢的备份方式,优点是恢复时省心,对拷过去就完事了。VPS商家提供的快照服务就是用的这种方式;
  2. 备份数据分区。网站的数据库、程序文件放在单独分区上,备份时复制这个分区就可以了。比整盘复制快,但同步数据量也大;
  3. 仅备份数据库和程序文件。备份数据量小,恢复时候麻烦点,要重新安装程序和运行环境,用docker能省心点。

因为是跨广域网备份,因此本站使用仅备份数据库和程序文件的方式,传输的数据量最小,能更快完成备份。

WordPress备份方式

具体到WordPress网站备份,有以下几种方式:

  1. 使用WordPress备份插件。有许多知名的WordPress备份插件,例如 UpdraftPlusBackWPupWP Time Capsule 等,支持将程序和数据备份到本地、ftp、dropbox、Google Drive等。这种方式适合于托管在虚拟主机的网站;
  2. 使用备份脚本。如果你的网站运行在自己的服务器上,可以自己写脚本或者用网络上的脚本备份。

本站使用自己写的备份脚本进行备份,详细脚本和功能请往下看。

WordPress备份脚本

本站使用本人自己写的备份脚本进行备份,备份脚本有以下特点:

  1. 网站程序文件使用 rsync 增量备份,同步速度快;
  2. 定期(默认每周)归档程序文件;
  3. 数据库全量备份;
  4. 自动删除过期的文件。

备份服务器要求是Linux或者有Linux运行环境,例如Cygwin

备份脚本使用方法

  1. 备份服务器上生成RSA公钥:ssh-keygen -t rsa -b 4096,然后将公钥传到网站服务器:ssh-copy-id -i ~/.ssh/id_rsa.pub root@网站服务器ip(如果已经进行过免密认证请跳过);
  2. 复制下文的脚本代码,保存到一个文件里,例如root家目录下的wp-backup.sh,按照提示将脚本里的IP、mysql数据库密码等改成你的;
  3. 编辑 /etc/crontab 文件,按照需求定时备份。例如每小时备份一次:0 * * * *  root bash /root/wp-backup.sh。对于个人博客,个人认为一天备份一次就行,毕竟平时都不变。

备份脚本代码

以下是备份脚本代码,请按照提示修改:

#!/bin/bash
# WordPress备份脚本,用法参考:https://tlanyan.me/wordpress-backup-plans-and-script

# 请修改这些变量的值
IP=这里填写你网站服务器ip
WEBDIR=这里填写网站程序目录,例如/data/wwwroot/tlanyan
DBPASS=这里填写Mysql数据库的root密码,如果不需要密码请填123456等任意字符
DBNAME=这里填写数据库的名称
BACKUPDIR=这里填写本地备份目录,例如/root/backup
EXPIRE_DAYS=14  #保留14天的备份,可以改成30天,200天等

# 好了,下面的内容一般无需改动

# 准备备份目录
mkdir -p ${BACKUPDIR}/db
mkdir -p ${BACKUPDIR}/tar
mkdir -p ${BACKUPDIR}/files
if [ ! -f ${BACKUPDIR}/db ]; then
    echo "无法创建备份目录"
    exit 1
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 {} \;

脚本注意事项

  1. IP可以是主机名或者域名;
  2. 如果ssh端口不是标准的22,在~/.ssh/config配置端口;
  3. 备份脚本分三个目录存放备份文件:db:存放数据库备份;tar:存放程序文件的归档,可使用 tar -jxf 文件名 解压;files:存放网站程序文件;
  4. 建议将网站服务器上的nginx配置文件、域名程序也下载到备份目录,恢复时拷贝过去即可。

有问题请留言。

参考

1. How to Back up your Website and Why It’s Important