Linux / mysql: è sicuro copiare i file db mysql con comando cp da un db all'altro?


11

La maggior parte delle guide consiglia mysqldump e SQL semplice per la copia di una tabella in anoter db. Che ne dici di Linux shell cp? Posso semplicemente fare

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

Risposte:


21

La copia è molto semplice per MyISAM e completamente rischiosa al 100% (quasi suicida) con InnoDB.

Dalla tua domanda, hai sollevato

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

MyISAM

Va bene farlo. Tuttavia, non puoi semplicemente spostare il .frm. È necessario spostare tutti i componenti. Dalla tua domanda, prendiamo una tabella chiamata db1.mytable. In un'installazione normale, la tabella si trova in / var / lib / mysql / db1. Ci sarebbero tre file che compongono la tabella.

  • /var/lib/mysql/db1/mytable.frm
  • /var/lib/mysql/db1/mytable.MYD (Database tabelle)
  • /var/lib/mysql/db1/mytable.MYI (indici delle tabelle)

È necessario spostare tutti e tre i file per spostare una tabella. Se tutte le tue tabelle utilizzano il motore di archiviazione MyISAM, puoi spegnere mysql e copiarlo. Se stai semplicemente facendo una copia della tabella e inserendola in un altro database, dovresti farlo usando SQL.

Ad esempio, se si desidera copiare db1.mytable nel database db2, procedere come segue:

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;

Ora se stai semplicemente spostando la tabella da db1 a db2, puoi farlo:

ALTER TABLE db1.mytable RENAME db2.mytable;

InnoDB

La copia è molto pericolosa a causa dell'infrastruttura su cui lavora InnoDB. Esistono due infrastrutture di base: 1) innodb_file_per_table disabilitato e 2) innodb_file_per_table abilitato

Il tallone d'Achille di InnoDB è il file del tablespace di sistema noto come ibdata1 (normalmente situato in / var / lib / mysql). Cosa è contenuto in quel file ?

  • Pagine dei dati della tabella
  • Pagine indice delle tabelle
  • Table MetaData (elenco di gestione ID tablespace)
  • Dati MVCC (per supportare l'isolamento delle transazioni e la conformità ACID )

InnoDB (innodb_file_per_table disabilitato)

Con innodb_file_per_table disabilitato, tutti questi tipi di informazioni di InnoDB vivono all'interno di ibdata1. L'unica manifestazione di qualsiasi tabella InnoDB al di fuori di ibdata1 è il file .frm della tabella InnoDB. La copia di tutti i dati di InnoDB in una sola volta richiede la copia di tutti / var / lib / mysql.

La copia di una singola tabella InnoDB è totalmente impossibile. È necessario mysqldump per estrarre un dump della tabella come rappresentazione logica dei dati e delle definizioni dell'indice corrispondenti. Quindi caricare quel dump su un altro database sullo stesso server o su un altro server.

InnoDB (innodb_file_per_table abilitato)

Con innodb_file_per_table abilitato, i dati della tabella e i relativi indici vivono nella cartella del database accanto al file .frm. Ad esempio, per la tabella db1.mytable, la manifestazione di quella tabella InnoDB al di fuori di ibdata1 sarebbe:

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

Tutti i metadati per db1.mytable risiedono ancora in ibdata1 e non c'è assolutamente modo di evitarlo . Anche i registri di ripetizione e i dati MVCC vivono ancora con ibdata1.

ATTENZIONE (o PERICOLO come direbbe il Robot in Lost in Space )

Se stai pensando di copiare semplicemente il file .frm e .ibd, sei in linea con il mondo del male. La copia del file .frm e .ibd di una tabella InnoDB è utile solo se si può garantire che l'id del tablespace del file .ibd corrisponda esattamente alla voce dell'ID del tablespace nei metdati del file ibdata1.

Ho scritto due post in DBA StackExchange su questo concetto di id del tablespace

Ecco un link eccellente su come ricollegare e .ibd file a ibdata1 in caso di ID spazio tabella non corrispondenti: http://www.chriscalender.com/?tag=innodb-error-tablespace-id-in-file . Dopo aver letto questo, dovresti essere in grado di capire perché ho detto vicino al suicidio.

Per InnoDB devi solo questo

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

per fare una copia di una tabella InnoDB. Se lo stai migrando su un altro server DB, usa mysqldump.


4
Altre risposte lo hanno detto, quindi forse "va da sé", ma è bene dirlo comunque: InnoDB continua a scrivere sui file anche se il database è inattivo, quindi copiare i suoi file mentre MySQL è in esecuzione è quasi certo che causerà corruzione! È possibile arrestare, eseguire un'istantanea del file system o utilizzare Percona XtraBackup per aggirare il problema.
Barone Schwartz

1
Ottima risposta come sempre, @Rolando! L'unica grande domanda che ho: perché qualcuno dovrebbe voler fare questo invece di fare un dump e un'importazione MySQL diretto? Sto assumendo le dimensioni del database puro, ma sento che dovrebbe essere cresciuto.
Jake Gould,

1
@JakeGould Il caricamento di uno script mysqldump in mysql richiede l'elaborazione di un sacco di SQL, l'inserimento di migliaia di righe alla volta, l'utilizzo di cicli di CPU, l'avvio di spiegazioni di piani, la ricostruzione di indici (inserimenti BTree, frazioni di nodi foglia, riequilibratura delle chiavi, una scansione delle tabelle per ogni non -unico da costruire) solo per produrre la stessa tabella. Nel caso di MyISAM, perché reinventare la ruota? Basta una copia del .frm, .MYDe .MYI.
RolandoMySQLDBA

@JakeGould Nel caso di InnoDB, avevo copiato un database live che utilizzava tutti InnoDB con rsync. Dopo aver copiato usando rsync, ho eseguito un arresto di mysql, ho eseguito un ultimo rsync e ho riavviato mysql senza problemi. Ho scritto un post come prima: serverfault.com/questions/288140/…
RolandoMySQLDBA

8

La copia dell'intero datadir di MySQL è una tecnica pratica, presumendo che il servizio MySQL sia interrotto e si desidera copiare l'intero server di database.

Questa è una tecnica utile per spostare database con indici di grandi dimensioni e un dump mysql non includerà gli indici, che dovranno essere rigenerati al momento dell'importazione. Ho trovato questa tecnica utile durante la configurazione degli slave MySQL.

La copia di un singolo file dipende dallo schema della tabella in uso, ma nella maggior parte dei casi non è una soluzione adatta.


2
Per spiegare: non è necessario arrestare il servizio di per sé, se il file system è in grado, è possibile eseguire uno snapshot LVM e fare il backup di quello; o congela il filesystem stesso.
thinice

Finché un personale può mangiare i tempi di inattività, questo è il modo più semplice. +1 !!!
RolandoMySQLDBA

2

Usa xtrabackup senza o senza wrapper innobackupex e starai bene su entrambi i database myisam e innodb. Nota che ripristinare i database innodb non sta solo copiando i file anche se usi xtrabackup. Indica se hai bisogno di maggiori informazioni


1

No, dovresti eseguire il backup con mysqdump e ripristinarlo con l'utilità mysql cli, copiando il file frm stai copiando solo la struttura della tabella e non i dati all'interno, e se sei su innodb non è possibile copiare direttamente il file.

Il modo migliore è scaricare e ripristinare la tabella.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.