El tutorial de hoy es sencillo y se puede realizar con unos cuantos comandos. Claro, si estas usando una GUI para MySQL no lo necesitarás, pero bueh, es otra cosa que es bueno aprender
Introducción
Esta es una tarea súper puntual que surgió por la necesidad de reparar una tabla que no conozco, pero que el script de respaldo avisa que tiene un error.
mariadb-dump: Error 1034: Index for table 'apcontact' is corrupt; try to repair it when dumping table `apcontact` at row: 115191
Como me lo tomé a la ligera, busqué en google para saber que hace esta tabla. Después de todo, los problemas con tablas y plugins son tan comunes que puedes buscar por el nombre de la tabla y google siempre tiene una respuesta, pero esta vez, el nombre es tan genérico que simplemente no hubo resultado.
Solucion
En realidad es muy sencillo, pero lo citaré desde donde encontré la solución que es una pagina de una empresa que ofrece servicios para bases de datos.
1 2 3 4 5 6 7 | select table_schema as database_name, table_name from information_schema.tables where table_type = 'BASE TABLE' and table_schema not in ('information_schema','mysql', 'performance_schema','sys') order by database_name, table_name; |
La consulta, que se realiza como administrador desde la consola o tu GUI preferida, es bastante sencilla. Busca de la tabla table_schema, a la cual le pone un alias database_name y de la tabla table_name desde la base de datos information_schema, la cual contiene la estructura del sistema de base de datos de MySQL.
Busca en la columna table_type cualquier fila que contenga el texto BASE TABLE y de la columna table_schema ignora ‘information_schema‘,’mysql‘, ‘performance_schema‘,’sys‘ terminando con ordenar por la columna database_name.
Esta consulta devuelve la lista de columnas que tienen todas las bases de datos en el servidor MySQL, con lo que rápidamente puedes echarle un ojo a la columna desconocida para saber a que base de datos corresponde. En mi caso, es una columna de una base de datos que ya no utilizo, pero que conservaré para la siguiente parte del tutorial.
Extra: Reparar tabla apcontact
Ya teniendo localizada la tabla, de inmediato cambio a la base de datos que la contiene con USE nombre_base;y procedemos a seguir los pasos como ya hicimos en el articulo tabla wpcomment corrupted
- Ejecuta el cliente mysql (o mariadb). mysql -u your_wordpress_user -p
- Cambia a la base de datos de tu instancia de wordpress. use your_wordpress_database
- Ejecuta el comando repair table wp_comments
Por supuesto, puede darse el caso de que te salga un error como este:
1 2 3 4 5 | +---------------------------+--------+----------+---------------------------------------------------------+ | Table | Op | Msg_type | Msg_text | +---------------------------+--------+----------+---------------------------------------------------------+ | db_interlan.apcontact | repair | note | The storage engine for the table doesn't support repair | +---------------------------+--------+----------+---------------------------------------------------------+ |
Debido a que esto es un cambio estructural, te recomiendo hacer un respaldo antes de cualquier cambio que vayas a hacer.
Encontré que la mayor parte de las soluciones implican restaurar desde un respaldo. Estoy de acuerdo con eso, pero vamos a experimentar a ver que pasa. Vamos a suicidar mi base de datos a ver si conseguimos que funcione, pero puedes revisar las fuentes de mi articulo para que tengas una vista mas lucida que la mía.
1 | ALTER TABLE tbl_name ENGINE=MyISAM; |
Por supuesto, dio error.
ERROR 1217 (23000): Cannot delete or update a parent row: a foreign key constraint fails
La razón de esto es porque el comando ALTER TABLE dispara los trigger de update y hay filas que estarán relacionadas con otras tablas, asi que esto puede causar errores de constraint. Por esta razón se suele sugerir que se restaure desde un respaldo.
Ahora como tampoco me preocupa el contenido de esa base de datos, elegiremos la opción nuclear.
1 | SET Database_name = 'yourdb'; SELECT CONCAT('ALTER TABLE ',TABLE_NAME,' ENGINE=MyISAM;') As sql_statements FROM INFORMATION_SCHEMA.TABLES WHERE table_schema = 'yourdb' AND ENGINE='InnoDB' AND TABLE_TYPE='BASE TABLE'; |
Lo que hace esto es simplemente alterar el engine de almacenamiento de toda la base de datos, con lo que no le darás tiempo a dar un contrain error, resolviendo el problema de no poder repararla. Pero ah, todavía queda reparar la tabla rota, así que intentamos de nuevo con el comando repair.
1 2 3 4 5 | +---------------------------+--------+----------+---------------------------------------------------------+ | Table | Op | Msg_type | Msg_text | +---------------------------+--------+----------+---------------------------------------------------------+ | db_interlan.apcontact | repair | note | The storage engine for the table doesn't support repair | +---------------------------+--------+----------+---------------------------------------------------------+ |
Nah, no se pudo. Mandale un respaldo desde un dump anterior jajaja.
Yo solo eliminaré la base de datos. Mi consejo será el mismo de siempre. Manten respaldos regulares y siempre mira los logs por si hay algún error por ahi que quiera agarrarte por sorpresa.
1 | DROP DATABASE db_interlan; |
Conclusiones
Las tablas corruptas se dan frecuentemente por fallos en la energía, el clasico «Sacrifiquen a los niños» y muchas razones. Reparar no es una opción muy viable, teniendo en cuenta la alta probabilidad de que no funcione. Puedes intentarlo, pero como te diste cuenta, tal vez salga mejor que restaures desde un respaldo. He hecho un script que sirve para hacerlos y de paso me manda un correo electrónico indicándome los resultados, con lo que pude ver el error. Si trabajas en esto de forma seria, no intentes reparar. sin duda alguna restaura desde un respaldo y mantelos regularmente. Si no, juega como yo y mira que sale si intentas reparar XD.


