Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Como:Limpar um mecanismo de armazenamento mysql InnoDB?


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:

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 para ibdata1

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:

  1. Dump (por exemplo, com mysqldump ) todos os bancos de dados em um .sql arquivo de texto (SQLData.sql é usado abaixo)

  2. Elimine todos os bancos de dados (exceto para mysql e information_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
    

  3. Faça login no mysql e execute SET GLOBAL innodb_fast_shutdown =0; (Isso liberará completamente todas as alterações transacionais restantes de ib_logfile0 e ib_logfile1 )

  4. Desligar o MySQL

  5. Adicione as seguintes linhas a /etc/my.cnf (ou meu.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 para innodb_buffer_pool_size , certifique-se de que innodb_log_file_size é 25% de innodb_buffer_pool_size .

    Também:innodb_flush_method=O_DIRECT não está disponível no Windows)

  6. Excluir ibdata* e ib_logfile* , Opcionalmente, você pode remover todas as pastas em /var/lib/mysql , exceto /var/lib/mysql/mysql .

  7. Inicie o MySQL (Isso irá recriar ibdata1 [10 MB por padrão] e ib_logfile0 e ib_logfile1 a 1G cada).

  8. Importar SQLData.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.

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.