É possível fazer o MySQL usar mais de um núcleo?


131

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

  1. 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)
  2. É 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

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


@Dtest: innodb_file_per_table = LIGADO. MOSTRAR STATUS DO INNODB DO MOTOR \ G é apenas linha de comando?
gbn 12/09

@Dtest: Eu tenho nenhuma saída em SQLyog e precisaria pedir a alguém para executar este a partir de linha de comando
GBN

1
webyog.com/forums/index.php?showtopic=1290 deve funcionar sem o \G. Além disso, eu acho que SHOW INNODB STATUSé depreciado em favor do SHOW ENGINE INNODB STATUSno 5.5 (eu recebo um erro de executar o ex-em-linha de comando.
Derek Downey

1
Embora todas as outras respostas sejam boas, como você é um desenvolvedor, recomendo dar uma olhada no Shard Query code.google.com/p/shard-query Isso pode ajudá-lo, especialmente em um ambiente de datawarehouse.
Jonathan

Obrigado, é uma opção em que pensamos. Também estou assumindo o papel de DBA.
gbn 14/09

Respostas:


123

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_concurrencyem 0 (simultaneidade infinita). Dessa forma, o InnoDB decide o melhor número innodb_concurrency_ticketspara abrir para uma determinada configuração de instância do MySQL.

Depois de definir innodb_thread_concurrency0, você pode definir innodb_read_io_threadse innodb_write_io_threads(ambos desde o MySQL 5.1.38) o valor máximo de 64. Isso deve envolver mais núcleos.


Vai tentar isso. Eu estava indo para definir innodb_thread_concurrency a 0 de qualquer maneira baseado em coisas que eu li muito
GBN

9
+1 para innodb_thread_concurrency = 0
randomx 12/09

3
@gbn - Vindo do primeiro lugar no DBA.SE, um agradecimento é um incentivo à confiança e é muito apreciado. Obrigado e de nada !!!
RolandoMySQLDBA

set global innodb_read_io_threads = 8 Código de erro: 1238. A variável 'innodb_read_io_threads' é uma variável somente leitura
wgq3g23g

2
@ wgq3g23g Se você estiver executando o RDS, altere-o no DB Parameter Group e reinicie a instância. Se você estiver executando o EC2 ou o bare metal, adicione essa opção ao my.cnfe reinicie o mysqld. por favor.
RolandoMySQLDBA 23/01

29

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 :

Se a ferramenta superior do Unix ou o Gerenciador de tarefas do Windows mostrar que a porcentagem de uso da CPU com sua carga de trabalho é menor que 70%, é provável que sua carga de trabalho esteja ligada ao disco. Talvez você esteja fazendo muitas confirmações de transação ou o pool de buffers é muito pequeno. Aumentar o buffer pool pode ajudar, mas não o configure para mais de 80% da memória física.

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 forcedirectioopção

  • Mude 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

    Naquela época, não havia bibliotecas de alocadores de memória ajustadas para CPUs com vários núcleos. Portanto, o InnoDB implementou seu próprio alocador de memória no subsistema mem. Esse alocador é protegido por um único mutex, que pode se tornar um gargalo.

    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).

    Observe que quando o alocador de memória do InnoDB está desativado, o InnoDB ignora o valor do parâmetro innodb_additional_mem_pool_size.

  • É 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 :

    Atualmente, a replicação não é bem dimensionada em máquinas com vários núcleos. O encadeamento escravo único executa eventos de replicação um por um e pode não lidar com uma carga produzida por conexões simultâneas de vários clientes atendidas pela CPU do servidor principal separado.

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.


Obrigado. Seção Configurações adicionada à pergunta. O problema são várias consultas intensivas usando um único núcleo: ainda não há configurações de memória ou thread. Mais threads ainda rodam no mesmo núcleo
gbn

@gbn obrigado pela atualização, ainda procurando. Eu estava pensando que era uma 'coincidência'. Gostaria de saber se é um problema apenas do solaris ( developers.sun.com/solaris/articles/mysql_perf_tune.html ), mas não sei muito sobre esse sistema.
Derek Downey

1
@Dtest: Eu também chuck esse artigo para o administrador do Solaris Algumas coisas boas lá
gbn

1
Agora, a replicação é (opcionalmente) multiencadeada no Escravo. O InnoDB melhorou desde que esta resposta foi escrita. Eu não recomendaria o uso do MyISAM, especialmente se estiver compactado.
Rick James

15

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.


(Atualização em 2015 :) Várias conexões com o máximo de 5.6 em 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 múltiplos núcleos para uma única conexão.
Rick James

Atualização (depois de acessar o OpenWorld da Oracle): a nova versão 8.x não terá paralelismo.
Rick James

9

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.


8

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 noatimeconfigurações de montagem /etc/fstabpara a partição que contém meu diretório de dados mysql ( /data01/mysqlno meu caso, com /dev/sdb1montado 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 noatimeopção de montagem no /etc/fstabponto de montagem desejado da seguinte maneira (exemplo no meu caso):

/dev/sdb1  /data01  ext4  defaults,noatime  0  2

Em seguida, remonte a partição:

mount -o,remount /data01

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.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.