Linux / mysql: ¿es seguro copiar archivos db mysql con el comando cp de un db a otro?

11

La mayoría de las guías recomiendan mysqldump y SQL simple para copiar una tabla a otro db. ¿Qué tal linux shell cp? ¿Puedo simplemente hacer

cp /db1/mytable.frm /db2/mytable.frm

giorgio79
fuente

Respuestas:

21

Copiar es muy simple para MyISAM y es completamente 100% arriesgado (casi suicida) con InnoDB.

De tu pregunta, mencionaste

cp /db1/mytable.frm /db2/mytable.frm

MyISAM

Esto está bien hacer. Sin embargo, no puede simplemente mover el .frm. Debes mover todos los componentes. De su pregunta, tomemos una tabla llamada db1.mytable. En una instalación normal, la tabla se encuentra en / var / lib / mysql / db1. Habría tres archivos que componen la mesa.

  • /var/lib/mysql/db1/mytable.frm
  • /var/lib/mysql/db1/mytable.MYD (Base de datos de tablas)
  • /var/lib/mysql/db1/mytable.MYI (Índices de tabla)

Debe mover los tres archivos para mover una tabla. Si todas sus tablas usan el motor de almacenamiento MyISAM, puede cerrar mysql y copiar. Si simplemente está haciendo una copia de la tabla y colocándola en otra base de datos, debe hacerlo usando SQL.

Por ejemplo, si desea copiar db1.mytable en la base de datos db2, haga esto:

CREATE TABLE db2.mytable LIKE db1.mytable;
ALTER TABLE db2.mytable DISABLE KEYS;
INSERT INTO db2.mytable SELECT * FROM db1.mytable;
ALTER TABLE db2.mytable ENABLE KEYS;

Ahora, si solo mueve la tabla de db1 a db2, puede hacer esto:

ALTER TABLE db1.mytable RENAME db2.mytable;

InnoDB

Copiar es muy peligroso debido a la infraestructura con la que trabaja InnoDB. Hay dos infraestructuras básicas: 1) innodb_file_per_table deshabilitado y 2) innodb_file_per_table habilitado

El talón de Aquiles de InnoDB es el archivo de espacio de tabla del sistema conocido como ibdata1 (normalmente ubicado en / var / lib / mysql). ¿Qué contiene ese archivo ?

  • Páginas de datos de tabla
  • Páginas de índice de tabla
  • Table MetaData (lista de administración de id de espacio de tabla)
  • Datos MVCC (para admitir el aislamiento de transacciones y el cumplimiento de ACID )

InnoDB (innodb_file_per_table deshabilitado)

Con innodb_file_per_table deshabilitado, todos estos tipos de información de InnoDB viven dentro de ibdata1. La única manifestación de cualquier tabla InnoDB fuera de ibdata1 es el archivo .frm de la tabla InnoDB. Copiar todos los datos de InnoDB a la vez requiere copiar todos / var / lib / mysql.

Copiar una tabla InnoDB individual es totalmente imposible. Debe mysqldump para extraer un volcado de la tabla como una representación lógica de los datos y sus correspondientes definiciones de índice. Luego cargaría ese volcado en otra base de datos en el mismo servidor u otro servidor.

InnoDB (innodb_file_per_table habilitado)

Con innodb_file_per_table habilitado, los datos de la tabla y sus índices viven en la carpeta de la base de datos al lado del archivo .frm. Por ejemplo, para la tabla db1.mytable, la manifestación de esa tabla InnoDB fuera de ibdata1 sería:

  • /var/lib/mysql/db1/mytable.frm
  • /var/lib/mysql/db1/mytable.ibd

Todos los metadatos para db1.mytable todavía residen en ibdata1 y no hay absolutamente nada de eso . Los registros de rehacer y los datos de MVCC también viven con ibdata1.

ADVERTENCIA (o PELIGRO como diría el Robot en Lost in Space )

