XFS handles database workloads better than ext4 – better concurrent I/O, more efficient metadata operations for tables-heavy schemas, and delayed allocation that improves write throughput. The obvious approach is to change MySQL’s datadir in the config. The less obvious approach is bind mounts, which keep every path where the system expects it.

Setup

Install XFS utilities alongside MySQL:

sudo apt-get install -y xfsprogs mysql-server

Create the filesystem on the dedicated volume:

grep -q xfs /proc/filesystems || sudo modprobe xfs
sudo mkfs.xfs -f /dev/sdx

Mount with noatime – no reason to update access timestamps on every read when MySQL is managing its own caching:

echo "/dev/sdx /data xfs noatime 0 0" | sudo tee -a /etc/fstab
sudo mkdir -m 000 /data
sudo mount /data

Bind mounts

Stop MySQL, move its directories to the XFS volume, then bind mount them back to the original paths:

sudo service mysql stop

sudo mkdir /data/etc /data/lib /data/log

sudo mv /etc/mysql     /data/etc/
sudo mv /var/lib/mysql  /data/lib/
sudo mv /var/log/mysql  /data/log/

sudo mkdir /etc/mysql /var/lib/mysql /var/log/mysql

Add the bind mounts to fstab:

echo "/data/etc/mysql /etc/mysql     none bind" | sudo tee -a /etc/fstab
echo "/data/lib/mysql /var/lib/mysql none bind" | sudo tee -a /etc/fstab
echo "/data/log/mysql /var/log/mysql none bind" | sudo tee -a /etc/fstab

sudo mount /etc/mysql
sudo mount /var/lib/mysql
sudo mount /var/log/mysql

Start MySQL:

sudo service mysql start

Verify with df -h /var/lib/mysql – it should show the XFS volume.

Why bind mounts

MySQL’s config hasn’t changed. Package upgrades, maintenance scripts, backup tools – anything that expects MySQL data at /var/lib/mysql continues to work. AppArmor profiles that reference the default paths don’t need updating. No custom MySQL configuration to maintain or explain.

The data lives on XFS. The paths stay where the system expects them. The bind mount is transparent to everything above the filesystem layer.

Rollback is straightforward: unmount the binds, move the directories back. The original paths are empty mount points – nothing was destroyed.