
很多站长直到第一次被插件冲突弄崩、或者主机磁盘故障之后,才意识到「我有备份」和「我能恢复」是两件完全不同的事。如何为 WordPress 站点搭一套真正能救命的数据库定时备份脚本?又该如何把这份备份送到异地,避免单点故障?这篇指南教你从零开始把脚本、任务计划、异地同步与恢复演练串起来,解决业务连续性最关键的一环,帮助你在事故发生时把损失压到最小。
为什么 WordPress 需要一套独立的数据库备份脚本
主机面板自带的备份通常以「整站打包」为粒度,恢复一个文章版本却要把上传目录和插件全部回滚,代价过大。WordPress 的核心数据(文章、评论、用户、配置)都在 MySQL/MariaDB 数据库里,单独把这部分拎出来按更高频率备份,才能在「误删一篇文章」「插件写坏 options 表」这类场景下快速止损。
数据库独立备份相对文件备份还有几个明显优势:单次体积只有几十 MB 到几百 MB,传输与保留成本低;可以做小时级甚至 15 分钟级的高频增量;容易加密并分发到异地;恢复速度快,单条 mysql 命令就能回灌;与文件备份解耦后还可以分别设计保留策略。
如果你的站点还在共享主机上,可以先阅读这份 WordPress 香港主机选购指南 评估升级到 VPS 的时机:脚本化备份需要 shell 与 cron 权限,多数共享主机不开放完整的 SSH。
脚本核心:mysqldump 加压缩加校验
最朴素也最稳的方案,就是用 mysqldump 导出 SQL 文本、用 gzip 压缩、再算一份 SHA256 校验。脚本本体不超过 30 行,但要把易错点都覆盖到:凭据要放在受限文件里、单事务模式避免锁表、错误码要传递给 cron。
一个最小可用版本如下:
#!/usr/bin/env bash
set -euo pipefail
CONF="/etc/wp-backup/db.cnf"
DB="wp_main"
DEST="/var/backups/wordpress"
STAMP=$(date +%F_%H%M)
FILE="${DEST}/${DB}_${STAMP}.sql.gz"
mkdir -p "${DEST}"
mysqldump --defaults-extra-file="${CONF}" \
--single-transaction --quick --routines --triggers \
--default-character-set=utf8mb4 "${DB}" \
| gzip -9 > "${FILE}"
sha256sum "${FILE}" > "${FILE}.sha256"
find "${DEST}" -name "${DB}_*.sql.gz" -mtime +14 -delete
落地时要特别注意:
- 凭据文件用 chmod 600 并归 root,避免与 web 用户共享
- single-transaction 仅对 InnoDB 安全,MyISAM 表需配合 lock-tables
- 字符集必须显式 utf8mb4,否则表情符号、部分简繁字会出错
- 用 set -euo pipefail 让任何子命令失败都直接终止
- 输出日志统一打到 /var/log/wp-backup/,便于事后排查
用 Cron 把脚本变成可靠的定时任务
写完脚本只是开始。让它在凌晨准点跑、跑失败能告警、不会跟其他任务撞车,才是定时备份「可靠」的关键。建议把数据库备份排在站点访问最低谷,例如每天 03:15,并避开主机商的整点维护窗口。
一个推荐的 crontab 配置:
MAILTO=ops@example.com
15 3 * * * /usr/local/bin/wp-db-backup.sh >> /var/log/wp-backup/cron.log 2>&1
30 3 * * * /usr/local/bin/wp-db-offsite-sync.sh >> /var/log/wp-backup/cron.log 2>&1
几个常被忽略的点:
- MAILTO 让脚本异常输出会自动发邮件,前提是本机能投递
- 重定向必须同时含 stdout 与 stderr,否则失败信息会丢
- 跨时区机器先 timedatectl 确认本地时间,再排时段
- 用 flock 包一层可以避免脚本跑超时被下一个实例叠加
- 容器或 systemd 环境下优先用 systemd timer 替代 cron
如果你刚开始接触服务器层运维,可以参考 美国 VPS 部署教程指南 把基础 shell 与防火墙先做齐,再叠加备份脚本会更顺。
异地同步:让备份真正离开「同一块磁盘」
本机备份只能解决误操作,不能解决「整台主机被勒索病毒加密」或「机房断电烧盘」这类事故。任何认真的备份方案都必须包含异地副本,业界常说的 3-2-1 原则就是:3 份数据、2 种介质、1 份异地。
可选的异地通道有几类:
- 同集群另一台 VPS:用 rsync over ssh,延迟低、成本低
- 对象存储:S3、阿里云 OSS、Backblaze B2,配合 rclone 即可
- 家用 NAS:通过 VPN 或反向 SSH 隧道回拉
- 第三方备份服务:开箱即用,但要核对加密与保留策略
- 离线介质:U 盘或冷盘,仅适合月度归档
rclone 是目前比较推荐的异地同步工具,可以加密落盘、断点续传、限速、做生命周期:
rclone copy /var/backups/wordpress remote-encrypted:wp-backup \
--transfers 4 --checkers 8 --bwlimit 8M --log-file=/var/log/wp-backup/rclone.log
建议在 rclone 之外再叠加一层 GPG 加密:哪怕远端账号泄露,攻击者拿到的也是密文。密钥要异地另存,最好同时打印一份纸质备份放保险柜,避免「备份和密钥一起没」。
恢复演练比备份本身更重要
「备份从未失败,但恢复经常失败」是运维圈的老话。脚本和异地同步只完成了一半工作,剩下的一半是定期演练。建议把恢复演练写成季度任务,至少做一次完整链路:从远端拉回最新备份、解密、解压、灌进一个干净的 MySQL 实例、再用脚本去 diff 关键表。
演练时重点确认几件事:远端备份在没有源站访问的情况下能独立解开;wp_options 中的 siteurl 与 home 可以被批量改写;wp_users 与 wp_usermeta 能登录新实例;媒体库路径与数据库中的 URL 不冲突;最终的恢复时间 RTO 与可接受丢失 RPO 都符合业务要求。
把演练结论写进运维手册,下次轮到新同事顶班时也不慌。如果你计划把演练环境放到独立的云主机,云服务器选购指南 中关于规格与计费模型的章节可以省下不少试错成本。
性能与并发:备份对站点的真实影响
很多人担心 mysqldump 会拖慢线上站点。在 InnoDB 单事务模式下,导出过程不会锁住业务读写,但仍会占用 IO 与 CPU。对中小型 WordPress 站点(数据库小于 2 GB)影响通常可控;超过这个量级,就该考虑 xtrabackup 物理热备或读库导出。
可以做的优化包括:把备份机器与数据库放在同一内网,避免走公网;在脚本里加 ionice 与 nice,给业务让 IO;大表用 where 条件做分片导出,再合并;对 wp_options 等高频表单独安排小频次备份;同时配合 WordPress W3 Total Cache 调优 把读压力下沉到对象缓存,减少备份窗口的争抢。
如果你的站点托管在主机商那里,工单里附上数据库大小与高峰 QPS,技术支持通常可以协助评估是否需要单独的备份节点。
一份可以照抄的落地清单
把上面的内容收敛成可执行清单:
- 用独立 OS 用户跑备份脚本,凭据文件 chmod 600
- mysqldump single-transaction 加 gzip 加 SHA256 校验三件套必备
- crontab 加 MAILTO、flock、统一日志目录
- 至少一条异地通道,优先对象存储 + rclone
- 备份在落盘前加 GPG 加密,密钥异地另存
- 保留策略:本地 14 天,异地 90 天,月度归档 1 年
- 季度演练恢复全链路,记录 RTO/RPO
- 文件备份与数据库备份分别管理,不互相依赖
总结来说,WordPress 数据库的可靠备份不是单一脚本,而是「脚本 + 定时任务 + 异地通道 + 加密 + 演练」的组合拳。建议先用最小可用版本跑起来,再按照清单逐项补齐。如果你需要把这套方案与现有主机或新购的 VPS 集成,可以考虑把异地节点放在不同地理区域;想了解更多 WordPress 运维场景,推荐继续阅读 WordPress 分类下的其他实战文章,把备份、缓存与安全这三块拼成一个完整的运维基线。