檢視原始碼 當 Erlang/OTP 變更時的升級

簡介

從 Erlang/OTP 17 開始,大多數應用程式都會提供有效的應用程式升級檔案 (appup)。許多應用程式都使用 restart_application 指令。這些應用程式對於支援真正的軟升級並非至關重要,例如工具和函式庫應用程式。restart_application 指令確保應用程式中的所有模組都重新載入,並因此執行新的程式碼。

核心應用程式的升級

核心應用程式 ERTS、Kernel、STDLIB 和 SASL 永遠不允許真正的軟升級,而是需要重新啟動 Erlang 執行時系統。這會透過升級指令 restart_new_emulator 指示給 release_handler。此指令永遠是執行的第一個指令,它會使用先前提到之核心應用程式的新版本和所有其他應用程式的舊版本重新啟動執行時系統。當節點重新啟動後,會執行所有其他升級指令,確保每個應用程式最終都執行其新版本。

進行兩步驟升級而不是只使用所有應用程式的新版本重新啟動執行時系統可能看起來很奇怪。此設計決策的原因是允許 code_change 函式具有副作用,例如變更磁碟上的資料。它也保證非核心應用程式的升級機制不會因核心應用程式是否同時變更而有所不同。

但是,如果偏好更激烈的變體,則可以使用單一升級指令 restart_emulator 手寫發行升級檔案。此指令與 restart_new_emulator 相反,會導致執行時系統使用所有應用程式的新版本重新啟動。

注意:如果在手寫的 relup 檔案中,restart_emulator 之前包含其他指令,則它們會在舊的執行時系統中執行。這是一個很大的風險,因為無法保證新的 BEAM 程式碼可以載入到舊的執行時系統中。在 restart_emulator 之後新增指令不會產生任何效果,因為 release_handler 不會執行它們。

關於發行升級檔案的資訊,請參閱 SASL 中的 relup。關於升級指令的更多資訊,請參閱 SASL 中的 appup

仍然不允許程式碼升級的應用程式

一些應用程式,例如 Erl_interface,不支援升級。這由僅包含 {Vsn,[],[]} 的應用程式升級檔案表示。任何嘗試使用此類輸入建立發行升級檔案都會失敗。強制升級涉及此類應用程式的唯一方法是手寫檔案 relup,最好如上所述,僅使用 restart_emulator 指令。