2 pontos por GN⁺ 2025-04-30 | 1 comentários | Compartilhar no WhatsApp
  • Testes do Jepsen confirmaram casos em que clusters Amazon RDS for PostgreSQL Multi-AZ não mantêm Snapshot Isolation, o nível de isolamento mais forte disponível em todos os nós
  • A causa principal é que a ordem de visibilidade das transações no primary é determinada por locks em memória, enquanto no secondary segue a ordem do WAL, e essas duas ordens podem divergir
  • Mesmo sem injeção de falhas nem failover, usando armazenamento gp3 e instâncias db.m6id.large, surgem ciclos G-nonadjacent a cada poucos minutos com cerca de 150 write TPS / 1600 read-only TPS
  • A anomalia corresponde a Long Fork e apareceu em todas as versões testadas, do PostgreSQL 13.15 ao 17.4 com suporte da AWS; Short Fork/Write Skew não foi observado
  • Em transações críticas para segurança, leituras em secondary read-only podem enxergar ordens de execução diferentes, então vale considerar usar apenas o writer endpoint ou incluir pelo menos 1 escrita

Atualização sobre a causa do Long Fork

  • Sergey Melnik, da AWS, e os participantes dos comentários no HN matashii e Ants Aasma identificaram a causa do Long Fork em clusters PostgreSQL
  • O primary do PostgreSQL determina a ordem em que as transações se tornam visíveis por meio de locks em memória
  • O secondary torna as transações visíveis conforme a ordem no Write-Ahead Log (WAL)
  • Quando a ordem dos locks e a ordem do WAL diferem, primary e secondary podem enxergar ordens aparentes diferentes para as transações
  • Esse comportamento já havia sido discutido em uma mensagem da mailing list do PostgreSQL em 2013, e Melnik publicou no blog da AWS um texto explicando transaction visibility em clusters PostgreSQL e read replicas
  • O Jepsen recomenda que AWS e PostgreSQL documentem esse problema junto com o trabalho de correção

Níveis de isolamento e arquitetura do RDS for PostgreSQL

  • PostgreSQL é um banco de dados SQL open source de uso geral e oferece três níveis de isolamento transacional com MVCC
    • Read Uncommitted e Read Committed funcionam ambos como Read Committed
    • Repeatable Read na prática não fornece Repeatable Read, e sim Snapshot Isolation
    • Serializable fornece Serializability
  • Amazon RDS for PostgreSQL é um serviço da AWS que oferece clusters PostgreSQL gerenciados
    • Automatiza provisionamento, gestão de armazenamento, replicação, backups e upgrades
    • Multi-AZ deployments distribuem nós do banco entre várias zonas de disponibilidade para reduzir a chance de falhas correlacionadas
    • O RDS usa replicação síncrona para só responder depois que a durabilidade da transação foi garantida no primary e em pelo menos 1 instância secondary
  • Para o usuário, são fornecidas duas URLs que falam o protocolo wire do PostgreSQL
    • primary endpoint: para transações de leitura e escrita
    • reader endpoint: para transações somente leitura
  • O primary endpoint suporta todos os níveis de isolamento do PostgreSQL, mas o secondary não suporta Serializable
  • O nível de isolamento mais forte disponível em todos os nós é o que o PostgreSQL chama de Repeatable Read, ou seja, Snapshot Isolation

Desenho do teste

  • O Jepsen adaptou a biblioteca de testes para PostgreSQL ao Amazon RDS for PostgreSQL e usou um pequeno programa wrapper
  • Em cada rodada de teste, o cluster RDS era provisionado pela API CreateDBCluster da AWS
    • armazenamento gp3
    • instâncias db.m6id.large
  • Um nó EC2 era iniciado para executar os testes, recebendo o main endpoint e o endpoint read-only do cluster RDS
  • Não houve injeção de falhas nem failover foi acionado
  • A carga principal consistia em transações que manipulavam listas de inteiros únicos
    • Cada lista era armazenada em uma única row, codificada em um campo TEXT com valores separados por vírgula
    • As transações liam a lista pela primary key ou adicionavam um inteiro único com CONCAT
  • Com essa carga, o Elle checker consegue inferir dependências de fluxo de dados entre transações e encontrar ciclos no grafo para verificar vários níveis de isolamento

