Cuotas de almacenamiento en MySQL: Qué pretendemos

En muchas ocasiones resulta necesario limitar el espacio de almacenamiento en un servidor atendiendo a diversos criterios, por ejemplo la limitación del espacio disponible para correo electrónico o para albergue de páginas web.

La limitación de espacio de almacenamiento no presenta mayores dificultades en los casos anteriores, ya que cada fichero que utilice el usuario será de su propiedad y el sistema de quotas realiza sus funciones directamente.

El caso de albergue de bases de datos como mysql no es tan simple debido a que son el usuario mysql y el grupo mysql los que adquieren la propiedad de todos los ficheros que utiliza, y sólo con esa información no podemos conseguir que el sistema de cuotas sea capaz de distinguir entre diversas bases de datos. Cada base de datos mantiene un directorio donde crea todos sus ficheros.

También hay que tener muy en cuenta que esta forma de limitación del espacio pudiera ocasionar un deterioro de la base de datos si se alcanza su limite por posibles actualizaciones parciales u operaciones en cache que no pueden actualizarse en disco. No olvide esta advertencia.


Pasos previos

Para asignar quotas de almacenamiento a una base de datos en mysql tendremos que seguir unos pasos previos para preparar el sistema:

En primer lugar asegurarnos que el núcleo Linux está compilado con las quotas activadas. Esto no debería plantear ningún problema, prácticamente todas las distribuciones incorporan un núcleo compilado con cuotas.

A continuación tenemos que asignar cuotas, al menos par el grupo, a la partición que contenga el directorio donde mysql almacena los ficheros de las bases de datos, /var/lib/mysql en mi caso.

Para asignar cuotas a un partición modificamos el fichero /etc/fstab y añadimos como opción grpquota en la línea correspondiente a esa partición, por ejemplo:


/dev/hda5     /var   ext3    defaults,usrquota,grpquota,nosuid 1 4

            

Esto permitiría poder controlar el espacio de almacenamiento asignado a un grupo en todo el directorio /var.

 


Asignación de cuotas a una base de datos existente.

Como hemos vito, Mysql crea y gestiona los ficheros asignándole como propietario mysql y como grupo también el grupo mysql. Aquí vamos a tener que, en primer lugar asegurarnos que el grupo propietario del directorio y su contenido pasan a propiedad del grupo que tiene la cuotas asignadas:


cd /var/lib/mysql
chgrp -R migrupo dir_basedatos

            

es decir, hacemos que dir_basedatos, que es el directorio que contiene la base de datos, pertenezca al grupo "migrupo". Este grupo es el que queremos limitar y al cual le vamos a asignar ls cuotas. Pero esto no es suficiente porque si creamos una nueva tabla, se crearía un nuevo fichero que volvería a tener como propietario mysql y como grupo mysql también, con lo cual no funcionaría el sistema de cuotas; tenemos que asegurarnos de que cada nuevo fichero que se cree en ese directorio tenga como grupo "migrupo" en lugar de "mysql". Esto es fácil, asignamos el permiso SGID al directorio y esto hace exáctamente lo que queremos, que cada nuevo fichero creado sea propiedad del grupo propietario del directorio, no del grupo que lo crea. Entonces:


chmod +s migrupo

            

El siguiente paso sería crear, si no lo tenemos, unas cuotas para una serie de usuarios prototipo. La idea es facilitar posteriormente las asignaciones de cuotas:


edquota -u prototipobd

            

Ahora ya podemos asignar cuotas de forma fácil al grupo "migrupo" copiando las cuotas que definimos para el usuario prototipobd.


edquota -p prototipobd -g migrupo

            

Ya el sistema debería controlar el espacio máximo de almacenamiento en la partición /var para el grupo "migrupo".


Crear un nueva base de datos con cuotas

Realmente el proceso es el mismo, en este caso o vamos a describir mediante un script que toma como argumentos el nombre de la base de datos y el nombre del grupo y realiza todo el proceso.


#!/bin/bash

# comprobamos una llamada correcta
if [ $# -ne 3 ]
then
        echo "Uso $0 basedatos  grupo
        exit
fi

# comprobamos que el grupo existe
if ! grep "$2:" /etc/group >/dev/null
then
        echo "el grupo no existe"
        # groupadd $2 también podríamos haber creado el grupo aquí
        exit
fi

# creamos la base de datos
mysqladmin -u root create $1

# comprobamos si la operación ha sido correcta
if [ $? -eq 1 ]
then
        echo "No he podido crear la base de datos $1"
        exit
fi

# le asignamos el grupo al directorio de  la base de datos
chgrp $2 /var/lib/mysql/$1

# asignamos el bit SGID al  directorio de  la base de datos
chmod +s /var/lib/mysql/$1

# le asignaamos al grupo las mismas quotas que el usuario prototipobd
edquota -p prototipobd  -g $2

            

Y con esto se supone que hemos creado una base de datos con limitación de espacio de almacenamiento por quotas.