Hold Off on Litestream 0.5.0

Michael Lynch

先別急著升級到 Litestream 0.5.0

Litestream 是一個能即時將 SQLite 資料庫備份到雲端儲存空間的開源工具。我很喜歡它,也在我的所有專案中使用它。

Litestream 由 Fly.io 持有,他們為了推動名為 LiteFS 的替代專案,暫停了 Litestream 將近兩年的開發。兩週前,Litestream 的創建者兼主要開發者 Ben Johnson(班·強森)宣布他們將重心轉回 Litestream,並剛發布了新版本 0.5.0

我試用了 Litestream 0.5.0,但我建議其他 Litestream 使用者先等下一個版本並經過更廣泛的測試後,再部署到正式環境。我在遷移到新版 Litestream 的過程中遇到了不少波折。

更新:Litestream 0.5.1 現已推出,修復了我遇到的大部分(但非全部)問題。

更新 2(2025-10-17):Litestream 0.5.2 修復了我遇到的所有錯誤,因此我計畫將其部署到我那些以 SQLite 為基礎的應用程式中。

註記:我並不是在抱怨 Litestream。我很喜歡 Litestream,也很樂見開發工作重新啟動。我只是希望能幫助其他 Litestream 使用者避免遇到我碰到的相同錯誤。

預期的遷移工作

從舊版 Litestream 升級到 v0.5.0 及以上版本,有兩項預期內的必要工作:

  1. 備份格式已經變更,因此 Litestream 0.5.0 無法從舊版 Litestream 建立的備份中還原。
  2. litestream.yml 設定檔格式略有變更。過去有一個名為 replicas 的陣列欄位,但在 0.5.0 中已改為名為 replica(單數)的字典。

Litestream 已發布了一份實用的遷移指南,其中有更詳細的說明。

Litestream 0.5.0 的其中一項好處是,現在有了官方的 Litestream Docker 映像檔。(編輯:讀者 placardloop 指出該 Docker 映像檔並非新推出;只是我之前沒注意到。)我以前所有的 Docker 容器都需要大量樣板程式碼來下載正確版本的 Litestream並使其可在容器中使用,但現在只需一行 Dockerfile 即可:

COPY --from=litestream/litestream:0.5.0 /usr/local/bin/litestream /app/litestream

我對 Litestream 0.5.0 的測試遷移

為了測試 Litestream 0.5.0,我試著將它部署到我的專案 What Got Done 上。這個專案很適合用來測試,原因如下:

  1. 我已經宣布將關閉這項服務,因此使用者已停止使用該網站。
  2. 伺服器一直因為Litestream 0.3.13 中的一個錯誤而故障,而該錯誤已在 0.5.0 中修復。

上傳至 Backblaze 後端的功能失效了

為了開始遷移,我使用 Litestream 0.3.13 下載了最新一份資料備份,然後嘗試使用 Litestream 0.5.0 以 Litestream 的新格式將其重新上傳至 Backblaze 的雲端儲存空間。但我遇到了這個錯誤:

error" db=store.db replica=s3 error="write ltx file: s3: upload to db/0000/0000000000000001-0000000000000001.ltx: operation error S3: PutObject, resolve auth scheme: resolve endpoint: endpoint rule error, Custom endpoint `s3.us-west-002.backblazeb2.com` was not a valid URI"

相同的 replica 定義在先前的版本中是可行的,所以我感到有點困惑。

access-key-id: ${LITESTREAM_ACCESS_KEY_ID}
secret-access-key: ${LITESTREAM_SECRET_ACCESS_KEY}
dbs:
  - path: ${DB_PATH}
    replica:
      url: s3://${LITESTREAM_BUCKET}/db
      endpoint: ${LITESTREAM_ENDPOINT}

我嘗試了幾種指定 Backblaze S3 端點的替代方式,但 Litestream 在嘗試備份之前就全數以設定錯誤為由拒絕。我的這份設定是 Litestream 唯一接受為有效設定的版本,但它卻無法完成備份。

我提交了 Backblaze replica 出現「Custom endpoint … was not a valid URI」錯誤 #789,Litestream 開發者 Cory LaNou(柯瑞·拉諾)在隔天修復了這個問題

既然我已經能夠以 Litestream 的新格式將資料上傳至 Backblaze,我就可以繼續將 Litestream 0.5.0 整合至 What Got Done 了。

-if-replica-exists 消失了

我將Litestream 0.5.0 部署到 What Got Done,但伺服器啟動失敗並顯示此錯誤:

flag provided but not defined: -if-replica-exists

我查看了指令說明文件,其中顯示 -if-replica-exists 仍受支援:

$ litestream restore -help | grep if-replica-exists --after-context=1
        -if-replica-exists
            Returns exit code of 0 if no backups found.

結果發現該旗標是被誤刪了,並將在 0.5.1 中恢復

還原失敗,顯示 transaction not available

儘管失去了 -if-replica-exists,我仍從啟動指令稿中移除了它。但接著我的伺服器又因新的錯誤而無法啟動:

level=ERROR msg="failed to run" error="cannot calc restore plan: transaction not available"

這結果與這個尚未解決的 Litestream 問題相符,其嚴重程度令人擔憂,標示為「CRITICAL - Complete Data Loss」:

Litestream 不再自動建立目錄

到了這個階段,我只想嘗試任何能讓服務重新上線的方法,因此我在 Docker 容器中從原始碼建置並執行了最新、最前沿版本的 Litestream。

幸好,最新版本繞過了我遇到的 transaction not available 問題,Litestream 在流程中又往前推進了一步!

不幸的是,仍有一個錯誤需要克服:

level=ERROR msg="failed to run" error="create temp database path: open /app/data/store.db.tmp: no such file or directory"

這個錯誤其實相當單純,讓我對發生了什麼事有了相當明確的推測。在先前的 Litestream 版本中,如果我指示它將 SQLite 資料庫還原到 /app/data/store.db,且 /app/data 路徑不存在,Litestream 會在寫入檔案前嘗試建立該目錄。

我檢查了原始碼,發現這個程式流程中的資料夾建立邏輯已經消失,但修復起來相當簡單,因此我提交了一個修正:

成功!

套用了最終 mkdir 修正的我的 Litestream fork,讓 What Got Done 重新上線並正常運作了!

心得

我透過一個預先發布的 fork 讓 Litestream 0.5.x 得以運作,但我打算再等一、兩個版本後再將其部署到我的其他專案。0.5.0 的變更似乎比 Litestream 團隊預期的更具破壞性,而且他們仍在處理一些嚴重的錯誤:

還有其他幾個嚴重的錯誤,他們已在開發版本中修復,但尚未包含在正式版本中更新:這些問題現已在 0.5.1 中修復):

註記:再次強調,這並非對 Litestream 的批評。Streaming replication(串流複寫)要正確實作非常困難,而他們的成果遠比我自己能做出的更加穩健。我很感謝 Litestream 團隊能迅速回應錯誤回報並快速修復問題。

原文由 Michael Lynch 發布

本文章由 muse-spark-1.2-contributor 進行翻譯