MYSQL TMPDIR em TMPFS com SELINUX ativado
Eu sou daqueles caras teimosos que insiste em usar o SELINUX ao invés de desligar ele após a instalação do servidor :)
Eis que estava montando um servidor MYSQL para o Zabbix no CentOS 6.5 e resolvi criar um diretório temporário para o MYSQL em um TMPFS para obter uma melhor performance do Zabbix.
Basicamente fiz o seguinte
service mysqld stop
Criei o diretório
mkdir /mytmp
No my.cnf coloquei o seguinte
tmpdir=/mytmp
No fstab coloquei o seguinte
tmpfs /mytmp tmpfs rw,uid=mysql,gid=mysql,size=1g,nr_inodes=10k,mode=0775 0 0
Montei o tmpfs
mount /mytmp
Iniciei o mysql
service mysqld start
Porém, quando eu iniciava o MYSQL, os seguintes erros apareciam no LOG
/usr/libexec/mysqld: Can't create/write to file '/tmpfs/ibbBLVnW' (Errcode: 13)
140829 12:23:42 InnoDB: Error: unable to create temporary file; errno: 13
140829 12:23:42 [ERROR] Plugin 'InnoDB' init function returned error.
140829 12:23:42 [ERROR] Plugin 'InnoDB' registration as a STORAGE ENGINE failed.
O sintoma do lado da aplicação era um access denied na conexão com o banco, os desavisados podem perder muito tempo tentando acertar permissões mas não é esse o problema, isto ocorria pois o MySQL não conseguia escrever no ponto de montagem TMPFS, veja o erro no detalhe
/usr/libexec/mysqld: Can't create/write to file '/tmpfs/ibbBLVnW' (Errcode: 13)
Sabendo que o SELINUX estava ligado fui olhar no /var/log/audit/audit.log
cat /var/log/audit/*.log |grep mysql|grep -v zabbix|grep tmpfs
Encontrei então a seguinte informação
type=AVC msg=audit(1408993827.194:10192): avc: denied { write } for pid=28603 comm="mysqld" name="/" dev=tmpfs ino=708243 scontext=unconfined_u:system_r:mysqld_t:s0 tcontext=unconfined_u:object_r:default_t:s0 tclass=dir
No log acima é possível ver que o MYSQL tentou escrever em um diretorio da raiz que montava um TMPFS e não conseguiu devido ao contexto do diretório, tive então que checar o contexto do diretório, para isto eu rodei o comando abaixo
ls -Z /|grep mytmp
A saída recebida foi esta
drwxr-xr-x. root root unconfined_u:object_r:default_t:s0 mytmp
Veja que o conexto acima está com o tipo default_t, e neste caso, quando o SELINUX está ativo, o mysql não consegue escrever no diretório.
Para resolver a questão foi necessário ajustar o contexto do diretório para mysqld_db_t, só assim o mysql terá condições de escrever dentro dele.
Usei o semanage para definir o contexto default do diretório
semanage fcontext -a -t mysqld_db_t "/mytmp(/.*)?"
E depois rodei um restorecon para corrigir o contexto do diretório
restorecon -Rv /mytmp/
Acompanhe a saída do restorecon
restorecon reset /mytmp context unconfined_u:object_r:tmp_t:s0->unconfined_u:object_r:mysqld_db_t:s0
Feito isto, iniciei o MYSQL sem erros no log.
Os erros na aplicação também foram solucionados.
O processo é o mesmo se deseja colocar o diretório DATA do MYSQL em outro local em um servidor com SELINUX ativado.
[s]
Guto