A tabela InnoDB com inserção pesada não usará toda a minha CPU

8

Eu tenho um banco de dados de log de pacotes, que quase nunca é consultado. Ele só precisa ser rápido nas pastilhas. Estou usando o InnoDB porque gostaria de manter a conformidade com o ACID, pois mesmo a perda de um único pacote pode ser prejudicial aos nossos clientes. Em um cenário de ajuste de desempenho, envio 1.000.000 de pacotes para o servidor por várias conexões de banco de dados. Mas não importa quais configurações eu uso no my.cnf, não consigo que o processo mysqld use mais de 900% da CPU em um sistema com 12 núcleos. (Nada mais está sendo executado na caixa.)

Eu defini o seguinte

  • innodb_file_per_table = 1
  • innodb_write_io_threads = 64
  • innodb_read_io_threads = 64
  • innodb_thread_concurrency = 0

Se eu usar o MyISAM, posso obter todos os pacotes escritos em cerca de 6 segundos. Mas o InnoDB leva cerca de 25 anos. Posso fazer o MySQL usar o restante dos recursos do sistema e inserir mais rapidamente?

Edit: Aqui está o esquema para a tabela:

+-------+----------------------+------+-----+---------+-------+
| Field | Type                 | Null | Key | Default | Extra |
+-------+----------------------+------+-----+---------+-------+
| t     | bigint(20) unsigned  | YES  |     | NULL    |       |
| a     | char(1)              | YES  |     | NULL    |       |
| sa    | int(10) unsigned     | YES  |     | NULL    |       |
| sb    | int(10) unsigned     | YES  |     | NULL    |       |
| sc    | int(10) unsigned     | YES  |     | NULL    |       |
| sd    | int(10) unsigned     | YES  |     | NULL    |       |
| sp    | smallint(5) unsigned | YES  |     | NULL    |       |
| da    | int(10) unsigned     | YES  |     | NULL    |       |
| db    | int(10) unsigned     | YES  |     | NULL    |       |
| dc    | int(10) unsigned     | YES  |     | NULL    |       |
| dd    | int(10) unsigned     | YES  |     | NULL    |       |
| dp    | smallint(5) unsigned | YES  |     | NULL    |       |
+-------+----------------------+------+-----+---------+-------+

edit2: agrupei mais inserções em lote para que uma única consulta tenha o tamanho máximo (cerca de 16.000.000 caracteres). O banco de dados agora atinge 1100% por dois segundos e depois cai para 100% pelo resto do tempo. O tempo total agora é 21 segundos, ou cerca de 16% mais rápido do que quando eu comecei.

sep332
fonte

Respostas:

7

Você também deve ativar o innodb_io_capacity .

O padrão é 200. Aumente para 5000 para iniciantes. Eu iria para 20000.

Você também pode querer certificar-se ib_logfile0e ib_logfile1são suficientemente grandes. O valor padrão para innodb_log_file_size é 5M. Eu aumentaria isso para 1G para iniciantes.

Um pool de buffers InnoDB maior também ajudaria, talvez 4G.

Para recapitular, use estas configurações adicionais:

[mysqld]
innodb_io_capacity=5000
innodb_buffer_pool_size=4G
innodb_log_file_size=1G

Após adicionar essas configurações ao my.cnf, para redimensionar ib_logfile0 / ib_logfile1, faça o seguinte

service mysql stop
rm -f /var/log/mysql/ib_logfile[01]
service mysql start

Os arquivos ib_logfile0 e ib_logfile1 são recriados. Não se preocupe, eu já fiz isso muitas vezes .

Talvez você precise fazer algo fora do comum para o InnoDB

Tente o seguinte:

  • Bloqueio de tabela completo na tabela do InnoDB
  • Executar a carga em massa
  • Solte a trava
RolandoMySQLDBA
fonte
Ajudaria ter vários buffer pools? Ou como é apenas uma mesa, isso importaria?
sep332 18/01/12
Apenas um buffer pool. Dessa forma, não há limite virtual. Eu tenho um cliente que possui o MySQL 5.5.9 usando um único buffer pool de 162GB e roda muito bem.
RolandoMySQLDBA 18/01/12
Usando isso, cheguei a cerca de 950% da CPU, mas não parece ser mais rápido.
sep332 18/01/12
Experimente um bloqueio de tabela completo na tabela do InnoDB antes do carregamento em massa.
RolandoMySQLDBA 18/01/12
3

Existem vários fatores que afetam a capacidade de maximizar o uso de vários núcleos.

  • Alguns mutexes afetarão várias CPUs, deixando algumas aguardando antes que possam prosseguir.
  • Você precisa de tantos threads ativos quanto de CPUs. Se sua carga de trabalho resultar em 9 threads paralelos, você não poderá preencher 12 núcleos.
  • A capacidade de E / S deve ser suficiente para fornecer trabalho suficiente para todas as CPUs. Se você estiver na fila de E / S do disco ou aguardando mensagens de rede, não poderá preencher as CPUs.

Ferramentas como o SAR permitirão determinar se existem gargalos que estão reduzindo sua capacidade. Apenas esteja avisado, eliminando um gargalo, apenas moverá o gargalo.

BillThor
fonte