O Uber, como você deve saber, é uma empresa que trouxe para o mercado uma forma rápida, eficiente, e consideravelmente mais barata que os taxis conencionais para se locomover em várias cidades do planeta.

O que talvez não saiba é sobre a tecnologia por trás do serviço.

Aqui vou falar um pouquinho sobre a migração de bancos de dados realizada pelo Uber recentemente. O artigo original foi publicado em um blog do próprio Uber 20 dias antes de eu escrever esse post.

Minha intenção aqui não é traduzir nem fazer um comentário extenso sobre o texto, mas apenas pontuar as informações que achei mais interessantes. Vamos lá:

O Postgres tem um funcionamento que faz gerar várias linhas (fisicamente, no disco, chamada ctid) para uma mesma linha no banco de dados, ou seja, se você tem uma tabela que armazena os dados de uma pessoa, e você altera o telefone dela, uma nova linha física (ctid) é gerada.

Para a maioria dos sistemas, isso não chega a ser um problema. O Postgres tem um recurso chamado auto-vacuum que faz a limpeza das linhas antigas. A questão é que, de tempos em tempos, pode ser necessário parar o sistema por algumas horas e executar um vacuum full (limpeza geral), e para sistemas que não podem parar, isso pode ser um problema. Se muito tempo passa sem a execução de um vacuum full, o sistema começa a ficar lento.

Mas a grande questão para o Uber é que eles replicam os dados em diferentes data centers (costa leste e costa oeste dos Estados Unidos) para Recuperação de Desastres e, nesse caso, a replicação dessas linhas torna-se muito lenta e cara. Com frequência uma alteração estava sendo realizada e não sendo sincronizada corretamente.

O problema é agravado pelo fato de que no caso deles, muitas tabelas tinham muitos índices, e updates pequenos e frequentes eram executados.

Repare que é uma situação específica: replicação de dados em data centers diferentes, com updates frequentes e muitos índices.

Nem todo serviço funciona dessa forma, e obviamente, isso não quer dizer que o Postgres é um banco de dados ruim. Mas no caso específico do Uber, eles tiveram problemas.

Segundo o artigo, o MySQL (com engine InnoDB) cria uma camada a mais de abstração, o que normalmente é uma desvantagem pois deixa o sistema todo mais lento, mas é uma solução no caso da replicação, pois o MySQL replica o DML (update, insert, delete) propriamente dito, e não o registro físico da informação.

Outra questão é a atualização de versão. Usando a versão 9.2, eles tiveram problemas para atualizar para a 9.3, porque demorava tempo demais e o serviço não poderia ficar parado durante esse tempo. Para agravar a situação, todas as réplicas têm que usar a mesma versão, ou seja, eles não poderiam fazer a atualização primeiro em uma ráplica e depois no master, por exemplo. Acrescentam que isso foi resolvido na versão 9.4 em diante, usando o recurso pglogical, que adicona uma camada lógica para replicação.

No MySQL esse problema não existe. É possível, na maioria das situações operar com versões diferentes (já que o que é replicado é o DML em si).

Outro grande problema do Postgres é relativo ao número de conexões. Mesmo em sistemas com abundância de recursos, é bem difícil abrir mais que algumas centenas de conexões, porque o número de conexões é diretamente ligado ao número de processos (mais conexões, mais processos). No MySQL, o número de conexões é diretamente ligado ao número de threads.

Isso faz com que no MySQL seja possível abrir 10 mil conexões sem grandes problemas.

Veja o artigo original para obter mais informações:

Outro artigo comentando o artigo do Uber: