Espera de E / S, causando tanto lentidão (EXT4 JDB2 a 99% de E / S) durante a confirmação do Mysql

14

Eu estou escrevendo um indexador, usando python, que indexa documentos e os insere no banco de dados, antes de ser um processo único, mas agora eu fiz o multiprocessamento com 4 processos paralelos em execução.

Agora, atingindo o problema de IO, o principal problema de IO não é o meu processo, mas o sistema de jourbond jdb2 do EXT4. Ele está em 99,99% e com a CPU que está aguardando a espera do IO em cada Confirmação do MySQL.

Vi muitos tendo esse problema na internet e sua solução é montar usando barreira = 0. Isso desativaria totalmente o diário? Meus servidores têm UPS e tentadores, devo?

Phyo Arkar Lwin
fonte
Todos os seus dados são InnoDB ???
RolandoMySQLDBA

Respostas:

4

Coloque o banco de dados em um sistema de arquivos sem registro no diário. Pelo menos servidores maiores (oracle, sql server) têm sua própria função de diário (log de transações) e otimizam suas E / S de acordo. Você possui log e banco de dados em sistemas de arquivos e discos separados e confia na funcionalidade interna do banco de dados para lidar com E / S ruins. Normalmente, não há alterações no sistema de arquivos (configuração maior), exceto a data de gravação, porque os arquivos não se expandem - eles seriam gerados com seu tamanho "final" (ok, os administradores podem mudar isso), e as alterações são como eu disse, rastreadas pelo banco de dados log de transações de nível.

Você também pode nos dizer qual é a sua camada de hardware. A maioria das pessoas subestima que o IOPS é o fator limitante para um banco de dados e acha que um pequeno conjunto de discos é um ambiente adequado para um grande banco de dados. Enquanto alguns de nós trabalham em bancos de dados usando um número maior de discos, potencialmente suportam um número maior de IOPS.

TomTom
fonte
Eu modificaria isso usando um sistema de arquivos que não usa o diário para dados, mas apenas metadados. O Ext4 também pode ser configurado dessa maneira.
the-wabbit
Sim. No final, o jouirnal dobra a IO - e o log do banco de dados fará o mesmo novamente, para que você tenha muito mais IOPS do que precisa. E redundância que basicamente não é necessária. O sistema de jouirnalling é NICE para proteger o arquivo ... mas inútil quando o aplicativo já o faz, quais bancos de dados o fazem.
TomTom
Qual oferece o melhor desempenho em não registro no diário? Obrigado!
Phyo Arkar Lwin
4

Sempre haverá uma troca entre resiliência e desempenho.

Com o MySQL no ext4, o padrão barreiras = 1 realmente causa uma lentidão, no entanto, a primeira ação não deve ser desativar o registro no diário ou ativar data = write-back.

Primeiro, se a resiliência é de grande importância, um RAID suportado por bateria certamente vale a pena.

As opções de montagem que escolhi, especialmente em RAID sem bateria, são:

/dev/mapper/vg-mysql--data  /var/lib/mysql/data ext4  defaults,noatime,nodiratime,barrier=1,data=ordered  0 0

Isso intencionalmente não está usando data = write-back, porque não quero arriscar a corrupção do sistema de arquivos, resultando em "dados antigos apareçam nos arquivos após uma falha e recuperação do diário" (a citação é de man mount).

A configuração ideal no my.cnf para resiliência total em torno das configurações relacionadas à E / S é:

[mysqld]
sync_binlog = 1
innodb_flush_log_at_trx_commit = 1

Optei pela seguinte sequência de trade-offs para aumentar o desempenho:

  1. sync_binlog = 0: esta é a primeira configuração do MySQL que mudo da resiliência total. A razão para isso é que ele fornece uma melhoria significativa no desempenho, especialmente onde binlog_format=row(infelizmente é necessário para o Jira). Estou usando réplicas MySQL suficientes no cluster para que, se o binlog fosse corrompido por um cenário de perda de energia, eu fizesse uma cópia binária de outra réplica.
  2. innodb_flush_log_at_trx_commit = 2: Embora seja necessário um valor 1 para conformidade total com ACID, com um valor de 2 ", o buffer de log é gravado no arquivo a cada confirmação, mas a operação de liberação para disco não é executada nele. No entanto, a liberação no o arquivo de log ocorre uma vez por segundo também quando o valor é 2. Observe que a liberação de uma vez por segundo não é 100% garantida para acontecer a cada segundo, devido a problemas de agendamento do processo. " (citação de documentos do MySQL)
  3. Atualize as opções de montagem para usar data=writeback. Observe que, se esse for o seu sistema de arquivos raiz, você também precisará passar uma opção de linha de comando do kernel. Eu dei alguns passos nisso na coderwall .
  4. Teste vários valores de innodb_flush_method. É mostrado que O_DIRECT melhora o desempenho em algumas cargas de trabalho, mas não é certo que isso funcione em seu ambiente.
  5. Melhore para SSDs, caso em que você também vai querer aumentar innodb_io_capacity, e ajustar configurações, como innodb_adaptive_flushing, innodb_read_io_threads, innodb_write_io_threads, innodb_purge_threads, e outras configurações possíveis.
