sql >> Base de Datos >  >> RDS >> Mysql

Mi base de datos MySQL está dañada... ¿Qué hago ahora?

¿Cómo se corrompen las tablas MySQL? Hay muchas maneras de estropear los archivos de datos. A menudo, la corrupción se debe a defectos en la plataforma subyacente, en la que se basa MySQL para almacenar y recuperar datos:subsistema de disco, controladores, canales de comunicación, controladores, firmware u otras fallas de hardware. La corrupción de datos también puede ocurrir si el demonio del servidor MySQL se reinicia repentinamente, o si su servidor se reinicia debido a un bloqueo de otros componentes del sistema operativo. Si la instancia de la base de datos estaba en medio de la escritura de datos en el disco, podría escribir los datos parcialmente, lo que podría terminar con una suma de verificación de página diferente a la esperada. También ha habido errores en MySQL, por lo que incluso si el hardware del servidor está bien, MySQL mismo puede causar daños.

Por lo general, cuando los datos de MySQL se corrompen, la recomendación es restaurarlos desde la última copia de seguridad, cambiar al servidor DR o eliminar el nodo afectado si tiene un clúster de Galera para servir datos inmediatamente desde otros nodos. En algunos casos, no puede:si la copia de seguridad no está allí, el clúster nunca se configuró, su replicación estuvo inactiva durante mucho tiempo o el procedimiento DR nunca se probó. Incluso si tiene una copia de seguridad, es posible que desee realizar algunas acciones para intentar la recuperación, ya que puede llevar menos tiempo volver a conectarse.

MyISAM, lo malo y lo feo

InnoDB es más tolerante a fallas que MyISAM. InnoDB tiene funciones de recuperación automática y es mucho más seguro en comparación con el antiguo motor MyISAM.

Las tablas MyISAM pueden corromperse fácilmente cuando ocurren muchas escrituras y muchos bloqueos en esa tabla. El motor de almacenamiento "escribe" datos en la memoria caché del sistema de archivos, lo que puede llevar algún tiempo antes de que se vacíe en el disco. Por lo tanto, si su servidor se reinicia repentinamente, se perderá una cantidad desconocida de datos en el caché. Esa es una forma habitual de corromper los datos de MyISAM. La recomendación es migrar de MyISAM a InnoDB, pero puede haber casos en los que esto no sea posible.

Primum non nocere, el respaldo

Antes de intentar reparar las tablas dañadas, primero debe hacer una copia de seguridad de los archivos de su base de datos. Sí, ya está roto, pero esto es para minimizar el riesgo de posibles daños adicionales que puedan ser causados ​​por una operación de recuperación. No hay garantía de que cualquier acción que realice no dañe los bloques de datos intactos. Forzar la recuperación de InnoDB con valores superiores a 4 puede dañar los archivos de datos, así que asegúrese de hacerlo con una copia de seguridad previa e idealmente en una copia física separada de la base de datos.

Para hacer una copia de seguridad de todos los archivos de todas sus bases de datos, siga estos pasos:

Detener el servidor MySQL

service mysqld stop

Escriba el siguiente comando para su directorio de datos.

cp -r /var/lib/mysql /var/lib/mysql_bkp

Una vez que tengamos una copia de respaldo del directorio de datos, estamos listos para comenzar a solucionar problemas.

Identificación de corrupción de datos

El registro de errores es tu mejor amigo. Por lo general, cuando se dañan los datos, encontrará información relevante (incluidos enlaces a la documentación) en el registro de errores. Si no sabe dónde se encuentra, consulte my.cnf y la variable log_error; para obtener más detalles, consulte este artículo https://dev.mysql.com/doc/refman/8.0/en/error-log-destination-configuration. html Lo que también debe saber es su tipo de motor de almacenamiento. Puede encontrar esta información en el registro de errores o en information_schema.

mysql> select table_name,engine from information_schema.tables where table_name = '<TABLE>' and table_schema = '<DATABASE>';

