Qual o tamanho do mysql innodb_buffer_pool_size?

170

Eu tenho um banco de dados ocupado apenas com tabelas InnoDB, com aproximadamente 5 GB de tamanho. O banco de dados é executado em um servidor Debian usando discos SSD e eu configurei o número máximo de conexões = 800, que às vezes saturam e fazem com que o servidor pare. A consulta média por segundo é de cerca de 2,5K. Portanto, preciso otimizar o uso da memória para abrir espaço para o máximo de conexões possíveis.

Vi sugestões de que innodb_buffer_pool_size deve ter até% 80 da memória total. Por outro lado, recebo esse aviso do script tuning-primer:

Max Memory Ever Allocated : 91.97 G
Configured Max Per-thread Buffers : 72.02 G
Configured Max Global Buffers : 19.86 G
Configured Max Memory Limit : 91.88 G
Physical Memory : 94.58 G

Aqui estão minhas variáveis ​​innodb atuais:

| innodb_adaptive_flushing                          | ON                                                                                                                     |
| innodb_adaptive_hash_index                        | ON                                                                                                                     |
| innodb_additional_mem_pool_size                   | 20971520                                                                                                               |
| innodb_autoextend_increment                       | 8                                                                                                                      |
| innodb_autoinc_lock_mode                          | 1                                                                                                                      |
| innodb_buffer_pool_instances                      | 1                                                                                                                      |
| innodb_buffer_pool_size                           | 20971520000                                                                                                            |
| innodb_change_buffering                           | all                                                                                                                    |
| innodb_checksums                                  | ON                                                                                                                     |
| innodb_commit_concurrency                         | 0                                                                                                                      |
| innodb_concurrency_tickets                        | 500                                                                                                                    |
| innodb_data_file_path                             | ibdata1:10M:autoextend                                                                                                 |
| innodb_data_home_dir                              |                                                                                                                        |
| innodb_doublewrite                                | ON                                                                                                                     |
| innodb_fast_shutdown                              | 1                                                                                                                      |
| innodb_file_format                                | Antelope                                                                                                               |
| innodb_file_format_check                          | ON                                                                                                                     |
| innodb_file_format_max                            | Antelope                                                                                                               |
| innodb_file_per_table                             | ON                                                                                                                     |
| innodb_flush_log_at_trx_commit                    | 2                                                                                                                      |
| innodb_flush_method                               | O_DIRECT                                                                                                               |
| innodb_force_load_corrupted                       | OFF                                                                                                                    |
| innodb_force_recovery                             | 0                                                                                                                      |
| innodb_io_capacity                                | 200                                                                                                                    |
| innodb_large_prefix                               | OFF                                                                                                                    |
| innodb_lock_wait_timeout                          | 50                                                                                                                     |
| innodb_locks_unsafe_for_binlog                    | OFF                                                                                                                    |
| innodb_log_buffer_size                            | 4194304                                                                                                                |
| innodb_log_file_size                              | 524288000                                                                                                              |
| innodb_log_files_in_group                         | 2                                                                                                                      |
| innodb_log_group_home_dir                         | ./                                                                                                                     |
| innodb_max_dirty_pages_pct                        | 75                                                                                                                     |
| innodb_max_purge_lag                              | 0                                                                                                                      |
| innodb_mirrored_log_groups                        | 1                                                                                                                      |
| innodb_old_blocks_pct                             | 37                                                                                                                     |
| innodb_old_blocks_time                            | 0                                                                                                                      |
| innodb_open_files                                 | 300                                                                                                                    |
| innodb_purge_batch_size                           | 20                                                                                                                     |
| innodb_purge_threads                              | 0                                                                                                                      |
| innodb_random_read_ahead                          | OFF                                                                                                                    |
| innodb_read_ahead_threshold                       | 56                                                                                                                     |
| innodb_read_io_threads                            | 4                                                                                                                      |
| innodb_replication_delay                          | 0                                                                                                                      |
| innodb_rollback_on_timeout                        | OFF                                                                                                                    |
| innodb_rollback_segments                          | 128                                                                                                                    |
| innodb_spin_wait_delay                            | 6                                                                                                                      |
| innodb_stats_method                               | nulls_equal                                                                                                            |
| innodb_stats_on_metadata                          | ON                                                                                                                     |
| innodb_stats_sample_pages                         | 8                                                                                                                      |
| innodb_strict_mode                                | OFF                                                                                                                    |
| innodb_support_xa                                 | ON                                                                                                                     |
| innodb_sync_spin_loops                            | 30                                                                                                                     |
| innodb_table_locks                                | ON                                                                                                                     |
| innodb_thread_concurrency                         | 4                                                                                                                      |
| innodb_thread_sleep_delay                         | 10000                                                                                                                  |
| innodb_use_native_aio                             | ON                                                                                                                     |
| innodb_use_sys_malloc                             | ON                                                                                                                     |
| innodb_version                                    | 1.1.8                                                                                                                  |
| innodb_write_io_threads                           | 4                                                                                                                      |

