2.3 数据库与文件:放服务器还是放 COS

网站装好了,朋友问了一个挺到位的问题:“数据到底存在哪?”我给他翻了一下服务器目录结构,他立刻意识到东西比想象的多。这篇就讲 WordPress 的数据有哪些、分别存在哪,以及哪些值得挪到对象存储 COS 去。这部分在部署阶段多想十分钟的回报是巨大的——以后备份和迁移能少掉好几根头发。

WordPress 的数据结构:一张表看懂

WordPress 的所有数据分成两类:数据库里的结构化内容,磁盘上的文件。我在服务器上做了个梳理:

数据类型 位置 内容 体积感
文章、页面、评论 MySQL 表 wp_posts、wp_comments 企业站十几条,很小 小
站点设置、主题配置 MySQL 表 wp_options 序列化存储,改动频繁 小
上传的图片、附件 磁盘 wp-content/uploads 每篇文章配图都在这里 随时间膨胀
主题与插件代码 磁盘 wp-content/themes、plugins 程序文件,可重装 小但重要
核心程序与配置 磁盘根目录、wp-config.php 版本号、连接信息 小

规律很明显:数据库小而珍贵,上传目录大而可重建。这个差异决定了后面的存放策略。

我给朋友打了个比方帮他理解:数据库是账本,丢了就什么都没了;上传目录是仓库里的货物,大件贵但没了还能重新拍。备份策略因此完全不同——账本天天抄一份,货物定期盘一次就行。

朋友又追问:那数据库能不能也放云上?可以,轻量服务器里的是自建 MySQL,你可以换成腾讯云数据库(那是腾讯云实战手记里的方案),但年成本立刻上去。小企业官网用自建的就够了,把导出的备份扔去 COS 是更经济的容灾方式。

另外提醒一句:wp_options 表里存着序列化的设置,体积不大但改动频繁。有人觉得把它单独搬到别处能优化性能,纯属多此一举——MySQL 自身缓存完全 handle 得了这个量级。优化精力请花在真正会膨胀的地方。

上传目录放大的问题

朋友的官网一开始只有产品图,uploads 占了几十 MB,岁月静好。但他后来要放产品手册 PDF 和实拍视频,单文件动辄几十 MB,三个问题马上冒出来:

问题 具体表现 影响
备份变慢 快照和打包都要带上大文件 备份窗口拉长
迁移犯难 换服务器要传几个 GB 容易中断、重传
带宽吃紧 大文件直接占 80 端口流量 套餐流量包消耗加快
上传受限 PHP 和 Nginx 对单文件大小有限制 视频根本传不上去

另外还有个安全面:uploads 目录如果权限开太大,被人传了脚本进去会很麻烦。目录默认不可执行 PHP 是基本配置,别手贱放开。

COS 在这里的两个角色

对象存储 COS 并不是“替代服务器磁盘”,我在这个项目里只给它派了两个活:

角色一:放大文件的落脚点。 产品手册 PDF、实拍视频这类静态大文件,上传到 COS 存储桶,网页里直接链存储桶的访问域名。服务器只留页面程序和必要的配图,磁盘占用稳稳的。也可配合 CDN 加速,这是另一篇的内容,具体可以翻COS 快速入门。

寄存桶的名字要全局唯一,权限先选私有,需要公开访问的文件再单独放开。给存储桶配一条生命周期规则:30 天前的备份自动转到低频存储,成本能再降一档,这些细节对正式上线后长期省钱很有帮助。设置存储桶的过程以COS 快速入门的步骤为准。

角色二:备份的终点站。 数据库每天导出一份 SQL,配上 wp-content 打个包,一起扔进 COS。服务器炸了数据还在别的机房,这是 5.2 会展开的方案。

服务器本地放什么、COS 放什么,我给朋友的建议是这样的取舍表:

数据 放服务器本地 放 COS 建议
MySQL 数据库 ✔ 运行必需 定期导出存过去 本地+备份到 COS
主题、插件代码 ✔ 打包备份 本地
产品配图等小图 ✔ 可选 本地,量小
PDF 手册、视频 ✘ 占地方 ✔ 放 COS 外链
全站备份压缩包 ✘ 同机风险 ✔ 放 COS

数据存放位置对比:本地、COS 还是混合

朋友看完取舍表又问:那到底哪种放法总体最优?我给他画了张三维对比表,按成本、速度、备份三个维度打分:

存放方案 成本 访问速度 备份与容灾 适合
全部放服务器 套餐内零额外成本,磁盘满了要升级套餐 最快,无网络往返 最差,服务器坏了全没 刚起步、数据小
全部放 COS 按量计费,量大时要注意 首次下载有延迟 好,多副本存储 静态站、大文件托管
混合(程序本地+大文件+备份 COS) 存储费极低 首屏快 好,重要数据异地 企业官网(我的方案)

