MariaDB
 sql >> Base de Dados >  >> RDS >> MariaDB

Otimização do mecanismo de armazenamento MySQL:configurando a otimização do InnoDB para alto desempenho

InnoDB é um dos mecanismos de armazenamento mais usados ​​no MySQL. Esse mecanismo de armazenamento é conhecido como mecanismo de armazenamento de alta confiabilidade e alto desempenho e suas principais vantagens incluem suporte ao bloqueio em nível de linha, chaves estrangeiras e seguir o modelo ACID. O InnoDB substitui o MyISAM como mecanismo de armazenamento padrão desde o MySQL 5.5, lançado em 2010.

Esse mecanismo de armazenamento pode ter um desempenho incrível e poderoso se otimizado corretamente. Hoje, estamos analisando o que podemos fazer para que ele tenha o melhor desempenho possível, mas antes de mergulhar no InnoDB, porém, devemos entender o que é o modelo ACID acima mencionado.

O que é ACID e por que é importante?

ACID é um conjunto de propriedades de transações de banco de dados. A sigla se traduz em quatro palavras:Atomicidade, Consistência, Isolamento e Durabilidade. Em suma, essas propriedades garantem que as transações do banco de dados sejam processadas de forma confiável e garantem a validade dos dados apesar de erros, quedas de energia ou quaisquer desses problemas. Um sistema de gerenciamento de banco de dados que adere a esses princípios é considerado um SGBD compatível com ACID. Veja como tudo funciona no InnoDB:

  • A atomicidade garante que as declarações em uma transação funcionem como uma unidade indivisível e que seus efeitos sejam vistos coletivamente ou não sejam vistos;
  • A consistência é tratada pelos mecanismos de log do MySQL que registram todas as alterações no banco de dados;
  • Isolamento refere-se ao bloqueio em nível de linha do InnoDB;
  • A durabilidade também é mantida porque o InnoDB mantém um arquivo de log que rastreia todas as alterações no sistema.

Compreendendo o InnoDB

Agora que cobrimos o ACID, provavelmente deveríamos ver como o InnoDB se parece nos bastidores. Veja como o InnoDB se parece por dentro (imagem cortesia de Percona):
InnoDB Internals

Na imagem acima podemos ver claramente que o InnoDB tem alguns parâmetros cruciais para o seu desempenho e são os seguintes:

  • O parâmetro innodb_data_file_path descreve o tablespace do sistema (o tablespace do sistema é a área de armazenamento para o dicionário de dados do InnoDB, os buffers duplos de gravação e alteração e logs de undo). O parâmetro descreve o arquivo onde os dados derivados das tabelas InnoDB serão armazenados;
  • O parâmetro innodb_buffer_pool_size é um buffer de memória que o InnoDB usa para armazenar dados e índices de suas tabelas em cache;
  • O parâmetro innodb_log_file_size descreve o tamanho dos arquivos de log do InnoDB;
  • O parâmetro innodb_log_buffer_size é usado para gravar nos arquivos de log no disco;
  • O parâmetro innodb_flush_log_at_trx_commit controla o equilíbrio entre conformidade estrita com ACID e desempenho superior;
  • O parâmetro innodb_lock_wait_timeout é o tempo em segundos que uma transação InnoDB espera por um bloqueio de linha antes de desistir;
  • O parâmetro innodb_flush_method define o método usado para liberar dados para arquivos de dados e arquivos de log do InnoDB que podem afetar a taxa de transferência de E/S.

O InnoDB também armazena os dados de suas tabelas em um arquivo chamado ibdata1 - os logs são armazenados em dois arquivos separados chamados ib_logfile0 e ib_logfile1:todos esses três arquivos residem no diretório /var/lib/mysql diretório.

Para tornar o InnoDB o mais eficiente possível, devemos ajustar esses parâmetros e otimizá-los o máximo que pudermos observando nossos recursos de hardware disponíveis.

Ajustando o InnoDB para alto desempenho

Para ajustar o desempenho do InnoDB em seu hardware, siga estas etapas:

  • Para estender innodb_data_file_path automaticamente, especifique o atributo autoextend na configuração e reinicie o servidor. Por exemplo:

innodb_data_file_path=ibdata1:10M:autoextend

