O MySQL é extenso e possui muitas áreas para otimizar e ajustar para o desempenho desejado. Algumas alterações podem ser executadas dinamicamente, outras requerem a reinicialização do servidor. É bastante comum encontrar uma instalação do MySQL com uma configuração padrão, embora esta última possa não ser apropriada por si só para sua carga de trabalho e configuração.
Aqui estão as principais áreas do MySQL que eu peguei de diferentes fontes especializadas no mundo do MySQL, bem como nossas próprias experiências aqui na Variousnines. Este blog serviria como sua folha de dicas para ajustar o desempenho e tornar seu MySQL ótimo novamente :-)
Vamos dar uma olhada nisso, descrevendo as principais áreas do MySQL.
Variáveis do sistema
O MySQL tem muitas variáveis que você pode considerar mudar. Algumas variáveis são dinâmicas, o que significa que podem ser definidas usando a instrução SET. Outros requerem uma reinicialização do servidor, após serem definidos no arquivo de configuração (por exemplo, /etc/my.cnf, etc/mysql/my.cnf). No entanto, vou falar sobre as coisas comuns que são bastante comuns para ajustar para tornar o servidor otimizado.
sort_buffer_size
Essa variável controla o tamanho do buffer de classificação de arquivos, o que significa que sempre que uma consulta precisar classificar as linhas, o valor dessa variável é usado para limitar o tamanho que precisa ser alocado. Observe que essa variável é por consulta que é processada (ou por conexão), o que significa que seria uma fome de memória quando você definir isso mais alto e se tiver várias conexões que exigem classificação de suas linhas. No entanto, você pode monitorar suas necessidades verificando a variável de status global Sort_merge_passes. Se esse valor for grande, você deve considerar aumentar o valor da variável de sistema sort_buffer_size. Caso contrário, leve-o ao limite moderado que você precisa. Se você definir isso muito baixo ou se tiver grandes consultas para processar, o efeito de classificar suas linhas pode ser mais lento do que o esperado porque os dados são recuperados aleatoriamente fazendo mergulhos de disco. Isso pode causar degradação do desempenho. No entanto, é melhor corrigir suas consultas. Caso contrário, se seu aplicativo for projetado para receber consultas grandes e exigir classificação, é eficiente usar ferramentas que lidam com o cache de consultas, como o Redis. Por padrão, no MySQL 8.0, o valor atual definido é 256 KiB. Defina isso de acordo apenas quando você tiver consultas que estão usando ou chamando classificações.
read_buffer_size
A documentação do MySQL menciona que para cada solicitação que executa uma varredura sequencial de uma tabela, ele aloca um buffer de leitura. A variável de sistema read_buffer_size determina o tamanho do buffer. Também é útil para MyISAM, mas esta variável afeta todos os mecanismos de armazenamento também. Para tabelas MEMORY, é usado para determinar o tamanho do bloco de memória.
Basicamente, cada thread que faz uma varredura sequencial para uma tabela MyISAM aloca um buffer desse tamanho (em bytes) para cada tabela que varre. Ele também se aplica a todos os mecanismos de armazenamento (incluindo o InnoDB), portanto, é útil para consultas que classificam linhas usando ORDER BY e armazenam em cache seus índices em um arquivo temporário. Se você fizer muitas varreduras sequenciais, inserir em massa em tabelas de partição, armazenar em cache os resultados de consultas aninhadas e considerar aumentar seu valor. O valor desta variável deve ser um múltiplo de 4KB. Se estiver definido para um valor que não seja um múltiplo de 4 KB, seu valor será arredondado para o múltiplo de 4 KB mais próximo. Leve em consideração que definir isso para um valor mais alto consumirá uma grande parte da memória do seu servidor. Sugiro não usar isso sem o benchmarking e o monitoramento adequados do seu ambiente.
read_rnd_buffer_size
Esta variável lida com a leitura de linhas de uma tabela MyISAM em ordem de classificação seguindo uma operação de classificação por chave, as linhas são lidas por meio desse buffer para evitar buscas em disco. A documentação diz que, ao ler linhas em uma sequência arbitrária ou de uma tabela MyISAM em ordem de classificação após uma operação de classificação de chaves, as linhas são lidas por meio desse buffer (e determinadas por meio desse tamanho de buffer) para evitar buscas de disco. Definir a variável para um valor grande pode melhorar bastante o desempenho de ORDER BY. No entanto, este é um buffer alocado para cada cliente, portanto, você não deve definir a variável global com um valor grande. Em vez disso, altere a variável de sessão apenas de dentro dos clientes que precisam executar consultas grandes. No entanto, você deve levar em consideração que isso não se aplica ao MariaDB, especialmente ao aproveitar o MRR. MariaDB usa mrr_buffer_size enquanto MySQL usa read_buffer_size read_rnd_buffer_size.
join_buffer_size
Por padrão, o valor é de 256K. O tamanho mínimo do buffer usado para varreduras de índice simples, varreduras de índice de intervalo e junções que não usam índices e, portanto, realizam varreduras de tabela completas. Também usado pela otimização BKA (que está desabilitada por padrão). Aumente seu valor para obter junções completas mais rápidas quando não for possível adicionar índices. Advertência, porém, pode ser problemas de memória se você definir isso muito alto. Lembre-se de que um buffer de junção é alocado para cada junção completa entre duas tabelas. Para uma junção complexa entre várias tabelas para as quais os índices não são usados, vários buffers de junção podem ser necessários. Melhor deixar baixo globalmente e definir alto em sessões (usando a sintaxe SET SESSION) que exigem grandes junções completas. Em plataformas de 64 bits, o Windows trunca valores acima de 4 GB para 4 GB-1 com um aviso.
max_heap_table_size
Este é o tamanho máximo em bytes para tabelas MEMORY criadas pelo usuário que podem crescer. Isso é útil quando seu aplicativo está lidando com tabelas do mecanismo de armazenamento MEMORY. Definir a variável enquanto o servidor está ativo não tem efeito nas tabelas existentes, a menos que sejam recriadas ou alteradas. O menor de max_heap_table_size e tmp_table_size também limita as tabelas internas na memória. Essa variável também está em conjunto com tmp_table_size para limitar o tamanho das tabelas internas na memória (isso difere das tabelas criadas explicitamente como Engine=MEMORY, pois aplica apenas max_heap_table_size), o que for menor é aplicado entre os dois.
tmp_table_size
O maior tamanho para tabelas temporárias na memória (não tabelas MEMORY), embora se max_heap_table_size for menor, o limite inferior será aplicado. Se uma tabela temporária na memória exceder o limite, o MySQL a converte automaticamente em uma tabela temporária no disco. Aumente o valor de tmp_table_size (e max_heap_table_size se necessário) se você fizer muitas consultas GROUP BY avançadas e tiver grande espaço de memória disponível. Você pode comparar o número de tabelas temporárias internas em disco criadas com o número total de tabelas temporárias internas criadas comparando os valores das variáveis Created_tmp_disk_tables e Created_tmp_tables. No ClusterControl, você pode monitorar isso via Dashboard -> Gráfico de objetos temporários.
table_open_cache
Você pode aumentar o valor dessa variável se tiver um grande número de tabelas acessadas com frequência em seu conjunto de dados. Será aplicado para todos os threads, ou seja, por base de conexão. O valor indica o número máximo de tabelas que o servidor pode manter abertas em qualquer instância de cache de tabela. Embora aumentar este valor aumente o número de descritores de arquivo que o mysqld requer, então você também pode considerar verificar seu valor open_files_limit ou verificar quão grande é o limite SOFT e HARD definido em seu sistema operacional *nix. Você pode monitorar isso se precisar aumentar o cache da tabela verificando a variável de status Opened_tables. Se o valor de Opened_tables for grande e você não usar FLUSH TABLES com frequência (o que apenas força todas as tabelas a serem fechadas e reabertas), então você deve aumentar o valor da variável table_open_cache. Se você tiver um valor pequeno para table_open_cache e um grande número de tabelas forem acessadas com frequência, isso pode afetar o desempenho do seu servidor. Se você notar muitas entradas na lista de processos do MySQL com status “Abrindo tabelas” ou “Fechando tabelas”, é hora de ajustar o valor dessa variável, mas observe a advertência mencionada anteriormente. No ClusterControl, você pode verificar isso em Dashboards -> Table Open Cache Status ou Dashboards -> Open Tables. Você pode conferir aqui para mais informações.
table_open_cache_instances
Definir essa variável ajudaria a melhorar a escalabilidade e, claro, o desempenho, o que reduziria a contenção entre as sessões. O valor definido aqui limita o número de instâncias de cache de tabelas abertas. O cache de tabelas abertas pode ser particionado em várias instâncias de cache menores de tamanho table_open_cache/table_open_cache_instances. Uma sessão precisa bloquear apenas uma instância para acessá-la para instruções DML. Isso segmenta o acesso ao cache entre instâncias, permitindo maior desempenho para operações que utilizam o cache quando há muitas sessões acessando tabelas. (As instruções DDL ainda requerem um bloqueio em todo o cache, mas essas instruções são muito menos frequentes do que as instruções DML.) Um valor de 8 ou 16 é recomendado em sistemas que usam rotineiramente 16 ou mais núcleos.
table_definition_cache
Definições de tabela de cache, ou seja, é onde o CREATE TABLE é armazenado em cache para acelerar a abertura de tabelas e apenas uma entrada por tabela. Seria razoável aumentar o valor se você tiver um grande número de tabelas. O cache de definição de tabela ocupa menos espaço e não usa descritores de arquivo, ao contrário do cache de tabela normal. Peter Zaitsev de Percona sugere se você pode tentar a configuração da fórmula abaixo,
The number of user-defined tables + 10% unless 50K+ tables
Mas observe que o valor padrão é baseado na seguinte fórmula limitada a um limite de 2000.
MIN(400 + table_open_cache / 2, 2000)
Portanto, caso você tenha um número maior de tabelas em comparação com o padrão, é razoável aumentar seu valor. Leve em consideração que com o InnoDB, esta variável é usada como um soft limit do número de instâncias de tabela abertas para o cache do dicionário de dados. Ele aplicará o mecanismo LRU assim que exceder o valor atual dessa variável. O limite ajuda a resolver situações em que quantidades significativas de memória seriam usadas para armazenar em cache instâncias de tabela raramente usadas até a próxima reinicialização do servidor. Portanto, as instâncias de tabela pai e filho com relacionamentos de chave estrangeira não são colocadas na lista LRU e podem impor um limite superior ao definido por table_definition_cache e não estão sujeitas a remoção na memória durante a LRU. Além disso, o table_definition_cache define um limite flexível para o número de tablespaces arquivo por tabela do InnoDB que podem ser abertos ao mesmo tempo, que também é controlado por innodb_open_files e, de fato, a configuração mais alta entre essas variáveis é usada, se ambas estiverem definidas . Se nenhuma variável for definida, table_definition_cache, que possui um valor padrão mais alto, será usado. Se o número de identificadores de arquivos de tablespace abertos exceder o limite definido por table_definition_cache ou innodb_open_files, o mecanismo LRU pesquisará a lista LRU de arquivos de tablespace por arquivos que foram totalmente liberados e não estão sendo estendidos no momento. Esse processo é executado sempre que um novo tablespace é aberto. Se não houver tablespaces “inativos”, nenhum arquivo de tablespace será fechado. Portanto, mantenha isso em mente.
max_allowed_packet
Este é o tamanho máximo por conexão de uma consulta ou linha SQL retornada. O valor foi aumentado pela última vez no MySQL 5.6. No entanto, no MySQL 8.0 (pelo menos no 8.0.3), o valor padrão atual é 64 MiB. Você pode considerar ajustar isso se tiver linhas BLOB grandes que precisam ser retiradas (ou lidas), caso contrário, você pode deixar essas configurações padrão com 8.0, mas em versões mais antigas, o padrão é 4 MiB, então você pode cuidar disso caso você encontrar o erro ER_NET_PACKET_TOO_LARGE. O maior pacote possível que pode ser transmitido de ou para um servidor ou cliente MySQL 8.0 é de 1 GB.
skip_name_resolve O servidor MySQL lida com conexões de entrada por resolução de nome de host. Por padrão, o MySQL não desativa nenhuma resolução de nome de host, o que significa que ele realizará pesquisas de DNS e, por acaso, se o DNS estiver lento, pode ser a causa de um desempenho ruim para seu banco de dados. Considere ativar isso se você não precisar de resolução de DNS e aproveitar a melhoria do desempenho do MySQL quando esta pesquisa de DNS estiver desabilitada. Leve em consideração que esta variável não é dinâmica, portanto, uma reinicialização do servidor é necessária se você definir isso em seu arquivo de configuração do MySQL. Você pode opcionalmente iniciar o daemon mysqld, passando a opção --skip-name-resolve para habilitar isso.
max_connections
Este é o número de conexões permitidas para seu servidor MySQL. Se você descobrir o erro no MySQL 'Too many connections', você pode considerar configurá-lo mais alto. Por padrão, o valor de 151 não é suficiente especialmente em um banco de dados de produção, e considerando que você possui maiores recursos do servidor (não desperdice seus recursos do servidor principalmente se for um servidor MySQL dedicado). No entanto, você deve ter descritores de arquivo suficientes, caso contrário você ficará sem eles. Nesse caso, considere ajustar o limite SOFT e HARD de seus sistemas operacionais *nix e defina um valor mais alto de open_files_limit no MySQL (5000 é o limite padrão). Leve em consideração que é muito frequente que o aplicativo não feche as conexões com o banco de dados corretamente, e definir um max_connections alto pode resultar em alguma falta de resposta ou alta carga do seu servidor. Usar um pool de conexões no nível do aplicativo pode ajudar a resolver o problema aqui.
thread_cache_size
Este é o cache para evitar a criação excessiva de threads. Quando um cliente se desconecta, os encadeamentos do cliente são colocados no cache se houver menos de encadeamentos thread_cache_size lá. As solicitações de encadeamentos são atendidas reutilizando encadeamentos retirados do cache, se possível, e somente quando o cache está vazio é criado um novo encadeamento. Essa variável pode ser aumentada para melhorar o desempenho se você tiver muitas novas conexões. Normalmente, isso não fornece uma melhoria de desempenho notável se você tiver uma boa implementação de thread. No entanto, se o seu servidor vê centenas de conexões por segundo, você normalmente deve definir thread_cache_size alto o suficiente para que a maioria das novas conexões use threads em cache. Examinando a diferença entre as variáveis de status Connections e Threads_created, você pode ver a eficiência do cache de thread. Usando a fórmula indicada na documentação, 8 + (max_connections / 100) é suficiente.
query_cache_size
Para algumas configurações, essa variável é seu pior inimigo. Para alguns sistemas com carga alta e ocupados com leituras altas, essa variável o atrapalhará. Houve benchmarks que foram bem testados por, por exemplo, Percona. Esta variável deve ser definida como 0 junto com query_cache_type =0 também para desativá-la. A boa notícia no MySQL 8.0 é que o MySQL Team parou de oferecer suporte a isso, pois essa variável pode realmente causar problemas de desempenho. Eu tenho que concordar em seu blog que é improvável que melhore a previsibilidade do desempenho. Se você for contratado para usar o cache de consulta, sugiro usar Redis ou ProxySQL.
Mecanismo de armazenamento - InnoDB
O InnoDB é um mecanismo de armazenamento compatível com ACID com vários recursos para oferecer, juntamente com suporte a chave estrangeira (Integridade Referencial Declarativa). Isso tem muitas coisas a dizer aqui, mas certas variáveis a serem consideradas para o ajuste:
innodb_buffer_pool_size
Esta variável age como um buffer de chave do MyISAM, mas tem muitas coisas a oferecer. Como o InnoDB depende muito do buffer pool, você consideraria definir esse valor normalmente para 70%-80% da memória do seu servidor. Também é favorável que você tenha um espaço de memória maior do que seu conjunto de dados e defina um valor mais alto para seu conjunto de buffers, mas não muito. No ClusterControl, isso pode ser monitorado usando nosso gráfico Dashboards -> InnoDB Metrics -> InnoDB Buffer Pool Pages. Você também pode monitorar isso com SHOW GLOBAL STATUS usando as variáveis Innodb_buffer_pool_pages*.
innodb_buffer_pool_instances
Para sua carga de trabalho de simultaneidade, definir essa variável pode melhorar a simultaneidade e reduzir a contenção como diferentes threads de leitura/gravação em páginas armazenadas em cache. O mínimo innodb_buffer_pool_instances deve estar entre 1 (mínimo) e 64 (máximo). Cada página armazenada ou lida no buffer pool é designada a uma das instâncias do buffer pool aleatoriamente, usando uma função de hash. Cada conjunto de buffers gerencia suas próprias listas livres, listas de liberação, LRUs e todas as outras estruturas de dados conectadas a um conjunto de buffers e é protegido por seu próprio mutex do conjunto de buffers. Observe que esta opção tem efeito somente quando innodb_buffer_pool_size>=1GiB e seu tamanho é dividido entre as instâncias do buffer pool.
innodb_log_file_size
Essa variável é o arquivo de log em um grupo de logs. O tamanho combinado dos arquivos de log (innodb_log_file_size * innodb_log_files_in_group) não pode exceder um valor máximo ligeiramente inferior a 512 GB. De acordo com Vadim, um tamanho de arquivo de log maior é melhor para o desempenho, mas tem uma desvantagem (significativa) com a qual você precisa se preocupar:o tempo de recuperação após uma falha. Você precisa equilibrar o tempo de recuperação no caso raro de uma recuperação de falha versus maximizar o rendimento durante as operações de pico. Essa limitação pode se traduzir em um processo de recuperação de falhas 20x mais longo!
Para elaborá-lo, um valor maior seria bom para logs de transação do InnoDB e é crucial para um desempenho de gravação bom e estável. Quanto maior o valor, menos atividade de liberação de ponto de verificação é necessária no buffer pool, economizando E/S de disco. No entanto, o processo de recuperação é bastante lento uma vez que seu banco de dados foi desligado de forma anormal (falha ou morto, OOM ou acidental). Idealmente, você pode ter 1-2GiB em produção, mas é claro que você pode ajustar isso. O benchmarking dessas alterações pode ser uma grande vantagem para ver como ele se comporta, especialmente após uma falha.
innodb_log_buffer_size
Para salvar a E/S do disco, o InnoDB grava os dados alterados no buffer de log do lt e usa o valor de innodb_log_buffer_size com um valor padrão de 8MiB. Isso é benéfico especialmente para transações grandes, pois não é necessário gravar o log de alterações no disco antes da confirmação da transação. Se o tráfego de gravação for muito alto (inserções, exclusões, atualizações), aumentar o buffer economiza E/S de disco.
innodb_flush_log_at_trx_commit
Quando innodb_flush_log_at_trx_commit é definido como 1, o buffer de log é liberado em cada confirmação de transação para o arquivo de log no disco e fornece integridade máxima de dados, mas também tem impacto no desempenho. Defini-lo como 2 significa que o buffer de log é liberado para o cache do arquivo do SO em cada confirmação de transação. A implicação de 2 é ótima e melhora o desempenho se você puder relaxar seus requisitos de ACID e puder perder transações no último ou dois segundos em caso de travamento do sistema operacional.
innodb_thread_concurrency
Com melhorias no mecanismo InnoDB, é recomendável permitir que o mecanismo controle a simultaneidade mantendo-o no valor padrão (que é zero). Se você vir problemas de simultaneidade, poderá ajustar essa variável. Um valor recomendado é 2 vezes o número de CPUs mais o número de discos. Sua variável dinâmica significa que pode definir sem reiniciar o servidor MySQL.
innodb_flush_method
Essa variável, no entanto, deve ser testada e testada em qual hardware melhor se adapta a você. Se você estiver usando um RAID com cache com bateria, DIRECT_IO ajuda a aliviar a pressão de E/S. A E/S direta não é armazenada em cache, portanto, evita o buffer duplo com o conjunto de buffers e o cache do sistema de arquivos. Se seu disco estiver armazenado em SAN, O_DSYNC poderá ser mais rápido para uma carga de trabalho de leitura intensa com principalmente instruções SELECT.
innodb_file_per_table
innodb_file_per_table está ativado por padrão no MySQL 5.6. Isso geralmente é recomendado, pois evita ter um enorme espaço de tabela compartilhado e permite que você recupere espaço ao descartar ou truncar uma tabela. O espaço de tabela separado também se beneficia do esquema de backup parcial do Xtrabackup.
innodb_stats_on_metadata
Isso tenta manter a porcentagem de páginas sujas sob controle e, antes do plugin Innodb, essa era realmente a única maneira de ajustar a liberação de buffer sujo. No entanto, tenho visto servidores com 3% de buffers sujos e eles estão atingindo sua idade máxima de checkpoint. A maneira como isso aumenta a liberação de buffer sujo também não escala bem em subsistemas de alta io, ele efetivamente apenas dobra a liberação de buffer sujo por segundo quando a % de páginas sujas excede esse valor.
innodb_io_capacity
Essa configuração, apesar de todas as nossas grandes esperanças de permitir que o Innodb faça melhor uso de nosso IO em todas as operações, simplesmente controla a quantidade de limpeza de páginas sujas por segundo (e outras tarefas em segundo plano, como leitura antecipada). Faça isso maior, você libera mais por segundo. Isso não se adapta, simplesmente faz muitos iops a cada segundo se houver buffers sujos para liberar. Ele eliminará efetivamente qualquer otimização da consolidação de E/S se você tiver uma carga de trabalho de gravação baixa o suficiente (ou seja, as páginas sujas são liberadas quase imediatamente, talvez seja melhor sem um log de transações nesse caso). Ele também pode reduzir rapidamente as leituras e gravações de dados no log de transações se você definir isso muito alto.
innodb_write_io_threads
Controla quantos threads terão gravações em andamento no disco. Não sei por que isso ainda é útil se você pode usar o AIO nativo do Linux. Eles também podem se tornar inúteis por sistemas de arquivos que não permitem gravação paralela no mesmo arquivo por mais de um thread (especialmente se você tiver relativamente poucas tabelas e/ou usar os espaços de tabela globais)
innodb_adaptive_flushing
Especifica se deve ajustar dinamicamente a taxa de liberação de páginas sujas no buffer pool do InnoDB com base na carga de trabalho. Ajustar a taxa de descarga dinamicamente destina-se a evitar picos de atividade de E/S. Normalmente, isso é ativado por padrão. Essa variável, quando habilitada, tenta ser mais inteligente ao liberar mais agressivamente com base no número de páginas sujas e na taxa de crescimento do log de transações.
innodb_dedicated_server
Esta variável é nova no MySQL 8.0, que é aplicada globalmente e requer uma reinicialização do MySQL, pois não é uma variável dinâmica. No entanto, como a documentação afirma que esta variável deve ser habilitada somente se seu MySQL estiver rodando em um servidor dedicado. Caso contrário, não habilite isso em um host compartilhado ou compartilhe recursos do sistema com outros aplicativos. Quando habilitado, o InnoDB fará uma configuração automática para a quantidade de memória detectada para as variáveis innodb_buffer_pool_size, innodb_log_file_size, innodb_flush_method. A única desvantagem é que você não pode ter a viabilidade de aplicar seus valores desejados nas variáveis detectadas mencionadas.
MeuISAM
key_buffer_size
O InnoDB é o mecanismo de armazenamento padrão agora do MySQL, o padrão para key_buffer_size provavelmente pode ser reduzido, a menos que você esteja usando o MyISAM produtivamente como parte de seu aplicativo (mas quem usa o MyISAM em produção agora?). Sugiro aqui definir talvez 1% de RAM ou 256 MiB no início, se você tiver memória maior e dedicar a memória restante ao cache do sistema operacional e ao pool de buffer InnoDB.
Outras disposições para desempenho
slow_query_log
Claro, esta variável não ajuda a impulsionar seu servidor MySQL. No entanto, essa variável pode ajudá-lo a analisar consultas de desempenho lento. O valor pode ser definido como 0 ou OFF para desabilitar o registro. Configurando para 1 ou ON para habilitar isso. O valor padrão depende se a opção --slow_query_log é fornecida. O destino da saída de log é controlado pela variável de sistema log_output; se esse valor for NONE, nenhuma entrada de log será gravada, mesmo que o log esteja ativado. Você pode definir o nome do arquivo ou destino do arquivo de log de consulta definindo a variável slow_query_log_file.
long_query_time
Se uma consulta demorar mais do que esse número de segundos, o servidor incrementará a variável de status Slow_queries. Se o log de consulta lenta estiver habilitado, a consulta será registrada no arquivo de log de consulta lenta. Esse valor é medido em tempo real, não em tempo de CPU, portanto, uma consulta que está abaixo do limite em um sistema pouco carregado pode estar acima do limite em um sistema muito carregado. Os valores mínimo e padrão de long_query_time são 0 e 10, respectivamente. Observe também que, se a variável min_examined_row_limit for definida> 0, ela não registrará consultas mesmo que demore muito se o número de linhas retornadas for menor que o valor definido em min_examined_row_limit.
Para obter mais informações sobre como ajustar o log de consultas lentas, consulte a documentação aqui.
sync_binlog
Esta variável controla com que frequência o MySQL irá sincronizar os logs binários com o disco. Por padrão (>=5.7.7), é definido como 1, o que significa que será sincronizado com o disco antes que as transações sejam confirmadas. No entanto, isso impõe um impacto negativo no desempenho devido ao aumento do número de gravações. Mas esta é a configuração mais segura se você deseja estritamente compatível com ACID junto com seus escravos. Como alternativa, você pode definir isso como 0 se quiser desabilitar a sincronização de disco e apenas confiar no sistema operacional para liberar o log binário para o disco de tempos em tempos. Defini-lo maior que 1 significa que o log binário é sincronizado com o disco depois que N grupos de confirmação de log binário foram coletados, onde N é> 1.
Despejar/Restaurar Buffer Pool
É bastante comum que seu banco de dados de produção precise aquecer a partir de uma inicialização/reinicialização a frio. Ao despejar o buffer pool atual antes de uma reinicialização, ele salvaria o conteúdo do buffer pool e, uma vez ativado, carregaria o conteúdo de volta no buffer pool. Assim, isso evita a necessidade de aquecer seu banco de dados de volta para o cache. Observe que esta versão foi introduzida no 5.6, mas o Percona Server 5.5 já o tem disponível, caso você se pergunte. Para habilitar este recurso, defina ambas as variáveis innodb_buffer_pool_dump_at_shutdown =ON e innodb_buffer_pool_load_at_startup =ON.
Hardware
Estamos agora em 2019, houve muitas novas melhorias de hardware. Normalmente, não há um requisito rígido de que o MySQL exija um hardware específico, mas isso depende do que você precisa que o banco de dados faça. Espero que você não esteja lendo este blog porque está fazendo um teste se ele roda em um Intel Pentium 200 MHz.
Para CPU, processadores mais rápidos com vários núcleos serão ideais para MySQL nas versões mais recentes, pelo menos desde 5.6. Os processadores Xeon/Itanium da Intel podem ser caros, mas testados para plataformas de computação escaláveis e confiáveis. A Amazon está enviando suas instâncias EC2 em execução na arquitetura ARM. Embora eu pessoalmente não tenha tentado executar ou lembrar de executar o MySQL na arquitetura ARM, existem benchmarks que foram feitos anos atrás. As CPUs modernas podem aumentar e diminuir suas frequências com base na temperatura, carga e políticas de economia de energia do sistema operacional. No entanto, há uma chance de que suas configurações de CPU em seu sistema operacional Linux sejam definidas para um governador diferente. Você pode verificar isso ou definir com o governador de “desempenho” fazendo o seguinte:
echo performance | sudo tee /sys/devices/system/cpu/cpu[0-9]*/cpufreq/scaling_governor
Para Memória, é muito importante que sua memória seja grande e possa igualar o tamanho do seu conjunto de dados. Certifique-se de ter swappiness =1. Você pode verificar verificando sysctl ou verificando o arquivo em procfs. Isto é conseguido fazendo o seguinte:
$ sysctl -e vm.swappiness
vm.swappiness = 1
Ou definindo-o para um valor de 1 da seguinte forma
$ sudo sysctl vm.swappiness=1
vm.swappiness = 1
Outra grande coisa a considerar para o gerenciamento de memória é considerar desativar o THP (Transparrent Huge Pages). No passado, lembro que tivemos alguns problemas estranhos encontrados com a utilização da CPU e pensamos que era devido à E/S do disco. Descobriu-se que o problema era com o encadeamento khugepaged do kernel, que aloca memória dinamicamente durante o tempo de execução. Não só isso, durante a desfragmentação do kernel, sua memória será alocada rapidamente à medida que for passando para o THP. A memória padrão do HugePages é pré-alocada na inicialização e não muda durante o tempo de execução. Você pode verificar e desabilitar isso fazendo o seguinte:
$ cat /sys/kernel/mm/transparent_hugepage/enabled
$ echo "never" > /sys/kernel/mm/transparent_hugepage/enabled
Para Disk, é importante que você tenha uma boa taxa de transferência. Usar o RAID10 é a melhor configuração para um banco de dados com uma unidade de backup de bateria. Com o advento das unidades flash que oferecem alta taxa de transferência de disco e alta E/S de disco para leitura/gravação, é importante que ele possa gerenciar a alta utilização de disco e E/S de disco.
Sistema operacional
A maioria dos sistemas de produção rodando no MySQL roda no Linux. É porque o MySQL foi testado e comparado no Linux, e parece que é o padrão de fato para uma instalação do MySQL. No entanto, é claro, não há nada que o impeça de usá-lo na plataforma Unix ou Windows. Seria mais fácil se sua plataforma fosse testada e houvesse uma ampla comunidade para ajudar, caso você tenha algum problema. A maioria das configurações é executada em sistemas RHEL/Centos/Fedora e Debian/Ubuntu. Na AWS, a Amazon tem seu Amazon Linux que eu vejo também sendo usado na produção por alguns.
O mais importante a considerar com sua configuração é que seu sistema de arquivos está usando XFS ou Ext4. Com certeza, existem prós e contras entre esses dois sistemas de arquivos, mas não entrarei em detalhes aqui. Alguns dizem que o XFS supera o Ext4, mas também há relatos de que o Ext4 supera o XFS. O ZFS também está saindo de cena como um bom candidato para um sistema de arquivos alternativo. Jervin Real (da Percona) tem um ótimo recurso sobre isso, você pode conferir esta apresentação durante a conferência ZFS.
Links externos
https://developer.okta.com/blog/2015/05/22/tcmalloc
https://www.percona.com/blog/2012/07/05/impact-of-memory-allocators-on-mysql-performance/
https://www.percona.com/live/18/sessions/benchmark-noise-reduction-how-to-configure-your-machines-for-stable-results
https://zfs.datto.com/2018_slides/real.pdf
https://docs.oracle.com/en/database/oracle/oracle-database/12.2/ladbi/disabling-transparent-hugepages.html#GUID-02E9147D-D565-4AF8-B12A-8E6E9F74BEEA