Limitações MySQL Parte 1: Single-Threaded a Replicação

Esta é a primeira de um serie de publicações a cerca do MySQL, onde destruiremos mitos e formas de otimizar a utilização da ferramenta.

Por | @gregoryylaborde Programação

Muito se comenta sobre algumas limitações a cerca de Postgres que tem sido superadas, por casos de especificidade de uso. Decidimos escrever uma série de posts sobre algumas limitações de grande relevância no MySQL. Iremos analisar as limitações mais explicitas e também necessidades importantes para determinadas áreas, mostrando e explorando todo o potencial do MySQL.

O primeiro problema mais explicito é a single-threaded e sua replicação. É bastante grave e fica cada vez pior quando falamos de servidores CPUs. O processo de repetição e replicação são executados em um único segmento, portanto para que isso não aconteça devemos manter a linha primária sempre ocupada pois muitas atualizações estão ocorrendo simultaneamente.

Em algumas aplicações web, isto não é visto como uma limitação de relevância. Isso porque esse tipo de aplicativo em sua maioria funcionam como leitura de tráfego, pois o primário pode encarregar a carga do trabalho de leitura a várias replicas, quando consideramos leitura e escrita estas funções exploram de forma muito simplória. Eventualmente poderam surgir problemas, caso a APP seja grande suficiente para gerar um fluxo de leitura e escrita considerável.

Aqui estão algumas soluções alternativas:

  • Use a replicação DRBD em vez da replicação MySQL. Problema: você fica com um servidor ocioso, que será utilizado apenas para recuperação em caso de desastres. Isso custa muito caro.
  • Shard escrita a carga de trabalho é a razão mais justa para o sharding. É muito ruim quando “não podemos manter a replica com a carga de trabalho para escrita” deixando assim uma razão de Shard. Acredito que isto pode ser evitado.
  • Fazer a replicação da replicação. Algumas aplicações onde não se utilizam built-in de replica, quando modificamos alguns dados, as alterações são salvas em ambos os lugares. Isso pode ser uma grande dor de cabeça.
  • Faça uso de técnicas obscuras, como por exemplo pocessos externos ao prefetch para os dados da replica e realizar a tentativa de modificação, para que possa ser feito mais rapidamente. Isso raramente funciona.


Não estamos realizando criticas a quem faz uso destes artifícios, na realidade não existe a melhor escolha e sim qual solução encaixa-se a sua necessidade.

Por que não existe multi-threaded na replicação? Acredito que a) não é tão simples quanto parece, e b) existem vários casos que tornam quase impossível uma solução que seja eficiente para todas as situações. Como por exemplo a mistura entre tabelas transacionais e não transacionais são um verdadeiro pesadelo.

Aqui estão algumas ideias:
  • Um thread por banco de dados. Se o aplicativo é construído de tal forma que cada banco de dados é totalmente independente, em seguida, na réplica, poderíamos iniciar um thread para cada banco de dados que vemos no log binário, e simplesmente passar os eventos de replicação para o segmento apropriado.
  • Um pool de threads sobre a réplica e um fio de coordenação que as são mãos de trabalho para cada um deles. O coordenador lia o relay do log até que valesse a pena uma transação completa de eventos (e não uma única instrução), e toda a transação para o segmento de trabalho. O segmento de trabalho seria executado até o COMMIT, mas na verdade não acontecia, e depois voltava-se para o segmento de coordenador. O fio coordenador iria garantir que todas as transações comecem na mesma ordem, conforme definido no relay log, e se comprometeriam na mesma ordem. Se algum erro ocorreu, como um impasse ou bloqueio por tempo limite de espera, então o coordenador teria que instruir os trabalhadores para reverter, e repetir ou fazê-los executar as transações problemáticas em série em vezes simultaneamente.
  • Binários e múltiplos registros no primário, em um banco de dados; por um processo de replicação por log binário na réplica. Isto gera a vantagem de que ela permitiria uma réplica para se inscrever em vários mestres, que atualmente é impossível.


Estas soluções representam uma gama de deferentes trade-offs. Por exemplo:
  • Só funcionam para casos específicos, não acredito que isso seja suficiente para caso de uso geral.
  • Possui um comportamento potencialmente complexo, que não funciona bem em alguns casos , mas de maneira geral é o menos perturbador do ponto de vista do usuário
  • Requer a modificação do código de log binário, o que é arriscado. Também requer a manutenção de muitos arquivos master.info na réplica, e a sintaxe SQL para administrar novas réplicas, e geralmente não é algo que eu pessoalmente desejo administrar, (replicação é frágil o suficiente ... imagine a recuperação depois de uma falha quando você tem que corrigir vários segmentos que esqueceu onde eles devem estar lendo o log binário múltiplo?).


Independentemente da solução, é certo que nada vai funcionar em todos os casos, na maioria dos acontecimentos comuns exigirão o uso de InnoDB com o nível adequado de isolamento de transação, mínimo. Este comportamento vai ser um padrão para single-threaded como replicação atualmente se faz, e só permitem o comportamento multi-threaded se o usuário configura-lo para fazê-lo.

Mais sobre: MySQL, logistica, banco de dados
Share Tweet
DESTAQUESMais compartilhados
Comentários