Change MySQL data folder on SELinux

When installing MySQL on SELinux (Security Enhanced Linux), you may get the following errors in mysqld.log if you

changed the default data directory for mysql database even you granted all necessary privileges to the user mysql:
111206  1:46:00 [Warning] Can’t create test file /data/mysql/devmysql.lower-test
111206  1:46:00 [Warning] Can’t create test file /data/mysql/devmysql.lower-test
/usr/libexec/mysqld: Can’t change dir to ‘/data/mysql/’ (Errcode: 13)
111206  1:46:00 [ERROR] Aborting

This is because on SELinux such as CentOS 6, all processes and files are labeled in a way that represents

security-relevant information. This information is called the SELinux context. For files, this is viewed using the

ls -Z command:
$ ls -Z file1
-rw-rw-r–  user1 group1 unconfined_u:object_r:user_home_t:s0 file1

In this example, SELinux provides a user (unconfined_u), a role (object_r), a type (user_home_t), and a level (s0).

This information is used to make access control decisions. On DAC systems, access is controlled based on Linux user

and group IDs. SELinux policy rules are checked after DAC rules. SELinux policy rules are not used if DAC rules

deny access first.

So when we change the mysql datadir to a different folder, besides granting the access permission for the mysql

user, we also need to  change the lable of the new folder.

First we need to know what it is the correct labeling using -Z command on the default data dir:
[root@xxx ~]# ls -lh -Zd /var/lib/mysql
drwxr-xr-x. mysql mysql system_u:object_r:mysqld_db_t:s0 /var/lib/mysql

Now change the label for the new location:
chcon -R -u system_u -r object_r -t mysqld_db_t /data/mysql

To verify the lable is changed:
ls -lh -Zd /data/mysql
drwxr-xr-x. mysql mysql system_u:object_r:mysqld_db_t:s0 /data/mysql

Note the mysql config file has a different lable, do not use that one for the data dir.

[root@xxx ~]# ls -lh -Z /etc/my.cnf
-rw-r–r–. root root system_u:object_r:mysqld_etc_t:s0 /etc/my.cnf

If binlog file is put in a different location (e.g. /mysql-log/mysql), we also need to change the label for the

root folder (/mysql-log) and the subfolder /mysql-log/mysql.

Now we can install the system tables:
mysql_install_db –datadir=/data/mysql –user=mysql

 

This entry was posted in Linux, MySQL. Bookmark the permalink.

10 Responses to Change MySQL data folder on SELinux

  1. Pingback: Selinux mysql | Tamihughson

  2. Suresh says:

    Very very helpful. Thanks a lot. I have been trying for almost a day to find out the reason for linux not allowing links or mount directories for /var/lib/mysql

    Reference: mysql on different data directory
    — sunambiar

  3. Igor says:

    Thanks for help.
    — igor

  4. Haluk Akin says:

    This was great help. In my case the parent directory was also causing problems. I had to run the following commands back to back:
    chcon -R –reference=/var/lib /database
    chcon -R –reference=/var/lib/mysql /database/mysql

  5. hansbaer says:

    Thanks a lot – I kept struggling all evening yesterday with that until I found this very helpful clue this morning.

  6. Gary Pullis says:

    Peter,

    Thanks for being another soldier in the constant war against SELinux driving sysadmins everywhere bat-poop crazy.

    With this tip, I got my databases moved to another mount-point and live to fight another day.

Leave a comment