Linux / mysql: é seguro copiar arquivos mysql db com o comando cp de um db para outro?

11

A maioria dos guias recomenda o mysqldump e o SQL simples para copiar uma tabela para o anoter db. Como sobre o linux shell cp? Posso simplesmente fazer

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

giorgio79
fonte

Respostas:

21

A cópia é muito simples para o MyISAM e completamente 100% arriscada (quase suicida) com o InnoDB.

Da sua pergunta, você trouxe

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

MyISAM

Tudo bem fazer isso. No entanto, você não pode simplesmente mover o .frm. Você deve mover todos os componentes. De sua pergunta, vamos pegar uma tabela chamada db1.mytable. Em uma instalação normal, a tabela está localizada em / var / lib / mysql / db1. Haveria três arquivos compondo a mesa.

  • /var/lib/mysql/db1/mytable.frm
  • /var/lib/mysql/db1/mytable.MYD (banco de dados de tabelas)
  • /var/lib/mysql/db1/mytable.MYI (índices de tabela)

Você deve mover todos os três arquivos para mover a uma tabela. Se todas as suas tabelas usarem o mecanismo de armazenamento MyISAM, você poderá desligar o mysql e copiar. Se você está simplesmente fazendo uma cópia da tabela e colocando-a em outro banco de dados, faça isso usando o SQL.

Por exemplo, se você deseja copiar o db1.mytable no banco de dados db2, faça o seguinte:

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;

Agora, se você apenas mover a tabela de db1 para db2, poderá fazer o seguinte:

ALTER TABLE db1.mytable RENAME db2.mytable;

InnoDB

A cópia é muito perigosa devido à infraestrutura em que o InnoDB trabalha. Existem duas infra-estruturas básicas: 1) innodb_file_per_table desativado e 2) innodb_file_per_table ativado

O calcanhar de Aquiles do InnoDB é o arquivo de espaço de tabela do sistema conhecido como ibdata1 (normalmente localizado em / var / lib / mysql). O que está contido nesse arquivo ?

  • Páginas de dados da tabela
  • Páginas de índice da tabela
  • Tabela MetaData (lista de gerenciamento de ID do espaço de tabela)
  • Dados MVCC (para oferecer suporte ao isolamento de transações e conformidade com ACID )

InnoDB (innodb_file_per_table desativado)

Com innodb_file_per_table desativado, todos esses tipos de informações do InnoDB ficam no ibdata1. A única manifestação de qualquer tabela InnoDB fora do ibdata1 é o arquivo .frm da tabela InnoDB. Copiar todos os dados do InnoDB de uma só vez requer a cópia de todos os arquivos / var / lib / mysql.

Copiar uma tabela individual do InnoDB é totalmente impossível. Você deve mysqldump para extrair um despejo da tabela como uma representação lógica dos dados e suas definições de índice correspondentes. Você carregaria esse despejo em outro banco de dados no mesmo servidor ou em outro servidor.

InnoDB (innodb_file_per_table ativado)

Com innodb_file_per_table ativado, os dados da tabela e seus índices ficam na pasta do banco de dados ao lado do arquivo .frm. Por exemplo, para a tabela db1.mytable, a manifestação dessa tabela InnoDB fora do ibdata1 seria:

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

Todos os metadados do db1.mytable ainda residem no ibdata1 e não há absolutamente nenhuma maneira de contornar isso . Os logs de refazer e os dados do MVCC também ainda vivem com o ibdata1.

AVISO (ou PERIGO, como o robô diria em Lost in Space )

Se você está pensando apenas em copiar os arquivos .frm e .ibd, está na fila para o mundo das feridas. A cópia do arquivo .frm e .ibd de uma tabela do InnoDB só é boa se você puder garantir que o ID do espaço de tabela do arquivo .ibd corresponda exatamente à entrada do ID do espaço de tabela nos metdados do arquivo ibdata1.

Escrevi duas postagens no DBA StackExchange sobre esse conceito de identificação de espaço de tabela

Aqui está um link excelente sobre como reconectar e arquivo .ibd ao ibdata1 no caso de IDs de espaço de tabela incompatíveis: http://www.chriscalender.com/?tag=innodb-error-tablespace-id-in-file . Depois de ler isso, você poderá ver por que eu disse quase suicida.

Para o InnoDB, você só precisa disso

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

para fazer uma cópia de uma tabela do InnoDB. Se você estiver migrando para outro servidor de banco de dados, use mysqldump.

RolandoMySQLDBA
fonte
4
Outras respostas disseram isso, então talvez seja "desnecessário dizer", mas é bom dizer assim mesmo: o InnoDB continua gravando nos arquivos mesmo que o banco de dados esteja ocioso, então copiar seus arquivos enquanto o MySQL está em execução é quase certo de causar corrupção! Você pode desligar, tirar um instantâneo do sistema de arquivos ou usar o Percona XtraBackup para solucionar isso.
Baron Schwartz
1
Excelente resposta como sempre, @Rolando! A única grande questão que tenho: Por que alguém iria querer fazer isso em vez de fazer uma importação e importação direta do MySQL? Estou assumindo o tamanho do banco de dados, mas acho que isso deve ser trazido à tona.
precisa saber é o seguinte
1
@JakeGould Carregar um script mysqldump no mysql requer o processamento de muitos SQL, a inserção de milhares de linhas por vez, o uso de ciclos de CPU, a criação de planos de explicação, a reconstrução de índices (exclusivo para compilar) apenas para produzir a mesma tabela. No caso do MyISAM, por que reinventar a roda? Basta copiar o .frm, .MYDe .MYI.
RolandoMySQLDBA
@JakeGould No caso do InnoDB, copiei um banco de dados ativo que estava usando todo o InnoDB com o rsync. Após copiar usando o rsync, executei um desligamento do mysql, fiz um rsync final e reiniciei o mysql sem problemas. Eu escrevi um post como antes: serverfault.com/questions/288140/…
RolandoMySQLDBA
8

Copiar todo o datadir do MySQL é uma técnica prática, presumindo que o serviço MySQL esteja parado e que você queira que todo o servidor de banco de dados seja copiado.

Essa é uma técnica útil para mudar bancos de dados com índices grandes, e um despejo do mysql não incluirá os índices, que precisarão ser regenerados no momento da importação. Eu achei essa técnica útil ao configurar escravos do MySQL.

A cópia de um arquivo individual depende do esquema da tabela em uso, mas na maioria das situações não é uma solução adequada.

Cooperativas
fonte
2
Para explicar: você não precisa interromper o serviço propriamente dito; se o seu sistema de arquivos é capaz, você pode executar um instantâneo LVM e fazer backup dele; ou congelar o próprio sistema de arquivos.
thinice
Contanto que um pessoal possa comer tempo de inatividade, essa é a maneira mais fácil. +1 !!!
RolandoMySQLDBA
2

Use xtrabackup w / ow sem wrapper innobackupex e você ficará bem nos bancos de dados myisam e innodb. Observe que a restauração de bancos de dados innodb não está apenas copiando os arquivos, mesmo se você usar o xtrabackup. Diga se você precisa de mais informações

Gabor Vincze
fonte
1

Não, você deve fazer backup com o mysqdump e restaurar com o utilitário mysql cli, copiando o arquivo frm, você está copiando apenas a estrutura da tabela e não os dados internos, e se você estiver no innodb, copie o arquivo diretamente, não é possível.

A melhor maneira é despejar e restaurar a tabela.

aleroot
fonte