我有幾個 n8n 工作流程可以運行 10–30 分鐘,它們都使用相同的 PostgreSQL 資料表。
我需要變更資料庫結構描述,但在遷移發生時,某些較舊的工作流程執行可能仍在使用舊結構。
例如,我可能會重新命名或移除一個欄位:
ALTER TABLE orders
DROP COLUMN legacy_status;
在遷移前啟動的工作流程仍可能期望該欄位存在。
你會暫時保留舊欄位、先部署新工作流程、等待現有執行完成,然後再移除舊結構描述嗎?
或者對於長時間運行的 n8n 工作流程,有更好的遷移策略嗎?
描述問題/錯誤/問題
錯誤訊息是什麼(如果有的話)?
請分享你的工作流程
(選取畫布上的節點,並使用鍵盤快捷鍵 CMD+C/CTRL+C 和 CMD+V/CTRL+V 複製和貼上工作流程。)
分享最後一個節點傳回的輸出
n8n 設定的相關資訊
- n8n 版本:
- 資料庫(預設值:SQLite):
- n8n EXECUTIONS_PROCESS 設定(預設值:own, main):
- 執行 n8n 的方式(Docker、npm、n8n cloud、桌面應用程式):
- 作業系統:
Hi @Roseline 最安全的做法是讓資料庫在一段時間內同時支援兩個版本。
例如,與其立即刪除 legacy_status,我會先添加替代方案:
ALTER TABLE orders
ADD COLUMN status_v2 TEXT;
然後部署更新的工作流程,這樣新的執行會使用 status_v2,而較舊的執行仍然可以使用 legacy_status。
添加新欄位
部署新工作流程
舊版本和新版本安全執行
等待舊執行完成
遷移剩餘資料
移除舊欄位
對於較大的更改,我也會追蹤結構/工作流程版本:
ALTER TABLE orders
ADD COLUMN schema_version INTEGER NOT NULL DEFAULT 1;
這在排除由不同工作流程版本建立的記錄時很有用。
同時避免只依賴固定的等待期間。在移除舊欄位之前,確認沒有主動執行或程序仍在依賴它。
主要理念是不要讓資料遷移和工作流程部署成為單一的重大更改。首先讓結構向後相容,將工作流程遷移過去、驗證所有內容都在使用新結構,然後才清理舊欄位。
是的,保留舊列直到沒有任何東西能使用它為止。包括暫停在 Wait 節點的執行和使用舊工作流的重試,不只是目前正在運行的執行。如果你只是移除 legacy_status,就不需要替換列。
對於重命名,上面序列中要改變的一點是:在切換讀取之前,先填充新列並保持寫入同步。否則新工作流可能會讀取空值或過時的值。
只在新工作流中更新兩列無法涵蓋仍在寫入 legacy_status 的舊執行。你可以暫時保留該列作為寫入來源,並使用 PostgreSQL 觸發器來同步替換列。一旦舊執行和回滾窗口被清除,就切換寫入,然後移除舊列和臨時同步。
社群成員 @Anshul_Namdev 和 @Emmas 都提供了正確的業界標準建議。在 n8n 中,活躍或暫停的執行(例如在等待節點處的執行)會在執行過程中保留其原始配置。在執行過程中更改資料庫結構描述會導致這些長時間執行的任務失敗。
以下是按簡潔順序撰寫的綜合逐步遷移策略:
步驟 1:新增欄位而不造成重大變更。執行 ALTER TABLE 命令以將新欄位新增至您的資料庫,同時完全保持舊欄位不變。
步驟 2:設定資料庫觸發器以進行同步。建立 PostgreSQL 觸發器以自動將寫入舊欄位的任何資料複製到新欄位。這可保護仍在執行且寫入舊結構描述的長時間執行工作流程。
步驟 3:回填現有資料。執行指令碼,將所有現有記錄的歷史資料從舊欄位複製到新欄位。
步驟 4:部署您更新的 n8n 工作流程。更新並發佈您的新 n8n 工作流程,以便所有新執行原生地目標指向新欄位。
步驟 5:監視並等待活躍執行完成。檢查 n8n 執行面板。等待所有較舊的執行、重試和暫停的等待節點完全完成執行。
步驟 6:安全地移除舊欄位。刪除暫時資料庫觸發器,並在沒有流量使用舊欄位後,從資料庫結構描述中刪除該欄位。