Fui apresentado a alguns servidores MySQL dedicados que nunca usam mais do que um único núcleo. Sou mais desenvolvedor que DBA para MySQL, então preciso de ajuda
Configuração
Os servidores são bastante robustos com uma carga do tipo OLAP / DataWarehouse (DW):
- Primário: 96 GB de RAM, 8 núcleos + matriz RAID 10 única
- Teste: 32 GB de RAM com 4 núcleos
- O maior banco de dados é de 540 GB, o total é de cerca de 1,1 TB e a maioria das tabelas do InnoDB
- Solaris 10 Intel-64
- MySQL 5.5.x
Nota: O maior banco de dados é o replicado do servidor de OLTP DR e o DW é carregado a partir dele. Não é um DW completo: dura apenas 6 meses a 6 semanas, portanto é menor que o banco de dados OLTP.
Observações em um servidor de teste
- 3 conexões separadas
- cada um tem um concorrente (e diferente)
ALTER TABLE...DROP KEY...ADD INDEX
- as 3 tabelas têm 2,5, 3,8 e 4,5 milhões de linhas
- O uso da CPU sobe para 25% (um núcleo é atingido no máximo) e não é maior
- os 3 ALTERs levam de 12 a 25 minutos (um dos menores leva 4,5)
Questões
- Que configuração ou correção é necessária para permitir que mais de um núcleo seja usado?
Ou seja, por que o MySQL não usa todos os núcleos disponíveis? (como outros RDBMS) - É uma consequência da replicação?
Outras notas
- Entendo a diferença entre um RDBMS "thread" e um OS "thread"
- Eu não estou perguntando sobre qualquer forma de paralelismo
- Algumas das variáveis de sistema para InnoDB e threads são sub-ideais
(buscando uma vitória rápida) - A curto prazo, não consigo alterar o layout do disco
- O sistema operacional pode ser ajustado se necessário
- Uma única ALTER TABLE na menor mesa leva 4,5 minutos (chocante IMO)
Editar 1
- innodb_thread_concurrency está definido como 8 em ambos. Sim, está errado, mas não fará o MySQL usar múltiplos núcleos
- innodb_buffer_pool_size tem 80 GB no primário e 10 GB em um teste (outra instância é encerrada). Isso está bom por enquanto.
- innodb_file_per_table = ON
Editar 2
- innodb_flush_log_at_trx_commit = 2
- innodb_use_sys_malloc = ON
- innodb_flush_method deve ser O_DIRECT (mas SHOW VARIABLES não mostra isso)
- innodb_doublewrite = OFF
- Sistema de arquivos = ZFS (E meu administrador de sistemas encontrou o seguinte: http://blogs.oracle.com/realneel/entry/mysql_innodb_zfs_best_practices )
Testar
- innodb_flush_method não está aparecendo como O_DIRECT quando deveria
- seguirá as configurações de RolandoMySQLDBA
Deixe-me saber se eu perdi alguma coisa importante
Felicidades
Atualizar
Alterado innodb_flush_method + 3 x configurações de thread na resposta do RolandoMySQLDBA
Resultado:> 1 núcleo usado para os testes = resultado positivo
\G
. Além disso, eu acho queSHOW INNODB STATUS
é depreciado em favor doSHOW ENGINE INNODB STATUS
no 5.5 (eu recebo um erro de executar o ex-em-linha de comando.Respostas:
Na verdade, discuti innodb_thread_concurrency com um especialista do MySQL na conferência Percona Live NYC em maio de 2011 .
Aprendi algo surpreendente: apesar da documentação, é melhor deixar
innodb_thread_concurrency
em 0 (simultaneidade infinita). Dessa forma, o InnoDB decide o melhor númeroinnodb_concurrency_tickets
para abrir para uma determinada configuração de instância do MySQL.Depois de definir
innodb_thread_concurrency
0, você pode definirinnodb_read_io_threads
einnodb_write_io_threads
(ambos desde o MySQL 5.1.38) o valor máximo de 64. Isso deve envolver mais núcleos.fonte
my.cnf
e reinicie o mysqld. por favor.O MySQL usará automaticamente vários núcleos; portanto, sua carga de 25% é coincidência 1 ou uma possível má configuração no Solaris. Não pretendo saber como ajustar o solaris, mas aqui está um artigo que aborda algumas informações de ajuste específicas do solaris .
As páginas de ajuste do InnoDB foram revisadas no MySQL 5.5, então também há algumas informações boas. Nas dicas de E / S do disco do InnoDB :
Algumas outras coisas para verificar:
Mudar o innodb_flush_method para O_DIRECT vale a pena testar. Se isso ajudar, pode ser necessário montar o sistema de arquivos com a
forcedirectio
opçãoMude o innodb_flush_log_at_trx_commit de 1 para 0 (se você não se importa em perder o último segundo no travamento do mysql) ou 2 (se você não se importa em perder o último segundo no travamento do SO).
Verifique o valor de innodb_use_sys_malloc . Este artigo tem mais informações sobre a variável
Mas existem algumas advertências no final da seção sobre o que significa ativar a variável (ela é ativada por padrão no 5.5).
É possível que a replicação esteja causando alguns dos problemas. Sei que você não está interessado em paralelismo, mas a partir da descrição deste log de trabalho :
Por fim, o InnoDB pode não ser o melhor mecanismo para armazenamento de dados, devido às operações baseadas em disco que ocorrem. Você pode alterar a (s) tabela (s) do datawarehouse como Compressed MyISAM .
1 Por coincidência, quero dizer que há um gargalo que impede que sua carga aumente acima de 25%, mas não é necessariamente um problema forçado de núcleo único.
fonte
Uma única conexão usará apenas um único núcleo. (OK, o InnoDB usa outros threads, portanto núcleos, para algum processamento de E / S, mas isso não é significativo.)
Você tinha 3 ALTERs e, portanto, não estava usando muito mais que o valor de 3 núcleos.
Infelizmente, nem mesmo a PARTITION usa múltiplos núcleos.
Até recentemente, várias conexões atingiam o limite máximo após 4-8 núcleos. O Xtradb da Percona (incluído no MariaDB) faz melhor uso de vários núcleos, mas ainda apenas um por thread. Eles atingem um máximo de 32 núcleos.
fonte
IMHO e no caso de uso descrito, você nunca usará mais de um núcleo. O motivo é que sua carga de trabalho é vinculada a E / S, não a CPU. Como suas três conexões estão criando um novo Índice, cada uma delas precisa ler a tabela inteira do disco: isso é o que está demorando, não computando os Índices.
fonte
Considere que seu gargalo pode ser o desempenho de E / S do seu sistema de arquivos.
Além das configurações sugeridas por @RolandoMySQLDBA , também defino as
noatime
configurações de montagem/etc/fstab
para a partição que contém meu diretório de dados mysql (/data01/mysql
no meu caso, com/dev/sdb1
montado em/data01
).Por padrão, o linux registra o tempo de acesso a TODAS as leituras ou gravações de disco, o que afeta negativamente o desempenho das E / S, especialmente para aplicativos de E / S alta, como bancos de dados. Isso significa que mesmo a leitura de dados de um arquivo aciona uma gravação no disco ... WAT!
Para desativar isso, adicione a
noatime
opção de montagem no/etc/fstab
ponto de montagem desejado da seguinte maneira (exemplo no meu caso):Em seguida, remonte a partição:
Isso deve aumentar o desempenho de leitura / gravação de aplicativos usando essa partição. MAS ... nada supera manter todos os seus dados na memória.
fonte