Moving the data directory for MySQL or MariaDB frees space on a cramped root filesystem, enables faster storage, and can simplify backups by keeping database files on a dedicated volume.
Both MySQL and MariaDB read the data location from the server configuration (the datadir option in the [mysqld] section). The mysqld daemon opens system tables, redo logs, and per-database directories from that path during startup, so a move requires a clean shutdown and a faithful copy that preserves ownership and permissions.
On Ubuntu and Debian, AppArmor often confines mysqld to approved filesystem paths, so the profile needs an alias or explicit rules for the new directory or the service can fail with permission denials. A data directory located on a separate partition also needs a persistent mount that comes up before the database service to avoid starting against an unintended empty directory.
Steps to change MySQL or MariaDB data directory in Ubuntu/Debian:
- Record the current datadir value.
$ sudo mysql --execute "SHOW VARIABLES LIKE 'datadir';" +---------------+----------------+ | Variable_name | Value | +---------------+----------------+ | datadir | /var/lib/mysql/| +---------------+----------------+
Add --password when local authentication prompts for a password.
- Stop the database service.
$ sudo systemctl stop mysql
Use
$ sudo systemctl stop mariadb
when the unit name is mariadb.service.
- Create the new data directory with restrictive permissions.
$ sudo install --directory --owner=mysql --group=mysql --mode=0750 /data/mysql
The target filesystem needs POSIX permissions (for example, ext4 or xfs).
- Confirm the new directory is on the intended filesystem.
$ df -h /data/mysql Filesystem Size Used Avail Use% Mounted on /dev/sdb1 200G 20G 170G 11% /data
A missing mount can hide the copied data later when the real filesystem mounts over the same path.
- Copy the existing data files to the new directory with metadata preserved.
$ sudo cp --archive /var/lib/mysql/. /data/mysql/
Replace /var/lib/mysql with the path printed by the earlier datadir query when it differs.
- Verify ownership and permissions on the new directory.
$ sudo stat --format "%U:%G %a %n" /data/mysql mysql:mysql 750 /data/mysql
- Rename the original data directory to keep a rollback copy.
$ sudo mv /var/lib/mysql /var/lib/mysql.old
Keep the original directory for rollback until service startup succeeds. Confirm the new datadir before deletion.
- Open the server configuration file in an editor.
$ sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf
MariaDB commonly uses /etc/mysql/mariadb.conf.d/50-server.cnf/ for server settings.
Locate the active datadir setting with
$ sudo grep --recursive --line-number "^[[:space:]]*datadir" /etc/mysql/
.
- Update the datadir setting under [mysqld] to the new path.
[mysqld] datadir = /data/mysql
- Open the AppArmor alias tunables file.
$ sudo nano /etc/apparmor.d/tunables/alias
- Add an alias mapping for the data directory.
alias /var/lib/mysql/ -> /data/mysql/,
When aliases are not used, add explicit rules to /etc/apparmor.d/usr.sbin.mysqld such as
/data/mysql/ r,
and
/data/mysql/** rwk,
.
- Reload the mysqld AppArmor profile.
$ sudo apparmor_parser --replace /etc/apparmor.d/usr.sbin.mysqld
- Start the database service.
$ sudo systemctl start mysql
Use
$ sudo systemctl start mariadb
when the unit name is mariadb.service.
- Confirm the service is running.
$ sudo systemctl status mysql --no-pager ● mysql.service - MySQL Community Server Loaded: loaded (/lib/systemd/system/mysql.service; enabled; vendor preset: enabled) Active: active (running) since Fri 2025-12-12 09:41:04 UTC; 6s ago Main PID: 12345 (mysqld) Status: "Server is operational" ##### snipped ##### - Verify datadir points at the new location.
$ sudo mysql --execute "SHOW VARIABLES LIKE 'datadir';" +---------------+-------------+ | Variable_name | Value | +---------------+-------------+ | datadir | /data/mysql/| +---------------+-------------+
- Inspect the journal for AppArmor denials when the service fails to start.
$ sudo journalctl --unit=mysql --no-pager --since "10 minutes ago" ##### snipped ##### apparmor="DENIED" operation="open" profile="usr.sbin.mysqld" name="/data/mysql/ibdata1" pid=12345 comm="mysqld" ##### snipped #####
On MariaDB, replace mysql with mariadb in the unit name.
- Remove the rollback directory when normal operation is confirmed.
$ sudo rm --recursive --force /var/lib/mysql.old
Deleting the rollback directory is irreversible, so keep a verified backup before running rm.
Mohd Shakir Zakaria is a cloud architect with deep roots in software development and open-source advocacy. Certified in AWS, Red Hat, VMware, ITIL, and Linux, he specializes in designing and managing robust cloud and on-premises infrastructures.
Comment anonymously. Login not required.
