MariaDB / How to Change the Data Directory on Ubuntu and Windows

To change where MariaDB stores its data, shut down the server cleanly, copy the complete data directory, and update the server's datadir setting and access permissions. Changing the setting alone does not move existing databases, and an ordinary file copy while the server is running can produce inconsistent data, so arrange a separate backup and a maintenance window first.

Scope and preparation

The data directory contains database files and storage-engine management files. The server variable datadir identifies its current location. This procedure changes the path of a standalone instance on the same computer and MariaDB version. An upgrade, a move between operating systems, replication, a Galera cluster, or a container-volume change requires its own migration plan.

Connect with an administrative MariaDB account and record the following SQL results. On Ubuntu, sudo mariadb works for typical installations using local socket authentication. On Windows, use bin\mariadb.exe -u root -p from the installation directory. Use the instance's actual administrative account if authentication differs.

SELECT VERSION(), @@datadir, @@port;
SHOW VARIABLES WHERE Variable_name IN (
  'log_error', 'log_bin_basename', 'innodb_data_home_dir',
  'innodb_log_group_home_dir', 'aria_log_dir_path'
);
  • Independent backup: keep a recoverable backup in another location and verify its restoration when handling production data. Retaining the old folder does not replace a separate backup. The MariaDB backup overview explains logical and physical backup approaches.
  • Paths and capacity: record the actual source and a destination with sufficient free space. The Ubuntu source /var/lib/mysql/ and Windows installation version 11.4 below are examples, not values to assume.
  • External files: binary logs at absolute paths, external tablespaces, encryption keys, symbolic links, and Windows reparse points may require separate handling. Changing datadir does not relocate every configured file.
  • Maintenance window: pause application writes, scheduled jobs, and anything that might restart the server automatically. Keep external writes blocked until verification is complete.

Do not run mariadb-install-db in the destination when moving an existing instance. Initialization creates a new instance; this procedure instead copies all of the existing instance's data.

Move the data directory on Ubuntu

Identify configuration files and the destination mount

A typical Ubuntu 24.04 package installation uses /etc/mysql/mariadb.conf.d/50-server.cnf for server options, but the installation method can change this. Inspect the service arguments and drop-ins with systemctl cat, and check the effective file options with mariadbd --print-defaults. Do not publish the output if it contains sensitive settings.

sudo systemctl cat mariadb
sudo mariadbd --print-defaults
sudo du -sh /var/lib/mysql
df -h /data
findmnt -T /data

If /data does not exist, prepare and mount the destination disk first. Confirm that df and findmnt identify the intended filesystem. As described in MariaDB option-file configuration, later options or service arguments can override earlier values. Back up the file that the service actually reads before editing it.

Stop the server and copy all data

The example uses service mariadb, operating-system account mysql, and destination /data/mariadb/. Install rsync before the maintenance window if needed. After stopping the service, confirm that it is inactive and that the server process has exited. An inactive service can make is-active return a nonzero exit code. Do not copy after a failed shutdown or while another instance uses the same directory.

sudo systemctl stop mariadb
sudo systemctl is-active mariadb
sudo systemctl status mariadb --no-pager

Use an empty destination; do not merge another instance's files into it. The following commands create the folder, set its owner and permissions, and copy hidden files and engine files as well as database subdirectories. The archive option -a preserves ownership and permissions. cp -a can also preserve attributes; a plain copy does not always have the same behavior.

sudo mkdir -p /data/mariadb
sudo chown mysql:mysql /data/mariadb
sudo chmod 750 /data/mariadb
sudo rsync -aHAX --numeric-ids /var/lib/mysql/ /data/mariadb/
sudo rsync -aHAXnci --numeric-ids /var/lib/mysql/ /data/mariadb/

The first rsync performs the copy. The second is a checksum-based dry run. Check that both exit successfully, and investigate any changes reported by the second command. The trailing slash on the source means “copy the contents.” If the destination filesystem cannot preserve access control lists (ACLs) or extended attributes, resolve the error and review the filesystem and options rather than ignoring it.

