先別急著升級到 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 及以上版本,有兩項預期內的必要工作:
- 備份格式已經變更,因此 Litestream 0.5.0 無法從舊版 Litestream 建立的備份中還原。
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 上。這個專案很適合用來測試,原因如下:
- 我已經宣布將關閉這項服務,因此使用者已停止使用該網站。
- 伺服器一直因為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 團隊預期的更具破壞性,而且他們仍在處理一些嚴重的錯誤:
- CRITICAL:Litestream 停機期間 checkpoint 後還原失敗,出現「nonsequential page numbers」錯誤 #752
- 本地 LTX Level 0 檔案永遠不會被壓縮/移除 #784
還有其他幾個嚴重的錯誤,他們已在開發版本中修復,但尚未包含在正式版本中(更新:這些問題現已在 0.5.1 中修復):
註記:再次強調,這並非對 Litestream 的批評。Streaming replication(串流複寫)要正確實作非常困難,而他們的成果遠比我自己能做出的更加穩健。我很感謝 Litestream 團隊能迅速回應錯誤回報並快速修復問題。
隨機一篇部落格