Skip to content

热升级(Relup)

该插件向运行中的 EMQX 节点应用一组 .relup 代码变更指令,使运维人员能够在不重启 VM 的情况下完成补丁发布。

运维人员通过每个节点上的 emqx ctl relup ... CLI 触发升级;集群级滚动由运维自行编排(插件内不包含编排逻辑)。

何时使用

热升级适用于以下场景:

  • 目标升级路径已被 emqx ctl relup list-supported-paths 列出(仅支持已声明的 {from, target} 跳转)。
  • 升级完一个节点后可立即验证再继续下一个。
  • 已备份 data/:已应用的升级跳转没有原地回滚能力(详见 回滚)。

如果上述条件无法满足,建议改用常规的滚动重启升级方式。

运维操作流程

1. 安装插件

从下方 下载 区获取与当前 EMQX 版本匹配的插件包,然后通过 Dashboard(或 REST API / CLI)按常规方式安装。

2. 确认升级路径已支持

bash
emqx ctl relup list-supported-paths

输出会列出当前插件版本 priv/relup/ 中包含的 {from, target} 跳转。如果未列出目标路径,则该路径下不支持热升级,需要使用常规的重启升级。

3. 在每个节点上准备目标发布包

在每个节点上将以下两个文件放到 EMQX 进程可访问的路径:

  • emqx-enterprise-<TargetVsn>-<os>-<arch>.tar.gz:目标版本发布包。
  • <tarball>.sha256:发布包的 sha256 摘要。支持标准 sha256sum 格式(<digest> <filename>)。

4. 触发升级

在每个节点上执行:

bash
emqx ctl relup upgrade <TarballPath> [--force]

升级流程:

  • <TarballPath>.sha256 校验 tarball 实际摘要,不匹配则拒绝解压。
  • 如果 data/patches/ 目录下存在任何 *.beam 文件,则拒绝继续升级。该目录通过 vm.args -pa 被前置到代码路径中,因此其中的热补丁文件会优先于目标版本中的同名模块被加载。如果目标版本已经包含相应修复,旧的 beam 文件仍可能被加载并继续运行。请先删除这些补丁文件;仅当确实希望它们继续叠加在目标版本之上时,才使用 --force 跳过该检查。
  • 解压 tarball 并读取 releases/emqx_vars 中的 REL_VSN
  • priv/relup/*.relup 中查找匹配的 {from, target} 跳转,执行代码变更指令与升级后回调。

5. 验证节点

继续之前确认两个关键信号:

  • emqx ctl status 显示节点正常运行。
  • cat <RootDir>/relup/current 输出目标版本,且 <RootDir>/relup/<TargetVsn>/ 下存在 bin/erts-*/lib/releases/

下次执行 emqx start / restart 时,bin/emqx 包装脚本会检测 relup/current 并切换到已部署的目录树(新的 ERTS、bin 脚本、lib)。原始 <RootDir> 仍是 data/etc/log/plugins/ 的权威目录。

6. 升级成功后清理

集群全部升级到目标版本后,手动删除暂存的发布包及其 .sha256 文件。插件不会跟踪源路径,无需做插件侧清理。

升级历史

每个节点会在本地的 emqx_relup_log 表中保存升级审计记录(基于磁盘存储,仅本节点可见)。卸载插件不会清除该表,重新安装后历史记录依旧可用。

通过 CLI 查看或清理:

bash
emqx ctl relup logs           # 查看最近的升级记录
emqx ctl relup logs-clear     # 清除本节点上的所有日志

回滚

已应用的升级跳转无法原地回滚。热升级会在运行中的 VM 上执行 code_changes,并可能在 post_upgrade_callbacks 中修改磁盘上的数据,这些操作无法通过插件本身回退。

可行的应急路径:

  • 在下次重启前,如升级已完成但新代码出现异常,且磁盘上的数据仍兼容旧版本:

    bash
    rm <RootDir>/relup/current
    # 可选:rm -rf <RootDir>/relup/<TargetVsn>/
    emqx restart

    包装脚本会回退到原始的 <RootDir>/bin/emqx。此方式只恢复启动路径,升级失败时 VM 中的运行时状态已无法找回。

  • 其他情况下,使用升级前 data/(mnesia、配置等)的备份恢复,并重新安装旧版本 EMQX。规划升级窗口时请考虑这一点。

编写升级跳转(开发者参考)

为新版本添加跳转的步骤:

  1. 添加 priv/relup/<from>-to-<to>.relup,声明该跳转的 code_changespost_upgrade_callbacks。schema、支持的指令以及升级后回调约定参见插件源码中的 priv/relup/README.md。特别注意:当在新版本 EMQX 的 emqx_post_upgrade 中新增 pr_NNNNN_* 回调时,relup 跳转必须先 reload 该模块再调用回调,或将回调以 emqx_post_upgrade_<TargetVsn>.erl 的形式直接放入本插件。
  2. 升级本插件的 VERSION 并重新发布。

插件启动时会校验 priv/relup/*.relup 中的每个条目,对格式错误的文件记录 warning 并跳过,不会因此启动失败。

下载

各 EMQX 版本对应的插件安装包:

EMQX 版本插件版本安装包
5.10.41.0.0emqx_relup-1.0.0.tar.gz