MySQL InnoDB perdió tablas pero existen archivos

33

Tengo un MySQL InnoDB que tiene todos los archivos de la tabla de la base de datos, pero MySQL no los ve y no los carga.

El problema ocurrió porque he eliminado estos tres archivos: ibdata1, ib_logfile0yib_logfile1

porque estaba teniendo problemas con el inicio de mysql, y lo que leí fue eliminarlos porque MySQL simplemente los regenerará (sé que debería haberlos respaldado pero no lo hice).

¿Qué puedo hacer para que MySQL vuelva a ver las tablas?

about_member.frm                              site_stories.frm
about_member.ibd                              site_stories.ibd
db.opt                                        stories.frm
FTS_00000000000000bb_BEING_DELETED_CACHE.ibd  stories.ibd
FTS_00000000000000bb_BEING_DELETED.ibd        story_comments.frm
FTS_00000000000000bb_CONFIG.ibd               story_comments.ibd
FTS_00000000000000bb_DELETED_CACHE.ibd        story_likes.frm
FTS_00000000000000bb_DELETED.ibd              story_likes.ibd
FTS_00000000000000f5_BEING_DELETED_CACHE.ibd  story_tags.frm
FTS_00000000000000f5_BEING_DELETED.ibd        story_tags.ibd
FTS_00000000000000f5_CONFIG.ibd               story_views.frm
FTS_00000000000000f5_DELETED_CACHE.ibd        story_views.ibd
FTS_00000000000000f5_DELETED.ibd              story_view_totals.frm
member_favorites.frm                          story_view_totals.ibd
member_favorites.ibd                          tags.frm
members.frm                                   tags.ibd
members.ibd
Salir de mi césped
fuente
¿Has intentado restaurar esos archivos? Los archivos de registro pueden permanecer eliminados. Realmente no deberías haber eliminado ibdata1
Ramhound
Copié el archivo de una versión anterior de mysql donde se encontraba el archivo, pero las tablas no aparecen.
Sal de mi césped el

Respuestas:

36

Aquí es por qué MySQL no puede ver esos archivos: El espacio de tabla del sistema (ibdata1) tiene un diccionario de datos específico de Storage-Engine que permite a InnoDB mapear el uso potencial de la tabla:

Arquitectura InnoDB

Mover tablas de InnoDB de un lugar a otro requiere comandos como

ALTER TABLE tblname DISCARD TABLESPACE;
ALTER TABLE tblname IMPORT TABLESPACE;

Aquí hay una parte de la documentación de MySQL 5.5 que explica lo que debe considerarse

Consideraciones de portabilidad para archivos .ibd

No puede mover libremente archivos .ibd entre los directorios de la base de datos como puede hacerlo con los archivos de tabla MyISAM. La definición de tabla almacenada en el espacio de tabla compartido InnoDB incluye el nombre de la base de datos. Los ID de transacción y los números de secuencia de registro almacenados en los archivos de espacio de tabla también difieren entre las bases de datos.

Para mover un archivo .ibd y la tabla asociada de una base de datos a otra, use una instrucción RENAME TABLE:

RENAME TABLE db1.tbl_name TO db2.tbl_name; Si tiene una copia de seguridad "limpia" de un archivo .ibd, puede restaurarlo a la instalación de MySQL desde la que se originó de la siguiente manera:

La tabla no debe haberse descartado ni truncado desde que copió el archivo .ibd, ya que al hacerlo cambia la ID de la tabla almacenada dentro del espacio de tabla.

Emita esta instrucción ALTER TABLE para eliminar el archivo .ibd actual:

ALTER TABLE tbl_name DESCARGAR TABLESPACE; Copie el archivo .ibd de respaldo en el directorio de base de datos adecuado.

Emita esta instrucción ALTER TABLE para decirle a InnoDB que use el nuevo archivo .ibd para la tabla:

ALTER TABLE tbl_name IMPORT TABLESPACE; En este contexto, una copia de seguridad de archivo .ibd "limpia" es aquella para la que se cumplen los siguientes requisitos:

No hay modificaciones no confirmadas por transacciones en el archivo .ibd.

No hay entradas de búfer de inserción no fusionadas en el archivo .ibd.

Purge ha eliminado todos los registros de índice marcados con eliminación del archivo .ibd.

mysqld ha vaciado todas las páginas modificadas del archivo .ibd del grupo de búferes al archivo.

Dadas estas advertencias y protocolos, aquí hay un curso de acción sugerido

Para este ejemplo, intentemos restaurar la tagstabla a la mydbbase de datos.

PASO 1

Asegúrese de tener copias de seguridad de esos .frmy .ibdarchivos en/tmp/innodb_data

PASO 2

Obtenga la CREATE TABLE tagsdeclaración y ejecútela como CREATE TABLE mydb.tags .... Asegúrese de que sea exactamente la misma estructura que el originaltags.frm

PASO 3

