sql >> Base de Datos >  >> RDS >> MariaDB

Mi base de datos MySQL no tiene espacio en disco

Cuando el servidor MySQL se quedó sin espacio en disco, vería uno de los siguientes errores en su aplicación (así como en el registro de errores de MySQL):

ERROR 3 (HY000) at line 1: Error writing file '/tmp/AY0Wn7vA' (Errcode: 28 - No space left on device)

Para el registro binario, el mensaje de error se ve así:

[ERROR] [MY-000035] [Server] Disk is full writing './binlog.000019' (OS errno 28 - No space left on device). Waiting for someone to free space... Retry in 60 secs. Message reprinted in 600 secs.

Para el registro de retransmisión, el mensaje de error se ve así:

[ERROR] [MY-000035] [Server] Disk is full writing './relay-bin.000007' (OS errno 28 - No space left on device). Waiting for someone to free space... Retry in 60 secs. Message reprinted in 600 secs.

Para el registro de consultas lentas, verá un mensaje de error como este:

[ERROR] [MY-011263] [Server] Could not use /var/log/mysql/mysql-slow.log for logging (error 28 - No space left on device). Turning logging off for the server process. To turn it on again: fix the cause, then either restart the query logging by using "SET GLOBAL SLOW_QUERY_LOG=ON" or restart the MySQL server.

Para InnoDB se ve así:

[ERROR] [MY-012144] [InnoDB] posix_fallocate(): Failed to preallocate data for file ./#innodb_temp/temp_8.ibt, desired size 16384 bytes. Operating system error number 28. Check that the disk is not full or a disk quota exceeded. Make sure the file system supports this function. Some operating system error numbers are described at http://dev.mysql.com/doc/refman/8.0/en/operating-system-error-codes.html
[Warning] [MY-012638] [InnoDB] Retry attempts for writing partial data failed.
[ERROR] [MY-012639] [InnoDB] Write to file ./#innodb_temp/temp_8.ibt failed at offset 81920, 16384 bytes should have been written, only 0 were written. Operating system error number 28. Check that your OS and file system support files of this size. Check also that the disk is not full or a disk quota exceeded.
[ERROR] [MY-012640] [InnoDB] Error number 28 means 'No space left on device'
[Warning] [MY-012145] [InnoDB] Error while writing 16384 zeroes to ./#

Todos informan el mismo número de código de error, que es 28. Alternativamente, podemos usar el código de error para ver el error real con el comando perror:

$ perror 28
OS error code  28: No space left on device

Lo anterior simplemente significa que el servidor MySQL no tiene espacio en disco, y la mayoría de las veces MySQL se detiene o se estanca en este punto. En esta publicación de blog, buscaremos formas de resolver este problema para MySQL que se ejecuta en un entorno basado en Linux.

Resolución de problemas

En primer lugar, debemos determinar qué partición de disco está llena. MySQL se puede configurar para almacenar datos en un disco o partición diferente. Mire la ruta como se indica en el error para comenzar. En este ejemplo, nuestro directorio está ubicado en la ubicación predeterminada, /var/lib/mysql, que se encuentra debajo de la partición /. Podemos usar el comando df y especificar la ruta completa al directorio de datos para obtener la partición en la que se almacenan los datos:

$ df -h /var/lib/mysql
Filesystem      Size Used Avail Use% Mounted on
/dev/sda1        40G 40G 20K 100% /

Lo anterior significa que tenemos que liberar algo de espacio en la partición raíz.

Soluciones provisionales

La solución temporal es liberar algo de espacio en el disco para que MySQL pueda escribir en el disco y reanudar la operación. Las cosas que podemos hacer si nos enfrentamos a este tipo de problema están relacionadas con:

  • La eliminación de archivos innecesarios
  • Purga de los registros binarios
  • Quitar mesas viejas o reconstruir una mesa muy grande

Eliminar archivos innecesarios

Éste suele ser el primer paso que se debe realizar si el servidor MySQL no funciona o no responde, o si no tiene habilitados los registros binarios. Por ejemplo, los archivos en /var/log/ suelen ser el primer lugar para buscar archivos innecesarios:

$ cd /var/log
$ find . -type f -size +5M -exec du -sh {} +
8.1M ./audit/audit.log.6
8.1M ./audit/audit.log.5
8.1M ./audit/audit.log.4
8.1M ./audit/audit.log.3
8.1M ./audit/audit.log.2
8.1M ./audit/audit.log.1
11M ./audit/audit.log
8.5M ./secure-20190429
8.0M ./wtmp

El ejemplo anterior muestra cómo recuperar archivos de más de 5 MB. Podemos eliminar de forma segura los archivos de registro rotados que normalmente tienen el formato {nombre de archivo}.{número}, por ejemplo, desde audit.log.1 hasta audit.log.6. Lo mismo puede decirse de cualquier copia de seguridad antigua enorme que esté almacenada en el servidor. Si realizó una restauración a través de Percona Xtrabackup o MariaDB Backup, todos los archivos con el prefijo xtrabackup_ se pueden eliminar del directorio de datos de MySQL, ya que ya no son necesarios para la restauración. El archivo xtrabackup_log suele ser el archivo más grande, ya que contiene todas las transacciones ejecutadas mientras el proceso xtrabackup copiaba el directorio de datos en el destino. El siguiente ejemplo muestra todos los archivos relacionados en MySQL datadir:

