機器的設定檔損毀時:舊版本存放在哪裡

每台機器都有一個小型文字檔。檔案損毀時只影響那台機器,而舊版本存放在兩個大多數人從不查看的地方。

AtlasPVE ·

本條目涵蓋以下問題

  • proxmox 修改 conf 後 vm 無法啟動
  • proxmox vm 從清單消失
  • proxmox 設定檔損毀
  • proxmox 還原 vm 設定
  • proxmox 停電後設定遺失

每台虛擬機器與每個容器都有一個小型文字檔。核心數、記憶體大小、使用哪顆磁碟、連接哪個網路:全都寫在裡面,而且是人可以直接閱讀的形式。

這個檔案損毀時會發生什麼事,舊版本在哪裡,手動編輯時又該注意什麼?

先說好消息:損毀的檔案只影響它自己的機器

每台機器各有一個獨立的檔案。其中一個檔案打錯字,不會讓面板當掉,不會讓其他機器停止,也不會影響伺服器。

常見的症狀是:那台機器不再出現在清單中,或無法啟動。其他一切照常運作。慌張之前先了解這一點,因為第一印象通常是系統壞了,但事實並非如此。

損毀的原因

手動編輯。這是最常見的原因。一個逗號、一個引號、一個打錯的鍵名。

在機器執行中編輯。即使檔案沒有損毀,也會發生意料之外的事:以為變更已立即生效,實際上要到下次啟動才生效。或者系統自行更新了檔案,覆蓋掉手動寫入的內容。

寫入中途中斷。停電、磁碟寫滿、處理程序被終止。檔案只寫了一半。

第三種最難察覺,值得另立一節說明。

寫了一半的檔案比完全沒有檔案更糟

檔案不存在是一種一目了然的狀態。程式去找,找不到,回報不存在,然後以預設值繼續執行。這種狀態很容易處理。

寫了一半的檔案則不同。它看起來就像一個檔案。程式檢查它是否存在,找到了,信任它,然後試著使用裡面不完整的資料。問題不是在讀取的當下出現,而是在之後。

解法很簡單,而且適用於每一次寫入:不直接覆寫檔案。先寫入一個暫存名稱,再把它移到定位。移動要嘛完整發生,要嘛完全沒發生,沒有中間狀態。如此一來,檔案內容不是舊的就是新的,絕不會只有一半。

撰寫會動到 Proxmox 設定的指令碼時,光是這一個習慣,就比其餘所有程式碼更有價值。

舊版本存放在兩個地方

在備份裡。機器的備份不只包含磁碟,也包含當下的設定檔。還原備份時,設定也會一併回來。多數人把備份只當成資料,從未意識到手上已握有一條救援途徑。

在快照裡。建立快照時,當下的設定會寫入同一個檔案中一個具名的區段。因此這個檔案本身就保存了自己的一部分歷史。

但這兩者無法互相取代,而且差異很重要:快照的紀錄位於同一個檔案之內。檔案本身一旦毀損,那份紀錄也會隨之消失。備份則存放在別處。真正的救援途徑是備份,快照只是一個日後可能想回到的時間點。

打算手動編輯時

先停止機器。

編輯前先複製一份,並把這份副本放到別的地方。存放設定的位置是為設定而設計的,不要把備份留在那裡。

完成變更後,啟動機器並確認它真的能運作。不要拖到下次重新啟動才看,結果忘了這件事;被遺忘的半完成編輯,幾個月後會以一個沒人聯想得到的故障重新出現。

通用規則:檔案不存在與檔案損毀是兩種不同的狀態

程式的救援途徑通常是以檔案不存在的狀態為前提撰寫的,因為這是最先想到的情況。檔案存在但內容損毀的狀態,則不會被想到。

然而真正危險的正是第二種,恰恰因為沒有人考慮過它。而且兩者的表現不同:檔案不存在會帶有一個標記,內容損毀則沒有。

Atlas 的做法

Atlas 本身保存了幾個小型設定檔,這裡有幾件事值得坦白說明,因為它們全都是實際量測時發現的。

兩個同類檔案的行為不一致。其中一個在檔案損毀時會自我修復:把損毀的檔案移到一旁,重新乾淨地開始。另一個則不會:它丟出錯誤後就停在那裡,也就是說該功能永久無法使用,使用者也沒有任何方法透過產品修復。

原因正是上面那條規則:救援分支是針對檔案不存在的狀態撰寫的。內容損毀的錯誤不帶那個標記,因此分支沒有攔截到,錯誤便往上拋出。

被隔離的副本從未被清理。每次損毀事件都會留下一個永久檔案,數量沒有任何上限。在一台運作中的機器上量測:其中兩個已經擺在那裡好幾個月。這和本 wiki 其他地方寫過的規則相同:所有會寫入的東西都需要上限。

同一瞬間的兩次隔離產生了相同的名稱,第二份副本覆蓋了第一份,於是一個損毀版本就無聲無息地消失了。

這些問題全都已修正,並且為隔離步驟本身訂下一條規則:無論在任何情況下,它都不會丟出錯誤。隔離是一個救援步驟,而救援步驟絕不能成為新的故障來源。這句話看似微不足道,卻是每個撰寫救援程式碼的人都應該釘在牆上的一句話。

資料來源

Proxmox 官方文件。內容為英文,且在此主題上以官方文件為準。

相關條目

這項工作在 Atlas 中是什麼樣子?

前往產品頁面