¿Cómo reparo una tabla InnoDB?
Pregunta
Nosotros (aparentemente) habíamos ejecutado pobremente nuestro motor de base de datos Solaris MySQL anoche. Al menos algunas de las tablas InnoDB están dañadas, con errores de fecha y hora fuera de orden en el registro de transacciones y un error específico sobre el índice que está dañado.
Conocemos las herramientas disponibles para las reparaciones de tablas de MyISAM, pero no podemos encontrar nada para InnoDB.
Nota al margen: al intentar optimizar una tabla (en mi intento de reconstruir el índice dañado), el servidor de la base de datos se bloquea.
Solución
En primer lugar, detenga el servidor e imprima el disco . No tiene sentido tener un solo disparo en esto. Luego eche un vistazo aquí .
Otros consejos
detenga su aplicación ... o detenga su esclavo para que no se agreguen nuevas filas
create table <new table> like <old table>;
insert <new table> select * from <old table>;
truncate table <old table>;
insert <old table> select * from <new table>;
reinicia tu servidor o esclavo
La siguiente solución se inspiró en la sugerencia de Sandro anterior.
Advertencia : mientras funcionó para mí, pero no puedo decir si funcionará para ti.
Mi problema fue el siguiente: la lectura de algunas filas específicas de una tabla (llamemos a esta tabla broken
) colapsaría MySQL. Incluso SELECT COUNT (*) FROM broken
lo mataría. Espero que tenga un PRIMARY KEY
en esta tabla (en la siguiente muestra, es id
).
- Asegúrese de tener una copia de seguridad o una instantánea del servidor MySQL dañado (en caso de que quiera volver al paso 1 y probar algo más)
-
CREAR TABLA broken_repair LIKE broken;
-
INSERT broken_repair SELECT * FROM broken WHERE id NOT IN (SELECT id FROM broken_repair) LIMIT 1;
- Repita el paso 3 hasta que bloquee la base de datos (puede usar
LIMIT 100000
y luego use valores más bajos, hasta que usarLIMIT 1
bloquee la base de datos). - Vea si tiene todo (puede comparar
SELECT MAX (id) FROM broken
con el número de filas enbroken_repair
). - En este punto, aparentemente tenía todas mis filas (excepto aquellas que probablemente fueron truncadas salvajemente por InnoDB). Si pierde algunas filas, puede intentar agregar un
OFFSET
alLIMIT
.
¡Buena suerte!
Aquí está la solución provista por MySQL: http://dev.mysql.com/doc/refman /5.5/en/forcing-innodb-recovery.html
Consulte este artículo: http://www.unilogica.com/mysql-innodb-recovery / (está en portugués)
Se explica cómo usar innodb_force_recovery y innodb_file_per_table . Descubrí esto después de la necesidad de recuperar una base de datos dañada con un solo ibdata1 .
Usando innodb_file_per_table, todas las tablas en InnoDB crearán un archivo de tabla separado, como MyISAM.
Paso 1.
Detener el servidor MySQL
Paso 2.
agregue esta línea a my.cnf (en Windows se llama my.ini)
set-variable=innodb_force_recovery=6
Paso 3.
eliminar ib_logfile0 y ib_logfile1
Paso 4.
Iniciar el servidor MySQL
Paso 5.
Ejecuta este comando:
mysqlcheck --database db_name table_name -uroot -p
Una vez que haya solucionado satisfactoriamente la tabla innodb dañada, no olvide eliminar # set-variable = innodb_force_recovery = 6 de my.cnf y luego reinicie el servidor MySQL nuevamente.