É possível limpar um mecanismo de armazenamento mysql innodb para que ele não armazene dados de tabelas excluídas?
Ou tenho que reconstruir um banco de dados sempre novo?
É possível limpar um mecanismo de armazenamento mysql innodb para que ele não armazene dados de tabelas excluídas?
Ou tenho que reconstruir um banco de dados sempre novo?
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
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.
OPTIMIZE TABLE
?Infelizmente, a execução OPTIMIZE TABLE
em uma tabela do InnoDB armazenada no arquivo de espaço de tabela compartilhado ibdata1
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.
OPTIMIZE TABLE
com innodb_file_per_table
?Suponha que você deveria adicionar innodb_file_per_table
a /etc/my.cnf (my.ini)
. Você pode então rodar OPTIMIZE TABLE
em todas as tabelas do InnoDB?
Boas notícias : quando você executa OPTIMIZE TABLE
com innodb_file_per_table
ativado, isso produz um .ibd
arquivo para essa tabela. Por exemplo, se você tiver uma tabela mydb.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ê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 ibdata1
NESTE PONTO! Observe que ibdata1
não encolheu nada.
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
e information_schema
) CAVEAT : como precaução, execute este script para garantir que você tenha todas as concessões de usuário em vigor:
mkdir /var/lib/mysql_grants
cp /var/lib/mysql/mysql/* /var/lib/mysql_grants/.
chown -R mysql:mysql /var/lib/mysql_grants
Entre no mysql e execute SET GLOBAL innodb_fast_shutdown = 0;
(Isso liberará completamente todas as mudanças transacionais restantes de ib_logfile0
e ib_logfile1
)
Desligamento do MySQL
Adicione as seguintes linhas ao /etc/my.cnf
(ou my.ini
no Windows)
[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 objetivo innodb_buffer_pool_size
, verifique se innodb_log_file_size
é 25% de innodb_buffer_pool_size
.
Também: innodb_flush_method=O_DIRECT
nã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_logfile0
e ib_logfile1
com 1G cada).
Importar SQLData.sql
Agora, ibdata1
ainda crescerá, mas conterá apenas metadados da 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 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 executar OPTIMIZE 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.
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 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
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, a Nov 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.
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.