Eu tenho a resposta completa para este.
Uma vez innodb_file_per_table é colocado no lugar, e novas tabelas InnoDB podem ser reduzidas usando ALTER TABLE <innodb-table-name> ENGINE=InnoDB';
Isso irá encolher novos .ibd
arquivos GARANTIDOS.
Se você executar ALTER TABLE <innodb-table-name> ENGINE=InnoDB';
em uma tabela InnoDB criada antes de usar innodb_file_per_table, ela arrancará os dados e índices daquela tabela do arquivo ibdata1 e armazenará em um arquivo .ibd
, Isto deixará um pombo permanente todo no ibdata1 que nunca pode ser reutilizado.
O arquivo ibdata1
normalmente abriga quatro tipos de informações
- Dados da tabela
- Índices da tabela
-
MVCC (Multiversioning Concurrency Control)
- Rollback Segments
- Desfazer espaço
- Metadados de tabela (dicionário de dados)
- Buffer de gravação dupla (gravação em segundo plano para evitar a dependência do armazenamento em cache do SO)
- Inserir buffer (gerenciamento de alterações em índices secundários não exclusivos)
- Veja as
Pictorial Representation of ibdata1
Aqui está a maneira garantida de reduzir o arquivo ibdata1 para sempre ...
PASSO 01) MySQLDump todos os bancos de dados em um arquivo de texto SQL (chamá-lo SQLData.sql)
PASSO 02) Abandone todos os bancos de dados (exceto os esquemas mysql, information_schema e performance_schema)
PASSO 03) Desligamento do mysql
PASSO 04) Adicione as seguintes linhas ao /etc/my.cnf
[mysqld]
innodb_file_per_table
innodb_flush_method=O_DIRECT
innodb_log_file_size=1G
innodb_buffer_pool_size=4G
innodb_data_file_path=ibdata1:10M:autoextend
Sidenote: Seja qual for o seu conjunto para innodb_buffer_pool_size, certifique-se de que innodb_log_file_size seja 25% de innodb_buffer_pool_size.
- PASSO 05) Exclua ibdata1, ib_logfile0 e ib_logfile1 ( consulte a atualização abaixo antes de excluir! )
Neste ponto, deve haver apenas o esquema mysql em / var / lib / mysql
- PASSO 06) Reinicie o mysql
Isso irá recriar ibdata1 em 10MB (não configure a opção), ib_logfile0 e ib_logfile1 em 1G cada
- PASSO 07) Recarregue o SQLData.sql no mysql
ibdata1
aumentará, mas conterá apenas metadados de tabela e dados MVCC intermitentes.
Cada tabela InnoDB existirá fora de ibdata1
Suponha que você tenha uma tabela InnoDB chamada mydb.mytable. Se você entrar em /var/lib/mysql/mydb
, verá dois arquivos representando a tabela
-
mytable.frm
(cabeçalho do mecanismo de armazenamento) -
mytable.ibd
(Índices da tabela de dados e tabela paramydb.mytable
)
ibdata1
nunca mais conterá dados e índices InnoDB.
Com a opção innodb_file_per_table em /etc/my.cnf
, você pode executar OPTIMIZE TABLE mydb.mytable
OR ALTER TABLE mydb.mytable ENGINE=InnoDB;
e o arquivo /var/lib/mysql/mydb/mytable.ibd
será realmente reduzido.
Eu tenho feito isso várias vezes na minha carreira como um DBA MySQL sem nenhum problema depois disso. Na verdade, na primeira vez que fiz isso, colapsei um arquivo ibdata1 de 50 GB em 50 MB.
Experimente. Se você tiver mais dúvidas sobre isso, envie-me um email. Confie em mim. Isso funcionará a curto prazo e a longo prazo.
ATUALIZAÇÃO 2013-07-02 15:08 EDT
Há uma ressalva que tenho a esse respeito que atualizei em outros posts meus, mas senti falta disso: estou atualizando minha resposta um pouco mais com innodb_fast_shutdown porque eu costumava reiniciar o mysql e parar o mysql para fazer isso. Agora, este passo é vital porque cada transação não comprometida pode ter outras partes móveis dentro e fora dos Logs de Transação InnoDB ( Veja infra-estrutura InnoDB ).
Por favor, note que a configuração de innodb_fast_shutdown para 2 limparia os registros mas também mais partes móveis ainda existem e são escolhidas no Crash Recovery durante a inicialização do mysqld. A configuração de 0 é melhor.