Uma observação lateral que pode ser relevante: Vejo que quando tento inserir uma postagem grande (digamos acima de 10 KB) do Drupal (que fica em um servidor Web separado) no banco de dados, ela dura para sempre e a página não retorna corretamente.

Com relação a isso, estou me perguntando qual deve ser o meu innodb_buffer_pool_size para obter o desempenho ideal. Agradeço suas sugestões para definir esse e outros parâmetros da melhor maneira possível para esse cenário.

alfish
fonte

Respostas:

252

Seu tamanho innodb_buffer_pool_s é enorme. Você definiu 20971520000. São 19,5135 GB. Se você tiver apenas 5 GB de dados e índices do InnoDB, deverá ter apenas 8 GB. Mesmo isso pode estar muito alto.

Aqui está o que você deveria fazer. Primeiro, execute esta consulta

SELECT CEILING(Total_InnoDB_Bytes*1.6/POWER(1024,3)) RIBPS FROM
(SELECT SUM(data_length+index_length) Total_InnoDB_Bytes
FROM information_schema.tables WHERE engine='InnoDB') A;

Isso fornecerá o RIBPS, tamanho recomendado do pool de buffers do InnoDB com base em todos os dados e índices do InnoDB, com um adicional de 60%.

Por exemplo

mysql>     SELECT CEILING(Total_InnoDB_Bytes*1.6/POWER(1024,3)) RIBPS FROM
    ->     (SELECT SUM(data_length+index_length) Total_InnoDB_Bytes
    ->     FROM information_schema.tables WHERE engine='InnoDB') A;
+-------+
| RIBPS |
+-------+
|     8 |
+-------+
1 row in set (4.31 sec)

mysql>

Com esta saída, você definiria o seguinte em /etc/my.cnf

[mysqld]
innodb_buffer_pool_size=8G

Próximo, service mysql restart

Após a reinicialização, execute o mysql por uma semana ou duas. Em seguida, execute esta consulta:

SELECT (PagesData*PageSize)/POWER(1024,3) DataGB FROM
(SELECT variable_value PagesData
FROM information_schema.global_status
WHERE variable_name='Innodb_buffer_pool_pages_data') A,
(SELECT variable_value PageSize
FROM information_schema.global_status
WHERE variable_name='Innodb_page_size') B;

Isso fornecerá quantos GB de memória reais estão sendo usados ​​pelos dados do InnoDB no buffer pool do InnoDB no momento.

Eu escrevi sobre isso antes: O que definir innodb_buffer_pool e por que ..?

Você pode simplesmente executar esta DataGBconsulta agora, em vez de reconfigurar, reiniciar e aguardar uma semana.

Esse valor DataGBse parece mais com o tamanho do InnoDB Buffer Pool + (porcentagem especificada em innodb_change_buffer_max_size). Estou certo de que isso será muito menor que os 20000M que você reservou no momento. A economia de RAM pode ser usada para ajustar outras coisas, como

CAVEAT # 1

É muito importante observar: Às vezes, o InnoDB pode exigir um adicional de 10% sobre o valor do tamanho innodb_buffer_pool_spool . Aqui está o que a documentação do MySQL diz sobre isso:

