Aqui está uma resposta mais completa em relação ao InnoDB. É um processo um pouco demorado, mas pode valer a pena o esforço.
Tenha em mente que
/var/lib/mysql/ibdata1
é o arquivo mais ocupado na infraestrutura InnoDB. Normalmente abriga seis tipos de informações:- Dados da tabela
- Índices de tabela
- MVCC (Multiversioning Concurrency Control)
Dados
- Segmentos de reversão
- Desfazer espaço
- Metadados de tabela (dicionário de dados)
- Double Write Buffer (gravação em segundo plano para evitar a dependência do cache do SO)
- Inserir buffer (gerenciar alterações em índices secundários não exclusivos)
- Veja a
Representação pictórica de ibdata1
Arquitetura InnoDB
Muitas pessoas criam vários
ibdata
arquivos esperando por um melhor gerenciamento de espaço em disco e desempenho, no entanto, essa crença é equivocada. Posso executar OPTIMIZE TABELA
?
Infelizmente, executando
OPTIMIZE TABLE
em uma tabela InnoDB armazenada no arquivo de espaço de tabela compartilhado ibdata1
faz duas coisas:- Torna os dados e índices da tabela contíguos dentro de
ibdata1
- Cria
ibdata1
crescem porque os dados contíguos e as páginas de índice são anexados paraibdata1
No entanto, você pode separar dados de tabela e índices de tabela de
ibdata1
e gerenciá-los de forma independente. Posso executar OPTIMIZE TABELA
com innodb_file_per_table
?
Suponha que você adicionasse
innodb_file_per_table
para /etc/my.cnf (my.ini)
. Você pode então executar OPTIMIZE TABLE
em todas as tabelas InnoDB? Boas notícias :quando você executa
OPTIMIZE TABLE
com innodb_file_per_table
habilitado, isso produzirá um .ibd
arquivo para essa tabela. Por exemplo, se você tiver a tabela mydb.mytable
com um datadir de /var/lib/mysql
, produzirá o seguinte:/var/lib/mysql/mydb/mytable.frm
/var/lib/mysql/mydb/mytable.ibd
O
.ibd
conterá as páginas de dados e as páginas de índice para essa tabela. Excelente. Más notícias :Tudo o que você fez foi extrair as páginas de dados e as páginas de índice de
mydb.mytable
de viver em ibdata
. A entrada do dicionário de dados para cada tabela, incluindo mydb.mytable
, ainda permanece no dicionário de dados (Veja a Representação pictórica de ibdata1
). VOCÊ NÃO PODE SIMPLESMENTE EXCLUIR ibdata1
NESTE PONTO!!! Observe que ibdata1
não encolheu em nada. Limpeza da infraestrutura do InnoDB
Para reduzir
ibdata1
de uma vez por todas você deve fazer o seguinte:-
Dump (por exemplo, commysqldump
) todos os bancos de dados em um.sql
arquivo de texto (SQLData.sql
é usado abaixo)
-
Elimine todos os bancos de dados (exceto paramysql
einformation_schema
) AVISO :Como precaução, execute este script para ter certeza absoluta de que todas as concessões de usuário estão em vigor:
mkdir /var/lib/mysql_grants cp /var/lib/mysql/mysql/* /var/lib/mysql_grants/. chown -R mysql:mysql /var/lib/mysql_grants
-
Faça login no mysql e executeSET GLOBAL innodb_fast_shutdown =0;
(Isso liberará completamente todas as alterações transacionais restantes deib_logfile0
eib_logfile1
)
-
Desligar o MySQL
-
Adicione as seguintes linhas a/etc/my.cnf
(oumeu.ini
no Windows)
[mysqld] innodb_file_per_table innodb_flush_method=O_DIRECT innodb_log_file_size=1G innodb_buffer_pool_size=4G
(Nota:Seja qual for o seu conjunto parainnodb_buffer_pool_size
, certifique-se de queinnodb_log_file_size
é 25% deinnodb_buffer_pool_size
.
Também:innodb_flush_method=O_DIRECT
não está disponível no Windows)
-
Excluiribdata*
eib_logfile*
, Opcionalmente, você pode remover todas as pastas em/var/lib/mysql
, exceto/var/lib/mysql/mysql
.
-
Inicie o MySQL (Isso irá recriaribdata1
[10 MB por padrão] eib_logfile0
eib_logfile1
a 1G cada).
-
ImportarSQLData.sql
Agora,
ibdata1
ainda crescerá, mas conterá apenas metadados de tabela porque cada tabela InnoDB existirá fora de ibdata1
. ibdata1
não conterá mais dados e índices do InnoDB para outras tabelas. Por exemplo, suponha que você tenha uma tabela InnoDB chamada
mydb.mytable
. Se você olhar em /var/lib/mysql/mydb
, você verá dois arquivos representando a tabela:minhatabela.frm
(Cabeçalho do mecanismo de armazenamento)minhatabela.ibd
(Dados e índices da tabela)
Com o
innodb_file_per_table
opção em /etc/my.cnf
, você pode executar OPTIMIZE TABLE mydb.mytable
e o arquivo /var/lib/mysql/mydb/mytable.ibd
vai realmente encolher. Já fiz isso muitas vezes na minha carreira como DBA MySQL. Na verdade, na primeira vez que fiz isso, encolhi 50 GB
ibdata1
arquivo para apenas 500 MB! De uma chance. Se tiver mais dúvidas sobre isso, é só perguntar. Confie em mim; isso funcionará no curto prazo, bem como no longo prazo.
AVISO
Na Etapa 6, se o mysql não puder reiniciar devido ao
mysql
início do esquema descartado, volte para a Etapa 2. Você fez a cópia física do mysql
esquema. Você pode restaurá-lo da seguinte maneira:mkdir /var/lib/mysql/mysql
cp /var/lib/mysql_grants/* /var/lib/mysql/mysql
chown -R mysql:mysql /var/lib/mysql/mysql
Volte para a Etapa 6 e continue
ATUALIZAÇÃO 2013-06-04 11:13 EDT
Com relação à configuração de innodb_log_file_size para 25% de innodb_buffer_pool_size na Etapa 5, essa regra geral é bastante antiga.
De volta em
03 de julho de 2006
, Percona tinha um bom artigo por que escolher um innodb_log_file_size adequado . Mais tarde, em 21 de novembro de 2008
, Percona seguiu com outro artigo sobre como calcular o tamanho adequado com base na carga de trabalho de pico mantendo uma hora de alterações
. Desde então, escrevi posts no DBA StackExchange sobre como calcular o tamanho do log e onde fiz referência a esses dois artigos do Percona.
27 de agosto de 2012
:Ajuste adequado para tabela InnoDB de 30 GB em servidor com 48 GB de RAM17 de janeiro de 2013
:MySQL 5.5 - Innodb - innodb_log_file_size maior que 4 GB combinados?
Pessoalmente, eu ainda seguiria a regra de 25% para uma configuração inicial. Então, como a carga de trabalho pode ser determinada com mais precisão ao longo do tempo na produção, você pode redimensionar os registros durante um ciclo de manutenção em apenas alguns minutos.