查看源代码 当 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
指令。