A razão pela qual o Data_free sempre retorna com o mesmo número em todas as tabelas é simples:
- Você não está usando innodb_file_per_table
- Todos os seus dados do InnoDB estão dentro deste grande arquivo chamado / var / lib / mysql / ibdata1.
Desde que estas duas condições existam, você nunca eliminará a fragmentação . Qualquer tentativa de executar OPTIMIZE TABLE em relação a uma tabela InnoDB tornará os dados e índices para a tabela contíguos, mas será adaptada para ibdata1, tornando o ibdata1 muito maior.
Em vista disso, você deve saber o que está dentro do ibdata1. Existem quatro (4) tipos de informação dentro:
- Páginas de dados de tabela
- Índice de páginas de tabela
- MetaData da tabela
- MVCC Data
Você deve fazer quatro (4) coisas importantes:
- Descarregar todos os bancos de dados
- Excluir ibdata1
- Rreconfigure o InnoDB usando innodb_file_per_table
- Recarregar despejo
Isso manterá todos os dados e índices fora do ibdata1 e os armazenará em arquivos .ibd separados. A partir daí, você pode executar OPTIMIZE TABLE na tabela InnoDB configurada como innodb_file_per_table. Assim, os arquivos .ibd podem ser desfragmentados individualmente.
- Escrevi originalmente sobre isso em 29 de outubro de 2010 no StackOverflow
- Também escrevi sobre isso em 4 de fevereiro de 2011 em ServerFault
- e novamente 11 de março de 2011 em ServerFault
Isso fará com que ibdata1 seja o menor possível, nunca mais se torne descontroladamente descontrolado. Todas as preocupações com a desfragmentação do InnoDB estão a apenas uma OPTIMIZE TABLE de distância.
- Deve-se notar que o OPTIMIZE TABLE em uma tabela INNODB opera de maneira um pouco diferente do que o uso de outros mecanismos de armazenamento. Percona tem um bom artigo sobre como melhorar a velocidade do OPTIMIZE TABLE e quando você deve / não deveria considerar executar a referida ação aqui .
"For InnoDB tables, OPTIMIZE TABLE is mapped to ALTER TABLE, which rebuilds the table to update index statistics and free unused space in the clustered index."