JinnKo
fonte
3

É bem provável que o seu back-end de E / S não esteja lidando bem com a carga. Você deve se certificar de que seu sistema de arquivos não esteja registrando dados no diário. Eu sugeriria o uso dos data=writeback,relatime,nobarrierparâmetros para montar na partição de dados do banco de dados como a primeira otimização rápida e suja.

Além disso, deduzindo dos seus sintomas, você aparentemente não está usando o cache de gravação com seu controlador. Você deve certificar-se de estar usando um cache de gravação com bateria ou com flash em seu controlador e habilitá-lo - isso deve proporcionar um aumento significativo no desempenho sem aumentar muito o risco de perda ou corrupção de dados. Observe que o uso do cache de gravação sem bateria ou backup flash aumenta significativamente o risco de perda ou corrupção de dados - faça isso apenas para fins de teste e / ou se você puder sofrer a perda.

o wabbit
fonte
então, que tal: data = writeback, relacionime, nobarrier e, em seguida, desabilite totalmente o registro do mysql? Eu acho que isso iria acelerar bastante as coisas?
Phyo Arkar Lwin
hdpram -i mostra que estou usando o cache de gravação. então hmm ??
Phyo Arkar Lwin
@ V3ss0n, você não pode desativar o log de um mecanismo transacional - é o coração dele. Você pode optar por mover o log de transações para um conjunto diferente de discos, pois ele possui um padrão de acesso totalmente diferente (principalmente gravações lineares) dos dados principais do banco de dados (leitura / gravação aleatória) - essa é uma configuração geralmente recomendada. Quanto à sua configuração de armazenamento: você não está usando um controlador RAID, mas simplesmente discos individuais com cache de gravação ativado? Isso não ajudaria nenhuma das gravações síncronas, pois elas vêm com solicitações de liberação de cache explícitas.
the-wabbit
É nobarriero mesmo que barrier=0?
Nic Cottrell
@NicCottrell sim, são os mesmos.
kouton
3

Essa é uma pergunta antiga, mas enfrentamos os mesmos problemas (alta espera de E / S e velocidades terríveis de inserção / atualização) na semana passada em um novo servidor dedicado e esta solução soluciona esse problema diretamente.

Desativar o registro no diário tune2fs -O "^has_journal" /dev/<drive>foi a solução mais rápida, pois elimina a espera de E / S por causa do processo JDB2. Mas isso não é recomendado, a menos que você tenha uma unidade com bateria, pois perderá dados em caso de falha. As tabelas do InnoDB são seguras se você tiver doublewriteativado no MySQL. Mas arquivos como .frm, logs etc. não são seguros. Tentamos mover esses arquivos para outra unidade (especialmente os logs de lixeira), mas a espera do jdb2 IO ainda persistia. Portanto, não nos deixou muito confortáveis.

data=writeback,relatime,nobarriernão ajudou a acelerar as gravações / leituras, além de desativar o registro no diário em toda a partição. Mais opções para ext4 estão no documento EXT4 .

O verdadeiro culpado no nosso caso foi sync_binlog. Nós tínhamos definido é como 1em /etc/mysql/my.cnfe foi matando desempenho.

A Percona valida isso aqui . Definimos como padrão 0e o desempenho disparou em mais de 500%.

kouton
fonte
0

Em qual mecanismo de banco de dados você está usando para inserir esses dados?

Se for o MyISAM: deve bloquear a tabela inteira durante uma gravação, portanto, executar threads de inserção simultâneos matará QUALQUER sistema, por mais poderoso que seja.

Verifique se você está usando o InnoDB para essas tabelas.

adaptr
fonte
Como ele está comprometendo transações, o mecanismo não seria o MyISAM, pois o MyISAM não suporta transações.
the-wabbit
Arr, peido cerebral.
adaptr
Estou usando o innodb, o mysql5.5 usa como padrão o innodb.
Phyo Arkar Lwin
0

Além disso, não está diretamente relacionado ao mysql, mas alguns HD têm problemas com o ext4 devido ao gerenciamento agressivo de energia ... quando isso acontece, a carga da máquina aumenta sem nenhuma atividade aparente.

Tente desativá-lo. primeiro verifique o valor que você possui (se precisar recuperá-lo sem reiniciar) e depois desative-o.

Verifique o valor atual:

    hdparm -B /dev/sda

Desativá-lo

   hdparm -B 255 /dev/sda

(ou qualquer que seja o seu HD) e teste. Provavelmente não ajudará na maioria dos problemas, mas pode ajudar alguns usuários por aí. A reinicialização redefinirá o valor ou substituirá manualmente o 255 pelo valor anterior.

Se ajudar, verifique a /etc/default/hdparmou /etc/hdparm.confpara uma configuração mais permanente, configurando-a na inicialização.

higuita
fonte