[Docker 時代的資料庫維護] 別再手動換版!用 bash 腳本搞定 MariaDB 跨版本升級痛點

在維護微服務或個人專案的容器化環境時,MariaDB 絕對是許多工程師的首選資料庫。然而,當隨著時間推進,伺服器上的 MariaDB 需要進行大版本升級(例如從 10.5 跨到 10.11 LTS 甚至 11.4)時,你是否也曾遭遇過資料庫啟動失敗、Schema 毀損,甚至是跨版本跳太快導致 mariadb-upgrade 報錯的噩夢?

今天這篇文章,我們就來聊聊 MariaDB 跨版本升級常見的痛點,並分享一套我寫好的自動化 Bash 腳本 mariadb-upgrade.sh,讓你透過容器化環境實現「無痛、自動化且具備備份防護」的升級流程!

為什麼 MariaDB 版號升級這麼難搞?

在容器化(Docker / Docker Compose)環境下,新手最常犯的錯誤就是直接把 Compose 檔裡面的 image: mariadb:10.5 改成 image: mariadb:11.4 然後執行 docker compose up -d。結果往往是 MariaDB 容器不斷崩潰重啟(CrashLoopBackOff)。

這背後主要有三大痛點:

痛點 1:無法「跨太多大版本」直接升級

MariaDB 的底層 Data Directory(預設位於 /var/lib/mysql)包含許多系統表單與引擎內部結構。官方社群與實務經驗強烈建議:升級時應循序漸進(Gradual Upgrade)。例如從 10.5 升到 11.4,最安全的做法是依序經歷 10.510.610.1111.4。如果直接跳版,極易發生非預期的資料格式衝突。

痛點 2:手動啟動臨時容器與執行 mariadb-upgrade 流程繁瑣

每次跨版本升級,你都需要:

  1. 停止生產環境容器。
  2. 開啟指定舊版本的臨時容器,掛載 Data Volume。
  3. 進入容器執行 mariadb-upgrade -u root -p 升級內部 Schema。
  4. 清理並關閉臨時容器。
  5. 重複以上步驟,切換到下一個目標版本。

這是一套極度耗時且容易因人為失誤(如忘記清理容器或傳錯參數)造成事故的流程。

痛點 3:缺乏升級前的防禦性備份

在升級前「手動壓縮備份 Data Directory」非常重要。許多工程師為了省時間跳過備份,萬一升級途中斷電或程序崩潰,原本的 Data Volume 就會變成不可讀的垃圾,只能從備份還原(如果你有的話)。

自動化救援神兵:mariadb-upgrade.sh

為了徹底解決上述繁瑣流程,我撰寫了一套自動化 Bash 工具 mariadb-upgrade.sh。這個腳本主要結合了 Docker 容器化運算與自動化階段升級機制,讓原本需要花半小時人工盯盤的流程,縮短為一行指令!

腳本核心特色

  • 自動打成 .tar.gz 壓檔備份:升級前自動隔離檔案並建立全量備份。
  • 支援多重指定 -u(漸進式升級):依照傳入的版號順序,自動輪流起臨時容器完成關聯升級。
  • 完全隔離與自動清理:使用獨立的臨時容器名稱,完成後自動清除不留垃圾。

完整 Bash 腳本原始碼 (Script Source Code)

你可以直接複製以下程式碼並儲存為 mariadb-upgrade.sh,接著給予執行權限即可使用:

實作與範例使用

我們直接來看看 mariadb-upgrade.sh 的指令用法與參數規格:

Bash

Auto upgrade MariaDB data directory across target versions.

Usage:
  mariadb-upgrade.sh [flags]

Flags:
  -b, --backup FILE        Create a .tar.gz backup archive before performing upgrades.
  -c, --container NAME     Temporary Docker container name for upgrade (default: mariadb_upgrade_container).
  -d, --data PATH          MariaDB data directory path (default: /var/lib/mysql).
  -p, --password PASS      Root password for the MariaDB database (if configured).
  -u, --upgrade VER        Specify target version to upgrade to (can be used multiple times).
  -h, --help               Help for mariadb-upgrade.sh

情境範例 1:升級前的資料安全備份

如果你只是想在執行任何危險操作前,先為 Data Directory 做一次完整的打包備份:

Bash

mariadb-upgrade.sh -b mysql_backup -d /var/lib/mysql

關鍵說明:這會自動把 /var/lib/mysql 資料打包成 mysql_backup.tar.gz,方便後續還原。

情境範例 2:跨多個 LTS 版本漸進式自動升級

假設你的 MariaDB Data Directory 目前停留在 10.5 版,目標是升級到全新的 11.4,最佳實踐是依序過渡 10.610.11。你可以直接傳入多個 -u 參數:

Bash

mariadb-upgrade.sh \
  -b mysql_backup_before_11_4 \
  -d /var/lib/mysql \
  -p "my_secret_pass" \
  -c mariadb_upgrade_worker \
  -u 10.6 \
  -u 10.11 \
  -u 11.4

腳本內部自動化的運作邏輯

  1. 備份階段:先確認路徑權限,並將 /var/lib/mysql 打包至 mysql_backup_before_11_4.tar.gz
  2. 第一階段升級 (10.6):啟動 mariadb:10.6 臨時容器,掛載資料路徑,等待資料庫 Ready 後自動執行 mariadb-upgrade 檢查並修復 Schema,完成後關閉並移除容器。
  3. 第二階段升級 (10.11):接著自動以 mariadb:10.11 重複上述步驟。
  4. 最後階段升級 (11.4):順利升級至 11.4 結構。升級完成!

常見坑點與 Troubleshooting

在使用本腳本或進行 MariaDB 升級時,建議注意以下幾點:

  1. 務必先停止正在讀寫該 Data Directory 的原容器
    • 坑點:若原本的 MariaDB 容器仍在運行中,多個容器同時存取同一份 Data Volume 會造成 InnoDB 資料頁損毀。
    • 解決方案:執行腳本前,請先執行 docker compose downdocker stop <your-mariadb-container>
  2. 記憶體與權限問題
    • 坑點:升級過程中臨時容器需要對 /var/lib/mysql 寫入新結構,若檔名權限(Chown)錯亂會導致啟動失敗。
    • 解決方案:確保執行腳本的使用者擁有讀寫資料目錄與執行 docker 的權限(如 sudo 權限)。
  3. 版本選擇不可逆
    • 坑點:MariaDB 的 Data Directory 無法降級(Downgrade)。一旦你升級到 11.4,就無法直接拿這份資料放回 10.6 的容器。
    • 解決方案:幸好腳本預設要求 -b 參數,若升級後應用程式有相容性問題,可以立刻拿 .tar.gz 解壓縮還原至升級前的狀態。

總結與 Takeaways

資料庫升級往往是維運中最讓人膽戰心驚的一環,但只要建立良好的自動化機制,就能把風險降至最低:

  • 防禦第一:永遠在升級前進行物理備份(.tar.gz 或快照)。
  • 循序漸進:跨大版本升級時,切忌貪快跳版,應依序經歷中介 LTS 版本。
  • 工具化維運:透過 mariadb-upgrade.sh 這種 Shell 腳本自動處理容器啟閉與修復,避免人工踩雷。

這套腳本非常適合整合進 CI/CD 或系統維護 Cronjob 中。如果你在維運 MariaDB 時也遇到過升級痛點,不妨嘗試看看這套腳本!

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *