管理正式環境資料庫與內容

正確使用基準結構與增量遷移、同步文件內容,並為正式環境資料保留可還原的紀錄。

正式發布不只包含 Worker 程式碼,也包含資料庫結構和 KV 中的文件內容。三者分別更新,不能將「Worker 上傳成功」理解為所有資料都已準備完成。

首次部署和後續更新已包含資料庫遷移與 KV 同步。一般發布時使用部署指令碼即可,本文中的獨立指令主要用於事前檢查、找出問題,以及接續中斷的步驟。

一、確認操作的是哪個資料庫

範本使用兩個 D1 資料庫:

繫結基準檔案基準識別資料表用途
DBschema/db-init.sqlsaas_user主要業務資料
ANALYTICS_DBschema/analytics-init.sqlanalytics_session流量統計資料

遠端目標由 wrangler.jsonc 中的帳戶和繫結 ID 決定。操作前請先核對這兩個繫結,不要只因為資料庫名稱相似,就認為選對了目標。

本機與遠端指令有明確區分:

npm run db:migrate:local
npm run db:migrate:remote

上面兩個指令是不同環境的入口,不需要每次連續執行。開發時先在本機驗證遷移,正式發布通常交由 deploy:update 執行遠端遷移。

二、遷移指令碼如何處理既有資料

db:migrate 會分別處理主資料庫和統計資料庫:

  1. 資料庫沒有使用者建立的資料表時,執行對應的基準檔案。
  2. 已有使用者建立的資料表,且存在基準識別資料表時,保留既有資料表,繼續套用增量遷移。
  3. 資料庫不是空的,卻缺少基準識別資料表時,停止並提示檢查。
  4. 套用 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:remote

gen: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 繫結和同步輸出。

下一步:首次部署與後續更新。