Quando o parâmetro autoextend é usado, o arquivo de dados aumenta automaticamente de tamanho em incrementos de 8 MB cada vez que é necessário espaço. Um novo arquivo de dados de extensão automática também pode ser especificado assim (neste caso, o novo arquivo de dados é chamado ibdata2):

innodb_data_file_path=ibdata1:10M;ibdata2:10M:autoextend
  • Ao usar o InnoDB, o principal mecanismo usado é o buffer pool. O InnoDB depende muito do buffer pool e, como regra geral, o parâmetro innodb_buffer_pool_size deve ser cerca de 60% a 80% do total de RAM disponível no servidor. Tenha em mente que você também deve deixar um pouco de RAM para os processos em execução no sistema operacional;

  • O innodb_log_file_size do InnoDB deve ser definido o maior possível, mas não maior do que o necessário. Nesse caso, lembre-se de que um tamanho de arquivo de log maior é melhor para o desempenho, mas quanto maior, mais tempo de recuperação após uma falha é necessário. Como tal, não existe uma solução “tamanho único”, mas diz-se que o tamanho combinado dos arquivos de log deve ser grande o suficiente. Isso ajuda o servidor MySQL a trabalhar regularmente em checkpoints e atividade de liberação de disco. Isso economiza muita CPU e E/S de disco e pode ser executado sem problemas durante o horário de pico ou atividade de alta carga de trabalho. Embora a abordagem recomendada seja testar e experimentar você mesmo e encontrar o valor ideal;

  • O valor innodb_log_buffer_size deve ser definido como pelo menos 16 milhões. Um buffer de log grande permite que transações grandes sejam executadas sem a necessidade de gravar o log em disco antes que as transações sejam confirmadas, salvando alguma E/S de disco;

  • Ao ajustar innodb_flush_log_at_trx_commit, lembre-se de que este parâmetro aceita três valores - 0, 1 e 2. Com um valor de 1, você obtém conformidade com ACID e com valores 0 ou 2 você obtém mais desempenho, mas menos confiabilidade, porque nesse caso as transações para as quais os logs ainda não foram liberados para o disco podem ser perdidas em uma falha;

  • Para definir innodb_lock_wait_timeout com um valor adequado, lembre-se de que este parâmetro define o tempo em segundos (o valor padrão é 50) antes emitindo o seguinte erro e revertendo a instrução atual:

ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
  • No InnoDB, existem vários métodos de liberação disponíveis. Por padrão, essa configuração é definida como “async_unbuffered” em máquinas Windows se o valor for definido como NULL e como “fsync” em máquinas Linux. Veja quais são os métodos e o que eles fazem:

Método InnoDB Flush

Propósito

normal

O InnoDB usará E/S assíncrona simulada e E/S em buffer.

sem buffer

O InnoDB usará E/S assíncrona simulada e E/S sem buffer.

async_unbuffered

O InnoDB usará E/S assíncrona do Windows e E/S sem buffer. Configurações padrão em máquinas Windows.

fsync

O InnoDB usará a função fsync() para liberar os dados e os arquivos de log. Configuração padrão em máquinas Linux.

O_DSYNC

O InnoDB usará O_SYNC para abrir e liberar os arquivos de log e a função fsync() para liberar os arquivos de dados. O_DSYNC é mais rápido que O_DIRECT, mas os dados podem ou não ser consistentes devido à latência ou a uma falha total.

nosync

Usado para teste de desempenho interno - não suportado.

littlesync

Usado para teste de desempenho interno - não suportado.

O_DIRECT

O InnoDB usará O_DIRECT para abrir os arquivos de dados e a função fsync() para liberar os dados e os arquivos de log. Em comparação com O_DSYNC, O_DIRECT é mais estável e mais consistente com os dados, mas mais lento. O cache do SO será evitado usando esta configuração - esta configuração é a configuração recomendada em máquinas Linux.

O_DIRECT_NO_FSYNC

