20140907

Cómo modificar el tmpdir de mysql y no tener problemas de permisos al reiniciar el servicio #ubuntu #apparmor #mysql #tmpdir


Estos días me he encontrado con problemas por falta de espacio en el /tmp al hacer consultas pesadas con ordenaciones o group-bys que generaban mucho espacio temporal, por defecto el servidor venía con 2Gbs en /tmp pero con una tabla de 2 millones de registros no podia hacer algunas consultas y me fallaban por falta de espacio en /tmp.

Al intentar cambiar la variable tmpdir del my.cnf me aparecia un error al reiniciar el mysql que evitaba que arrancase (de mal en peor).

El error que me encontraba era:

/usr/sbin/mysqld: Can't create/write to file '/mnt/sdb1/tmp/ib05T1js' (Errcode: 13)
140907 10:50:18  InnoDB: Error: unable to create temporary file; errno: 13

Al final el culpable era el apparmor que define ciertos directorios donde puede escribir el mysql y otros procesos críticos del sistema.

En este mini-tutorial además aprovecharemos para crear un temporary filesystem para mejorar la eficiencia de los sorts de mysql.

NOTA: No hay garantía de que funcione! sólo lo he probado con un ubuntu 12.04 y es probable que se tengan que modificar detalles para otros sistemas.

En resumen, la idea es modificar el directorio tmpdir de mysql utilizando un temporary filesystem en un disco secundario y solucionando los problemas que da el apparmor.

Vamos a asumir que tenemos montado un filesystem en un disco secundario con poca carga /mnt/sdb1

Primero crearemos un directorio tmp en este filesystem:

cd /mnt/sdb1
mkdir -p tmp

Le damos permisos adecuados:

chmod 0777 tmp
chown mysql:mysql tmp

Obtenemos el id de grupo y de usuario de mysql:

id mysql

Editamos el /etc/fstab e incluimos la linea:

tmpfs /mnt/sdb1/tmp tmpfs rw,gid=110,uid=105,size=4G,nr_inodes=10k,mode=0700 0 0

OJO: utilizar el gid y el uid obtenidos en el paso anterior y definir size al valor que nos interese, en el ejemplo 4G (4 Gigas)

Re-montamos los filesystems:

mount -a

Editamos la configuración del tmpdir de mysql (/etc/mysql/my.cnf), parametro tmpdir:

tmpdir=/mnt/sdb1/tmp

Este es el punto crítico ya que si reiniciamos en este punto y tenemos el apparmor activado nos dará error ya que el apparmor no tiene el direcotio /mnt/sdb1/tmp como permitido para mysql.

Editamos el fichero de configuración de apparmor para mysql /etc/apparmor.d/local/usr.sbin.mysqld añadimos estas dos líneas al final:

/mnt/sdb1/tmp/ r,
/mnt/sdb1/tmp/** rw,

Reiniciamos el apparmor:

service apparmor reload

Ahora ya podemos reiniciar el mysql sin problemas:

service mysql restart


Espero que os sirva!