MariaDB: The usage of MARIADB_AUTO_UPGRADE

When you're running MariaDB and keep it up to date, binaries are updated (either because of updates running within OS update, or by updating Docker containers), and you won't have to do anything - it just works.
In MySQL, this isn't a problem; the database dictionary as well as internal objects were just upgraded implicitly when starting the database with ne newest binaries.
In Oracle, it can be a problem: when you apply patches ("release updates"), which are something like a minor release update, you'll have to execute datapatch
, which updates internal database objects to the latest version. If you forget to do it, you might never get an error - but your database is not in the best state.
So what about MariaDB?
When you have a look into MariDB log files, you might see something like this:
MariaDB upgrade (mariadb-upgrade or creating healthcheck users) required, but skipped due to $MARIADB_AUTO_UPGRADE setting
In my case, my docker-compose.yml
looks like this:
services:
db:
image: mariadb
hostname: mariadb
ports:
- 13306:3306
environment:
- MARIADB_ROOT_PASSWORD=XxXxXxXx
The logfile already gives us a hint what to do:
MariaDB upgrade required, but skipped due to $MARIADB_AUTO_UPGRADE setting
So let's just add this parameter to my YAML file:
services:
db:
image: mariadb
hostname: mariadb
ports:
- 13306:3306
environment:
- MARIADB_ROOT_PASSWORD=XxXxXxXx
- MARIADB_AUTO_UPGRADE=true
Now, let's restart the container:
# docker compose up -d
And have look at the log files:
# docker compose logs -f
db-1 | 2025-06-13 09:48:01+00:00 [Note] [Entrypoint]: Backing up system database to system_mysql_backup_11.7.2-MariaDB.sql.zst
db-1 | 2025-06-13 09:48:01+00:00 [Note] [Entrypoint]: Backing up complete
db-1 | 2025-06-13 09:48:01+00:00 [Note] [Entrypoint]: Starting mariadb-upgrade
db-1 | The --upgrade-system-tables option was used, user tables won't be touched.
db-1 | Major version upgrade detected from 11.7.2-MariaDB to 11.8.2-MariaDB. Check required!
db-1 | Phase 1/8: Checking and upgrading mysql database
db-1 | Processing databases
db-1 | mysql
db-1 | mysql.column_stats OK
db-1 | mysql.columns_priv OK
db-1 | mysql.db OK
db-1 | mysql.event OK
db-1 | mysql.func OK
db-1 | mysql.global_priv OK
db-1 | mysql.gtid_slave_pos OK
db-1 | mysql.help_category OK
db-1 | mysql.help_keyword OK
db-1 | mysql.help_relation OK
db-1 | mysql.help_topic OK
db-1 | mysql.index_stats OK
db-1 | mysql.innodb_index_stats OK
db-1 | mysql.innodb_table_stats OK
db-1 | mysql.plugin OK
db-1 | mysql.proc OK
db-1 | mysql.procs_priv OK
db-1 | mysql.proxies_priv OK
db-1 | mysql.roles_mapping OK
db-1 | mysql.servers OK
db-1 | mysql.table_stats OK
db-1 | mysql.tables_priv OK
db-1 | mysql.time_zone OK
db-1 | mysql.time_zone_leap_second OK
db-1 | mysql.time_zone_name OK
db-1 | mysql.time_zone_transition OK
db-1 | mysql.time_zone_transition_type OK
db-1 | mysql.transaction_registry OK
db-1 | Phase 2/8: Installing used storage engines... Skipped
db-1 | Phase 3/8: Running 'mysql_fix_privilege_tables'
db-1 | Phase 4/8: Fixing views... Skipped
db-1 | Phase 5/8: Fixing table and database names ... Skipped
db-1 | Phase 6/8: Checking and upgrading tables... Skipped
db-1 | Phase 7/8: uninstalling plugins
db-1 | Phase 8/8: Running 'FLUSH PRIVILEGES'
db-1 | OK
db-1 | 2025-06-13 09:48:18+00:00 [Note] [Entrypoint]: Finished mariadb-upgrade
db-1 | 2025-06-13 09:48:18+00:00 [Note] [Entrypoint]: Stopping temporary server
db-1 | 2025-06-13 9:48:18 0 [Note] mariadbd (initiated by: unknown): Normal shutdown
db-1 | 2025-06-13 9:48:18 0 [Note] InnoDB: FTS optimize thread exiting.
db-1 | 2025-06-13 9:48:18 0 [Note] InnoDB: Starting shutdown...
db-1 | 2025-06-13 9:48:19 0 [Note] InnoDB: Removed temporary tablespace data file: "./ibtmp1"
db-1 | 2025-06-13 9:48:19 0 [Note] InnoDB: Shutdown completed; log sequence number 47629; transaction id 18
db-1 | 2025-06-13 9:48:19 0 [Note] mariadbd: Shutdown complete
db-1 | 2025-06-13 09:48:19+00:00 [Note] [Entrypoint]: Temporary server stopped
db-1 | 2025-06-13 9:48:19 0 [Note] Starting MariaDB 11.8.2-MariaDB-ubu2404 source revision 8d36cafe4fc700e6e577d5a36650c58707e76b92 server_uid i/adQyORMBjdCbV+zs20lFGiMUA= as process 1
[...]
So what does MARIADB_AUTO_UPGRADE
mean? Let's have a look at the MariaDB documentation:
Set MARIADB_AUTO_UPGRADE to a non-empty value to have the entrypoint check whether mariadb-upgrade needs to run, and if so, run the upgrade before starting the MariaDB server.
Ok, without setting MARIADB_AUTO_UPGRADE
, there will be no check and no upgrade.
Before the upgrade, a backup of the system database is created in the top of the datadir with the name system_mysql_backup_*.sql.zst. This backup process can be disabled with by setting MARIADB_DISABLE_UPGRADE_BACKUP to a non-empty value.
So, when enabling MARIADB_AUTO_UPGRADE
, a backup of the dictionary will be made.
IfMARIADB_AUTO_UPGRADE
is set, and the.my-healthcheck.cnf
file is missing, thehealthcheck
users are recreated if they don't exist, MARIADB_HEALTHCHECK_GRANTS
grants are given, the passwords of thehealthcheck
users are reset to a random value and the.my-healthcheck.cnf
file is recreated with the new password populated.
Great: healthcheck users are created automatically if they do not exist.
At this point, I'd rather keep MARIADB_HEALTHCHECK_GRANTS
set as long as I never intend to go back to an older version (say: downgrade). But this needs a development or test system, which I always recommend to have for a production system. Or, if your MariaDB server is only production, there should be other possibilities to roll back to an older state - like filesystem snapshots.
Let me say it in short words: always test each update. And always have backups. And if you have, use non-production systems to test updates there. Then, automatic updates are completely fine 😄