Change the default MySQL data directory with SELinux enabled

This is a short article that explains how you change the default MySQL data directory and adjust SELinux to account for the changes. The article assumes that you’re running either RHEL, CentOS, Scientific Linux or Fedora with SELinux enabled. This works with the most recent EL (6.2) version.

We’ll be doing this in the following order.

  • Stopping the MySQL server
  • Create a new data directory and move the content from the old data directory
  • Correct the MySQL configuration file
  • Adjust SELinux parameters to accept our new change
  • Starting the MySQL server

Stopping the MySQL server

# service mysqld stop

Create a new data diretory and move the content from the old one

Creating a new data directory

# mkdir /srv/mysql/
# chown mysql:mysql /srv/mysql

Moving the original data files

 # mv /var/lib/mysql/* /srv/mysql/

Correct the MySQL configuration file

Edit the my.cnf file for your distribution. In my example it’s located in the /etc/mysql/ directory. RHEL/CentOS/Scientific Linux put the my.cnf file directly in /etc by default.

# nano /etc/mysql/my.cnf









and save the file.

Adjust SELinux parameters to accept our new change

Should the following command output “Permissive” or “Disabled” then you may skip the details for SELinux.

# getenforce

Run the semanage command to add a context mapping for /srv/mysql.

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

Now use the restorecon command to apply this context mapping to the running system.

# restorecon -Rv /srv/mysql

Starting the MySQL server

# service mysqld start

Verifying access and connectivity

$ mysql -u root -p
mysql> show databases;

If this is working, you’re up and running. Should you get a message that says

ERROR 2002 (HY000): Can’t connect to local MySQL server through socket ‘/var/lib/mysql/mysql.sock’

then add the following to your /etc/my.cnf

socket = /srv/mysql/mysql.sock

Optionally you can just use

$ mysql -u root -p --protocol tcp

to avoid connecting via the socket.

// CrashMAG

17 thoughts on “Change the default MySQL data directory with SELinux enabled”

  1. I had try it on RHEL 6.2 and it works fine. So i’m sure it will work also on CentOS 6.2

  2. Thank you very much for this concise guide. It saved me a lot of a hassle fiddling with SELinux!!!

  3. Hi,

    I carefully followed your instruction but it failed when I start the mysql service. What I did, is to reboot(restart) the server after applying the “semanage” and “restorecon”.

    For all the people out there trying to move datadir, this is the step. Follow the instruction until you reached here,

    # semanage fcontext -a -t mysqld_db_t “/diskmnt/data1/mysql_data/mysql(/.*)?”

    then apply restorecon command to apply context mapping,

    # restorecon -Rv /diskmnt/data1/mysql_data/mysql

    As suggested in the link, I can start the mysql services

    # service mysqld start

    Since mine has failed when I start the mysql service, I decided to restart/reboot the Server, cause I was thinking may be the SELinux still looking/expecting for the default datadir ‘/var/lib/mysql’. After rebooting the server, I expect that the changes made in SELinux has been loaded or something like that. Then mysql services has started successfully after invoking “/etc/init.d/mysqld start”.

  4. On CentOS 6.0 with the 5.x installation of MySQL, the semanage context needs to be mysqld_safe_t, not mysqld_db_t.
    “semanage fcontext -a -t mysqld_safe_t “/srv/mysql(/.*)?”
    Instead of:
    “semanage fcontext -a -t mysqld_db_t “/srv/mysql(/.*)?”

  5. Thanks for the clean steps. Saved some hours. Below setting helped me.

    socket = /srv/mysql/mysql.sock

  6. I have phpmyadmin installed, which, after the above steps, can not connect to mysql. Does anyone else have this problem/solution? Thanks!!

  7. A simpler solution from an SELinux perspective would have been to simply set a Equivalency label.

    # semanage fcontext -a -e /var/lib/mysql /srv/mysql
    # restorecon -R -v /src/mysql

    grep /var/lib/mysql /etc/selinux/targeted/contexts/files/file_contexts/var/lib/mysql(/.*)? system_u:object_r:mysqld_db_t:s0
    /var/lib/mysql/mysql\.sock -s system_u:object_r:mysqld_var_run_t:s0

    Since the mysql.sock is labeled differently then the database.

    Of course I would prever if the sock was in /run/mysql/mysql.sock which would be labeled correctly.

    Socket files should be in the run directory.

Leave a Reply

Your email address will not be published. Required fields are marked *


You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>