Observação de ciclos G-nonadjacent

  • Mesmo em condições normais e com concorrência moderada, o Amazon RDS for PostgreSQL 17.4 apresentou ciclos G-nonadjacent a cada poucos minutos
  • Em uma execução de teste de 2 minutos, foram alcançados cerca de 150 write TPS e 1600 read-only TPS, com um ciclo de 4 transações
  • O ciclo de exemplo é composto por quatro transações: T1, T2, T3, T4
    • T1 adicionou 9 à row 89, formando a lista [4 9], e T2 observou isso
    • T3 adicionou 11 à row 90, criando a lista [11]
    • T4 adicionou 3 à row 90 e, ao ler a lista resultante [11, 3], sobrescreveu a versão de T3
    • T2 viu a adição de T1 na row 89, mas não viu a adição de T3 na row 90
    • Em contrapartida, T4 viu a adição de T3 na row 90, mas não percebeu a adição de T1 na row 89
  • Esse ciclo inclui uma dependência read-write entre transações não adjacentes, portanto é um ciclo G-nonadjacent que viola Snapshot Isolation
  • Em Repeatable Read do PostgreSQL padrão, esse comportamento não deveria acontecer, e o Jepsen não o observou no PostgreSQL padrão

Por que isso entra em conflito com Snapshot Isolation

  • Em Snapshot Isolation, toda transação deve parecer operar sobre um snapshot do banco no timestamp inicial s
  • Os efeitos da transação só devem se tornar visíveis a outras transações no timestamp de commit c
  • Ao expressar as observações do ciclo de exemplo como relações entre timestamps, surge uma contradição
    • Como T2 leu a adição de T1, o início de T2 deve ser posterior ao commit de T1: c1 < s2
    • Como T2 não viu a adição de T3, então s2 < c3
    • Como T4 sobrescreveu e observou T3, então c3 < s4
    • Como T4 não viu a adição de T1, então s4 < c1
  • Todas essas relações não podem ser verdadeiras ao mesmo tempo, o que entra em conflito com o modelo de timestamps de Snapshot Isolation

Long Fork e resultados por versão

  • Esse ciclo também é um exemplo de Long Fork
    • A primeira e a segunda transação formam um fork de um estado lógico
    • A terceira e a quarta transação formam o segundo fork
    • Os dois forks atualizam rows diferentes, mas não observam os efeitos um do outro
  • Short Fork, ou seja, Write Skew, não foi observado
  • O resultado sugere que o Amazon RDS for PostgreSQL pode estar fornecendo Parallel Snapshot Isolation, um pouco mais fraco que Snapshot Isolation
  • As anomalias G-nonadjacent apareceram em vários formatos, inclusive conectadas apenas por arestas write-read e envolvendo mais de 4 transações
  • O mesmo tipo de anomalia apareceu em todas as versões testadas, da mais antiga com suporte da AWS, PostgreSQL 13.15, até a mais recente, 17.4

Pontos que os usuários devem revisar

  • Como existem Long Fork e outros ciclos G-nonadjacent, clusters Amazon RDS for PostgreSQL Multi-AZ não garantem Snapshot Isolation
  • Nesse aspecto, os clusters RDS for PostgreSQL Multi-AZ oferecem semântica de segurança mais fraca do que o PostgreSQL de nó único, que em testes anteriores do Jepsen pareceu fornecer Strong Snapshot Isolation
  • Usuários podem verificar se a estrutura de suas transações é vulnerável a Long Fork ou validar experimentalmente se as invariantes pretendidas estão sendo mantidas
  • Transações de leitura podem ver resultados diferentes umas das outras quanto à ordem de execução das transações
  • Como a anomalia parece estar relacionada a consultas no secondary read-only, pode ser possível recuperar Snapshot Isolation das seguintes formas
    • usar apenas o writer endpoint

      • incluir pelo menos 1 escrita em todas as transações críticas para segurança
      • A verificação do Jepsen é uma abordagem experimental: ela pode provar a existência de bugs, mas não sua ausência
      • Este relatório não é resultado de uma investigação profunda do funcionamento do RDS for PostgreSQL, e sim de uma exploração preliminar