Las principales herramientas/comandos para diagnosticar problemas de corrupción de datos son CHECK TABLE, REPAIR TABLE y myisamchk. El cliente mysqlcheck realiza el mantenimiento de tablas:comprueba, repara (MyISAM), optimiza o analiza tablas mientras se ejecuta MySQL.

mysqlcheck -uroot -p <DATABASE>

Reemplace BASE DE DATOS con el nombre de la base de datos y reemplace TABLA con el nombre de la tabla que desea verificar:

mysqlcheck -uroot -p <DATABASE> <TABLE>

Mysqlcheck comprueba la base de datos y las tablas especificadas. Si una tabla pasa la verificación, mysqlcheck muestra OK para la tabla.

employees.departments                              OK
employees.dept_emp                                 OK
employees.dept_manager                             OK
employees.employees                                OK
Employees.salaries
Warning  : Tablespace is missing for table 'employees/salaries'
Error    : Table 'employees.salaries' doesn't exist in engine
status   : Operation failed
employees.titles                                   OK

Los problemas de corrupción de datos también pueden estar relacionados con problemas de permisos. En algunos casos, el sistema operativo puede cambiar el punto de montaje al modo de solo lectura debido a problemas de lectura/escritura o esto puede ser causado por un usuario que accidentalmente cambió la propiedad de los archivos de datos. En tales casos, encontrará información relevante en el registro de errores.

[[email protected] employees]# ls -rtla
...
-rw-rw----. 1 mysql mysql  28311552 05-10 06:24 titles.ibd
-rw-r-----. 1 root  root  109051904 05-10 07:09 salaries.ibd
drwxr-xr-x. 7 mysql mysql      4096 05-10 07:12 ..
drwx------. 2 mysql mysql      4096 05-10 07:17 .

Cliente MySQL

MariaDB [employees]> select count(*) from salaries;
ERROR 1932 (42S02): Table 'employees.salaries' doesn't exist in engine

Entrada de registro de errores

2018-05-10  9:15:38 140703666226944 [ERROR] InnoDB: Failed to find tablespace for table `employees`.`salaries` in the cache. Attempting to load the tablespace with space id 9
2018-05-10  9:15:38 140703666226944 [ERROR] InnoDB: Operating system error number 13 in a file operation.
2018-05-10  9:15:38 140703666226944 [ERROR] InnoDB: The error means mysqld does not have the access rights to the directory.
2018-05-10  9:15:38 140703666226944 [ERROR] InnoDB: Cannot open datafile for read-only: './employees/salaries.ibd' OS error: 81
2018-05-10  9:15:38 140703666226944 [ERROR] InnoDB: Operating system error number 13 in a file operation.
2018-05-10  9:15:38 140703666226944 [ERROR] InnoDB: The error means mysqld does not have the access rights to the directory.
2018-05-10  9:15:38 140703666226944 [ERROR] InnoDB: Could not find a valid tablespace file for `employees/salaries`. Please refer to http://dev.mysql.com/doc/refman/5.7/en/innodb-troubleshooting-datadict.html for how to resolve the issue.

Recuperación de la tabla InnoDB

Si está utilizando el motor de almacenamiento InnoDB para una tabla de base de datos, puede ejecutar el proceso de recuperación de InnoDB.
Para habilitar la recuperación automática, MySQL necesita que la opción innodb_force_recovery esté habilitada. Innodb_force_recovery obliga a InnoDB a iniciarse mientras evita que se ejecuten operaciones en segundo plano, para que pueda volcar sus tablas.

Para hacer esto, abra my.cnf y agregue la siguiente línea a la sección [mysqld]:

[mysqld]
innodb_force_recovery=1
service mysql restart

Debe comenzar desde innodb_force_recovery=1, guardar los cambios en el archivo my.cnf y luego reiniciar el servidor MySQL usando el comando apropiado para su sistema operativo. Si puede volcar sus tablas con un valor de innodb_force_recovery de 3 o menos, entonces está relativamente seguro. En muchos casos tendrás que subir hasta 4 y como ya sabes eso puede corromper los datos.

[mysqld]
innodb_force_recovery=1
service mysql restart

