iT邦幫忙

2026 iThome 鐵人賽

DAY 26
0
Kubernetes

從零到一:使用 K8S + GitOps 打造異構技術棧的資料分析平台系列 第 26

[Day 26] 資料庫演進:在 K8S 上使用 Liquibase 管理 DB 遷移 —— 自動化更新資料庫 Schema,告別手動執行 SQL 的風險。

  • 分享至 

  • xImage
  •  

Day 26: 資料庫演進:在 K8S 上使用 Liquibase 管理 DB 遷移

自動化更新資料庫 Schema,告別手動執行 SQL 的風險。

1. 傳統 DB 變更的問題

新功能需要改資料庫 Schema 時,傳統做法是有人手動連進資料庫執行 ALTER TABLE。這種做法有兩個明確的風險:一是容易忘記執行、或在錯誤的環境執行;二是「程式碼版本」與「資料庫版本」是分離的兩套狀態,沒有機制保證兩者對得上。新版本的程式碼一啟動,如果資料庫還是舊 Schema,直接崩潰。

2. Liquibase 的做法

Liquibase 把 Schema 變更寫成版本化的 changeset,記錄在程式碼庫裡(services/user-service/src/main/resources/db/changelog/),跟應用程式碼一起進版控。應用程式啟動時,Liquibase 會自動比對資料庫目前的狀態與 changelog,把還沒套用的 changeset 依序執行。

<changeSet id="20260519-baseline-schema" author="wafer-bi">
    <preConditions onFail="MARK_RAN">
        <not><tableExists tableName="auth_groups"/></not>
    </preConditions>
    <createTable tableName="auth_groups">
        <column name="id" type="SERIAL"><constraints primaryKey="true" nullable="false"/></column>
        <column name="name" type="VARCHAR(255)"><constraints unique="true" nullable="false"/></column>
    </createTable>
    ...
</changeSet>

preConditions 是關鍵:每個 changeset 執行前會先檢查前提條件(例如「這個 table 還不存在」),已經套用過的 changeset 不會重複執行。Liquibase 會在資料庫裡維護一張 DATABASECHANGELOG 表,記錄每個 changeset 的 id、作者、執行時間——這張表本身就是遷移歷史的真相來源。

3. 實測:新增一個真實的 Schema 變更

直接示範一次完整流程。新增 002-add-last-login.xml

<changeSet id="20260721-add-last-login" author="carrot">
    <preConditions onFail="MARK_RAN">
        <not><columnExists tableName="users" columnName="last_login_at"/></not>
    </preConditions>
    <addColumn tableName="users">
        <column name="last_login_at" type="TIMESTAMP"/>
    </addColumn>
</changeSet>

加進 db.changelog-master.xml<include> 清單,重新 build image、kubectl rollout restart deployment/user-service——過程中沒有連進資料庫下任何一行 SQL:

https://ithelp.ithome.com.tw/upload/images/20260828/2018254921Ve5IERvp.png

▲ Liquibase 自動遷移:rollout 前後直接對比 users table 的欄位變化,DATABASECHANGELOG 記錄新 changeset 的真實執行時間

rollout 前 users table 沒有 last_login_at;rollout 後這個欄位自動出現,且 DATABASECHANGELOG 裡多了一筆對應的紀錄,時間戳記是 Pod 啟動的當下——這證明遷移是應用程式啟動時自動跑的,不是我手動介入的結果。

4. Kubernetes 環境下的意義

這個機制在 K8S 場景下特別有價值:Pod 隨時可能因為 HPA 擴容、滾動更新、或節點遷移而重新調度到不同節點、甚至產生新的 Pod。只要 image 裡帶著正確版本的 changelog,Schema 遷移就會在任何一個新啟動的 Pod 上自動核對並執行——不需要額外寫一支「遷移用的 Job」或請人記得手動操作。

多副本同時啟動時 Liquibase 有內建的鎖機制(DATABASECHANGELOGLOCK 表)避免多個 Pod 同時搶著跑遷移造成衝突,只有取得鎖的那個 Pod 會實際執行 changeset,其餘的等待鎖釋放後發現版本已經一致,直接跳過。

5. 小結

Schema 變更跟應用程式碼綁定在同一次發布裡,遷移歷史有真實紀錄可查、可追溯。明天討論另一個層面的風險管理:如果整個叢集或資料真的損毀了,要怎麼復原。


上一篇
[Day 25] 彈性伸縮:根據負載自動擴展 (HPA) 的實戰配置 —— 讓叢集在高峰期自動增加副本,離峰期自動縮減省錢。
下一篇
[Day 27] 災難恢復:K8S 叢集備份與數據復原策略 —— 面對最壞的情況,我們如何快速重建整套 BI 平台。
系列文
從零到一:使用 K8S + GitOps 打造異構技術棧的資料分析平台30
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言