O InnoDB usará O_DIRECT durante a liberação de E/S - a parte “NO_FSYNC” define que a função fsync() será ignorada.

  • Você também deve considerar habilitar a configuração innodb_file_per_table. Este parâmetro está ativado por padrão no MySQL 5.6 e superior. Esse parâmetro alivia você de problemas de gerenciamento relacionados às tabelas do InnoDB, armazenando-as em arquivos separados e evitando dicionários principais e tabelas de sistema inchados. Ativar esta variável também evita enfrentar a complexidade da recuperação de dados quando uma determinada tabela está corrompida
  • Agora que você modificou essas configurações de acordo com as instruções descritas acima, você deve estar quase pronto para começar! Antes de começar, você provavelmente deve ficar de olho no arquivo mais ocupado em toda a infraestrutura do InnoDB - o ibdata1.

Lidando com ibdata1

Existem várias classes de informações que são armazenadas em ibdata1:

  1. Os dados das tabelas InnoDB;
  2. Os índices das tabelas InnoDB;
  3. Metadados da tabela InnoDB;
  4. Dados de controle de simultaneidade de várias versões (MVCC);
  5. O buffer de escrita dupla - esse buffer permite que o InnoDB se recupere de páginas semi-escritas. O objetivo desse buffer é evitar a corrupção de dados;
  6. O buffer de inserção - esse buffer é usado pelo InnoDB para armazenar atualizações na mesma página para que possam ser executadas de uma só vez e não uma após a outra.

Ao lidar com grandes conjuntos de dados, o arquivo ibdata1 pode ficar extremamente grande e isso pode ser o centro de um problema muito frustrante - o arquivo só pode crescer e, por padrão, não pode diminuir. Você pode encerrar o MySQL e excluir este arquivo, mas isso não é recomendado, a menos que você saiba o que está fazendo. Quando excluído, o MySQL não funcionará corretamente, pois o dicionário e as tabelas do sistema desapareceram, portanto, a tabela principal do sistema está corrompida.

Para reduzir o ibdata1 de uma vez por todas, siga estas etapas:
  1. Descarregue todos os dados dos bancos de dados InnoDB. Você pode usar mysqldump ou mysqlpump para esta ação;
  2. Retire todos os bancos de dados, exceto os bancos de dados mysql, performance_schema e information_schema;
  3. Parar o MySQL;
  4. Adicione o seguinte ao seu arquivo my.cnf:
    [mysqld]
    innodb_file_per_table = 1
    innodb_flush_method = O_DIRECT
    innodb_log_file_size = 25% of innodb_buffer_pool_size
    innodb_buffer_pool_size = up to 60-80% of available RAM.
  5. Apague os arquivos ibdata1 e ib_logfile* (estes serão recriados na próxima reinicialização do MySQL);
  6. Inicie o MySQL e restaure os dados do dump que você fez antes. Após executar as etapas descritas acima, o arquivo ibdata1 ainda crescerá, mas não conterá mais os dados das tabelas InnoDB - o arquivo conterá apenas metadados e cada tabela InnoDB existirá fora de ibdata1. Agora, se você for ao diretório /var/lib/mysql, verá dois arquivos representando cada tabela que você tem com o mecanismo InnoDB. Os arquivos ficarão assim:
    1. demotable.frm
    2. demotable.ibd

O arquivo .frm contém o cabeçalho do mecanismo de armazenamento e o arquivo .ibd contém os dados da tabela e os índices de sua tabela.

Antes de implementar as alterações, certifique-se de ajustar os parâmetros de acordo com sua infraestrutura. Esses parâmetros podem aumentar ou diminuir o desempenho do InnoDB, portanto, fique de olho neles o tempo todo. Agora você deve estar pronto para ir!

Resumo

Para resumir, otimizar o desempenho do InnoDB pode ser um grande benefício se você desenvolver aplicativos que exigem integridade de dados e alto desempenho ao mesmo tempo - o InnoDB permite alterar a quantidade de memória permitida ao mecanismo consumir, para alterar o tamanho do arquivo de log, o método flush que o mecanismo usa e assim por diante - essas alterações podem fazer com que o InnoDB tenha um desempenho extremamente bom se forem ajustados corretamente. Antes de executar qualquer aprimoramento, tome cuidado com as consequências de suas ações para o servidor e o MySQL.

Como sempre, antes de otimizar qualquer coisa para desempenho, sempre faça (e teste!) backups para que você possa restaurar seus dados, se necessário, e sempre teste quaisquer alterações em um servidor local antes de implementar as alterações na produção.