Quanto maior você definir esse valor, menos E / S de disco será necessária para acessar os dados nas tabelas. Em um servidor de banco de dados dedicado, você pode definir isso para até 80% do tamanho da memória física da máquina. Esteja preparado para reduzir esse valor se esses outros problemas ocorrerem:

A competição por memória física pode causar paginação no sistema operacional.

O InnoDB reserva memória adicional para buffers e estruturas de controle, para que o espaço total alocado seja aproximadamente 10% maior que o tamanho especificado.

O espaço de endereço deve ser contíguo, o que pode ser um problema nos sistemas Windows com DLLs carregadas em endereços específicos.

O tempo para inicializar o buffer pool é aproximadamente proporcional ao seu tamanho. Em instalações grandes, esse tempo de inicialização pode ser significativo. Por exemplo, em um servidor Linux x86_64 moderno, a inicialização de um buffer pool de 10 GB leva aproximadamente 6 segundos. Consulte a Seção 8.9.1, “O pool de buffers do InnoDB” .

CAVEAT # 2

I Veja os seguintes valores em seu my.cnf

| innodb_io_capacity                                | 200 |
| innodb_read_io_threads                            | 4   |
| innodb_thread_concurrency                         | 4   |
| innodb_write_io_threads                           | 4   |

Esse número impedirá o InnoDB de acessar vários núcleos

Defina o seguinte:

[mysqld]
innodb_io_capacity = 2000
innodb_read_io_threads = 64
innodb_thread_concurrency = 0
innodb_write_io_threads = 64

Eu escrevi sobre isso antes no DBA StackExchange

Acabei de responder a uma pergunta como esta no ServerFault usando uma fórmula mais concisa :

SELECT CONCAT(CEILING(RIBPS/POWER(1024,pw)),SUBSTR(' KMGT',pw+1,1))
Recommended_InnoDB_Buffer_Pool_Size FROM
(
    SELECT RIBPS,FLOOR(LOG(RIBPS)/LOG(1024)) pw
    FROM
    (
        SELECT SUM(data_length+index_length)*1.1*growth RIBPS
        FROM information_schema.tables AAA,
        (SELECT 1.25 growth) BBB
        WHERE ENGINE='InnoDB'
    ) AA
) A;
RolandoMySQLDBA
fonte
1
Obrigado por este ótimo post! Sua fórmula começando com SELECT (PagesData*PageSize)/POWER(1024,3) DataGB FROM...gera o seguinte erro no MySQL 5.7: " O recurso 'INFORMATION_SCHEMA.GLOBAL_STATUS' está desativado; consulte a documentação para 'show_compatibility_56' ". Você teria uma versão atualizada por acaso?
Benjamin
Recebo 307 RIBPS e 264G. Isso significa que eu preciso de 307 GB de RAM?
E_Blue
Mais como 264G. Mas você deve ter RAM suficiente para isso, caso contrário, forneça os 80% mencionados de sua RAM ao mysql, dependendo do que mais for executado no sistema.
S28
2
O melhor post que eu já li! Eu tenho um ~ grande banco de dados em torno de 3GB. Depois de ler sua resposta / artigo e a velocidade dos links chegou a 2x
fat_mike 10/12/16
4
@ Benjamin: A partir do MySQL 5.7.6, o information_schema é mesclado no performance_schema. Portanto, basta alterar "information_schema" para "performance_schema" na consulta para fazê-lo funcionar. Fonte: dev.mysql.com/doc/refman/5.7/en/status-table.html
Ralph Bolton
11

Algo assim? Usando SHOW VARIABLESe SHOW GLOBAL STATUS:

Expressão: innodb_buffer_pool_size / _ram
Significado: % da RAM usada para o InnoDB buffer_pool
Intervalo recomendado: 60 ~ 80%

Expressão: Innodb_buffer_pool_reads / Innodb_buffer_pool_read_requests
Significado: Leia solicitações que precisavam acessar o disco
Intervalo recomendado: 0-2%
O que fazer se estiver fora do intervalo: Aumente innodb_buffer_pool_size se você tiver o suficiente RAM.

