4 升级 Erlang/OTP 后的升级
4.1 介绍
从 Erlang/OTP 17 开始,大多数应用程序都提供有效的应用程序升级文件 (appup)。在早期版本中,Erlang/OTP 中的大多数应用程序不支持升级。许多应用程序使用 restart_application 指令。这些是对于支持真正的软升级来说并不重要的应用程序,例如工具和库应用程序。restart_application 指令确保应用程序中的所有模块都重新加载,从而运行新的代码。
4.2 核心应用程序的升级
核心应用程序 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(4) 手册页。有关升级指令的更多信息,请参见 SASL 中的 appup(4) 手册页。
4.3 仍然不允许代码升级的应用程序
一些应用程序(如 erl_interface)不支持升级。这由仅包含 {Vsn,[],[]} 的应用程序升级文件指示。任何尝试使用此类输入创建发布升级文件的尝试都会失败。强制涉及此类应用程序的升级的唯一方法是手动编写文件 relup,最好如上所述,只使用 restart_emulator 指令。