¿Qué causaría que mysqlcheck informara incorrectamente que una tabla no está dañada?

¿Qué causaría que mysqlcheck informara incorrectamente que una tabla no está dañada?

Estamos administrando un servidor MySQL para uno de nuestros clientes que tiene >100 bases de datos con aproximadamente 50 tablas cada una, muchas de ellas tablas InnoDB. El servidor falló y estoy intentando encontrar al culpable. Al reiniciar con innodb_force_recovery = 2, puedo conectarme y no veo ningún error en el archivo error.log. Más importante aún, mysqlcheck --all-databasesinforma "OK" para todas las tablas. Pero cuando elimino innodb_force_recovery, el servidor vuelve a fallar, escribe un seguimiento de la pila en error.log y solo se puede detener con kill -9.

¿Cómo se supone que debo encontrar la base de datos infractora en estas circunstancias y qué causaría que mysqlcheck omitiera las tablas corruptas? Por favor, no me diga que simplemente lo ignore y restaure todas las bases de datos desde los volcados. Eso podría ser aceptable para una o dos bases de datos y si ocurre solo una vez en una luna azul, pero he tenido problemas con el mismo servidor más de una vez y restaurar todo desde los volcados simplemente requiere demasiado tiempo y trabajo manual para hacerlo cada vez. tiempo.

La versión del servidor es 5.5.46 y innodb_file_per_tableestá activa.

Extracto de error.log según lo solicitado (¿significa que The tablespace free space info is corrupthay un error que no está en una tabla específica y que no se puede corregir?):

180222 17:13:48 mysqld_safe Starting mysqld daemon with databases from /home/mysql
180222 17:13:48 [Warning] 'THREAD_CONCURRENCY' is deprecated and will be removed in a future release.
180222 17:13:48 [Note] /usr/libexec/mysqld (mysqld 5.5.46) starting as process 26242 ...
180222 17:13:48 [Note] Plugin 'FEDERATED' is disabled.
180222 17:13:48 InnoDB: The InnoDB memory heap is disabled
180222 17:13:48 InnoDB: Mutexes and rw_locks use InnoDB's own implementation
180222 17:13:48 InnoDB: Compressed tables use zlib 1.2.3
180222 17:13:48 InnoDB: Using Linux native AIO
180222 17:13:48 InnoDB: Initializing buffer pool, size = 128.0M
180222 17:13:49 InnoDB: Completed initialization of buffer pool
180222 17:13:49 InnoDB: highest supported file format is Barracuda.
180222 17:13:49  InnoDB: Waiting for the background threads to start
180222 17:13:50 InnoDB: 5.5.46 started; log sequence number 1632912830888
180222 17:13:50 [Note] Server hostname (bind-address): '0.0.0.0'; port: 3306
180222 17:13:50 [Note]   - '0.0.0.0' resolves to '0.0.0.0';
180222 17:13:50 [Note] Server socket created on IP: '0.0.0.0'.
180222 17:13:50 [Note] Event Scheduler: Loaded 0 events
180222 17:13:50 [Note] /usr/libexec/mysqld: ready for connections.
Version: '5.5.46'  socket: '/var/lib/mysql/mysql.sock'  port: 3306  MySQL Community Server (GPL) by Remi
InnoDB: Dump of the tablespace extent descriptor:  len 40; hex 000000000000000200000000061600000000126e00000004ffffffffffffffffffffffffffffbfaa; asc                    n                    ;
InnoDB: Serious error! InnoDB is trying to free page 512
InnoDB: though it is already marked as free in the tablespace!
InnoDB: The tablespace free space info is corrupt.
InnoDB: You may need to dump your InnoDB tables and recreate the whole
InnoDB: database!
InnoDB: Please refer to
InnoDB: http://dev.mysql.com/doc/refman/5.5/en/forcing-innodb-recovery.html
InnoDB: about forcing recovery.
180222 17:13:50  InnoDB: Assertion failure in thread 2499464080 in file fsp0fsp.c line 3309
InnoDB: We intentionally generate a memory trap.
InnoDB: Submit a detailed bug report to http://bugs.mysql.com.
InnoDB: If you get repeated assertion failures or crashes, even
InnoDB: immediately after the mysqld startup, there may be
InnoDB: corruption in the InnoDB tablespace. Please refer to
InnoDB: http://dev.mysql.com/doc/refman/5.5/en/forcing-innodb-recovery.html
InnoDB: about forcing recovery.
16:13:50 UTC - mysqld got signal 6 ;
This could be because you hit a bug. It is also possible that this binary
or one of the libraries it was linked against is corrupt, improperly built,
or misconfigured. This error can also be caused by malfunctioning hardware.
We will try our best to scrape up some info that will hopefully help
diagnose the problem, but since we have already crashed,
something is definitely wrong and this may fail.