Eliminar el vacío tags.ibdusando MySQL

ALTER TABLE mydb.tags DISCARD TABLESPACE;

ETAPA 4

Traiga la copia de seguridad de tags.ibd

cd /var/lib/mysql/mydb
cp /tmp/innodb_data.tags.ibd .
chown mysql:mysql tags.ibd

PASO # 5

Agregar tagstabla al diccionario de datos InnoDB

ALTER TABLE mydb.tags IMPORT TABLESPACE;

PASO 6

Probar la accesibilidad de la mesa

SHOW CREATE TABLE mydb.tags\G
SELECT * FROM mydb.tags LIMIT 10;

Si obtiene resultados normales, felicidades, importe una tabla InnoDB.

PASO 7

En el futuro, no elimine ibdata1 y sus registros.

Darle una oportunidad !!!

He discutido cosas como esta antes

ADVERTENCIA

¿Qué pasa si no conoce la estructura de la tabla tags?

Hay herramientas para obtener la instrucción CREATE TABLE simplemente usando el .frmarchivo. También escribí una publicación sobre esto: ¿Cómo puedo extraer el esquema de la tabla solo del archivo .frm? . En esa publicación, copié un archivo .frm en una máquina Windows desde un cuadro de Linux, ejecuté la herramienta de Windows y obtuve la CREATE TABLEdeclaración.

RolandoMySQLDBA
fuente
Gracias por la increíble respuesta! Todavía estoy en el proceso de importar una tabla, porque sigo creando problemas, pero eventualmente llegaré allí, ¡y les haré saber cómo funciona! ¡Gracias!
Sal de mi césped el
1
Cuando ejecuto la creación obtengo: ERROR 1813 (HY000): Tablespace for table ' weblyize. tags'existe. DESECHE el espacio de tabla antes de IMPORTAR. Entonces trato de ejecutar primero el tablespace alter y obtengo este error: ERROR 1146 (42S02): La tabla 'weblyize.tags' no existe . ¿Que puedo hacer?
Sal de mi césped el
¡Gracias! Para corregir mi error, creé una nueva base de datos, ejecuté CREATE TABLE ...y seguí tus pasos. ¡Me salvaste de tener que reescribirlos al 100% desde cero! No importó claves externas, pero está bien, ¡puedo hacerlo yo mismo! ¡Gracias otra véz!
Sal de mi césped el
¿Qué pasa si tengo 100 tablas que deberían arreglarse de esta manera? No haré operaciones para cada mesa a mano. ¿Cómo podría ser automatizado?
Oleg Abrazhaev
10

Tengo la misma situación, no puedo soltar o crear tblname específico. Mi procedimiento de reparación es:

  1. Detener MySQL

    service mysql stop
    
  2. Elimine ib_logfile0 e ib_logfile1.

    cd /var/lib/mysql;
    rm ib_logfile0 ib_logfile1
    
  3. Eliminar archivos tblname. ADVERTENCIA: ESTO BORRARÁ PERMANENTEMENTE SUS DATOS

    cd /var/lib/mysql/dbname;
    rm tblname*
    
  4. Inicia MySQL.

    service mysql start
    
usuario293871
fuente
1
Gracias, esto solucionó mi problema, no hice el paso 3, simplemente eliminé los archivos de registro y comencé a respaldar mysql.
Jeff Wilbert
Eres absolutamente fantástico! Resuelto mi problema
Alex GP
2

Yo tuve este problema también. Eliminé ibdata1accidentalmente y se perdieron todos mis datos.

Después de 1-2 días de búsqueda en Google y SO, finalmente encontré una solución que me salvó la vida (tenía tantas bases de datos y tablas con grandes registros).

  1. tomar una copia de seguridad de /var/lib/mysql

  2. recuperar el esquema de la tabla del .frmarchivo con dbsake (¡había otra opción! mysqlfrm . pero no funcionó para mí)

dbsake frmdump --type-codes /var/lib/mysql/database-name/tbl.frm
  1. crear nueva tabla (con nuevo nombre) con esquema exportado.

  2. descarte los nuevos datos de la tabla con este comando:

ALTER TABLE `tbl-new` DISCARD TABLESPACE;
  1. copie los datos de la tabla anterior y péguelo en lugar de uno nuevo y establezca el permiso correcto para ello.
cp tbl.ibd [email protected] && chown mysql:mysql [email protected]
  1. Importar datos a una nueva tabla.
ALTER TABLE `tbl-new` IMPORT TABLESPACE;
  1. ¡bien! Tenemos datos en una tabla nueva y podemos descartar la anterior.
DROP TABLE `tbl`;
  1. compruebe /var/lib/mysql/database-namey si hay datos ( .ibdarchivo) para la tabla anterior, elimínelos.
rm tbl.ibd
  1. y finalmente renombra la nueva tabla al nombre original
ALTER TABLE `tbl-new` RENAME `tbl`;
mostafaznv
fuente