Hot Upgrade (Relup)
This plugin applies a .relup set of code-change instructions to a running EMQX node, so operators can roll out a patched release without restarting the VM.
Operators drive it through the emqx ctl relup ... CLI on each node; cluster-wide rollout is the operator's responsibility (no orchestration is built in).
When to Use
A hot upgrade is appropriate when:
- The hop you want to apply is listed by
emqx ctl relup list-supported-paths(only declared{from, target}hops are supported). - You can verify the target node before moving on to the next.
- You have a backup of
data/. There is no in-place rollback for an applied hop (see Rollback).
If you cannot satisfy these, do a normal rolling restart instead.
Operator Workflow
1. Install the plugin
Download the tarball matching your EMQX version from the Download section below and install it from the Dashboard (or via the REST API / CLI like any other plugin).
2. Confirm the upgrade path is supported
emqx ctl relup list-supported-pathsThe output lists the {from, target} hops bundled in priv/relup/ of this plugin version. If your hop is missing, hot upgrade for that path is not available; fall back to a normal restart-based upgrade.
3. Stage the target release on every node
For each node, copy two files to a path the EMQX process can read:
emqx-enterprise-<TargetVsn>-<os>-<arch>.tar.gz: The EMQX target release tarball.<tarball>.sha256: The sha256 digest. The standardsha256sumformat (<digest> <filename>) is accepted.
4. Trigger the upgrade
On each node:
emqx ctl relup upgrade <TarballPath> [--force]The handler:
- Verifies
<TarballPath>.sha256against the actual digest and refuses to extract on mismatch. - Refuses to continue if
data/patches/contains any*.beamfiles. This directory is prepended to the code path throughvm.args -pa, so those files would take precedence over modules from the upgrade target. If the target release already includes the hot-patched fix, a stale beam file could still be loaded. Delete the patch files first, or pass--forceonly if you intend to keep them applied on top of the target release. - Extracts the tarball and reads
REL_VSNfromreleases/emqx_vars. - Looks up the matching
{from, target}hop inpriv/relup/*.relupand runs the declared code-change instructions and post-upgrade callbacks.
5. Verify the node
Check these signals before moving on:
emqx ctl statusreports the node running.cat <RootDir>/relup/currentmatches the target version, and<RootDir>/relup/<TargetVsn>/containsbin/,erts-*/,lib/,releases/.
On the next emqx start / restart, the bin/emqx wrapper detects relup/current and execs into the deployed tree (new ERTS, new bin scripts, new lib). The original <RootDir> remains the authority for data/, etc/, log/, plugins/.
6. Clean up after success
Once the cluster is fully on the target version, manually remove the staged tarball and its .sha256 sidecar. The plugin does not track the source path, so there is no plugin-side state to clean.
Upgrade History
Each node keeps its own audit trail in the emqx_relup_log table (disc-backed, local content). The history survives plugin uninstall; reinstalling re-attaches and the rows are still there.
Inspect or clear via CLI:
emqx ctl relup logs # show recent upgrade attempts
emqx ctl relup logs-clear # delete all log rows on this nodeRollback
There is no in-place rollback for an applied hop. The hot-upgrade runs code_changes against the live VM and any post_upgrade_callbacks may have mutated data on disk; reversing that is not supported by this plugin.
Practical fallback paths:
Before the next restart, if the upgrade succeeded but the new code is misbehaving and the data on disk is still compatible with the old release:
bashrm <RootDir>/relup/current # optional: rm -rf <RootDir>/relup/<TargetVsn>/ emqx restartThe wrapper falls back to the original
<RootDir>/bin/emqxtree. This recovers only the boot path; live state inside the VM at the time of the bad upgrade is already gone.Otherwise, restore from the pre-upgrade backup of
data/(mnesia, configs, etc.) and reinstall the old EMQX release. Plan the upgrade window with this in mind.
Authoring a Hop (Developer Notes)
To add a new hop, for each release that needs one:
- Add
priv/relup/<from>-to-<to>.relupdeclaring thecode_changesandpost_upgrade_callbacksfor the hop. Seepriv/relup/README.mdin the plugin source for the schema, the supported instructions, and the post-upgrade callback contract. In particular, when adding apr_NNNNN_*callback to the new EMQX'semqx_post_upgrade, the relup hop must reload that module before invoking the callback, or ship the callback in this plugin asemqx_post_upgrade_<TargetVsn>.erl. - Bump this plugin's
VERSIONand re-publish.
The plugin validates every priv/relup/*.relup at app start and logs a warning for malformed entries; bad files are skipped, not fatal.
Download
Tarballs for each EMQX release:
| EMQX Version | Plugin Version | Package |
|---|---|---|
| 5.10.4 | 1.0.0 | emqx_relup-1.0.0.tar.gz |