key_buffer_size=268435456
read_buffer_size=1048576
max_used_connections=0
max_threads=512
thread_count=0
connection_count=0
It is possible that mysqld could use up to
key_buffer_size + (read_buffer_size + sort_buffer_size)*max_threads = 1314506 K  bytes of memory
Hope that's ok; if not, decrease some variables in the equation.

Thread pointer: 0x0
Attempting backtrace. You can use the following information to find out
where mysqld died. If you see no messages after this, something went
terribly wrong...
stack_bottom = 0 thread_stack 0x30000
/usr/libexec/mysqld(my_print_stacktrace+0x33)[0x842a1f3]
/usr/libexec/mysqld(handle_fatal_signal+0x42b)[0x82d9d3b]
[0x7bc420]
[0x7bc410]
/lib/libc.so.6(gsignal+0x50)[0x626b10]
/lib/libc.so.6(abort+0x101)[0x628421]
/usr/libexec/mysqld[0x85012e7]
/usr/libexec/mysqld[0x850147e]
/usr/libexec/mysqld[0x849c0b1]
/usr/libexec/mysqld[0x84a8a61]
/usr/libexec/mysqld[0x8561fef]
/usr/libexec/mysqld[0x85570a9]
/usr/libexec/mysqld[0x847b082]
/usr/libexec/mysqld[0x846bf04]
/usr/libexec/mysqld[0x846dad4]
/lib/libpthread.so.0[0x50d912]
/lib/libc.so.6(clone+0x5e)[0x6d347e]
The manual page at http://dev.mysql.com/doc/mysql/en/crashing.html contains
information that should help you find out what is causing the crash.
180222 17:13:50 mysqld_safe Number of processes running now: 0
180222 17:13:50 mysqld_safe mysqld restarted

Respuesta1

El mensaje de error en sí le indica por qué verificar los datos de la tabla no soluciona el problema. Intentó liberar una página (probablemente de una tabla o índice); pero esa página ya estaba marcada como libre. En otras palabras, una de sus tablas o índices estaba usando una página, cuando la página se considera disponible para dársela a otra tabla o índice. Y, obviamente, si InnoDB no sabe qué páginas son realmente gratuitas, pueden pasar cosas malas.

Deshacerse de todos los datos de la tabla/índice y volver a cargarlos significa darle a InnoDB la oportunidad de reconstruir su colección de páginas gratuitas. Lo ideal sería hacer esto en una base de datos nueva. ¿Por qué? Bueno, nunca debes asumir que hay un solo error de corrupción solitario. Entonces, si mueve los datos a una instalación nueva, no tiene que preocuparse si hubo problemas de corrupción adicionales no detectados.

Respuesta2

Como se sugirió, volcar y restaurar desde esos volcados fue la forma que finalmente elegí para restaurar todas las bases de datos. Afortunadamente, innodb_force_recovery = 2me permitió volcar todo sin errores, por lo que no tuve que usar volcados de copias de seguridad. Por supuesto, preferiría haber descubierto la verdadera causa del error, pero MySQL no ofrece ayuda aparte de algunas menciones de "La información del espacio libre del espacio de tabla está corrupta" en los informes de errores. Sin identificar y eliminar la causa del error, espero que vuelva a ocurrir eventualmente; nuestro cliente probablemente estará aún más enojado que yo.

Quizás el culpable sea el hardware defectuoso, pero los datos SMART de todos los discos del sistema se ven bien y /var/log/messagesno contienen nada sospechoso en el momento del fallo. Tampoco hubo una pérdida de energía inesperada ni un reinicio.

información relacionada