Update datadir and security rules

Edit the existing datadir entry in a server option group that the service reads. Do not add conflicting entries throughout the configuration.

[mysqld]
datadir=/data/mariadb

Correct ownership alone does not guarantee access. AppArmor restricts a program's filesystem access on Linux. Inspect active profiles and kernel logs for DENIED messages associated with the MariaDB executable.

sudo aa-status
sudo journalctl -k -b --no-pager

If an enforcing MariaDB profile permits only the old path, adjust that profile's local rules or an applicable alias. The MariaDB startup troubleshooting guide describes this alias in /etc/apparmor.d/tunables/alias. First verify that the active profile uses it, back up the file, and check that sudo systemctl reload apparmor succeeds after editing. Profile layouts differ between distributions and packages; this alias is not mandatory on every installation.

alias /var/lib/mysql/ -> /data/mariadb/,

Also inspect ReadWritePaths, ProtectSystem, and related service restrictions in systemctl cat mariadb. For a separate disk, sudo systemctl edit mariadb can add the following mount dependency. This does not format a disk or replace a persistent mount entry in /etc/fstab. See systemd's RequiresMountsFor option.

[Unit]
RequiresMountsFor=/data/mariadb

The example avoids /home and /root, which the default service policy can block. If additional write access is necessary, allow the required path instead of disabling the entire security mechanism. The MariaDB systemd documentation explains these service restrictions.

Start the service and check the active path

Reload the service manager if you changed unit settings, then start MariaDB. The SQL result should identify /data/mariadb/. Moving the data directory does not require changing the client's socket path; avoid unrelated option changes.

sudo systemctl daemon-reload
sudo systemctl start mariadb
sudo systemctl status mariadb --no-pager
sudo mariadb -e "SELECT @@datadir;"

If startup fails or the old path is still reported, keep applications disconnected and use the troubleshooting steps below.

Move the data directory on Windows

Find the service, account, and my.ini

Run the following in an elevated PowerShell window to inspect the actual service name, logon account, and executable arguments. Replace service name MariaDB and installation version 11.4 throughout the examples with your values. The default name in the Windows MSI installation guide may differ from the registered service.

Get-CimInstance Win32_Service |
  Where-Object { $_.PathName -match 'mariadbd|mysqld' } |
  Select-Object Name, State, StartName, PathName
sc.exe qc MariaDB

Check the my.ini selected by --defaults-file in the service command line. If no explicit file is selected, inspect the option-file search locations reported by that executable's --help --verbose output and the actual files. In File Explorer, enable View → Show → File name extensions so that an edited file is not saved as my.ini.txt. Record @@datadir and back up the active configuration elsewhere.

Stop the service and copy the files

This example moves C:\Program Files\MariaDB 11.4\data to a new, empty C:\MariaDB folder. Confirm that the service is Stopped before copying. If the destination already exists, inspect it first and do not merge unrelated data.

Stop-Service -Name 'MariaDB'
Get-Service -Name 'MariaDB'
New-Item -ItemType Directory -Path 'C:\MariaDB'
robocopy "C:\Program Files\MariaDB 11.4\data" "C:\MariaDB" /E /COPY:DAT /DCOPY:DAT /R:1 /W:1 /XJ /XF my.ini
$copyExit = $LASTEXITCODE
if ($copyExit -ge 8) { throw "Robocopy failed: $copyExit" }

The command copies subdirectories but excludes my.ini, which remains at its original location. /COPY:DAT copies data, attributes, and timestamps; destination permissions are set separately. /XJ excludes junctions, so external content requires an explicit plan. According to the Microsoft Robocopy reference, exit codes of 8 or greater indicate a copy failure. For codes 0–7, still inspect failed or mismatched items and unexpected extra files in the summary.

Grant service access and edit datadir

