Cómo recuperar una tabla InnoDB cuyos archivos se movieron

13

Así que tengo un servidor de base de datos de prueba que se configuró en una secuencia de replicación. Sobre el nombre apareció una optimización que rápidamente llenó el espacio en el datadir de esclavos. Mysql obedientemente estaba esperando un poco más de espacio.

Este datadir es un sistema de archivos utilizado SOLO como el datadir de mysql, por lo que no había nada más que liberar.

Tenía una tabla de prueba innodb de 4 gigas que no formaba parte del flujo de replicación, así que pensé en probar algo para ver si funcionaba, y al ser un entorno de prueba, no me preocupaba demasiado si las cosas salían terriblemente mal.

Aquí están los pasos que tomé

  1. Vacié la mesa que estaba a punto de mover.
  2. Coloqué un bloqueo de lectura en él (aunque no había nada escrito y no estaba en la secuencia de replicación)
  3. Copié el .frm y .ibd en un sistema de archivos con alguna habitación libre
  4. Desbloqueó la mesa
  5. Truncado esa tabla: esto liberó suficiente espacio para que la optimización finalice y la replicación comience a funcionar nuevamente.
  6. Dejar de esclavizar / apagar mysql
  7. Copie el archivo de tmp nuevamente al directorio de datos
  8. Reiniciar mysql

No aparece nada en el registro .err, las cosas se ven bien. Me conecto y uso mydb; y veo la mesa con la que estaba jugando en las mesas de exhibición. Pero si lo intento

select * from testtable limit 10;

Me sale el error

ERROR 1146 (42S02): Table 'mydb.testtable' doesn't exist

Por lo que puedo decir hasta ahora, puedo leer de todas las otras tablas muy bien y la replicación comenzó de nuevo sin ninguna queja.

¿Hay algo que pueda hacer para recuperarme de este punto? Puedo reconstruirlo desde cero si es necesario, pero tenía curiosidad sobre lo que otros pensaban sobre esta empresa en general. ¿Hubo algo en la serie de pasos que tomé que hubiera terminado con resultados más perfectos?

¿Qué pasaría si este no fuera un servidor de prueba que no podría simplemente 'hacerlo en vivo' y ver qué pasa? ¿Cuál sería la mejor manera de liberar espacio temporalmente en un esclavo de producción si me tuviera que gustar?

atxdba
fuente

Respuestas:

15

Lo más grande que la mayoría de la gente olvida de TRUNCATE TABLE es que TRUNCATE TABLE es DDL y no DML . En InnoDB, los metadatos dentro de ibdata1 contienen una lista numerada de tablas InnoDB. El uso de TRUNCATE TABLE hace que la identificación interna de metadatos de la tabla InnoDB cambie. Esto sucede porque TRUNCATE TABLE efectivamente hace lo siguiente:

Ejemplo: truncar una tabla InnoDB llamada mydb.mytb

USE mydb
CREATE TABLE newtb LIKE mytb;
ALTER TABLE mytb RENAME oldtb;
ALTER TABLE newtb RENAME mytb;
DROP TABLE oldtb;

El nuevo mytb tendría una identificación interna de metadatos diferente.

Cuando copió el archivo .ibd a otro lugar, el .ibd contiene en su interior el ID de metadatos interno original. Simplemente volver a colocar el archivo .ibd no causa una conciliación de la identificación interna de metadatos con la de ibdata1.

Lo que deberías haber hecho es esto:

Copie el archivo .ibd de la tabla InnoDB. Entonces, ejecuta esto

ALTER TABLE tablename DISCARD TABLESPACE;

Para recuperarlo más tarde, copie el archivo .ibd nuevamente en datadir y luego ejecute

ALTER TABLE tablename IMPORT TABLESPACE;

Esto habría preservado la identificación interna de metadatos.

Asegúrese de que .frm esté siempre presente.

Una vez ayudé a un cliente a restaurar 30 tablas de InnoDB que él manejó de la misma manera. Tuve que usar otro servidor de base de datos y jugar algunos juegos agregando y soltando tablas de InnoDB para buscar la identificación interna de metadatos correcta.

El cliente encontró este artículo: http://www.chriscalender.com/?tag=innodb-error-tablespace-id-in-file . Lo usamos y ayudó mucho. Espero que te ayude.

RolandoMySQLDBA
fuente
1
Tengo 2 bases de datos donde todas las tablas dicen Table 'X' doesn't exist in engine. ¿Tengo que hacer el método anterior para cada una de las tablas o hay mejores formas de solucionarlo?
papanito
-2

Experimenté con mi Mac, antes de vender a un amigo, simplemente copie la carpeta XAMPP solo en mi disco duro. (NO ÉXITO) Desafortunadamente, me estaba causando problemas, porque intenté los siguientes pasos: - Instalé XAMPP nuevo y copié todo \ httdocs y var \ mysql en mi nueva Mac, esos db solo con .frm y .ibd, NO FUNCIONA, todavía no puedo acceder a las tablas dentro de PHPMyAdmin ... - Traté de instalar la misma versión xampp y repito los pasos anteriores, aún NO FUNCIONA. - Decidí ir a la cama.

(ÉXITO) - Esta mañana, traje mi disco de respaldo y probé con Windows 7. - Instale la última versión de XAMPP para Windows, c: \ xampp - Tengo un sitio web (carpeta) de mi copia de seguridad \ httdocs y la carpeta de la base de datos correspondiente dentro de \ var \ mysql está LISTO en mi Windows 7, solo quiero probar con un sitio web y luego probar el resto porque tengo muchos proyectos dentro de httdocs \ y \ var \ mysql - Copio la carpeta mencionada httdocs \ a windows c: \ xampp \ httdocs y copie \ var \ mysql en c: \ xampp \ mysql \ data

AÚN NO PASÓ Copio ib_logfile0, ib_logfile1, ibdata1 de mi archivo de copia de seguridad a Windows xampp c: \ xampp \ mysql \ data

Actualizo el http: // localhost / mywebsite

WOW WOW HECHO ... está funcionando ...

Armindo
fuente