¿Cómo identificas la corrupción de la tabla InnoDB?

24

Tengo algunas tablas que están particionadas y tienen varios índices en un esclavo replicado. Después de copiar la instantánea (verificado seguro) a un nuevo esclavo y actualizar mysqld de 5.1.42 a 5.5.15 y reiniciar la replicación, recibo bloqueos de InnoDB con el mensaje de error "Puntero no válido ..."

Estos errores han ocurrido en 2 servidores con hardware y O / S diferentes. Despues de correr:

ALTER TABLE .... COALESCE PARTION n;

El problema desaparece para esa mesa.

Sin embargo, mi pregunta tiene un alcance mayor y es "¿Cómo identificas la corrupción de la tabla InnoDB?" o reformulado "¿Cómo evalúa el estado de la tabla InnoDB?" ¿Es "CHECK TABLE" la única herramienta disponible para identificar problemas previos al bloqueo?

No estoy seguro de si es importante, pero se produjeron bloqueos al ejecutarse: Versión: socket '5.5.15-55-log': puerto '/opt/mysql.sock': servidor 3306 Percona (GPL), versión rel21.0, revisión 158

randomx
fuente
2
Hola randy Creo que las respuestas aquí son creíbles: InnoDB identificó su propia corrupción. Tal vez deberías reformular tu pregunta, ¿por qué lo que estás haciendo causa que InnoDB sea corrupto?
Morgan Tocker

Respuestas:

18

Morgan da una pista en su comentario de que InnoDB está constantemente buscando páginas corruptas haciendo sumas de verificación en las páginas que lee. Si InnoDB encuentra una desigualdad suma de comprobación, será estrellarse detener el servidor.

Si desea acelerar ese proceso (en lugar de esperar a que InnoDB lea la página dañada), puede usar innochecksum:

Debido a que las discrepancias en la suma de comprobación harán que InnoDB apague deliberadamente un servidor en ejecución, puede ser preferible usar esta herramienta en lugar de esperar a que un servidor en uso de producción encuentre las páginas dañadas.

Una advertencia interesante:

innochecksum no se puede utilizar en archivos de espacio de tabla que el servidor ya tiene abierto. Para tales archivos, debe usar CHECK TABLE para verificar las tablas dentro del espacio de tablas.

Entonces sí, para una tabla en línea CHECK TABLEes probablemente la herramienta (o como se señala en otra respuesta mysqlcheck si desea hacer más de una base de datos a la vez).

Si puede cerrar su base de datos, puede forzarla a usar las sumas de verificación innochecksum

Anécdota: en un espacio de tabla innodb de 29 GB (con innodb_file_per_table=1), este script tardó aproximadamente 2 minutos

