A arquitetura do InnoDB exige o uso de quatro tipos básicos de páginas de informações
- Páginas de dados da tabela
- Páginas de índice da tabela
- Tabela MetaData
- Dados MVCC (para oferecer suporte ao isolamento de transações e conformidade com ACID )
- Segmentos de reversão
- Desfazer espaço
- Buffer de gravação dupla (gravação em segundo plano para evitar a dependência do cache do SO)
- Inserir buffer (gerenciando alterações em índices secundários não exclusivos)
Veja a representação pictórica do ibdata1
Por padrão, innodb_file_per_table está desativado. Isso faz com que todos os quatro tipos de página de informações obtenham um único arquivo chamado ibdata1. Muitas pessoas tentam espalhar os dados criando vários arquivos ibdata. Isso pode levar à fragmentação dos dados e das páginas de índice.
É por isso que geralmente recomendo limpar a infraestrutura do InnoDB, usando o arquivo ibdata1 padrão e nada mais .
A cópia é muito perigosa devido à infraestrutura sob a qual o InnoDB trabalha. Existem duas infra-estruturas básicas
- innodb_file_per_table desativado
- innodb_file_per_table ativado
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 copiar todos os arquivos / var / lib / mysql.
Copiar uma tabela InnoDB individual é totalmente impossível. Você deve despejar o MySQL 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.
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
Espaço de tabela do sistema ibdata1
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.
Quando se trata de fragmentação de tabela, eis o que acontece com ibdata1:
- innodb_file_per_table ativado : você pode reduzir o db1.mytables com
ALTER TABLE db1.mytable ENGINE=InnoDB;
ouOPTIMIZE TABLE db1.mytable;
. Isso resulta em /var/lib/mysql/db1/mytable.ibd sendo fisicamente menor, sem fragmentação.
- innodb_file_per_table desativado : não é possível reduzir o db1.mytables com
ALTER TABLE db1.mytable ENGINE=InnoDB;
ouOPTIMIZE TABLE db1.mytable;
porque ele reside com ibdata1. Na execução de qualquer comando, torne a tabela contígua e mais rápida para ler e gravar. Infelizmente, isso ocorre no final do ibdata1. Isso faz com que o ibdata1 cresça rapidamente. Isso é totalmente resolvido no meu Post de limpeza do InnoDB .
Se você está pensando em copiar apenas os arquivos .frm e .ibd, está alinhado com o mundo da dor. A cópia do arquivo .frm e .ibd de uma tabela do InnoDB só é boa se, e somente 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 metadados do arquivo ibdata1 .
Escrevi duas postagens no DBA StackExchange sobre esse conceito de identificação de espaço de tabela
Aqui está um excelente link sobre como reconectar qualquer 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ê deve perceber imediatamente que copiar arquivos .ibd é simplesmente louco.
Para o InnoDB, você precisa apenas de algo para mover
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.
No que diz respeito à mistura de todas as tabelas do InnoDB de todos os bancos de dados, eu posso realmente ver a sabedoria de fazê-lo. Na empresa de hospedagem de banco de dados / Web do meu empregador, eu tenho um cliente MySQL que possui uma tabela em um banco de dados cujas restrições são mapeadas para outra tabela em outro banco de dados na mesma instância do MySQL. Com um repositório de metadados comum, torna possível o suporte transacional e a operacionalidade do MVCC em vários bancos de dados.
Você pode alternar o InnoDB para armazenar tabelas por arquivo, adicionando innodb-file-per-table ao seu cnf.
O Innodb realmente se importa apenas com as páginas de dados em um nível básico. De fato, você pode configurar o InnoDB para usar apenas um dispositivo de bloco bruto, sem sistema de arquivos! http://dev.mysql.com/doc/refman/5.5/en/innodb-raw-devices.html
Existem conveniências para armazenar tabelas para arquivos, como recuperar mais facilmente o espaço usado via otimização.
Mesmo com arquivos por tabela, você não pode simplesmente copiar os arquivos ibd tão facilmente, pois o InnoDB é transacional e armazena informações sobre seu estado nos arquivos ibdata / log compartilhados globalmente.
Isso não quer dizer que não possa ser feito. Se a tabela estiver offline, você pode descartar / importar os espaços de tabela e copiar os .idbs em http://dev.mysql.com/doc/refman/5.5/en/innodb-multiple-tablespaces.html
fonte
Esse é o comportamento padrão, mas não obrigatório. Dos documentos do MySQL, usando os espaços de tabela por tabela :
Quanto ao motivo, provavelmente o motivo são as diferentes arquiteturas dos dois mecanismos (MyISAM e InnoDB). Por exemplo, no InnoDB, você não pode simplesmente copiar o arquivo .ibd para outro banco de dados ou instalação. Explicação (da mesma página):
fonte