$ ls -lah /var/lib/mysql | grep xtrabackup_
-rw-r-----.  1 mysql root   286 Feb 4 11:30 xtrabackup_binlog_info
-rw-r--r--.  1 mysql root    24 Feb 4 11:31 xtrabackup_binlog_pos_innodb
-rw-r-----.  1 mysql root    83 Feb 4 11:31 xtrabackup_checkpoints
-rw-r-----.  1 mysql root   808 Feb 4 11:30 xtrabackup_info
-rw-r-----.  1 mysql root  179M Feb 4 11:31 xtrabackup_logfile
-rw-r--r--.  1 mysql root     1 Feb 4 11:31 xtrabackup_master_key_id
-rw-r-----.  1 mysql root   248 Feb 4 11:31 xtrabackup_tablespaces

Por lo tanto, es seguro eliminar los archivos mencionados. Inicie el servicio MySQL una vez que haya al menos un 10 % más de espacio libre.

Purgar los registros binarios

Si el servidor MySQL sigue respondiendo y tiene el registro binario habilitado, por ejemplo, para la replicación o la recuperación de un punto en el tiempo, podemos eliminar los archivos de registro binarios antiguos usando la instrucción PURGE y proporcionando la intervalo. En este ejemplo, estamos eliminando todos los registros binarios anteriores a hace 3 días:

mysql> SHOW BINARY LOGS;
mysql> PURGE BINARY LOGS BEFORE DATE(NOW() - INTERVAL 3 DAY);
mysql> SHOW BINARY LOGS;

Para la replicación de MySQL, es seguro eliminar todos los registros que se replicaron y aplicaron en los esclavos. Compruebe el valor de Relay_Master_Log_File en el servidor:

mysql> SHOW SLAVE STATUS\G
...
        Relay_Master_Log_File: binlog.000008
...

Y elimine los archivos de registro más antiguos, por ejemplo, binlog.000007 y anteriores. Es una buena práctica reiniciar el servidor MySQL para asegurarse de que tiene suficientes recursos. También podemos permitir que la rotación del registro binario se realice automáticamente a través de la variable expire_logs_days (

mysql> SET GLOBAL expire_logs_days = 3;

Luego, agregue la siguiente línea en el archivo de configuración de MySQL en la sección [mysqld]:

expire_logs_days=3

En MySQL 8.0, use binlog_expire_logs_seconds en su lugar, donde el valor predeterminado es 2592000 segundos (30 días). En este ejemplo, lo reducimos a solo 3 días (60 segundos x 60 minutos x 24 horas x 3 días):

mysql> SET GLOBAL binlog_expire_logs_seconds = (60*60*24*3);
mysql> SET PERSIST binlog_expire_logs_seconds = (60*60*24*3);

SET PERSIST se asegurará de que la configuración se cargue en el próximo reinicio. La configuración establecida por este comando se almacena dentro de /var/lib/mysql/mysqld-auto.cnf.

Eliminar tablas antiguas/Reconstruir tablas

Tenga en cuenta que la operación DELETE no liberará espacio en el disco a menos que se ejecute OPTIMIZE TABLE después. Por lo tanto, si ha eliminado muchas filas y desea devolver el espacio libre al sistema operativo después de una gran operación de ELIMINACIÓN, ejecute OPTIMIZE TABLE o reconstruya. Por ejemplo:

mysql> DELETE tbl_name WHERE id < 100000; -- remove 100K rows
mysql> OPTIMIZE TABLE tbl_name;

También podemos forzar la reconstrucción de una tabla usando la instrucción ALTER:

mysql> ALTER TABLE tbl_name FORCE;
mysql> ALTER TABLE tbl_name; -- a.k.a "null" rebuild

Tenga en cuenta que la operación DDL anterior se realiza a través de DDL en línea, lo que significa que MySQL permite operaciones DML simultáneas mientras la reconstrucción está en curso. Otra forma de realizar una operación de desfragmentación es utilizar mysqldump para volcar la tabla en un archivo de texto, soltar la tabla y volver a cargarla desde el archivo de volcado. En última instancia, también podemos usar DROP TABLE para eliminar la tabla no utilizada o TRUNCATE TABLE para borrar todas las filas de la tabla, lo que en consecuencia devuelve el espacio al sistema operativo.

Soluciones permanentes para problemas de espacio en disco

La solución permanente es, por supuesto, agregar más espacio al disco o partición correspondiente, o aplicar una regla de retención más corta para mantener los archivos innecesarios en el servidor. Si está ejecutando sobre un sistema de almacenamiento de archivos escalable, debería poder escalar el recurso sin demasiados problemas, o con una interrupción y un tiempo de inactividad mínimos para el servicio MySQL. Para obtener más información sobre cómo dimensionar su almacenamiento y comprender la planificación de la capacidad de MySQL y MariaDB, consulte esta publicación de blog.

Resumen

Los problemas de la base de datos relacionados con el disco son uno de los problemas más frecuentes que afectan a los administradores y desarrolladores de la base de datos MySQL que trabajan con RDBMS por igual; sin embargo, aunque esos problemas pueden ser frecuentes, también hay muchas maneras de resolverlos y resolverlos para siempre. Las formas de abordar este problema pueden no ser siempre sencillas, sin embargo, todas se pueden resolver con un poco de esfuerzo y la asistencia proporcionada por herramientas como ClusterControl.

Con las capacidades de monitoreo proactivo de ClusterControl, los problemas relacionados con la base de datos deberían ser la menor de sus preocupaciones:recibirá una notificación en forma de advertencia cuando el espacio en disco haya alcanzado el 80% y una notificación en forma de advertencia crítica si su el uso del disco alcanza el 90% o más. Esperamos que esta publicación de blog le haya permitido resolver al menos un par de problemas relacionados con el uso de espacio en disco de MySQL, disfrute de su uso de ClusterControl y nos vemos en el próximo blog.