Existe realmente apenas uma maneira de conseguir isso. Você terá que exportar os dados usando o mysqldumps, descartar todos os bancos de dados, desligar o mysqld, excluir ib_logfile0, excluir ib_logfile1, excluir ib_logfile1, excluir ibdata1, adicionar innodb_file_per_table
sob o [mysqld]
cabeçalho, iniciar o mysql.
Publiquei esta resposta no StackOverflow em outubro de 2010
Aqui estão as etapas listadas verticalmente:
Etapa 01) MySQLDump todos os bancos de dados em um arquivo de texto SQL (chame-o SQLData.sql)
Etapa 02) Solte todos os bancos de dados (exceto o esquema mysql)
Etapa 03) Desligar o mysql
CAVEAT : Para limpar totalmente transações não confirmadas dos arquivos InnoDB, execute este
mysql -uroot -p... -Ae"SET GLOBAL innodb_fast_shutdown = 0;"
service mysql stop
Etapa 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
Nota: Qualquer que seja o seu conjunto para innodb_buffer_pool_size, verifique se innodb_log_file_size é 25% de innodb_buffer_pool_size.
Etapa 05) Excluir ibdata1, ib_logfile0 e ib_logfile1
Neste ponto, deve haver apenas o esquema mysql em / var / lib / mysql
Etapa 06) Reinicie o mysql
Isso recriará ibdata1 em 10 MB, ib_logfile0 e ib_logfile1 em 1G cada
Etapa 07) Recarregar SQLData.sql no mysql
ibdata1 crescerá, mas conterá apenas metadados da tabela
Cada tabela do InnoDB existirá fora do ibdata1
Suponha que você tenha uma tabela do InnoDB chamada mydb.mytable. Se você acessar / var / lib / mysql / mydb, verá dois arquivos representando a tabela
- mytable.frm (cabeçalho do mecanismo de armazenamento)
- mytable.ibd (Página inicial dos dados e índices da tabela para mydb.mytable)
O ibdata1 nunca mais conterá dados e índices do InnoDB.
Com a opção innodb_file_per_table em /etc/my.cnf, você pode executar o OPTIMIZE TABLE mydb.mytable e o arquivo /var/lib/mysql/mydb/mytable.ibd realmente diminuirá.
Eu fiz isso muitas vezes na minha carreira como DBA MySQL
De fato, na primeira vez em que fiz isso, reduzi um arquivo ibdata1 de 50 GB em 500 MB.
De uma chance. Se você tiver mais perguntas sobre isso, envie-me um e-mail. Confie em mim. Isso funcionará a curto prazo e a longo prazo. !!!
Existe uma alternativa que extrairá a tabela InnoDB sem reduzir o ibdata1.
Etapa 01) 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
Etapa 02) service mysql restart
Etapa 03) Para extrair uma única tabela do InnoDB chamada mydb.mytable, faça o seguinte:
ALTER TABLE mydb.mytable ENGINE=InnoDB;
Isso criará um arquivo pleus manter o arquivo de estrutura original
- /var/lib/mysql/mydb/mytable.frm
- /var/lib/mysql/mydb/mytable.ibd
Você pode fazer isso para todas as tabelas do InnoDB. Infelizmente, o ibdata1 ficará com 150 GB.
ERROR 1071 (42000) at line 25: Specified key was too long; max key length is 1000 bytes
alguma idéia?innodb_file_per_table
e, em seguida, fizer issoALTER TABLE
em todas as tabelas, será possível excluir o arquivo ibdata1 para recuperar o espaço sem precisar restaurar?Se você deseja recuperar o espaço do ibdata, uma despejo / restauração é sua única opção, como aponta Rolando . Também é provavelmente o melhor desempenho para fazer isso.
No entanto, se você quiser apenas reduzir suas perdas e "perder" esses 150 GB no disco rígido, basta ativar
innodb_file_per_table
o my.cnf e reiniciar o servidor.Em seguida, para cada tabela, emita:
O problema aqui é que espaços de tabela grandes levarão um tempo.
O que eu sugeriria é configurar um escravo do seu banco de dados ao vivo, executar a conversão no escravo, desligar o mestre / escravo e copiar o novo espaço de dados para o mestre, ou promover o escravo para ser o mestre depois de capturado .
Você terá dificuldade em fazer essa alteração sem tempo de inatividade.
fonte