← All posts

Moving PostgreSQL and MariaDB to an ARM cloud server

Databases run well on an ARM cloud server: PostgreSQL, MariaDB and MySQL all have native ARM64 builds, packaged by every major Linux distribution. Moving one is a normal database migration with one ARM-specific rule: move the data logically, as a dump or through logical replication, rather than copying the files on disk. This guide covers both routes and the checks that matter when you migrate to ARM.

VPS GB runs only ARM, so this is the migration we see most after web sites.

The rule: move data, not data files

A database's files on disk are written by that build of that server, on that platform. Copying them to a different architecture is the step that can go wrong, and the one you never need to take:

  • PostgreSQL documents that physical copies of the data directory, and physical (streaming) replication, need the same major version on compatible hardware. Across x86-64 and ARM64, use pg_dump or logical replication instead. Collations are a second reason: text indexes depend on the C library's sort order, which can differ between operating system releases, so a logical move rebuilds them correctly on the new server.
  • MariaDB and MySQL InnoDB files are designed to be portable between platforms, but a dump or replication is still the safer route, especially if the version or the distribution changes at the same time.

Logical dumps and logical replication are plain data, independent of the processor, which is why both routes below work in either direction.

Route 1: dump and restore

Simplest, and the right choice when you can stop writes for as long as a dump and restore takes. That depends on the size of the database and the disks, so time a trial run against a copy before you schedule the real one.

PostgreSQL:

pg_dump -Fc -d appdb -f appdb.dump          # on the old server
createdb appdb                              # on the new server
pg_restore -d appdb --no-owner -j 4 appdb.dump

Roles are not in a single-database dump; copy them with pg_dumpall --roles-only. Run ANALYZE after the restore so the planner has statistics before real traffic arrives.

MariaDB or MySQL:

mysqldump --single-transaction --routines --triggers --events \
    appdb > appdb.sql                       # on the old server
mysql appdb < appdb.sql                     # on the new server

--single-transaction gives a consistent snapshot of InnoDB tables without locking them. Users and grants live in the mysql system database; recreate them on the new server rather than copying that database between versions.

To keep the freeze short, stop writes (put the application in maintenance mode), dump, restore, point the application at the new server, and test before you reopen.

Route 2: replicate, then cut over

For larger databases, or when the freeze has to be seconds, replicate to the ARM server first and switch when it has caught up.

PostgreSQL logical replication (version 10 and later):

  1. Restore the schema only on the new server: pg_dump --schema-only appdb | psql -d appdb.
  2. On the old server: CREATE PUBLICATION migrate FOR ALL TABLES; (wal_level must be logical).
  3. On the new server: CREATE SUBSCRIPTION migrate CONNECTION '...' PUBLICATION migrate; It copies existing rows, then streams changes.
  4. When it has caught up, stop writes, wait for the last changes, and move the application across.

Logical replication does not carry sequence values in the versions most people run, so set each sequence on the new server before you switch, or new rows will collide with old IDs. Tables need a primary key (or a replica identity) for updates and deletes to replicate.

MariaDB and MySQL replication is logical too: the binary log records changes, not disk pages, so a primary on x86 can feed a replica on ARM. Take a consistent dump with the binary log position or GTID recorded, restore it on the ARM server, start it as a replica, and promote it when it has caught up. Keep both sides on the same major version line while they replicate.

Extensions and plugins

The data is portable; native code is not always:

  • PostgreSQL extensions are compiled libraries. The common ones, such as PostGIS, pgvector, TimescaleDB and the contrib modules, are available for ARM64 from distribution packages, the PostgreSQL project's repositories or the extension's own. List what you use with SELECT * FROM pg_extension; and check each one before you move.
  • MariaDB and MySQL plugins from the server's own packages are fine. Check any third-party storage engine or authentication plugin.
  • Managed services' own extensions do not come with you. If you are leaving a managed database, look for features specific to that provider.

After the move

Check row counts on the largest tables, run the application's test suite against the new server, and compare a few slow queries with EXPLAIN on both. Tune the new server rather than copying old settings blindly: memory settings such as shared_buffers or innodb_buffer_pool_size should follow the new machine's RAM, not the old one's.

If your database runs in containers, the official postgres, mariadb and mysql images are all multi-architecture; see moving Docker workloads to ARM. Just do not move the volume itself: dump and restore into the new container.

VPS GB runs only 64-bit ARM, hosted in the UK. Why we chose ARM, and what does and does not run on it.