Fui presenteado com alguns servidores MySQL dedicados que nunca usam mais do que um único núcleo. Eu sou mais desenvolvedor do que DBA para MySQL, então preciso de ajuda
Configurar
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 principalmente tabelas InnoDB
- Solaris 10 Intel-64
- MySQL 5.5.x
Nota: O maior DB é o replicado do servidor OLTP DR e o DW é carregado a partir dele. Não é um DW completo: dura apenas 6 meses a 6 semanas, por isso é menor que o OLTP DB.
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 vai até 25% (um núcleo está no máximo) e não mais
- os 3 ALTERs levam de 12 a 25 minutos (um único no menor leva 4,5)
Perguntas
- Qual configuração ou patch é necessário 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
- Eu entendo a diferença entre um "thread" de RDBMS e um "thread" de SO
- Eu não estou perguntando sobre qualquer forma de paralelismo
- Algumas das variáveis do sistema para InnoDB e threads são sub-ótimas
(procurando uma vitória rápida) - A curto prazo, não consigo alterar o layout do disco
- O SO pode ser ajustado, se necessário
- Uma única ALTER TABLE na menor mesa leva 4,5 minutos (chocante IMO)
Editar 1
- innodb_thread_concurrency é definido como 8 em ambos. Sim, está errado, mas não fará o MySQL usar vários núcleos
- innodb_buffer_pool_size é 80 GB no primário, 10 GB em um teste (outra instância é encerrada). Isso está bem por enquanto.
- innodb_file_per_table = ATIVADO
Editar 2
- innodb_flush_log_at_trx_commit = 2
- innodb_use_sys_malloc = ATIVADO
- innodb_flush_method deve ser O_DIRECT (mas SHOW VARIABLES não mostra isso)
- innodb_doublewrite = OFF
- Sistema de arquivos = ZFS (E meu sysadmin encontrou isto: http://blogs.oracle.com/realneel/entry/mysql_innodb_zfs_best_practices )
Testar
- innodb_flush_method não está aparecendo como O_DIRECT quando deveria estar
- seguirá as configurações do 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
Na verdade, discuti innodb_thread_concurrency com um MySQL Expert 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
a ser aberto para uma determinada configuração de instância do MySQL.Depois de definir
innodb_thread_concurrency
como 0, você pode definirinnodb_read_io_threads
einnodb_write_io_threads
(ambos desde o MySQL 5.1.38) para o valor máximo de 64. Isso deve envolver mais núcleos.O MySQL usará automaticamente vários núcleos, portanto, sua carga de 25% é coincidência 1 ou uma possível configuração incorreta no Solaris. Não vou fingir 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 reformuladas no MySQL 5.5, então há algumas boas informações lá também. Das dicas de E/S do disco InnoDB :
Algumas outras coisas para verificar:
Vale a pena testar a mudança do innodb_flush_method para O_DIRECT. Se isso ajudar, talvez seja necessário montar o sistema de arquivos com a
forcedirectio
opçãoAltere 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 sistema operacional).
Verifique o valor de innodb_use_sys_malloc . Este artigo tem mais informações sobre a variável.
Mas há algumas advertências no final da seção sobre o que significa ativar a variável (ela está ativada por padrão na versão 5.5).
É possível que a replicação esteja causando alguns dos problemas. Percebo que você não está interessado em paralelismo, mas pela descrição deste log de trabalho :
Em última análise, o InnoDB pode não ser o melhor mecanismo para datawarehousing, devido às operações baseadas em disco que ocorrem. Você pode considerar alterar a(s) tabela(s) do datawarehouse para ser MyISAM compactado .
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 de núcleo único forçado.
Nota: Esta resposta é sobre uma única conexão usando vários núcleos. A pergunta do OP era ambígua; ele assumiu incorretamente que o MySQL como um todo não poderia usar mais de um núcleo. As outras respostas apontam corretamente que o caso de teste 3-Alter é realmente limitado por E/S, portanto, falhando em provar a pergunta do título.
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, então você não estava usando muito mais do que 3 núcleos.
Infelizmente, nem mesmo PARTITION usa vários núcleos.
Até recentemente, várias conexões atingiriam o 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 assim apenas um por thread. Eles atingem o máximo em cerca de 32 núcleos.
(Atualização em 2015:) Várias conexões com 5,6 atingem o máximo de cerca de 48 núcleos. 5.7 promete ser ainda melhor. (É o que dizem os benchmarks da Oracle.) Mas ainda não há uso de vários núcleos para uma única conexão.
Atualização (depois de ir para o OpenWorld da Oracle): a nova versão 8.x não terá nenhum paralelismo.
Atualização adicional - 8.0.17 tem casos em que usará vários núcleos em poucas consultas selecionadas. (Isto é, não fique animado.)
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 vinculada à CPU. Como suas 3 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.
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 para/data01
).Por padrão, o linux registra o tempo de acesso para TODA leitura ou gravação de disco que afeta negativamente o desempenho de E/S, especialmente para aplicativos de E/S altos, como bancos de dados. Isso significa que até mesmo a leitura de dados de um arquivo aciona uma gravação no disco... WAT!
Para desabilitar isso, adicione a
noatime
opção de montagem/etc/fstab
para o ponto de montagem desejado da seguinte forma (exemplo no meu caso):Em seguida, remonte a partição:
Isso deve aumentar o desempenho de leitura/gravação dos aplicativos que usam essa partição. MAS... nada supera manter todos os seus dados na memória.