1 comentários

 
GN⁺ 2025-04-30
Opiniões no Hacker News
  • Eu gostaria que textos no mundo do software fossem mais frequentemente assim: “Amazon RDS for PostgreSQL é um serviço da Amazon Web Services (AWS) que fornece instâncias gerenciadas de bancos de dados PostgreSQL. Mostramos que clusters multi-AZ do Amazon RDS for PostgreSQL violam o isolamento por snapshot, o modelo de consistência mais forte suportado em todos os endpoints...”
    É direto, vai ao ponto e sem enfeites, parecido com a forma de compartilhar resultados de pesquisa em outras áreas STEM. Houve uma época em que eu gostava de posts de blog espirituosos explicando coisas com memes, mas agora sinto falta de textos plain e simples

    • Em uma empresa onde trabalhei antes, havia um blog interno em que qualquer pessoa podia escrever e comentar, não era obrigatório e não contava em nada para avaliação. Parecia resultado de um hackathon, mas eu gostava bastante porque curto escrita técnica
      Quando eu escrevia textos técnicos muito profundos, quase não recebia curtidas nem comentários, a ponto de um Staff Engineer dizer que “seria melhor estreitar mais o público-alvo”. Por outro lado, ao testar o Kubecost inicial, escrevi que as recomendações reduziam pouco o custo e poderiam causar problemas de desempenho em contêineres; embora fosse um texto bem técnico tratando de CPU throttling e cgroups, quando coloquei memes as pessoas adoraram
      Mais tarde, fiz uma pequena biblioteca externa para Python em C, acessei com ctypes e escrevi um texto mais seco comparando alocação em stack/heap; coloquei memes também e tive resultado parecido. Não gosto dessa tendência, mas, se a ideia é alcançar um público amplo, não sei bem como evitá-la. Jensen não mirou esse público, e uma escrita rigorosa e pura merece aplausos
    • Já não tenho a menor vontade de ler posts de blog cheios de memes. Especialmente porque muitas vezes esticam à força algo que caberia em um parágrafo, e hoje em dia os textos sobre vulnerabilidades de segurança costumam ser os piores nisso
    • Eu tinha acabado de pensar que sentia falta do Jepsen antigo. Era igualmente factual e direto, mas cheio de memes. O antigo texto sobre Redis https://aphyr.com/posts/283-call-me-maybe-redis é um bom exemplo
    • A Amazon é conhecida por ter uma cultura saudável de escrita técnica, e, pelo que vi diretamente, era mesmo assim. Essa é uma opinião pessoal, não da empresa. Também há um texto público relacionado: https://quartr.com/insights/business-philosophy/amazon-s-wri...
  • Não está no título e também não fica muito claro no texto, mas este problema se limita a um recurso relativamente novo do RDS, os clusters multi-AZ. É diferente das instâncias multi-AZ com as quais muita gente está acostumada
    Instâncias multi-AZ são um recurso antigo em que o DB primário é replicado de forma síncrona para um DB secundário em outra zona de disponibilidade e, se o primário falha, o RDS faz failover para o secundário
    Clusters multi-AZ têm dois secundários, e a transação é replicada de forma síncrona para pelo menos um deles. Eles são mais robustos do que instâncias multi-AZ quando um secundário falha ou perde desempenho, e também permitem acesso somente leitura aos secundários
    Porém, clusters multi-AZ provavelmente têm mais mágica adicional internamente que não é funcionalidade nativa do PostgreSQL, e talvez por isso tenham falhado nos testes do Jepsen

    • É interessante por que essa mágica é necessária. O PostgreSQL básico também suporta commit por quórum, então uma configuração assim é possível. Com Patroni também dá para criar um cluster multi-AZ equivalente e, salvo bugs, ajustar a promoção do primário para não perder transações nem tornar visíveis transações que não sejam duráveis
      Ainda assim, o PostgreSQL tem uma falha que pode permitir um problema parecido com esse padrão. Uma transação não replicada em que o cliente desaparece durante o commit se torna visível imediatamente. No exemplo, se T1 acontece em um líder isolado e a conexão cai durante o commit, T2 também acontece no nó isolado, e T3/T4 acontecem depois no novo líder, dá para ver o mesmo resultado. Mas isso não combina muito bem com a descrição de que não houve fault injection neste teste
      Correção: eu não tinha visto o texto dizendo que esse padrão é explicado pela inconsistência na ordem de commits entre a réplica e o nó primário. Meio constrangedor, já que já apresentei uma forma de corrigir esse problema
    • Se uma violação de snapshot ocorre dentro de uma instância multi-AZ, fico me perguntando se ela também poderia ocorrer em uma configuração com várias réplicas de leitura em uma única região. Talvez, porém, na configuração multi-AZ a latência seja maior e isso seja observado com mais facilidade
    • Isso aparece logo na segunda frase do texto: “Amazon RDS for PostgreSQL multi-AZ clusters violate Snapshot Isolation”. Temos que esperar que as pessoas leiam
  • Boa investigação. Hoje em dia, muitos desenvolvedores de software nem entendem bem transações em si, e muito menos os diversos modelos de transação. Já vi até desenvolvedor CRUD chamado de “desenvolvedor sênior” que não sabia absolutamente nada sobre transações de banco de dados
    Na prática, quando há volume de tráfego e o software resolve problemas que não são triviais, transações e modelos de transação são muito importantes para desempenho e para código sem erros
    Por exemplo, em um projeto grande, depois de muita análise, mudamos o padrão Read Committed do SQL Server para Read Committed Snapshot Isolation, e a contenção de locks praticamente desapareceu, deixando os usuários muito satisfeitos. Os engenheiros de software daquele projeto usavam muitas transações, mas, até ensinarmos o básico, não sabiam nada sobre modelos de transação ou locks

    • Isso não se limita a desenvolvedores sêniores. Já vi arquitetos de sistemas que não conheciam níveis de isolamento, e algumas pessoas confundiam a “consistência” do ACID com a “consistência” do CAP
      Como trabalho principalmente no varejo, vejo com frequência sistemas cheios de erros parecidos com condições de corrida, e é uma pena porque esses níveis de isolamento poderiam ajudar bastante nesses pontos
      Dito isso, vi esse tipo de caso principalmente em engenheiros de startup; já os desenvolvedores típicos de Oracle/MSSQL em grandes empresas pelo menos tinham o básico correto, então os avalio bem melhor
    • A falta de consciência sobre transações eu vi principalmente em ambientes serverless/edge. Se é que dá para chamar de arquitetura de backend, são lugares em que ela é movida inteiramente pelas necessidades do cliente. Por exemplo, consultas ao banco de dados são modeladas como React hooks ou chamadas sequenciais de API
      Algumas vezes na carreira vi essa abordagem dar resultados realmente ruins
    • Em breve, a maioria dos desenvolvedores de software vai simplesmente transcrever lixo de LLM para o código sem nem saber o que está acontecendo de fato. Na Shopify isso já se tornou obrigatório, e a Microsoft se gaba de que 1/3 do software foi escrito dessa forma. Se não haverá empregos de engenharia no futuro, também fica a dúvida de quem vai dedicar tempo para aprender
    • Minha recomendação para juniores é a mesma há 10 anos. Leia um livro sobre bancos de dados SQL em um fim de semana e, no fim de semana seguinte, leia um livro sobre o banco de dados usado no projeto atual. Aí é bem provável que você vire o especialista em banco de dados desse projeto
    • Alguns anos atrás tivemos uma situação parecida, e mudamos um produto que hoje tem US$ 1 bilhão de receita de Read Committed para Read Committed Snapshot, com uma grande melhora de desempenho
      Porém, um cuidado nessa transição é que todo código que depende de leituras bloqueantes quebra. Por exemplo, código como select with exists precisa ser reescrito com locks explícitos ou por outros meios
  • Em uma empresa anterior, quando alteramos o comando pg_dump dos scripts de backup para começar a usar workers paralelos (flag -j), raramente víamos, durante a restauração, erros que sugeriam inconsistência, como erros de chave duplicada e erros de restrição de chave estrangeira
    Na época tentei reportar isso à AWS e à lista de e-mails do PostgreSQL, mas não consegui reproduzir facilmente, então não houve progresso; no fim, desistimos e voltamos para dumps de thread única. Fico curioso se o fenômeno que vi naquela época tem relação com este problema

    • Fico curioso se era uma instância única, uma instância com standby em outra zona de disponibilidade, ou o cluster multi-AZ testado aqui
  • Lendo este texto, parece que o impacto real é que dados obsoletos podem ser retornados quando uma leitura acontece rapidamente logo após uma escrita na mesma linha. A transação de escrita é marcada como concluída, mas antes que toda a camada distribuída da instância RDS multi-AZ esteja totalmente atualizada; se a mesma linha for lida imediatamente, a linha pode ainda não existir ou a coluna pode não estar totalmente atualizada, retornando o valor anterior
    Pelo modelo de snapshots do PostgreSQL, não parece significar que apenas alguns bytes de uma coluna multibyte sejam atualizados e se leia um valor sem sentido
    No fim, parece uma condição de corrida que converge com o tempo. Ou será que alguém leu isso como significando que transações posteriores do “long fork” podem nunca ser concluídas, mesmo em condições normais?

    • Isso não é apenas dado obsoleto no sentido de “um snapshot consistente de um determinado ponto no tempo que não reflete algumas transações recentes”. Aqui parece ser uma situação em que uma transação somente leitura em um nó secundário observa uma transação T, mas pode deixar de ver transações que, logicamente, deveriam ter sido executadas antes de T
  • A frase “este trabalho foi realizado de forma independente pela Jepsen, sem remuneração” não é algo que um stakeholder de RDBMS queira ver nem em um dia bom. Imagino que alguns e-mails preocupados tenham circulado internamente. Como sempre, respeito ao aphyr

    • Quem seria “stakeholder de RDBMS”?
    • Se eu estivesse do lado que recebe, acho que ficaria até feliz. Tradicionalmente, ninguém passa ileso pela Jepsen, mas receber atenção do Aphyr significa que o caso está sendo tratado com seriedade
  • Não está totalmente claro se isso não é um problema em clusters PostgreSQL upstream com múltiplas instâncias. Fico curioso se é correto entender que a AWS faz algo na configuração do cluster, ou adicionou um patch que provoca esse comportamento

    • Boa pergunta. Ainda não entendo a arquitetura de replicação da AWS o suficiente para reimplementá-la com PostgreSQL padrão. Em PostgreSQL de nó único, esse comportamento parece não ocorrer, mas pode ocorrer em algumas configurações de replicação
      Em geral, há várias formas de replicação no PostgreSQL, com resultados diferentes. Por exemplo, há o relatório de Bin Wang sobre Patroni: https://www.binwang.me/2024-12-02-PostgreSQL-High-Availabili...
    • Não é um problema em um cluster PostgreSQL de instância única. Mas um cluster PostgreSQL de múltiplas instâncias composto por um único nó primário e réplicas por streaming/físicas é afetado
      O que também foi observado aqui é que o PostgreSQL atualmente não fornece um comportamento de snapshot consistente entre o nó primário e as réplicas. Provavelmente a transação somente leitura T2 foi executada em um nó secundário, enquanto as transações de alteração T1/T3/T4 foram executadas no nó primário
      Como contexto, o snapshot de um nó PostgreSQL secundário, ao decidir quais transações são visíveis, depende da ordem de persistência das transações, ou seja, da posição dos registros de commit no WAL. Já no nó primário, a ordem de visibilidade é determinada pelo momento em que o backend que aprovou aquela transação recebe pela primeira vez a notificação de que a transação foi totalmente commitada e, depois disso, pelo momento em que marca o commit
      Dentro do nó primário e dentro do nó secundário, a ordem de commit entre os backends conectados é consistente, mas a ordem de commit entre primário e secundário pode diferir um pouco. Há trabalho em andamento para melhorar isso, mas ainda está em uma fase muito ativa
    • Depende do que se quer dizer com “cluster PostgreSQL upstream multi-instância”. O PostgreSQL não oferece suporte oficial a failover de instância primária; ele só tem mecanismos de replicação PostgreSQL que podem ser sincronizados. É possível criar suas próprias ferramentas ao redor disso para montar um cluster, e o Patroni é uma dessas ferramentas
      A AWS parece ter aplicado patches ao PostgreSQL para replicar em duas instâncias e considerar suficiente quando uma delas confirma a alteração. Quando exatamente essa confirmação ocorre não é informação pública
      Pessoalmente, acho que para PostgreSQL é melhor uma replicação em nível de sistema de arquivos, como drbd. As instâncias AWS Multi-AZ do estilo antigo provavelmente usavam esse método. Porém, isso reduz a vazão e não permite leitura na instância secundária
    • Sim, é diferente. Há um vídeo aqui explicando mais a fundo o que fizeram: https://youtu.be/fLqJXTOhUg4
      Em especial este ponto: https://youtu.be/fLqJXTOhUg4?t=434
  • O título enviado pergunta pelo ponto central. RDS for PostgreSQL 17.4 não implementa corretamente o isolamento por snapshot

    • É preciso um pouco de contexto, porque o pessoal do HN frequentemente reclama dos títulos dos relatórios da Jepsen. Os relatórios da Jepsen geralmente são produto de uma longa colaboração com o cliente, e os clientes muitas vezes têm opiniões fortes sobre o título do relatório
      As discussões podem ficar bem intensas: se o título é duro demais com o sistema, favorável demais, se captura o mais significativo entre a dúzia de problemas encontrados, se é justo segundo o critério da Jepsen de tentar ser uma intermediária honesta dos resultados de segurança de bancos de dados, e como será interpretado daqui a 10 anos, quando as pessoas continuarem linkando, mas ele já não se aplicar mais às versões recentes
      Depois de algumas tentativas frustrantes, evitamos esse problema adotando a política de colocar todos os títulos de relatório no formato “Jepsen: ”. Se o HN quiser um texto de link mais explicativo ou mais colorido, claro, pode escolher por conta própria
    • Este comentário também deixa de fora o ponto central: isso acontece em clusters multi-AZ
      Ainda assim, isto foi escrito por Kyle Kingsbury, o Chuck Norris das garantias transacionais, então a AWS precisa responder ou esclarecer. Mesmo que pareça se aplicar apenas a uma das duas opções do RDS para PostgreSQL, o cluster multi-AZ. Implantações Multi-AZ podem ter uma ou duas instâncias de banco de dados em standby; aqui se trata da configuração com duas instâncias de banco de dados em standby
      A documentação da AWS não faz essa promessa. O manual de 5.494 páginas do RDS também quase só menciona isolation ou serializable na documentação de parâmetros de cada engine
      Também não há nada sobre consistência global de leitura em clusters Multi-AZ. Dizem que, por ser replicação semissíncrona, o writer espera a confirmação dos registros de log de um standby, mas dois readers podem estar em snapshots diferentes
      [1] - "New Amazon RDS for MySQL & PostgreSQL Multi-AZ Deployment Option: Improved Write Performance & Faster Failover" - https://aws.amazon.com/blogs/aws/amazon-rds-multi-az-db-clus...
      [2] - "Amazon RDS Multi-AZ with two readable standbys: Under the hood" - https://aws.amazon.com/blogs/database/amazon-rds-multi-az-wi...
    • Enviei um e-mail aos moderadores pedindo para mudarem para a frase copiada exatamente do artigo linkado: “Amazon RDS for PostgreSQL multi-AZ clusters violate Snapshot Isolation”
  • O desenvolvedor assumiu isolamento por snapshot, mas se o Amazon RDS for PostgreSQL na prática oferece apenas isolamento por snapshot paralelo, fico curioso sobre quais bugs de segurança ou bugs em nível de aplicação podem surgir, especialmente em configurações multi-AZ que usam endpoints de réplica de leitura

    • Dá para pensar em um fluxo como git push. Você inicia uma transação, lê o estado atual, verifica se ele corresponde ao estado esperado, grava o novo estado e faz o commit junto com o hash do novo estado. Em uma situação azarada, pode surgir um hash de commit que não corresponde a nenhum estado válido
      O próprio fato de ser difícil raciocinar sobre isso torna difícil evitar o problema. Por isso, a solução mais simples, para escritas condicionadas a leituras, provavelmente seria algo como “talvez seja possível recuperar o isolamento por snapshot usando apenas o endpoint do writer”
      Dito isso, é surpreendente que a abordagem de “usar apenas o endpoint do writer” não tenha sido testada, especialmente em situações de perda de disponibilidade
    • Dá para pensar na situação de deixar um comentário abaixo de um post. Suponha que seja preciso dar um “first commenter badge” ao primeiro usuário que comentar
      O User1 comenta, depois o User2 comenta, e então o User1, em uma transação separada, verifica que há apenas 1 comentário e recebe o badge. O User2 também faz a mesma verificação em uma transação separada e, vendo apenas seu próprio 1 comentário, pode receber o badge
      Com isolamento por snapshot, isso é impossível. Pelo menos uma das transações separadas teria que ver 2 comentários
      O artigo original sobre snapshots paralelos também vale a leitura: https://scispace.com/pdf/transactional-storage-for-geo-repli...
  • Ao ver a frase “esse fenômeno ocorreu em todas as versões testadas, da 13.15 à 17.4”, fiquei preocupado se atualizar a versão major teria sido uma escolha errada, mas parece que não é o caso. Isso parece mais uma solicitação de recurso ou um bug antigo do que uma regressão