Open services.msc and check the target service's Properties → Log On. In the new folder's Properties → Security → Edit → Add, grant Modify access to the actual service account. A MariaDB SQL user such as root is different from the Windows account running the service. Broad Full control access for Everyone is unnecessary.

Use the following only after confirming that the service's virtual account is NT SERVICE\MariaDB. Substitute the real account if the service uses a different name or a local/domain user. (OI)(CI)M grants Modify permissions inherited by files and subdirectories. See the Microsoft icacls reference.

icacls "C:\MariaDB" /grant "NT SERVICE\MariaDB:(OI)(CI)M"
icacls "C:\MariaDB"

Update the existing server option group in the original my.ini and save it in place. Forward slashes avoid backslash escaping issues. Keep --defaults-file pointing to the original file; moving the configuration file is a separate task.

[mysqld]
datadir=C:/MariaDB

Start the service and connect

Start MariaDB and open a client connection. Enter the password at the prompt rather than placing it after -p in the command.

Start-Service -Name 'MariaDB'
Get-Service -Name 'MariaDB'
& 'C:\Program Files\MariaDB 11.4\bin\mariadb.exe' -u root -p

Run SELECT @@datadir; and confirm C:\MariaDB\, or its equivalent forward-slash form. A service reporting Running does not by itself prove that the correct data has opened.

Verify existing data, new writes, and restart persistence

Compare existing databases and representative row counts or known values with your pre-move records. Then confirm that the following test database name is unused before running the SQL with an administrative connection. If it exists, choose another unique name and change all statements consistently. Do not create test objects inside a business database.

SELECT @@datadir;
CREATE DATABASE datadir_move_check_13862;
CREATE TABLE datadir_move_check_13862.probe (id INT PRIMARY KEY);
INSERT INTO datadir_move_check_13862.probe VALUES (1);
SELECT * FROM datadir_move_check_13862.probe;

The final query should return one row with id equal to 1. Keep external writes blocked, restart the service cleanly once more, reconnect, and run:

SELECT @@datadir;
SELECT * FROM datadir_move_check_13862.probe;

The new path and row 1 should both persist. Remove only the test database with the following statement, then check the application's real connection and read/write behavior before resuming traffic. A newly created folder alone does not prove that all InnoDB data was migrated correctly.

DROP DATABASE datadir_move_check_13862;

Retain the source directory until verification and your backup-retention requirements are satisfied. Update backup jobs and monitoring to cover the new location.

Troubleshoot failed startup or an unchanged path

  • The old datadir appears: check whether you edited the wrong file, a later option or service argument overrides it, or the client connected to another instance's port or socket.
  • Permission denied or a test file cannot be created: verify the service account, traversal access through parent directories, and destination write access. Check AppArmor/systemd denials on Ubuntu and the actual service account's ACL on Windows.
  • Missing system tables or databases: look for an extra directory level or an incomplete copy. Do not initialize the destination or delete ibdata1 and log files in an attempt to fix it.
  • Failure after reboot: confirm persistent mounting, startup ordering, and stable drive letters.

On Ubuntu, inspect the failing path and timestamp in the logs. namei helps identify permissions on every parent directory.

sudo journalctl -u mariadb -b -n 100 --no-pager
sudo journalctl -k -b --no-pager
namei -l /data/mariadb
sudo systemctl cat mariadb

On Windows, check the configured log_error location, .err files in the new and old data directories, and relevant Event Viewer messages. A generic service error such as 1067 does not establish the cause. Consult MariaDB startup diagnostics for error-specific checks.

When and how to roll back

If external writes have not been allowed at the new location, stop MariaDB and verify that it has exited, then restore the saved configuration or the original datadir value. Revert only the AppArmor alias or systemd drop-in introduced for this move, retaining unrelated settings. If unit settings changed, run daemon-reload before starting the service, then verify the original path and existing data.

If real writes have already occurred at the new location, the retained source is stale. Simply pointing back can lose those changes. Block writes again, back up the latest data, and plan a stopped reverse migration or an appropriate recovery. Do not mix files from the two directories or run both copies simultaneously.