Suponha que você deveria adicionar innodb_file_per_tablea /etc/my.cnf (my.ini). Você pode então rodar OPTIMIZE TABLEem todas as tabelas do InnoDB?
Boas notícias : quando você executa OPTIMIZE TABLEcom innodb_file_per_tableativado, isso produz um .ibdarquivo para essa tabela. Por exemplo, se você tiver uma tabela mydb.mytablecom um dado /var/lib/mysql, ela produzirá o seguinte:
/var/lib/mysql/mydb/mytable.frm
/var/lib/mysql/mydb/mytable.ibd
O .ibdconterá as páginas de dados e páginas de índice para essa tabela. Ótimo.
Más notícias : tudo o que você fez foi extrair as páginas de dados e as páginas de índice de sua mydb.mytableresidência ibdata. A entrada do dicionário de dados para todas as tabelas, inclusive mydb.mytable, ainda permanece no dicionário de dados (consulte a representação pictórica do ibdata1 ). VOCÊ NÃO PODE APAGAR SIMPLESMENTE ibdata1NESTE PONTO! Observe que ibdata1não encolheu nada.
Limpeza da infraestrutura do InnoDB
Para diminuir de ibdata1uma vez por todas, você deve fazer o seguinte:
Despejar (por exemplo, com mysqldump) todos os bancos de dados em um .sqlarquivo de texto ( SQLData.sqlé usado abaixo)
Elimine todos os bancos de dados (exceto mysqle information_schema) CAVEAT : como precaução, execute este script para garantir que você tenha todas as concessões de usuário em vigor:
Entre no mysql e execute SET GLOBAL innodb_fast_shutdown = 0;(Isso liberará completamente todas as mudanças transacionais restantes de ib_logfile0e ib_logfile1)
Desligamento do MySQL
Adicione as seguintes linhas ao /etc/my.cnf(ou my.inino Windows)
(Nota: qualquer que seja o seu objetivo innodb_buffer_pool_size, verifique se innodb_log_file_sizeé 25% de innodb_buffer_pool_size.
Também: innodb_flush_method=O_DIRECTnão está disponível no Windows)
Excluir ibdata*e ib_logfile*, opcionalmente, você pode remover todas as pastas /var/lib/mysql, exceto /var/lib/mysql/mysql.
Inicie o MySQL (isso irá recriar ibdata1[10 MB por padrão] ib_logfile0e ib_logfile1com 1G cada).
Importar SQLData.sql
Agora, ibdata1ainda crescerá, mas conterá apenas metadados da tabela, porque cada tabela InnoDB existirá fora de ibdata1. ibdata1não conterá mais dados e índices do InnoDB para outras tabelas.
Por exemplo, suponha que você tenha uma tabela InnoDB denominada mydb.mytable. Se você olhar /var/lib/mysql/mydb, verá dois arquivos representando a tabela:
mytable.frm (Cabeçalho do mecanismo de armazenamento)
mytable.ibd (Dados e índices da tabela)
Com a innodb_file_per_tableopção ativada /etc/my.cnf, você pode executar OPTIMIZE TABLE mydb.mytablee o arquivo /var/lib/mysql/mydb/mytable.ibddiminuirá.
Eu já fiz isso muitas vezes na minha carreira como DBA do MySQL. De fato, na primeira vez que fiz isso, reduzi um arquivo de 50 GBibdata1 para apenas 500 MB!
De uma chance. Se você tiver mais perguntas sobre isso, basta perguntar. Confie em mim; isso funcionará a curto prazo e a longo prazo.
EMBARGO
Na Etapa 6, se o mysql não puder reiniciar devido ao mysqlinício do esquema, olhe para a Etapa 2. Você fez a cópia física do mysqlesquema. Você pode restaurá-lo da seguinte maneira:
Pessoalmente, eu continuaria com 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 logs durante um ciclo de manutenção em apenas alguns minutos.
Também usei a opção innodb_file_per_table com grande efeito: tendo 200 bancos de dados com 200 tabelas cada em um único servidor, consegui desvincular bancos de dados de diferenças em diferentes partições, usando mais buffers e eixos de E / S que, de outra forma, estariam disponíveis :)
Dave Rix
2
@SeanDowney BTW lembre- innodb_open_tablesse de aumentar, se necessário. O padrão é 300.
RolandoMySQLDBA
2
@ giorgio79, você precisa definir sua inserção em massa para um valor maior. Este é um bom argumento. Acrescentarei a essência da sua pergunta à minha resposta.
RolandoMySQLDBA
3
Em sistemas de 32 bits, um valor de 4Gb para innodb_buffer_pool_size não é permitido. O MySQL começará silenciosamente com o innodb desativado e as tabelas restauradas serão alteradas para myisam. Use um valor um pouco menor para corrigi-lo.
David
5
Bom Deus. Eu só quero dizer que esta é talvez uma das melhores respostas que eu já vi no ótimo trabalho, senhor. Ajudou-me a encontrar uma solução para o meu problema quando estava recebendo um ERRO 2013 (HY000) ao importar um 154g db. Obrigado pela excelente resposta!
Josh Brown
4
O mecanismo do InnoDB não armazena dados excluídos. À medida que você insere e exclui linhas, o espaço não utilizado fica alocado nos arquivos de armazenamento do InnoDB. Com o tempo, o espaço geral não diminuirá, mas com o tempo o espaço 'excluído e liberado' será reutilizado automaticamente pelo servidor do banco de dados.
Você pode ajustar e gerenciar ainda mais o espaço usado pelo mecanismo por meio de uma reorganização manual das tabelas. Para fazer isso, despeje os dados nas tabelas afetadas usando o mysqldump, descarte as tabelas, reinicie o serviço mysql e recrie as tabelas dos arquivos de despejo.
Respostas:
Aqui está uma resposta mais completa em relação ao InnoDB. É um processo um pouco demorado, mas pode valer a pena.
Lembre-se de que esse
/var/lib/mysql/ibdata1
é o arquivo mais ocupado da infraestrutura do InnoDB. Normalmente, abriga seis tipos de informações:Pictorial Representation of ibdata1
Arquitetura InnoDB
Muitas pessoas criam vários
ibdata
arquivos esperando um melhor gerenciamento e desempenho do espaço em disco, no entanto, essa crença está errada.Posso correr
OPTIMIZE TABLE
?Infelizmente, a execução
OPTIMIZE TABLE
em uma tabela do InnoDB armazenada no arquivo de espaço de tabela compartilhadoibdata1
faz duas coisas:ibdata1
ibdata1
porque os dados contíguos e as páginas de índice são anexados aibdata1
No entanto, você pode separar os dados da tabela e os índices da tabela
ibdata1
e gerenciá-los independentemente.Posso correr
OPTIMIZE TABLE
cominnodb_file_per_table
?Suponha que você deveria adicionar
innodb_file_per_table
a/etc/my.cnf (my.ini)
. Você pode então rodarOPTIMIZE TABLE
em todas as tabelas do InnoDB?Boas notícias : quando você executa
OPTIMIZE TABLE
cominnodb_file_per_table
ativado, isso produz um.ibd
arquivo para essa tabela. Por exemplo, se você tiver uma tabelamydb.mytable
com um dado/var/lib/mysql
, ela produzirá o seguinte:/var/lib/mysql/mydb/mytable.frm
/var/lib/mysql/mydb/mytable.ibd
O
.ibd
conterá as páginas de dados e páginas de índice para essa tabela. Ótimo.Más notícias : tudo o que você fez foi extrair as páginas de dados e as páginas de índice de sua
mydb.mytable
residênciaibdata
. A entrada do dicionário de dados para todas as tabelas, inclusivemydb.mytable
, ainda permanece no dicionário de dados (consulte a representação pictórica do ibdata1 ). VOCÊ NÃO PODE APAGAR SIMPLESMENTEibdata1
NESTE PONTO! Observe queibdata1
não encolheu nada.Limpeza da infraestrutura do InnoDB
Para diminuir de
ibdata1
uma vez por todas, você deve fazer o seguinte:Despejar (por exemplo, com
mysqldump
) todos os bancos de dados em um.sql
arquivo de texto (SQLData.sql
é usado abaixo)Elimine todos os bancos de dados (exceto
mysql
einformation_schema
) CAVEAT : como precaução, execute este script para garantir que você tenha todas as concessões de usuário em vigor:Entre no mysql e execute
SET GLOBAL innodb_fast_shutdown = 0;
(Isso liberará completamente todas as mudanças transacionais restantes deib_logfile0
eib_logfile1
)Desligamento do MySQL
Adicione as seguintes linhas ao
/etc/my.cnf
(oumy.ini
no Windows)(Nota: qualquer que seja o seu objetivo
innodb_buffer_pool_size
, verifique seinnodb_log_file_size
é 25% deinnodb_buffer_pool_size
.Também:
innodb_flush_method=O_DIRECT
não está disponível no Windows)Excluir
ibdata*
eib_logfile*
, opcionalmente, você pode remover todas as pastas/var/lib/mysql
, exceto/var/lib/mysql/mysql
.Inicie o MySQL (isso irá recriar
ibdata1
[10 MB por padrão]ib_logfile0
eib_logfile1
com 1G cada).Importar
SQLData.sql
Agora,
ibdata1
ainda crescerá, mas conterá apenas metadados da tabela, porque cada tabela InnoDB existirá fora deibdata1
.ibdata1
não conterá mais dados e índices do InnoDB para outras tabelas.Por exemplo, suponha que você tenha uma tabela InnoDB denominada
mydb.mytable
. Se você olhar/var/lib/mysql/mydb
, verá dois arquivos representando a tabela:mytable.frm
(Cabeçalho do mecanismo de armazenamento)mytable.ibd
(Dados e índices da tabela)Com a
innodb_file_per_table
opção ativada/etc/my.cnf
, você pode executarOPTIMIZE TABLE mydb.mytable
e o arquivo/var/lib/mysql/mydb/mytable.ibd
diminuirá.Eu já fiz isso muitas vezes na minha carreira como DBA do MySQL. De fato, na primeira vez que fiz isso, reduzi um arquivo de 50 GB
ibdata1
para apenas 500 MB!De uma chance. Se você tiver mais perguntas sobre isso, basta perguntar. Confie em mim; isso funcionará a curto prazo e a longo prazo.
EMBARGO
Na Etapa 6, se o mysql não puder reiniciar devido ao
mysql
início do esquema, olhe para a Etapa 2. Você fez a cópia física domysql
esquema. Você pode restaurá-lo da seguinte maneira:Volte para a Etapa 6 e continue
UPDATE 2013-06-04 11:13 EDT
No que diz respeito à configuração de innodb_log_file_size para 25% de innodb_buffer_pool_size na Etapa 5, essa regra geral é bastante antiga.
De volta
July 03, 2006
, a Percona tinha um bom artigo sobre por que escolher um tamanho innodb_log_file_size adequado . Posteriormente, aNov 21, 2008
Percona acompanhou outro artigo sobre como calcular o tamanho adequado com base no pico de carga de trabalho, mantendo as alterações de uma hora .Desde então, escrevi postagens no DBA StackExchange sobre o cálculo do tamanho do log e onde referenciei esses dois artigos da Percona.
Aug 27, 2012
: Ajuste adequado para a tabela InnoDB de 30 GB no servidor com 48 GB de RAMJan 17, 2013
: MySQL 5.5 - Innodb - innodb_log_file_size maior que 4 GB combinados?Pessoalmente, eu continuaria com 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 logs durante um ciclo de manutenção em apenas alguns minutos.
fonte
innodb_open_tables
se de aumentar, se necessário. O padrão é 300.O mecanismo do InnoDB não armazena dados excluídos. À medida que você insere e exclui linhas, o espaço não utilizado fica alocado nos arquivos de armazenamento do InnoDB. Com o tempo, o espaço geral não diminuirá, mas com o tempo o espaço 'excluído e liberado' será reutilizado automaticamente pelo servidor do banco de dados.
Você pode ajustar e gerenciar ainda mais o espaço usado pelo mecanismo por meio de uma reorganização manual das tabelas. Para fazer isso, despeje os dados nas tabelas afetadas usando o mysqldump, descarte as tabelas, reinicie o serviço mysql e recrie as tabelas dos arquivos de despejo.
fonte