Si está pensando en copiar el archivo .frm y .ibd, está en línea para un mundo de daños. Copiar el archivo .frm y .ibd de una tabla InnoDB solo es bueno si puede garantizar que el id del espacio de tabla del archivo .ibd coincida exactamente con la entrada de id del espacio de tabla en los metadatos del archivo ibdata1.

Escribí dos publicaciones en DBA StackExchange sobre este concepto de id de espacio de tabla

Aquí hay un excelente enlace sobre cómo volver a adjuntar y el archivo .ibd a ibdata1 en caso de id. De espacio de tabla no coincidentes: http://www.chriscalender.com/?tag=innodb-error-tablespace-id-in-file . Después de leer esto, deberías poder ver por qué dije casi suicida.

Para InnoDB solo necesitas esto

CREATE TABLE db2.mytable LIKE db1.mytable;
INSERT INTO db2.mytable SELECT * FROM db1.mytable;

hacer una copia de una tabla InnoDB. Si lo está migrando a otro servidor de base de datos, use mysqldump.

RolandoMySQLDBA
fuente
44
Otras respuestas dijeron esto, así que tal vez "no hace falta decirlo", pero es bueno decirlo de todos modos: ¡InnoDB sigue escribiendo en los archivos incluso si la base de datos está inactiva, por lo que copiar sus archivos mientras MySQL se está ejecutando es casi seguro que causará corrupción! Puede cerrar, tomar una instantánea del sistema de archivos o usar Percona XtraBackup para solucionar esto.
Baron Schwartz
1
Excelente respuesta como siempre, @Rolando! La única gran pregunta que tengo es: ¿por qué alguien querría hacer esto en lugar de hacer un volcado e importación directo de MySQL? Estoy asumiendo el tamaño de la base de datos, pero creo que debería mencionarse.
JakeGould
1
@JakeGould Cargar un script mysqldump en mysql requiere procesar muchos SQL, insertar miles de filas a la vez, usar ciclos de CPU, elaborar planes explicativos, reconstruir índices (BTree Insertions, Leaf Node Splits, reequilibrar Keys, una exploración de tabla para cada no -unico para construir) solo para producir la misma tabla. En el caso de MyISAM, ¿por qué reinventar la rueda? Solo copia de la .frm, .MYDy .MYI.
RolandoMySQLDBA
@JakeGould En el caso de InnoDB, había copiado una base de datos en vivo que estaba usando todo InnoDB con rsync. Después de copiar usando rsync, ejecuté un apagado de mysql, hice un rsync final y reinicé mysql sin problemas. Escribí una publicación como antes: serverfault.com/questions/288140/…
RolandoMySQLDBA
8

Copiar todo el datadir de MySQL es una técnica práctica, suponiendo que el servicio de MySQL se detenga y desee copiar todo el servidor de la base de datos.

Esta es una técnica útil para cambiar bases de datos con índices grandes, y un volcado de mysql no incluirá los índices, que deberán regenerarse en el momento de la importación. He encontrado esta técnica útil al configurar esclavos MySQL.

Copiar un archivo individual dependerá del esquema de la tabla en uso, pero en la mayoría de las situaciones no es una solución adecuada.

Cooperativas
fuente
2
Para exponer: no tiene que detener el servicio per se, si su sistema de archivos es capaz, puede realizar una instantánea LVM y hacer una copia de seguridad de eso; o congelar el sistema de archivos en sí.
thinice
Mientras un personal pueda comer tiempo de inactividad, esta es la forma más fácil. +1 !!!
RolandoMySQLDBA
2

Utilice xtrabackup w / ow w / o innobackupex wrapper y estará bien en las bases de datos myisam e innodb. Tenga en cuenta que la restauración de las bases de datos innodb no es solo copiar los archivos incluso si usa xtrabackup. Dile si necesitas más información

Gabor Vincze
fuente
1

No, debe hacer una copia de seguridad con mysqdump y restaurar con la utilidad mysql cli, copiando el archivo frm que está copiando solo la estructura de la tabla y no los datos en el interior, y si está en innodb, copiar el archivo directamente no es posible.

La mejor manera es volcar y restaurar la tabla.

aleroot
fuente