How do I change the MySQL database directory?

I can't confirm this from cpanel, as I don't have access, but this is an example from the console connected by ssh and sudo to root. There are arguments for using a bind entry in /etc/fstab instead of a symlink, but this works for me.

My normal procedure is to stop mysql, move the directory contents, link the original, and restart mysqld.

[tomh@workstation001 ~]$ sudo su -
[root@workstation001 ~]# 

[root@workstation001 ~]# service mysqld stop
Stopping mysqld (via systemctl):  
                                                           [  OK  ]

[root@workstation001 ~]# mv /var/lib/mysql/ /opt/

[root@workstation001 ~]# ln -s /opt/mysql /var/lib/


[root@workstation001 ~]# ls -la /var/lib/mysql
lrwxrwxrwx 1 root root 10 Feb 26 23:02 /var/lib/mysql -> /opt/mysql

[root@workstation001 ~]# service mysqld start
Starting mysqld (via systemctl):                           [  OK  ]


[root@workstation001 ~]# mysql -uroot 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.5.18-log MySQL Community Server (GPL)

mysql> show databases;
...
| Database              |
+-----------------------+
| information_schema    |
| mysql                 |
| performance_schema    |
| test   

I just noticed a similar question, of which this is close to a duplicate of, which mentions some issues of doing that above with selinux enabled; http://crashmag.net/change-the-default-mysql-data-directory-with-selinux-enabled

So if you have selinux there are some additional steps.


if you want to change mysql data directory, you should do edit the mysql config file and change datadir value.

datadir = /home/user/data

Your new data directory MUST be owned by mysql and has proper SELinux security context.

chown -R    mysql:mysql /home/user/data
chcon -R -t mysqld_db_t /home/user/data

Then restart the mysql server:

systemctl restart mysql
# or
/etc/init.d/mysqld restart

I found this step by step guide working for me.

You must install:

yum install policycoreutils-python

Guide:

View the SELinux context of the default database location for mysql:

~]# ls -lZ /var/lib/mysql
drwx------. mysql mysql system_u:object_r:mysqld_db_t:s0 mysql

This shows mysqld_db_t which is the default context element for the location of database files. This context will have to be manually applied to the new database location that will be used in this example in order for it to function properly.

Stop the mysqld daemon:

~]# systemctl stop mariadb.service

Create a new directory for the new location of the database(s). In this example, /mysql/ is used:

~]# mkdir -p /mysql

Copy the database files from the old location to the new location:

~]# cp -R /var/lib/mysql/* /mysql/

Change the ownership of this location to allow access by the mysql user and group. This sets the traditional Unix permissions which SELinux will still observe:

~]# chown -R mysql:mysql /mysql

Run the following command to see the initial context of the new directory:

~]# ls -lZ /mysql
drwxr-xr-x. mysql mysql unconfined_u:object_r:usr_t:s0   mysql

The context usr_t of this newly created directory is not currently suitable to SELinux as a location for MariaDB database files. Once the context has been changed, MariaDB will be able to function properly in this area.

Open the main MariaDB configuration file /etc/my.cnf with a text editor and modify the datadir option so that it refers to the new location. In this example the value that should be entered is /mysql:

[mysqld]
datadir=/mysql

Save this file and exit.

Start mysqld. The service should fail to start, and a denial message will be logged to the /var/log/messages file:

~]# systemctl start mariadb.service
Job for mariadb.service failed. See 'systemctl status postgresql.service' and 'journalctl -xn' for details.

However, if the audit daemon is running and with him the setroubleshoot service, the denial will be logged to the /var/log/audit/audit.log file instead:

SELinux is preventing `/usr/libexec/mysqld` "write" access on /mysql. For complete SELinux messages. run `sealert -l b3f01aff-7fa6-4ebe-ad46-abaef6f8ad71`

The reason for this denial is that mysql is not labelled correctly for MariaDB data files. SELinux is stopping MariaDB from having access to the content labelled as usr_t. Perform the following steps to resolve this problem:

Run the following command to add a context mapping for mysql. Note that the semanageutility is not installed by default. If it missing on your system, install the policycoreutils-python package.

~]# semanage fcontext -a -t mysqld_db_t "/mysql(/.*)?"

This mapping is written to the /etc/selinux/targeted/contexts/files/file_contexts.local file:

~]# grep -i mysql /etc/selinux/targeted/contexts/files/file_contexts.local

/mysql(/.*)?    system_u:object_r:mysqld_db_t:s0

Now use the restorecon utility to apply this context mapping to the running system:

~]# restorecon -R -v /mysql

Now that the mysql location has been labelled with the correct context for MariaDB, mysqld starts:

~]# systemctl start mariadb.service

Confirm the context has changed for mysql:

~]$ ls -lZ /mysql
drwxr-xr-x. mysql mysql system_u:object_r:mysqld_db_t:s0 mysql

The location has been changed and labelled, and mysqld has started successfully. At this point all running services should be tested to confirm normal operation.