Por que o InnoDB armazena todos os bancos de dados em um arquivo?

51

Era conveniente que o MyISAM usasse para armazenar cada tabela em um arquivo correspondente. O InnoDB fez avanços em muitos aspectos, mas me pergunto por que o InnoDB armazena todos os bancos de dados em um arquivo ( ibdata1por padrão).

Entendo que o InnoDB mapeará a localização dos dados no arquivo por arquivos de índice individuais para tabelas, mas não entendo por que ele mistura todos os dados em um arquivo. E mais importante, por que misturar os dados de todos os bancos de dados no servidor?

Uma característica interessante do MyISAM é que se pode copiar / colar uma pasta de banco de dados em outra máquina e depois usá-lo (sem despejo).

Googlebot
fonte

Respostas:

66

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

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 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.

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

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 comALTER 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 comALTER 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 .

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

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.

RolandoMySQLDBA
fonte
Isso significa quando eu uso o arquivo innodb por tabela ativada e Se eu precisar importar meus dados de um servidor para outro, terei que usar apenas o mysqldump e não outras ferramentas como o Percona xtrabackup?
tesla747
14

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

atxdba
fonte
Sem dúvida, o InnoDB é um mecanismo flexível, mas não entendo como o armazenamento de todos os dados em um arquivo é benéfico (pois essa nova estrutura foi implementada no InnoDB em comparação com o MyISAM).
Googlebot
Eu acho que é mais uma daquelas retrospectivas são 20/20 coisas. A opção arquivo por tabela foi adicionada depois que o innodb saiu das prateleiras. Fora dar a ele seu próprio dispositivo de bloco para evitar sobrecarga do sistema de arquivos, não posso fornecer uma razão pela qual despejá-los todos juntos é melhor (e a coisa toda sobre o dispositivo de bloco é seu próprio debate). Todas as minhas configurações do innodb têm o arquivo por tabela ativado.
Atxdba
Esse é o ponto, não depender do sistema de arquivos pode ser inestimável, mas não está ativo por padrão. Assim, alguns usuários o usarão.
Googlebot
11
A opção de um arquivo por tabela pode causar danos se você tiver muitas tabelas e pouca RAM (uma loja Magento, por exemplo, pode ter cerca de 1000 tabelas). E a configuração de arquivos abertos também precisa ser otimizada (considerando as limitações do SO). Portanto, use com cuidado.
ypercubeᵀᴹ
Certamente pode prejudicar os esforços de recuperação. Sim, você deve ter um backup, mas caso contrário, o InnoDB dificulta as coisas por causa dessa estrutura.
Mikato # 6/15
10

Esse é o comportamento padrão, mas não obrigatório. Dos documentos do MySQL, usando os espaços de tabela por tabela :

Por padrão, todas as tabelas e índices do InnoDB são armazenados no espaço de tabela do sistema. Como alternativa, você pode armazenar cada tabela do InnoDB e seus índices em seu próprio arquivo . Esse recurso é chamado de "vários espaços de tabela" porque cada tabela criada quando essa configuração está em vigor possui seu próprio espaço de 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):

Considerações sobre portabilidade para arquivos .ibd

Você não pode mover livremente os arquivos .ibd entre os diretórios do banco de dados, como pode com os arquivos de tabela MyISAM. A definição de tabela armazenada no espaço de tabela compartilhado do InnoDB inclui o nome do banco de dados. Os IDs da transação e os números de sequência do log armazenados nos arquivos do espaço de tabela também diferem entre os bancos de dados.

ypercubeᵀᴹ
fonte
Resposta muito informativa e esclareceu o problema, mas ainda estou curioso para saber como um arquivo grande contendo todos os bancos de dados pode melhorar o desempenho (se houver).
Googlebot
O desempenho não é melhor por ter um arquivo para todos. Várias características, como o bloqueio no nível da linha, em vez do nível da tabela, ajudam no desempenho. E é claro que a principal vantagem são transações e restrições de FK (e, portanto, a integridade do banco de dados).
ypercubeᵀᴹ
11
Você está certo sobre integridade! Entendo por que é melhor colocar todas as tabelas de um banco de dados em um único arquivo; mas não entendo por que colocar todos os bancos de dados (que são completamente independentes) no mesmo arquivo. Por padrão, o InnoDB usa apenas um arquivo para armazenar dados.
Googlebot