2025 年 Airflow 峰會將於 10 月 07 日至 09 日舉行。立即註冊享早鳥票優惠!

將 Airflow® 升級到新版本

為何需要升級

較新的 Airflow 版本可能包含資料庫遷移,因此您必須執行 airflow db migrate 來使用您正在升級到的 Airflow 版本中的模式更改遷移資料庫。別擔心,即使沒有遷移要執行,執行此命令也是安全的。

Airflow 版本 x 和 y 之間有哪些變化?

發行說明 列出了任何給定 Airflow 版本中包含的更改。

升級準備 - 備份資料庫

強烈建議在進行任何遷移之前備份元資料資料庫。如果您的資料庫沒有“熱備份”能力,則應在關閉 Airflow 例項後進行備份,以確保資料庫備份的一致性。如果您沒有進行備份而遷移失敗,可能會陷入半遷移狀態,此時從備份恢復資料庫並重復遷移可能是唯一簡便的出路。例如,這可能是由於遷移過程中您的 CLI 與資料庫之間的網路連線中斷造成的,因此進行備份是避免此類問題的重要預防措施。

何時需要升級

如果您有基於 virtualenv 或 Docker 容器的自定義部署,通常需要在升級過程中手動執行資料庫遷移。

在某些情況下,升級會自動進行——這取決於您的部署中是否將升級作為安裝後操作內建。例如,當您使用啟用了升級後鉤子 (post-upgrade hooks) 的 Apache Airflow Helm Chart 時,資料庫升級在新軟體安裝完成後會自動進行。類似地,所有 Airflow 即服務 (Airflow-As-A-Service) 解決方案在您透過其使用者介面選擇升級 Airflow 時,也會自動為您執行升級。

如何升級

重新安裝 Apache Airflow®,指定所需的新版本。

要升級引導啟動的本地例項,您可以在重新執行安裝命令之前將 AIRFLOW_VERSION 環境變數設定為目標版本。請按補丁版本遞增升級:例如,如果要從版本 2.8.2 升級到 2.8.4,請先升級到 2.8.3。有關更詳細的指導,請參閱快速入門

要升級 PyPI 包,請在您的環境中重新執行 pip install 命令,使用所需版本作為約束。有關更詳細的指導,請參閱從 PyPI 安裝

要手動遷移資料庫,您應在您的環境中執行 airflow db migrate 命令。它可以在您的虛擬環境中執行,也可以在允許您訪問 Airflow CLI 使用命令列介面 以及資料庫的容器中執行。

離線 SQL 遷移指令碼

如果您想離線執行升級指令碼,可以使用 -s--show-sql-only 標誌來獲取將要執行的 SQL 語句。您還可以使用 --from-version 標誌指定起始 Airflow 版本,並使用 -n--to-version 標誌指定結束 Airflow 版本。此功能從 Airflow 2.0.0 版本起在 Postgres 和 MySQL 中受支援。

Airflow 2.7.0 或更高版本的示例用法

airflow db migrate -s --from-version "2.4.3" -n "2.7.3" airflow db migrate --show-sql-only --from-version "2.4.3" --to-version "2.7.3"

警告

自 Airflow 2.7.0 版本起,airflow db upgrade 已被 airflow db migrate 替換,前者已被棄用。

處理遷移問題

MySQL 資料庫編碼錯誤

如果您使用舊的 Airflow 1.10 作為資料庫,該資料庫最初是手動建立的,或者使用之前版本的 MySQL 建立的,則根據資料庫的原始字元集,您在遷移到較新版本的 Airflow 時可能會遇到問題,並且遷移可能會因奇怪的錯誤(“key size too big”、“missing indexes”等)而失敗。下一章將描述如何手動修復此問題。

為什麼可能會出現這個錯誤?MySQL 8 資料庫推薦的字元集/排序規則分別是 utf8mb4utf8mb4_bin。然而,這在不同版本的 MySQL 中一直在變化,而且您可能自定義建立了使用不同字元集的資料庫。如果您的資料庫是使用舊版本的 Airflow 或 MySQL 建立的,則在建立資料庫時或在遷移過程中,編碼可能就是錯誤的或損壞的。

不幸的是,MySQL 限制了索引鍵的大小,在使用 utf8mb4 時,Airflow 的索引鍵大小可能對於 MySQL 來說太大了。因此,在 Airflow 中,我們強制所有“ID”鍵使用 utf8 字元集(在 MySQL 8 中等同於 utf8mb3)。這限制了索引的大小,以便 MySQL 可以處理它們。

以下是在您嘗試遷移之前可以遵循的修復步驟(但如果您知道自己在做什麼,也可以選擇自己的方式進行)。

熟悉 Airflow 的內部資料庫結構,您可以在資料庫 ERD 模式中找到它,並在資料庫遷移參考中找到遷移列表。

  1. 備份您的資料庫,以便在出錯時可以恢復。

  2. 檢查哪些表需要修復。檢視這些表

SHOW CREATE TABLE task_reschedule;
SHOW CREATE TABLE xcom;
SHOW CREATE TABLE task_fail;
SHOW CREATE TABLE rendered_task_instance_fields;
SHOW CREATE TABLE task_instance;

確保複製輸出。最後一步會用到。您的 dag_idrun_idtask_idkey 列應明確設定為 utf8utf8mb3 字元集,類似於

``task_id`` varchar(250) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,  # correct

``task_id`` varchar(250) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin NOT NULL,  # correct

問題在於,如果您的欄位沒有編碼

