管理生产数据库与内容
正确使用基线和增量迁移,同步文档内容,并为生产数据保留可恢复的记录。
生产发布既包含 Worker 代码,也包含数据库结构和 KV 中的文档内容。三者分别更新,不能把“Worker 上传成功”理解为所有数据都已准备好。
首次部署和后续更新已经包含数据库迁移与 KV 同步。正常发布时使用部署脚本即可,本文中的独立命令主要用于提前检查、定位问题和恢复中断的步骤。
一、确认操作的是哪个数据库
模板使用两份 D1:
| 绑定 | 基线文件 | 基线识别表 | 用途 |
|---|---|---|---|
DB | schema/db-init.sql | saas_user | 主业务数据 |
ANALYTICS_DB | schema/analytics-init.sql | analytics_session | 访问统计数据 |
远程目标由 wrangler.jsonc 中的账户和绑定 ID 决定。操作前先核对这两个绑定,不要只看数据库名称相似就认为选对了。
本地与远程命令明确分开:
npm run db:migrate:local
npm run db:migrate:remote上面两条是不同环境的入口,不要求每次连续运行。开发时先在本地验证迁移,生产发布通常交给 deploy:update 执行远程迁移。
二、迁移脚本怎样处理现有数据
db:migrate 会分别处理主库和统计库:
- 数据库没有用户表时,执行对应基线文件。
- 已有用户表且存在基线识别表时,保留现有表,继续应用增量迁移。
- 数据库不为空,却缺少基线识别表时,停止并提示检查。
- 应用
schema/migrations中属于该数据库的待执行迁移。
基线识别表只用于判断数据库是否像一个已初始化的项目,不代表脚本已经逐字段验证了整个 Schema。旧版数据库或手工修改过的数据库,应先审查实际结构,再准备迁移。
如果错误信息提到 db:reset:remote,也不要把它当成普通修复步骤。Reset 会重建数据结构,已有用户、订单或业务记录的生产库不应通过重置解决迁移问题。
三、为业务变化编写增量迁移
新增业务表的完整示例见从业务表到用户数据 API。部署时重点检查迁移文件是否跟随代码一起提交。
文件放在 schema/migrations/,命名规则为四位编号、目标库和说明,例如:
schema/migrations/
├── 0001-db-saved-links.sql
└── 0002-analytics-add-source-field.sql这些名称只演示规则,不要求创建第二个文件。主库文件使用 -db-,统计库使用 -analytics-,其余说明使用小写字母、数字和连字符。
不要再沿用旧文档中的 schema/init.sql、payment.sql、event-execution.sql 等分散初始化命令。当前主库基线已由 schema/db-init.sql 统一维护。
新增迁移时遵循三个原则:
- 先在本地执行并验证业务,不能只确认 SQL 没有语法错误。
- 已经执行过的迁移不再改写,后续修正放进新编号文件,保留可追踪的历史。
- 不要把同一条建表语句同时放进基线和迁移,否则空库执行基线后,应用迁移时会重复建表。
可以通过以下只读命令查看远程待执行迁移:
npx wrangler d1 migrations list DB --remote
npx wrangler d1 migrations list ANALYTICS_DB --remote四、迁移需要兼容仍在运行的旧版本
deploy:update 的顺序是先验证代码,再迁移远程数据库,随后发布新 Worker。这意味着迁移执行期间,旧 Worker 仍可能接收请求。
例如要把业务字段从 title 改为 name,不要在同一次发布中先删除 title,再期待新代码马上接管。可以分阶段增加新字段、迁移数据、切换读写,确认旧代码不再使用后再清理旧字段。
普通新增表也需要考虑发布失败后的状态:数据库可能已经有新表,但 Worker 仍是旧版本。只要迁移没有破坏旧代码所依赖的结构,就更容易修复后继续发布。
两份 D1 也不是一个跨库事务。如果主库迁移成功而统计库失败,先检查两个库分别执行到了哪里,再处理失败项,不要假设脚本会自动撤销前一个库的变化。
五、在结构变更前准备恢复记录
有真实数据后,发布记录应包含迁移文件、执行时间、数据库目标和可用恢复点。Cloudflare D1 提供 Time Travel,可以获取数据库恢复书签,具体保留范围和恢复方式见官方说明。
npx wrangler d1 time-travel info DB
npx wrangler d1 time-travel info ANALYTICS_DB需要单独保存 SQL 导出时,可以执行:
npx wrangler d1 export DB --remote --output=./db-before-release.sql
npx wrangler d1 export ANALYTICS_DB --remote --output=./analytics-before-release.sql执行前确认文件名不会覆盖需要保留的旧备份。导出文件可能包含账户和业务数据,应移到受保护的备份位置,不提交 Git,也不放进 public。
恢复数据库会改变实际业务状态。恢复前先确认哪些后续写入会丢失,以及订单、队列任务和外部支付平台是否需要重新对账。仅有一份导出文件,还不等于已经验证过恢复流程。
D1 备份也不会包含 R2 文件、KV 内容和 Durable Objects 状态,这些资源应按各自用途制定保存与恢复方式。
六、同步文档和博客内容
本地文章经过编译后,生产内容会同步到 MAIN_KV。因此只部署 Worker,可能出现页面代码已更新,但正文、侧边栏或文章列表仍是旧内容的情况。
当前项目提供:
npm run gen:search-index
npm run kv:sync:local
npm run kv:sync:remotegen:search-index 编译内容集合并生成搜索索引,不上传远程 KV。两个同步命令分别作用于本地和远程 KV,执行前确认需要更新的是哪一个环境。
KV 同步会更新当前内容,并清理对应内容前缀下已经不在本地集合中的旧键。删除文章、改路径或减少语言时,也要审查这次同步的变化,不要把同步理解为永远只追加。
通常使用 deploy:update 完成发布即可,它包含构建和远程 KV 同步。单独执行 KV 同步适合修复“代码已发布、内容同步中断”的情况,正文、路径或搜索内容发生变化时仍要确认静态搜索索引与内容属于同一版本。
七、检查结果
迁移后可以用只读查询确认基线表存在:
npx wrangler d1 execute DB --remote --command="SELECT name FROM sqlite_schema WHERE type = 'table' AND name = 'saas_user';"
npx wrangler d1 execute ANALYTICS_DB --remote --command="SELECT name FROM sqlite_schema WHERE type = 'table' AND name = 'analytics_session';"表存在只说明基础结构可见,继续验证本次受影响的真实业务。例如新增收藏链接表后,应创建一条记录再读取,不能只检查表名。
内容同步后,打开正式站点的文档入口、其中一篇正文和搜索结果,确认语言、侧边栏与正文一致。若首页正常而文档 404,优先检查内容开关、MAIN_KV 绑定和同步输出。
下一步:首次部署与后续更新。