Expressão: Innodb_pages_read / Innodb_buffer_pool_read_requests
Significado: Leia solicitações que precisavam acessar o disco
Intervalo recomendado: 0-2%
O que fazer se estiver fora do intervalo: Aumente innodb_buffer_pool_size se você tiver RAM suficiente.

Expressão: Innodb_pages_written / Innodb_buffer_pool_write_requests
Significado: solicitações de gravação que precisavam acessar o disco
Intervalo recomendado: 0-15%
O que fazer se estiver fora do intervalo: Verifique innodb_buffer_pool_size

Expressão: Innodb_buffer_pool_reads / Uptime
Significado:
Faixa recomendada: 0-100 / seg.
O que fazer se estiver fora do intervalo: Aumente o tamanho innodb_buffer_pool_spool?

Expressão: (Innodb_buffer_pool_reads + Innodb_buffer_pool_pages_flushed) / Uptime
Significado: InnoDB I / O
Faixa recomendada: 0-100 / seg.
O que fazer se estiver fora do intervalo: Aumente o tamanho innodb_buffer_pool_spool?

Expressão: Innodb_buffer_pool_pages_flushed / Uptime
Significado: Gravações (descargas)
Faixa recomendada: 0-100 / seg.
O que fazer se estiver fora do intervalo: Aumente o tamanho innodb_buffer_pool_spool?

Expressão: Innodb_buffer_pool_wait_free / Uptime
Significado: Contador para quando não houver páginas livres no buffer_pool. Ou seja, todas as páginas estão sujas.
Faixa recomendada: 0-1 / seg.
O que fazer se estiver fora do intervalo: Primeiro, verifique se innodb_buffer_pool_size está configurado razoavelmente; se ainda houver problemas, diminua innodb_max_dirty_pages_pct

Rick James
fonte
Obrigado @ Rick pelo bom comentário. Qual innodb_buffer_pool_sizevalor especifica? Tamanho real ou um configurado?
Joker
1
@joker - innodb_buffer_pool_sizeindica o tamanho máximo. Em um servidor típico, o "buffer pool" começa pequeno, mas cresce rapidamente para esse tamanho máximo e permanece lá. Nota: Se for maior que a RAM (ou mesmo fechar), isso leva à troca, o que é terrível para o desempenho.
Rick James
7

Seu título pergunta sobre innodb_buffer_pool_size, mas suspeito que esse não seja o problema real. (Rolando comentou por que você o definiu grande o suficiente, até grande demais).

Eu configurei o número máximo de conexões = 800, que às vezes saturam e moem o servidor para interromper.

Isso não está claro. 800 usuários no modo "Suspensão" têm praticamente zero impacto no sistema. 800 threads ativos seriam um desastre. Quantas threads estão "em execução"?

Os threads estão bloqueando um ao outro? Consulte MOSTRAR ESTADO DO MOTOR INNODB para obter algumas dicas sobre impasses, etc.

Há alguma dúvida aparecendo no slowlog? Vamos otimizá-los.

Qual versão você está usando? O XtraDB (um substituto para o InnoDB) faz um trabalho melhor usando vários núcleos. 5.6.7 faz um trabalho ainda melhor.

innodb_buffer_pool_instances - altere para 8 (assumindo um buffer_pool 20G); isso reduzirá um pouco a contenção da Mutex.

Você está ligado à E / S ou à CPU? As soluções são radicalmente diferentes, dependendo da sua resposta.

SSD - pode ser melhor se todos os arquivos de log estiverem em unidades não SSD.

Rick James
fonte
6

Mais memória é sempre melhor, mas na minha experiência, na maioria das vezes, o tamanho do buffer pool não deve se ajustar ao tamanho dos dados. Muitas tabelas ficam inativas na maioria das vezes, como tabelas de backup, portanto o tamanho do buffer pool do innodb deve ser adequado ao tamanho de dados ativo.

O período de tempo especificado para as páginas ativas influencia o desempenho, mas há um ponto ideal, onde você não terá mais desempenho para um tamanho de buffer maior. Você pode estimar / calcular / medir issoshow engine innodb status

user77376
fonte