``task_id`` varchar(250),  # wrong !!

或僅將排序規則設定為 utf8mb4

``task_id`` varchar(250) COLLATE utf8mb4_unicode_ci DEFAULT NULL,  # wrong !!

或將字元集和排序規則都設定為 utf8mb4

``task_id`` varchar(250) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,  # wrong !!

您需要修復那些字元集/排序規則設定錯誤的欄位。

3. 刪除需要修改的表的外部鍵索引(您不需要刪除所有索引——只需刪除需要修改的那些表的索引)。您需要在最後一步重新建立它們(這就是為什麼需要保留步驟 2 中 SHOW CREATE TABLE 的輸出)。

ALTER TABLE task_reschedule DROP FOREIGN KEY task_reschedule_ti_fkey;
ALTER TABLE xcom DROP FOREIGN KEY xcom_task_instance_fkey;
ALTER TABLE task_fail DROP FOREIGN KEY task_fail_ti_fkey;
ALTER TABLE rendered_task_instance_fields DROP FOREIGN KEY rtif_ti_fkey;

4. 修改您的 ID 欄位以擁有正確的字元集/編碼。只對編碼錯誤的欄位進行修改(這裡列出了您可能需要使用的所有潛在命令)

ALTER TABLE task_instance MODIFY task_id VARCHAR(250) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin;
ALTER TABLE task_reschedule MODIFY task_id VARCHAR(250) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin;

ALTER TABLE rendered_task_instance_fields MODIFY task_id VARCHAR(250) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin;
ALTER TABLE rendered_task_instance_fields MODIFY dag_id VARCHAR(250) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin;

ALTER TABLE task_fail MODIFY task_id VARCHAR(250) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin;
ALTER TABLE task_fail MODIFY dag_id VARCHAR(250) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin;

ALTER TABLE sla_miss MODIFY task_id VARCHAR(250) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin;
ALTER TABLE sla_miss MODIFY dag_id VARCHAR(250) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin;

ALTER TABLE task_map MODIFY task_id VARCHAR(250) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin;
ALTER TABLE task_map MODIFY dag_id VARCHAR(250) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin;
ALTER TABLE task_map MODIFY run_id VARCHAR(250) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin;

ALTER TABLE xcom MODIFY task_id VARCHAR(250) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin;
ALTER TABLE xcom MODIFY dag_id VARCHAR(250) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin;
ALTER TABLE xcom MODIFY run_id VARCHAR(250) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin;
ALTER TABLE xcom MODIFY key VARCHAR(250) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin;
  1. 重新建立在步驟 3 中刪除的外部鍵。

對所有您刪除的索引重複此操作。請注意,根據您擁有的 Airflow 版本,索引可能略有不同(例如 map_index 在 2.3.0 中新增),但如果您保留了步驟 2 中準備好的 SHOW CREATE TABLE 輸出,您將找到正確的 CONSTRAINT_NAMECONSTRAINT 來使用。

# Here you have to copy the statements from SHOW CREATE TABLE output
ALTER TABLE <TABLE> ADD CONSTRAINT `<CONSTRAINT_NAME>` <CONSTRAINT>

這應該能使資料庫達到可以執行到新 Airflow 版本遷移的狀態。

升級後警告

通常您只需要成功執行 airflow db migrate 命令即可完成。然而,在某些情況下,遷移可能會在您的資料庫中發現一些舊的、過時的且可能錯誤的資料,並將其移到單獨的表中。在這種情況下,您可能會在 Webserver UI 中看到關於找到這些資料的警告。

您可能看到的典型訊息

Airflow 在元資料庫的 <原始表> 表中發現不相容的資料,並在資料庫升級遷移期間將其移至 <新表>。請檢查已移動的資料,決定是否需要保留它們,並手動刪除 <新表> 以解除此警告。

當您看到這樣的訊息時,意味著您的一些資料已損壞,您應該檢查它以確定是否要保留或刪除部分資料。最有可能的是這些資料是損壞的,並且是某些 bug 留下的,可以安全刪除——因為這些資料無論如何都不會在 Airflow 中可見或有用。但是,如果您出於審計或歷史原因有特殊需要,可以選擇將其儲存在其他地方。除非您有特定理由保留資料,否則最有可能的最佳選擇是刪除它。

您可以透過多種方式檢查和刪除資料——如果您使用自己的工具(通常是顯示資料庫物件的圖形工具)直接訪問資料庫,則可以使用這些工具刪除、重新命名該表或將其移動到另一個數據庫。如果您沒有此類工具,可以使用 airflow db shell 命令——這會將您帶入資料庫的資料庫 shell 工具,您將能夠檢查和刪除該表。

如何使用 Kubernetes 刪除表

  1. 進入任何 Airflow Pods(Webserver 或 Scheduler):kubectl exec -it <your-webserver-pod> python

  2. 在 Python shell 中執行以下命令

from airflow.settings import Session

session = Session()
session.execute("DROP TABLE _airflow_moved__2_2__task_instance")
session.commit()

請在示例中將 <table> 替換為警告訊息中顯示的實際表名。

檢查表

SELECT * FROM <table>;

刪除表

DROP TABLE <table>;

遷移最佳實踐

根據資料庫的大小和實際遷移操作,遷移可能需要相當長的時間,因此如果您有較長的歷史記錄和龐大的資料庫,建議先複製資料庫並執行一次測試遷移,以評估遷移所需的時間。通常,“主要”升級可能需要更長時間,因為新增新功能有時需要重構資料庫。

此條目有幫助嗎?