Si es necesario, cambie al valor más alto, seis es el máximo y el más peligroso.

Una vez que pueda iniciar su base de datos, escriba el siguiente comando para exportar todas las bases de datos al archivo bases de datos.sql:

mysqldump --all-databases --add-drop-database --add-drop-table > dump.sql

Inicie mysql y luego intente eliminar la base de datos o las bases de datos afectadas mediante el comando DROP DATABASE. Si MySQL no puede eliminar una base de datos, puede eliminarla manualmente siguiendo los pasos a continuación después de detener el servidor MySQL.

service mysqld stop

Si no pudo eliminar una base de datos, escriba los siguientes comandos para eliminarla manualmente.

cd /var/lib/mysql
rm -rf <DATABASE>

Asegúrese de no eliminar los directorios de la base de datos interna.
Una vez que haya terminado, comente la siguiente línea en [mysqld] para desactivar el modo de recuperación de InnoDB.

#innodb_force_recovery=...

Guarde los cambios en el archivo my.cnf y luego inicie el servidor MySQL

service mysqld start

Escriba el siguiente comando para restaurar las bases de datos desde el archivo de copia de seguridad que creó en el paso 5:

mysql> tee import_database.log
mysql> source dump.sql

Reparación de MyISAM

Si mysqlcheck informa un error para una tabla, escriba el comando mysqlcheck con el indicador -reparar para corregirlo. La opción de reparación de mysqlcheck funciona mientras el servidor está en funcionamiento.

mysqlcheck -uroot -p -r <DATABASE> <TABLE>

Si el servidor no funciona y por alguna razón mysqlcheck no puede reparar su tabla, aún tiene la opción de realizar la recuperación directamente en los archivos usando myisamchk. Con myisamchk, debe asegurarse de que el servidor no tenga las mesas abiertas.

Detener MySQL

service mysqld stop
cd /var/lib/mysql

Cambie al directorio donde se encuentra la base de datos.

cd /var/lib/mysql/employees
myisamchk <TABLE>

Para verificar todas las tablas en una base de datos, escriba el siguiente comando:

myisamchk *.MYI

Si el comando anterior no funciona, puede intentar eliminar los archivos temporales que pueden estar impidiendo que myisamchk se ejecute correctamente. Para hacer esto, vuelva al directorio de datos y luego ejecute el siguiente comando:

ls */*.TMD

Si hay algún archivo .TMD en la lista, elimínelo:

rm */*.TMD

Luego vuelva a ejecutar myisamchk.

Para intentar reparar una tabla, ejecute el siguiente comando, reemplazando TABLE con el nombre de la tabla que desea reparar:

myisamchk --recover <TABLE>

Reinicie el servidor MySQL

service mysqld start

Cómo evitar la pérdida de datos

Hay varias cosas que puede hacer para minimizar el riesgo de datos irrecuperables. En primer lugar, copias de seguridad. El problema con las copias de seguridad es que a veces se pueden pasar por alto. Para las copias de seguridad programadas por cron, generalmente escribimos scripts de contenedor que detectan problemas en el registro de la copia de seguridad, pero eso no incluye los casos en los que la copia de seguridad no se inició en absoluto. Cron a veces puede bloquearse y, a menudo, no hay un conjunto de monitoreo en él. Otro problema potencial podría ser el caso cuando la copia de seguridad nunca se configuró. La buena práctica es ejecutar informes desde una herramienta separada que analizará el estado de la copia de seguridad y le informará sobre los programas de copias de seguridad faltantes. Puede usar ClusterControl para eso o escribir sus propios programas.

Informe de respaldo operativo de ClusterControl

Para reducir el impacto de la posible corrupción de datos, siempre debe considerar los sistemas en clúster. Es solo cuestión de tiempo que la base de datos se bloquee o se corrompa, por lo que es bueno tener una copia a la que pueda cambiar. Podría ser la replicación Maestro/Esclavo. El aspecto importante aquí es tener una recuperación automática segura para minimizar la complejidad del cambio y minimizar el tiempo de recuperación (RTO).

Características de recuperación automática de ClusterControl