前端第一次备份数据库,被权限这个坑整不会了

2 阅读6分钟

上周我们那个小项目要换服务器,带我的哥让我顺手把数据库备份一下。说顺手的时候他语气特别轻松,我也真以为这事儿不难。毕竟我正经是个写前端的,平时的工作就是调接口、改页面、对着设计稿抠像素,数据库顶多打开 Navicat 点两下看看表里有什么。备份嘛,不就是导出一份文件,谁不会。

结果这份自信撑到了凌晨两点。我坐在屏幕前面,看着恢复出来的库连不上应用,报错刷了一屏,第一次认真怀疑自己到底算不算个能扛点儿事儿的开发。

我原以为备份就是敲一条命令导个文件

我们项目用的是 Postgres。我凭着以前瞄过几眼的印象,在终端里敲了那条据说最常用命令。

pg_dump appdb > backup.sql

跑完我看了一眼文件大小,好几个 G,心里还挺踏实。数据都在,能出什么岔子。旧服务器我直接关了,新服务器起来,我把 backup.sql 灌进去,泡了杯咖啡等它恢复原样。

然后应用报连不上。

看到那屏报错我第一反应是把文件又翻了一遍,表明明都在,我甚至 SELECT count(*) 数了几个核心表,行数对得上。可应用一启动就报错连不上,日志里全是连库失败。我当时真有点蒙,数据都在,怎么就不让连。我又在另一台机器 psql -f backup.sql 重跑了一遍,刷出来一堆 ERROR,越看越乱。

真正的坑,角色和权限压根不在那个文件里

后半夜我一边查一边才搞明白,Postgres 里角色,也就是用户和账号,是挂在集群上的,不是挂在某个具体数据库上的。pg_dump 后面跟着一个库名,它就只导这个库内部的表、数据、索引、视图这些东西,角色的定义它一个字都不会写进文件。

等于说我导出的那份 backup.sql,有表有数据,却没有那个只读账号,也没有库的 owner。恢复到一台干净的新实例时,新库里根本没有这些角色,原来的授权语句一条条全失败,应用连不上是必然的。

还有个更隐蔽的,扩展(extension)。我们库用到了 uuid-ossp,恢复完应用还是报错,说 uuid_generate_v4 这个函数不存在。一查才知道,扩展也是挂在库上的对象,自己建的扩展不会跟着纯数据备份自动回来,得在恢复前先 CREATE EXTENSION。这一个小坑我又卡了半个钟头。

要连角色一起带走,得用 pg_dumpall,或者至少 pg_dumpall --roles-only 把角色单独导一份出来。我那晚上但凡早知道 pg_dump 和 pg_dumpall 这俩名字差一个字母、管的事完全不一样,也不至于后半夜还在跟文档死磕。

平时救命的 AI,这次只递了半截梯子

说个有点丢人的细节。我平时卡住基本都扔给 AI 问,它大多数时候能给我一个靠谱的下一步,所以我越来越习惯遇事不自己翻文档。这次也一样,我截图报错丢过去,它先给我一段 pg_dump 的命令,我照做还是错,又问为什么恢复会报 role 不存在,它列了几种可能让我挨个试。

试到第三种才对上号。

那一刻我有点恍惚。原来有些坑不是问一句就能绕过去的,AI 给我的是地图上某一个点,路还得我自己一步步走。这两年总听说 AI 越来越能写代码、越来越能替人干活,我这个做前端的偶尔会慌,怕自己只会长用工具、不长真本事。但这次凌晨的报错让我反过来想,恰恰是最基础、最脏手的那部分活儿,AI 替不了我,也得我自己踩、自己记。

前端为啥也会撞上这种脏活

说起来有点无奈。我们组就那么几个人,没有专门的 DBA,也没有运维,谁离数据库近谁上。我虽然写前端,但项目小,库也在我本地跑过,自然就被抓来干这个。平时用 ORM 写个查询都嫌麻烦,真到了要搬整个库,才知道自己离底层有多远。

我们组写前端的就我一个女生,这种杂活反而更容易落到我头上,大概因为大家默认前端比较闲。我一开始还不敢问,怕显得连备份都不会,挺丢人的。后来发现,不问才真的丢人,问出来才发现好多人第一次都栽过。

MySQL 那边其实是一样的坑

我们还有个更老的项目跑在 MySQL 上。mysqldump 指定一个库导出,同样不带用户和授权。想把账号也带走,要么连 mysql 那个系统库一起导,要么用 mysqlpump 带上 --users,要么先用 pt-show-grants 把授权导成文本。

我踩完 Postgres 的坑,转头去翻 MySQL 的备份方式,发现逻辑一模一样,只是命令换了个壳。这也算一种安慰,坑虽然多,套路是通的。

现在我给自己定的备份规矩

翻车之后我整理了一套自己能记住的流程,不敢说多专业,至少下次不用凌晨爬起来救火。

Postgres 要连角色一起走,我直接用 pg_dumpall 导整个集群,或者分开两步,pg_dumpall --roles-only 出一份角色文件,pg_dump 出业务库。恢复的时候一定先建好角色再灌数据,顺序反了就又是一屏幕报错。

MySQL 我先用 pt-show-grants 把授权落一份文本存着,再 mysqldump 业务库,两份文件打一起,恢复时对着来。

还有一条最重要,备份完别觉得自己安全了,一定要找台别的机器真恢复一遍。我就是太信自己导出的文件,没验证,才在切换当天当场社死。后来我学乖了,恢复完不急着关终端,先在本地 Docker 起一个空 Postgres 把流程完整走一遍。上次就是这么试出来 extension 漏了的,幸好是在切换前一天发现,不是当天。

有点乱的结尾

写这些有点不好意思。我工作不算特别短了,可数据库这种基础设施还是靠搜索和 AI 现学现卖。圈子里好多人已经能随手写迁移脚本、调存储参数,我还在为权限这档子事卡住。

有时候刷到那种全栈从入门到精通的帖子会有点慌,觉得自己是不是太慢了。前两天我跟一个同样写前端的姐妹聊起这事儿,她说她第一次独立备份也翻过车,我居然松了口气。

做我们这行,女生本来就没那么多,半夜对着报错抓瞎的时候,更容易觉得自己是不是不适合吃这碗饭。但每次跟人一聊,发现大家其实都翻过车,那种孤单感就淡了点。

技术这东西,踩过的坑才真正长在自己身上。权限这个坑,我大概这辈子都忘不了。如果你也是前端、也被后端这些运维的活儿绊过,咱们评论区聊聊,我挺想知道你们都踩过什么,互相壮壮胆。