#!/bin/bash
for i in $(ls /var/lib/mysql/*/*.ibd)
do
  innochecksum -v $i
done

Sin embargo, como beneficio adicional, ya que está ejecutando Percona, implementaron un nuevo método para la suma de comprobación rápida innodb . Nunca lo he usado, pero podría acelerar el proceso.

Derek Downey
fuente
1
Voy a intentarlo aquí, parece ser la solución que @randymelder está buscando +1
marcio
2
El servidor Percona tiene algunas otras características agradables. Ver innodb_corrupt_table_action percona.com/doc/percona-server/5.5/reliability/… (!!)
Morgan Tocker
@DTest: innochecksum es el camino a seguir. Este es un guardián. +1 !!!
RolandoMySQLDBA
@DTest: ¡Felicitaciones hoy por este!
RolandoMySQLDBA
@MorganTocker Interesante. Voy a tener que obtener mi vacío de conocimiento e investigar un poco sobre percona
Derek Downey
6

ADVERTENCIA: antes de intentar cualquiera de estas instrucciones, se recomienda verificar que haya una copia de seguridad de su base de datos en manos, por si acaso. (gracias a @Nick por la advertencia)

Intenta usar el mysqlcheckcomando. En una terminal:

mysqlcheck -u username -p --databases database1 database2

Este comando generará una lista de todas las tablas y un estado que le indicará si hubo algún tipo de corrupción:

table1  OK
table2  OK
table3  OK
tableN  OK

Con eso en las manos, ya sabrá qué tablas debe reparar. En caso de que quiera reparar todo de una vez:

mysqlcheck -u username -p --auto-repair --databases database1 database2 

Más sobre mysqlcheck: http://dev.mysql.com/doc/refman/5.0/en/mysqlcheck.html

Nota: etiquetó su pregunta con . No tenía idea de qué era eso, así que busqué en Google. Parece ser una bifurcación de MySQL, pero no tengo ninguna razón para creer que los comandos son incompatibles (dedos cruzados).


Alguien me señaló esta guía que tiene instrucciones más específicas para la recuperación de la base de datos InnoDB para situaciones más críticas en las que no se inicia toda la base de datos: http://www.softwareprojects.com/resources/programming/t-how-to-fix-mysql -database-myisam-innodb-1634.html

marcio
fuente
1
mysqlcheck es sinónimo de 'check table ...' -1
randomx
No es verdad. Primero, mysqlcheck es una utilidad de línea de comandos y CHECK TABLE es una declaración SQL (es como comparar naranja con lemmons) .También, NO PUEDE verificar una base de datos completa con CHECK TABLE sin incluir TODOS los nombres de tabla en la declaración SQL ( no sería muy productivo también)
marcio
Y mysqlcheck tiene una opción para - reparar automáticamente las tablas que están dañadas, mientras que CHECK TABLE solo verifica si las tablas están dañadas o no, pero no puede hacer ninguna reparación.
marcio
2
@randymelder: te equivocas al decir que mysqlcheck es sinónimo de CHECK TABLE. La documentación se ha vinculado a los estados: " mysqlcheckutiliza las sentencias SQL CHECK TABLE, REPAIR TABLE, ANALYZE TABLE, y OPTIMIZE TABLEde una manera conveniente para el usuario determina qué estados de uso para la operación que desea realizar y, a continuación, envía las declaraciones al servidor para ser ejecutados.. " Eso no es sinónimo; esa es una interfaz de usuario para una colección de declaraciones.
Nick Chammas
6

De acuerdo con la Guía de estudio de certificación MySQL 5.0, página 443,444 Sección 30.4 :

Puede verificar las tablas de InnoDB usando el comando CHECK TABLE o usando un programa cliente para emitir la declaración por usted. Sin embargo, si una tabla InnoDB tiene problemas, no puede solucionarla utilizando REPAIR TABLE porque esa declaración se aplica solo a MyISAM.

Si una comprobación de la tabla indica que una tabla de InnoDB tiene problemas, debería poder restaurar la tabla a un estado coherente descargándola con mysqldump, soltándola y volviéndola a crear desde ese volcado.

En el caso de un bloqueo de un servidor MySQL o en el host en el que se ejecuta, algunas tablas de InnoDB pueden necesitar reparaciones. Normalmente, es suficiente simplemente reiniciar el servidor porque el motor de almacenamiento InnoDB realiza la recuperación automática como parte de su secuencia de inicio. En casos excepcionales, el servidor podría no iniciarse debido a la falla de la recuperación automática de InnoDB. Si eso sucede, utilice el siguiente procedimiento:

  • Reinicie el servidor con la opción --innodb_force_recovery establecida en un valor en la rabia de 1 a 6. Estos valores indican niveles crecientes de precaución para evitar un bloqueo y niveles crecientes de tolerancia para posibles inconsistencias en las tablas recuperadas. Un buen valor para comenzar es 4.

  • Cuando inicia el servidor con --innodb_force_recovery establecido en un valor distinto de cero, InnoDB trata el espacio de tabla como de solo lectura. En consecuencia, debe volcar las tablas InnoDB con mysqldump y luego soltarlas mientras la opción esté vigente. Luego reinicie el servidor sin la opción --innodb_force_recovery. Cuando aparezca el servidor, recupere las tablas InnoDB de los archivos de volcado.

  • Si los pasos anteriores fallan, es necesario restaurar las tablas InnoDB de una copia de seguridad anterior.

Lea los documentos de MySQL sobre InnoDB Forced Recovery  

RolandoMySQLDBA
fuente
3
FWIW, la guía de certificación tiene una respuesta políticamente correcta :) Si CHECK TABLE en una tabla InnoDB y en realidad está corrupto, nunca volverá como "corrupto", bloqueará el servidor. La declaración es casi obsoleta en InnoDB, porque cada vez que lee las páginas de InnoDB está buscando corrupción (a través de sumas de verificación de página).
Morgan Tocker
2

Me pregunto qué sucede si alguien usa los datos de InnoDB creados a través del complemento InnoDB y luego cambia a otra versión de InnoDB. Eso podría crear una posible corrupción de página a los ojos de mysqld.

Tenga en cuenta lo que dice la documentación de MySQL sobre el formato de archivo InnoDB sobre esta posibilidad:

En general, una versión más nueva de InnoDB puede crear una tabla o índice que no se puede leer o escribir con seguridad con una versión anterior de InnoDB sin riesgo de bloqueos, bloqueos, resultados incorrectos o corrupciones. El complemento InnoDB presenta un nuevo mecanismo para protegerse contra estas condiciones y para ayudar a preservar la compatibilidad entre los archivos de base de datos y las versiones de InnoDB.

Descartaría los datos del esclavo. De hecho, usaría la fuerza bruta obteniendo un volcado lógico (mysqldump) de los datos:

  • Descarte todas las bases de datos usando InnoDB en el esclavo
  • Apagar mysql en el esclavo
  • Eliminar ibdata1, ib_logfile0 e ib_logfile1 en el esclavo
  • Inicie mysql en el esclavo, dejando que ibdata1, ib_logfile0 e ib_logfile1 sean recreados
  • mysqldump los datos del maestro en el esclavo

Mi respuesta original publicada se considera 'vieja escuela'. Sin embargo, en este caso, definitivamente examinaría los formatos de archivo utilizados por .ibd y / o ibdata1.

RolandoMySQLDBA
fuente