Qual é a melhor maneira de reduzir o tamanho do ibdata no mysql?


63

Eu tenho alguns servidores de produção cujos ibdataarquivos aumentam de tamanho dia a dia.

Já consumiu 290 GB de espaço.

As tabelas nos servidores são principalmente o InnoDB e existem altas solicitações de leitura e gravação.

O tamanho do arquivo de log também está aumentando. Há uma enorme quantidade de dados nas tabelas.

Como posso controlar o tamanho crescente de ambos?

Eu não estou usando innodb_file_per_table.

Respostas:


104

Lembre-se de que o arquivo mais ocupado da infraestrutura do InnoDB é / var / lib / mysql / ibdata1

Esse arquivo normalmente abriga muitas classes de informações (quando innodb_file_per_table é 0)

  • Dados da tabela
  • Índices de tabela
  • Dados MVCC (controle de simultaneidade de várias versões)
    • Segmentos de reversões
    • Desfazer espaço de tabela
  • Metadados da tabela
  • Consulte Representação pictórica

Muitas pessoas criam vários arquivos ibdata esperando um melhor gerenciamento e desempenho do espaço em disco. Isso não ajuda.

Infelizmente, OPTIMIZE TABLE em uma tabela do InnoDB armazenada no ibdata1 faz duas coisas:

  • Torna os dados e índices da tabela contíguos dentro de ibdata1
  • Faz ibdata1 crescer porque os dados contíguos são anexados a ibdata1

É possível segregar os dados da tabela e os índices da tabela do ibdata1 e gerenciá-los independentemente usando innodb_file_per_table . Para reduzir ibdata1 de uma vez por todas, você deve fazer o seguinte

Etapa 01) MySQLDump todos os bancos de dados em um arquivo de texto SQL (chame-o SQLData.sql) ( Mais detalhes aqui )

Passo 02) deixe cair todos os bancos de dados (excepto mysql, performance_schema, e information_schema)

Etapa 03) Desligar o mysql

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 aumentará, 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 OPTIMIZE TABLE mydb.mytablee o arquivo /var/lib/mysql/mydb/mytable.ibddiminuirá.

Eu fiz isso muitas vezes na minha carreira como um 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. !!!

Se você deseja ver quantos dados reais são armazenados no MyISAM e InnoDB, execute esta consulta:

SELECT IFNULL(B.engine,'Total') "Storage Engine",
CONCAT(LPAD(REPLACE(FORMAT(B.DSize/POWER(1024,pw),3),',',''),17,' '),' ',
SUBSTR(' KMGTP',pw+1,1),'B') "Data Size", CONCAT(LPAD(REPLACE(
FORMAT(B.ISize/POWER(1024,pw),3),',',''),17,' '),' ',
SUBSTR(' KMGTP',pw+1,1),'B') "Index Size", CONCAT(LPAD(REPLACE(
FORMAT(B.TSize/POWER(1024,pw),3),',',''),17,' '),' ',
SUBSTR(' KMGTP',pw+1,1),'B') "Table Size"
FROM (SELECT engine,SUM(data_length) DSize,SUM(index_length) ISize,
SUM(data_length+index_length) TSize FROM information_schema.tables
WHERE table_schema NOT IN ('mysql','information_schema','performance_schema')
AND engine IS NOT NULL GROUP BY engine WITH ROLLUP) B,
(SELECT 3 pw) A ORDER BY TSize;

Mesmo com as configurações sugeridas para my.cnf (que eu já tenho), excluindo ib_logfile0 e 1 e iniciando o mysql, os novos arquivos são criados e, em segundos, crescem para igualar o tamanho do banco de dados, conforme exibido na consulta acima. Não tenho certeza se o mysql está copiando todas as tabelas e índices para esses arquivos, mantendo também cada tabela em um arquivo separado.
Allen King
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.