Percona versions & verifying a migration
Two things decide how a cross-host move behaves in practice: the Percona
version on each end, and how carefully you verify the result. This page
covers both — the version-specific behaviour of xoct and xmass, the
maintenance pause that keeps the MySQL watchdog from racing a controlled move,
and the before/after checklist that lets you trust a migration instead of hoping.
For the mechanics of each tool, start with Cross-host migration and Site import & export; for the Percona 8 upgrade itself, see Percona 8 readiness.
Which tool crosses versions
The transport each tool uses decides whether it can bridge a version gap.
xoctexports a logical dump withmydumperon the source and loads it withmyloaderon the target. A logical dump is portable, soxoctis cross-version safe — a Percona 5.7 account migrates cleanly onto a Percona 8.4 box. This is the tool that performs the actual version jump.xmasstakes a physical xtrabackup snapshot and brings the target up as a GTID replica of the source. Physical backup plus replication require identical Percona versions on both ends, soxmass initrefuses a mismatch before it touches any data.xmassevacuates a whole box within a version; it does not upgrade one.
The result is a clear adoption path onto Percona 8: upgrade a target box to
Percona 8 first, then use xoct to migrate accounts onto it from the older 5.7
boxes. Once a whole region is on 8.4, xmass can evacuate boxes wholesale within
that version. The 5.7→8.4 upgrade itself runs in two steps — the strict upgrade
path clamps a direct 5.7→8.4 request to 8.0 first — so a box reaches 8.4 through
one 5.7→8.0 run and one 8.0→8.4 run.
The MySQL watchdog is paused during a move
BOA runs a MySQL watchdog from cron that keeps a production server alive: if
mysqld looks down it restarts it, if a table looks stuck it breaks the lock,
and it kills queries that run too long. During everyday operation that is exactly
right. During a deliberate database operation it is a hazard — the watchdog
cannot distinguish a genuine hang from a controlled FLUSH TABLES WITH READ LOCK
at cutover, a slow innodb_fast_shutdown=0 package upgrade, or an in-progress
xtrabackup snapshot, and "healing" any of those mid-flight can lose data.
BOA resolves this with a single maintenance marker, /run/boa_sql_maintenance.pid.
While the marker is present the watchdog stands down completely — it exits
before running any check, so it never restarts, lock-breaks, or query-kills a
server that is under deliberate maintenance. The operations that need the pause
set the marker around their own critical section and clear it afterwards:
- a Percona package upgrade holds it across the whole apt transaction and the clean-shutdown restart;
xmassholds it on both hosts acrossinit(the source snapshot and the target restore and replica bring-up) and across the wholecutover— the read-lock window at cutover is the single highest-risk moment in the toolchain;xoctholds it forexportandimport(themyloaderload plus the in-place host rename's dump and reimport).
Two safeguards keep the pause from ever becoming a foot-gun. A marker older than
four hours is treated as abandoned — left behind by an operation that died
without cleaning up — so the watchdog removes it and resumes normal healing
rather than staying muted forever; and because the marker lives on a memory-backed
filesystem, a reboot clears it too. In normal operation you never touch the marker
by hand, and the one operational rule is simple: during a migration or a Percona
upgrade, do not force the watchdog to run expecting it to help — it is muted on
purpose. The single exception is a hard recovery — if a migration or Percona
upgrade dies mid-flight and you are cleaning up by hand, confirm the marker is gone
(ls /run/boa_sql_maintenance.pid) before you rely on the watchdog again; the
four-hour auto-abandonment clears a stale one regardless, so it never mutes
auto-heal for good. See
Process guards for the watchdog itself.
What xmass adapts to on Percona 8
Whole-server replication changed substantially between 5.7 and 8.x. xmass is
version-aware and adapts automatically; the details are here so the behaviour is
understood, not so you configure anything.
- xtrabackup build and repositories. Physical backup needs the xtrabackup
build that matches the server — the
-24build for 5.7,-80for 8.0, and the-84-ltsbuild for 8.4. BOA's base install configures only the Percona server repository, soxmassenables the matching backup repository (reusing the server repository's keyring and release codename) before installing. It also enables Percona'stoolsrepository, because xtrabackup depends on a Perl MySQL driver whose Debian build pulls a MariaDB client library that BOA keeps uninstallable; the Perconatoolsbuild of that driver depends on the Percona client instead and resolves cleanly. - Binlog expiry. The older
expire_logs_dayssetting was removed in 8.4, so on 8.0 and laterxmasswrites the seconds-based equivalent. - Replication vocabulary. The
MASTER/SLAVEstatement family (CHANGE MASTER TO,START SLAVE,SHOW SLAVE STATUS, and the rest) was removed in 8.4 in favour of theSOURCE/REPLICAvocabulary.xmassselects the correct dialect for the running version in every phase — setup, sync, status and cutover — not only at setup time. - GTID persistence. Turning GTID on at runtime is not enough: the restore
restarts the server, and an unpersisted setting reverts on restart and silently
breaks the replica.
xmasswrites the GTID settings into the include directory the server's configuration actually reads, and confirms GTID is on after the restart. - Replica authentication. The default 8.0+ authentication plugin refuses a
replica login over a plain (non-TLS) channel unless the replica is told to
fetch the source's public key first.
xmasssets that option on the replication link and confirms both replica threads are running before it continues.
None of this applies to a same-version 5.7→5.7 move, which uses the -24
xtrabackup build and the legacy vocabulary throughout. The whole cluster of 8.x
requirements only appears once both ends are genuinely on Percona 8.
Cache state after a cross-version move
A migrated-in site can arrive carrying the source box's stale object cache and,
on Drupal 8 and later, a stale service container. BOA does not attempt a per-site
cache rebuild on import — outside the front-end's bootstrap context that rebuild
is unreliable on modern Drupal. Instead both xoct import and xmass post-mig
flush hard at the infrastructure level: the object-cache service is cold-restarted
to drop its contents, and every PHP-FPM master is restarted to drop opcode and
APCu caches. This is the treatment BOA trusts against cache and container
poisoning after a move.
The visible consequence is that sites are briefly unavailable — a few seconds — immediately after the flush, and warm up on the next request. That is expected, not a fault. Each site's PHP-version pin is preserved separately across the move, so a site stays on its own PHP version rather than falling back to the target account's default.
Verifying a migration
A site returning 200 proves surprisingly little on its own — it can be the
front-end catch-all, a page cached from the source, or the wrong account's pool
answering. Verification means recording a real baseline on the source and
checking the same facts on the target, fetched directly to the target.
Before the move, capture per site: a unique marker string in the page body; a
200 on a real application route rather than the front page; a known row count
in a table you can re-count; and a clean drush bootstrap.
After the move, confirm each of these against the target directly:
| Check | What it proves |
|---|---|
| the served page contains the exact baseline marker | the right content is live — not a cache or a catch-all |
200 on the same real route, direct to the target |
the correct account's pool is executing, not a 403/503 |
| the marker table's row count matches the baseline | the database imported completely |
drush bootstraps against the target |
settings, credentials and paths rewrote correctly |
| the file store's contents are present on the target | files transferred |
site-level files/private are still symlinks |
the storage layout survived the move |
| the source serves the same marker through its proxy | the source→target proxy hop is live for the DNS window |
A whole-server xmass move adds a few gates of its own: init confirms the
version match; both replica threads run with lag falling to zero; each sync
reaches a clean dry-run before you run it live; status shows lag under a minute
before cutover; and after cutover every account serves its marker on the target,
replication is torn down so the target stands alone, and the old box has become a
proxy.
The cross-version refusal is itself a gate worth checking deliberately: pointing
xmass from a 5.7 source at an 8.4 target must stop at the version check, before
any snapshot or replication step, and leave the target untouched. That refusal is
the correct outcome — crossing versions is xoct's job.
Field-validated
The behaviour on this page was validated end-to-end on Devuan Daedalus servers
across the full version matrix: single-account and whole-server moves at
5.7→5.7, single-account 5.7→8.4 and 8.4→8.4, whole-server 8.4→8.4, and the
5.7→8.4 whole-server refusal. Each target account carried a Drupal 7 site on PHP
7.4 and a Drupal 10 site on PHP 8.4 with page and database markers, and the
Percona 8 boxes reached 8.4 through the real two-step upgrade. The version-aware
xmass behaviour and the watchdog pause described above were driven into the
shipped tools by that campaign.