我的结论很明确:混合方案是 WordPress 站点的甜点。运行要的本机留,静态大件和备份扔云上。想一步到位了解混合架构的玩法,可以参照腾讯云实战手记里 COS 与服务器配合的实战例子。

体积增长的观察:哪些会膨胀,哪些不会

跑了一个季度后我统计过一次,数据很有意思,对规划很有参考价值:

数据项 起步体积 三个月后 增长原因
MySQL 数据库 约 2 MB 约 5 MB 文章和设置而已,增速很慢
wp-content/uploads 约 20 MB 约 400 MB 产品图加 PDF 手册,主力膨胀源
主题插件代码 约 50 MB 约 55 MB 只换过一次主题
备份压缩包 约 30 MB 约 300 MB uploads 膨胀的直接后果

规律值得记住:数据库几乎不涨,上传目录是膨胀大头。这意味着备份 MySQL 成本极低(每天一次也就几 MB),真正需要设计策略的是 uploads。也正因为如此,把 PDF 和视频挪去 COS 之后,备份包一夜之间缩回 50 MB 以内,整个运维节奏都轻松了。

自己弄几台机器做冷备份当然是另一条路,NAS 与家庭服务器的玩法可以参考NAS 与家庭服务器手记,不过对一个小企业官网,COS 的月成本几乎可以忽略。

操作层面怎么做

把上传策略落地,我顺手做了三件事,都很轻:

第一,调整上传限制。编辑 PHP 配置放开单文件大小,再放开 Web 服务器的请求体限制:

sudo sed -i 's/^upload_max_filesize.*/upload_max_filesize = 64M/' /etc/php/*/fpm/php.ini
sudo sed -i 's/^post_max_size.*/post_max_size = 64M/' /etc/php/*/fpm/php.ini
sudo systemctl restart php-fpm

第二,装 COS 插件或手动传文件。少量大文件直接在 COS 控制台上传再拷链接最省事;如果图片多,可用 WordPress 的对象存储插件自动转存,配置一次以后无感。

第三,确认 uploads 目录权限只给 Web 用户,并且目录里不放可执行脚本的解析规则。

存储桶开通后的第一件事是确认访问域名。COS 会给每个桶一个默认域名,也可以配自定义域名走 CDN。给企业站用,我建议图片小文件仍留服务器,只把 PDF 和视频这类大件挪过去——网页打开速度主要取决于首屏,首屏图片那几十 KB 的差异不值得为此多养一套插件。

一个判断公式很实用:文件大小超过 5 MB、又不常变的,放 COS;随文章一起出现的小图,留服务器。按这个规则切分,朋友的站磁盘占用稳定在 300 MB 以内,备份包控制在 50 MB 上下,后面 5.2 的自动化脚本跑起来就很快。

顺带算个账:COS 存储按容量和请求计费,一个小企业官网的备份量级,每个月成本几乎可以忽略不计,比买额外磁盘划算得多,也比快照省钱(快照是按整盘计费的)。

手动备份的一行命令

在自动化备份上线之前,我先手动跑过几次,确保这套链路能通。数据库导出加文件打包,其实就几行:

mysqldump -u wpuser -p wpdb > /tmp/wpdb.sql
tar -czf /tmp/site-$(date +%F).tar.gz wp-content /tmp/wpdb.sql

把压缩包下载到本地,或上传到 COS 存储桶,一次手工备份就完成了。别小看这两行:它验证了账号权限、备份路径、压缩大小这些关键环节,等 5.2 写自动化脚本时就不用在黑盒里调试。手动跑通的事情,自动化才有把握。

踩坑与解法

坑一:外链存储桶被刷流量。 存储桶按量计费,链接被人盗用会一直扣费。关掉公共读、改用带签名的临时链接,或者只对自己的域名开放访问。

坑二:备份只放服务器本地。 磁盘坏了备份一起没,等于没备份。一定养成“本地一份、COS 一份”的习惯。

坑三:插件自动转存后旧图没同步。 文章里老图的链接还指向服务器,记得旧文件保留一段时间再清理。

坑四:数据库导出没带字符集。 导出的 SQL 乱码,通常是没指定 utf8mb4。手动导出时加参数:

mysqldump --default-character-set=utf8mb4 -u wpuser -p wpdb > wpdb.sql

坑五:把数据库也搬去 COS。 有朋友问数据库能不能也放 COS 省事——不行,COS 是对象存储,不是关系型数据库,MySQL 只能跑在服务器或云数据库上。COS 存的只能是导出后的备份文件。这个概念分清了,云上的存储产品就不会用错。

延伸阅读