O que faria com que o mysqlcheck relatasse incorretamente uma tabela como não danificada?

O que faria com que o mysqlcheck relatasse incorretamente uma tabela como não danificada?

Estamos administrando um servidor MySQL para um de nossos clientes que possui mais de 100 bancos de dados com cerca de 50 tabelas cada, muitas delas tabelas InnoDB. O servidor travou e estou tentando encontrar o culpado. Ao reiniciar com innodb_force_recovery = 2, consigo me conectar e não vejo nenhum erro no error.log. Mais importante ainda, mysqlcheck --all-databasesreporta “Ok” para todas as tabelas. Mas quando eu removo innodb_force_recovery, o servidor trava novamente, grava um rastreamento de pilha em error.log e só pode ser interrompido com kill -9.

Como devo encontrar o banco de dados incorreto nessas circunstâncias e o que faria com que o mysqlcheck perdesse as tabelas corrompidas? Por favor, não me diga para simplesmente ignorar isso e restaurar todos os bancos de dados dos dumps. Isso pode ser aceitável para um ou dois bancos de dados e se ocorrer apenas uma vez na lua azul, mas tive problemas com o mesmo servidor mais de uma vez e restaurar tudo dos despejos requer muito tempo e trabalho manual para fazer isso todos tempo.

A versão do servidor é 5.5.46 e innodb_file_per_tableestá ativa.

Trecho de error.log conforme solicitado (significa que The tablespace free space info is corrupthá um erro que não está em uma tabela específica e que não pode ser corrigido?):

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

Responder1

A própria mensagem de erro informa por que a verificação dos dados da tabela não resolve o problema. Tentou liberar uma página (provavelmente de uma tabela ou índice); mas essa página já estava marcada como gratuita. Em outras palavras, uma de suas tabelas ou índices estava utilizando uma página, quando a página é considerada disponível para ser cedida a outra tabela ou índice. E, obviamente, se o InnoDB não souber quais páginas são realmente gratuitas, coisas ruins podem acontecer.

Despejar todos os dados da tabela/índice e recarregar significa dar ao InnoDB a chance de reconstruir sua coleção de páginas gratuitas. Idealmente, você faria isso em um novo banco de dados. Por que? Bem, você nunca deve presumir que há apenas um único e solitário erro de corrupção. Portanto, se você mover os dados para uma nova instalação, não precisará se preocupar se houver problemas adicionais de corrupção não detectados.

Responder2

Conforme sugerido, descarregar e restaurar esses despejos foi a maneira que escolhi para restaurar todos os bancos de dados. Felizmente, innodb_force_recovery = 2me permitiu despejar tudo sem erros, para não precisar usar despejos de backups. É claro que eu preferiria ter descoberto a verdadeira causa do erro, mas o MySQL não oferece nenhuma ajuda além de algumas menções de "As informações de espaço livre do espaço de tabela estão corrompidas" em relatórios de erros. Sem identificar e remover a causa do erro, espero que ele ocorra novamente - nosso cliente provavelmente ficará ainda mais chateado do que eu.

Talvez a culpa seja do hardware ruim, mas os dados SMART de todos os discos do sistema parecem bons e /var/log/messagesnão contêm nada suspeito no momento da falha. Também não houve perda de energia ou reinicialização inesperada.

informação relacionada