2P by GN⁺ | ★ favorite | 댓글 1개
  • Jepsen 테스트에서 Amazon RDS for PostgreSQL Multi-AZ 클러스터가 전체 노드 기준 최강 격리 수준인 Snapshot Isolation을 지키지 않는 사례가 확인됨
  • 핵심 원인은 primary의 트랜잭션 표시 순서가 메모리 내 락으로 정해지는 반면, secondary는 WAL 순서를 따르면서 두 순서가 어긋날 수 있다는 점임
  • 장애 주입이나 failover 없이 gp3 스토리지와 db.m6id.large 인스턴스를 사용한 조건에서도 약 150 write TPS / 1600 read-only TPS에서 몇 분마다 G-nonadjacent cycle이 나타남
  • 이상 현상은 Long Fork에 해당하며, AWS가 지원한 PostgreSQL 13.15부터 17.4까지 테스트한 모든 버전에서 나타났고 Short Fork/Write Skew는 관찰되지 않음
  • 안전이 중요한 트랜잭션은 read-only secondary 사용 시 실행 순서를 다르게 볼 수 있어, writer endpoint만 쓰거나 최소 1개 write를 포함하는 방식의 검토가 필요함

Long Fork 원인 업데이트

  • AWS의 Sergey Melnik과 HN 댓글 참여자인 matashii, Ants Aasma가 PostgreSQL 클러스터의 Long Fork 원인을 식별함
  • PostgreSQL primary는 트랜잭션을 보이게 하는 순서를 메모리 내 락으로 결정함
  • secondary는 트랜잭션을 Write-Ahead Log(WAL) 안의 순서에 따라 보이게 함
  • 락 순서와 WAL 순서가 달라지면 primary와 secondary가 트랜잭션의 겉보기 순서를 다르게 볼 수 있음
  • 이 동작은 2013년 PostgreSQL 메일링리스트 글에서 다뤄졌고, Melnik은 AWS 블로그에 PostgreSQL 클러스터와 read replica의 transaction visibility를 설명하는 글을 작성함
  • Jepsen은 AWS와 PostgreSQL이 수정 작업과 함께 이 이슈를 문서화하기를 권장함

RDS for PostgreSQL의 격리 수준과 구조

  • PostgreSQL은 범용 오픈소스 SQL 데이터베이스이며, MVCC로 세 가지 트랜잭션 격리 수준을 제공함
    • Read UncommittedRead Committed는 모두 Read Committed로 동작함
    • Repeatable Read는 실제로 Repeatable Read가 아니라 Snapshot Isolation을 제공함
    • SerializableSerializability를 제공함
  • Amazon RDS for PostgreSQL은 관리형 PostgreSQL 클러스터를 제공하는 AWS 서비스임
    • 프로비저닝, 스토리지 관리, 복제, 백업, 업그레이드 등을 자동화함
    • Multi-AZ deployments는 데이터베이스 노드를 여러 가용 영역에 분산해 상관 장애 가능성을 줄임
    • RDS는 primary와 최소 1개 secondary 인스턴스 모두에서 트랜잭션 내구성이 확보된 뒤 응답하도록 동기 복제를 사용함
  • 사용자에게는 PostgreSQL wire protocol을 말하는 두 URL이 제공됨
    • primary endpoint: read-write 트랜잭션용
    • reader endpoint: read-only 트랜잭션용
  • primary endpoint는 모든 PostgreSQL 격리 수준을 지원하지만, secondary는 Serializable을 지원하지 않음
  • 전체 노드에서 쓸 수 있는 최강 격리 수준은 PostgreSQL이 Repeatable Read라고 부르는 Snapshot Isolation

테스트 설계

  • Jepsen은 PostgreSQL용 테스트 라이브러리를 Amazon RDS for PostgreSQL에 맞게 조정하고, 작은 wrapper program을 사용함
  • 각 테스트 라운드마다 AWS의 CreateDBCluster API로 RDS 클러스터를 프로비저닝함
    • 스토리지는 gp3
    • 인스턴스는 db.m6id.large
  • 테스트 실행용 EC2 노드 1개를 띄우고 RDS 클러스터의 main endpoint와 read-only endpoint를 제공함
  • 장애 주입은 하지 않았고 failover도 트리거하지 않음
  • 주 workload는 고유 정수 리스트를 다루는 트랜잭션으로 구성됨
    • 각 리스트는 단일 row에 저장되고, 쉼표로 구분된 값을 담은 TEXT 필드로 인코딩됨
    • 트랜잭션은 primary key로 리스트를 읽거나 CONCAT으로 고유 정수를 리스트에 append함
  • 이 workload를 통해 Elle checker가 트랜잭션 간 데이터 흐름 의존성을 추론하고 그래프 cycle을 찾아 여러 격리 수준을 검증할 수 있음

G-nonadjacent cycle 관찰

  • 정상 조건과 중간 수준의 동시성에서도 Amazon RDS for PostgreSQL 17.4는 몇 분마다 G-nonadjacent cycle을 보임
  • 2분 테스트 실행은 약 150 write TPS와 1600 read-only TPS를 수행했고, 4개 트랜잭션 cycle을 포함함
  • 예시 cycle은 네 트랜잭션 T1, T2, T3, T4로 구성됨
    • T1은 row 89에 9를 append해 리스트 [4 9]를 만들었고, T2가 이를 관찰함
    • T3는 row 90에 11을 append해 리스트 [11]을 만듦
    • T4는 row 90에 3을 append하고 결과 리스트 [11, 3]을 읽어 T3의 version을 덮어씀
    • T2는 row 89에서 T1의 append를 관찰했지만 row 90에서 T3의 append는 보지 못함
    • 반대로 T4는 row 90에서 T3의 append를 관찰했지만 row 89에서 T1의 append는 놓침
  • 이 cycle은 서로 인접하지 않은 read-write dependency를 포함하므로 Snapshot Isolation 위반인 G-nonadjacent cycle임
  • 표준 PostgreSQL의 Repeatable Read에서는 이런 동작이 발생해서는 안 되며, Jepsen은 표준 PostgreSQL에서 이를 관찰하지 못함

Snapshot Isolation과 충돌하는 이유

  • Snapshot Isolation에서는 모든 트랜잭션이 시작 timestamp s 시점의 데이터베이스 snapshot 위에서 동작하는 것처럼 보여야 함
  • 트랜잭션의 효과는 이후 commit timestamp c에 다른 트랜잭션에 보이게 됨
  • 예시 cycle의 관찰 결과를 timestamp 관계로 쓰면 서로 모순됨
    • T2T1의 append를 읽었으므로 T2의 시작은 T1의 commit 뒤여야 함: c1 < s2
    • T2T3의 append를 관찰하지 못했으므로 s2 < c3
    • T4T3를 덮어쓰고 관찰했으므로 c3 < s4
    • T4T1의 append를 관찰하지 못했으므로 s4 < c1
  • 이 관계들은 모두 동시에 성립할 수 없어 Snapshot Isolation의 timestamp 모델과 충돌함

Long Fork와 버전별 결과

  • 해당 cycle은 Long Fork의 예시이기도 함
    • 첫 번째와 두 번째 트랜잭션은 하나의 논리적 상태 fork를 구성함
    • 세 번째와 네 번째 트랜잭션은 두 번째 fork를 구성함
    • 두 fork는 서로 다른 row를 갱신하지만 서로의 효과를 관찰하지 못함
  • Short Fork, 즉 Write Skew는 관찰되지 않음
  • 이 결과는 Amazon RDS for PostgreSQL이 Snapshot Isolation보다 약간 약한 Parallel Snapshot Isolation을 제공할 가능성을 시사함
  • G-nonadjacent 이상 현상은 write-read edge만으로 연결된 경우와 4개를 넘는 트랜잭션을 포함한 경우까지 다양하게 나타남
  • AWS가 지원한 가장 오래된 버전인 PostgreSQL 13.15부터 최신 버전인 17.4까지 테스트한 모든 버전에서 같은 종류의 이상 현상이 발생함

사용자가 점검할 부분

  • Long Fork와 다른 G-nonadjacent cycle이 존재하므로 Amazon RDS for PostgreSQL Multi-AZ 클러스터는 Snapshot Isolation을 보장하지 않음
  • 이 점에서 RDS for PostgreSQL Multi-AZ 클러스터는 이전 Jepsen 테스트에서 Strong Snapshot Isolation을 제공하는 것으로 보였던 단일 노드 PostgreSQL보다 약한 안전성 의미론을 제공함
  • 사용자는 트랜잭션 구조가 Long Fork에 취약한지 살펴보거나, 의도한 불변 조건이 유지되는지 실험으로 검증할 수 있음
  • read 트랜잭션은 트랜잭션 실행 순서에 대해 다른 트랜잭션과 서로 다른 결과를 볼 수 있음
  • 이상 현상은 read-only secondary에 대한 쿼리와 관련된 것으로 보이므로, 다음 방식으로 Snapshot Isolation을 회복할 가능성이 있음
    • writer endpoint만 사용

      • 안전이 중요한 모든 트랜잭션에 최소 1개 write 포함
      • Jepsen의 검증은 실험적 접근이며, 버그의 존재는 증명할 수 있지만 부재는 증명할 수 없음
      • 이 보고서는 RDS for PostgreSQL 동작을 자세히 조사한 결과가 아니라 예비적 탐색의 산물임

댓글과 토론

Hacker News 의견들
  • 소프트웨어 세계의 글도 더 자주 이런 식이면 좋겠음: “Amazon RDS for PostgreSQL은 PostgreSQL 데이터베이스의 관리형 인스턴스를 제공하는 Amazon Web Services(AWS) 서비스다. Amazon RDS for PostgreSQL multi-AZ 클러스터가 모든 엔드포인트에서 지원되는 가장 강한 일관성 모델인 스냅샷 격리를 위반한다는 것을 보인다…”
    직접적이고, 핵심만 있고, 꾸밈이 없어서 다른 STEM 분야의 연구 결과 공유 방식과 비슷함. 한때는 밈으로 설명하는 재치 있는 블로그 글을 좋아했지만, 이제는 plain하고 단순한 글이 그리움

    • 예전에 있던 회사에는 누구나 글을 쓰고 댓글을 달 수 있는 사내 블로그가 있었고, 의무도 아니며 평가에도 전혀 반영되지 않았음. 해커톤 결과물 같았는데, 기술 글쓰기를 좋아해서 꽤 즐겼음
      아주 깊은 기술 글을 쓰면 좋아요와 댓글이 거의 없었고, Staff Engineer가 “대상을 더 좁게 잡는 게 좋겠다”고 말할 정도였음. 반대로 초기 Kubecost를 테스트하면서 권장사항이 비용 절감도 작고 컨테이너 성능 문제를 만들 수 있다는 글을 썼는데, CPU throttling과 cgroups를 다루는 꽤 기술적인 글이었음에도 을 넣자 사람들이 엄청 좋아했음
      나중에 C로 작은 Python 외부 라이브러리를 만들고 ctypes로 접근하며 스택/힙 할당을 비교하는 더 건조한 글에도 밈을 넣었더니 비슷한 결과가 나왔음. 이런 흐름은 마음에 안 들지만, 넓은 독자에게 도달하려면 달리 피할 방법도 잘 모르겠음. Jensen은 그런 독자를 겨냥하지 않았고, 엄밀하고 순수한 글쓰기는 박수받을 만함
    • 밈이 잔뜩 들어간 블로그 글은 이제 정말 읽기 싫음. 특히 한 문단짜리 내용을 억지로 늘리는 경우가 너무 많고, 요즘은 보안 취약점 글이 그 최악인 편임
    • 예전 Jepsen이 그리웠다는 생각을 막 하고 있었음. 같은 식으로 사실 위주이고 직접적이면서도 밈이 가득했음. 예전 Redis 글 https://aphyr.com/posts/283-call-me-maybe-redis가 좋은 예임
    • Amazon은 기술 글쓰기 문화가 건강한 것으로 알려져 있고, 직접 보아도 그랬음. 이 생각은 회사가 아니라 개인 의견임. 관련 공개 글도 있음: https://quartr.com/insights/business-philosophy/amazon-s-wri...
  • 제목에도 없고 글에서도 아주 명확하진 않은데, 이 문제는 RDS의 비교적 새로운 기능인 multi-AZ 클러스터에 한정됨. 많은 사람이 익숙한 multi-AZ 인스턴스와는 다름
    multi-AZ 인스턴스는 기본 DB가 다른 가용 영역의 보조 DB에 동기 복제되고, 기본이 실패하면 RDS가 보조로 장애 조치하는 오래된 기능임
    multi-AZ 클러스터는 보조가 두 개이고 트랜잭션이 그중 최소 하나에 동기 복제됨. 보조 하나가 실패하거나 성능이 떨어질 때 multi-AZ 인스턴스보다 더 견고하고, 보조에 대한 읽기 전용 접근도 가능함
    다만 multi-AZ 클러스터는 내부에 PostgreSQL 기본 기능이 아닌 추가 마법이 더 있을 것이고, 아마 그래서 Jepsen 테스트에서 실패한 듯함

    • 왜 이런 마법이 필요한지 흥미로움. 기본 PostgreSQL도 쿼럼 커밋을 지원해서 이런 구성이 가능함. Patroni로도 동등한 multi-AZ 클러스터를 만들 수 있고, 버그를 제외하면 트랜잭션을 잃거나 durable하지 않은 트랜잭션을 보이게 하지 않도록 기본 승격을 조정함
      다만 PostgreSQL에는 이 패턴과 비슷한 문제를 가능하게 하는 결함이 아직 있음. 클라이언트가 커밋 도중 사라지는 비복제 트랜잭션은 즉시 보이게 됨. 예시에서 T1이 분리된 리더에서 일어나고 커밋 중 연결이 끊기며, T2도 분리된 노드에서 일어나고 T3/T4가 나중에 새 리더에서 일어나면 같은 결과를 볼 수 있음. 하지만 이 테스트에서 fault injection을 하지 않았다는 설명과는 잘 맞지 않음
      수정: 복제본과 기본 노드의 커밋 순서 불일치로 이 패턴이 설명된다는 글을 못 봤음. 이 문제를 고치는 방법을 발표한 적이 있어서 좀 민망함
    • multi-AZ 인스턴스 안에서 스냅샷 위반이 발생한다면, 단일 리전에서 여러 읽기 복제본을 둔 구성에서도 발생할 수 있는지 궁금함. 다만 multi-AZ 구성에서는 지연이 커서 더 쉽게 관측되는 것일 수도 있음
    • 글의 두 번째 문장에 바로 나옴: “Amazon RDS for PostgreSQL multi-AZ clusters violate Snapshot Isolation”. 사람들이 읽을 거라고 기대해야 함
  • 좋은 조사임. 요즘 소프트웨어 개발자는 트랜잭션 자체도 잘 모르는 경우가 많고, 다양한 트랜잭션 모델은 더더욱 모르는 편임. 심지어 “시니어 개발자”라고 불리는 CRUD 개발자 중에도 데이터베이스 트랜잭션을 전혀 모르는 사람을 봤음
    실제로 트래픽 규모가 있고 소프트웨어가 사소하지 않은 문제를 풀 때는 트랜잭션과 트랜잭션 모델이 성능과 오류 없는 코드에 매우 중요함
    예를 들어 큰 프로젝트에서 많은 분석 끝에 SQL Server의 기본 Read Committed에서 Read Committed Snapshot Isolation으로 바꿨고, 락 경합이 크게 사라져 사용자들이 매우 만족했음. 그 프로젝트의 소프트웨어 엔지니어들은 트랜잭션을 많이 쓰고 있었지만, 기본을 가르치기 전까지 트랜잭션 모델이나 락을 전혀 몰랐음

    • 이건 시니어 개발자에게만 국한되지 않음. 격리 수준을 모르는 시스템 아키텍트도 봤고, 어떤 사람들은 ACID의 “일관성”과 CAP의 “일관성”을 혼동하기도 했음
      주로 리테일 분야에서 일하다 보니 경쟁 조건과 비슷한 오류로 가득한 시스템을 자주 보는데, 이런 격리 수준이 큰 도움이 될 수 있는 부분이라 더 아쉬움
      다만 이런 경우는 주로 스타트업 엔지니어에게서 보였고, 대기업의 전형적인 Oracle/MSSQL 개발자들은 적어도 기본기는 맞아서 꽤 높게 평가함
    • 트랜잭션 인식 부족은 주로 서버리스/엣지 환경에서 많이 봤음. 백엔드 아키텍처라고 부를 수 있다면, 그것이 전적으로 클라이언트 요구에 의해 움직이는 곳들임. 예를 들어 데이터베이스 쿼리가 React hook이나 순차 API 호출로 모델링됨
      커리어 중 몇 번은 이 방식이 정말 나쁜 결과를 내는 걸 봤음
    • 곧 대부분의 소프트웨어 개발자는 실제로 무슨 일이 일어나는지도 모른 채 LLM 쓰레기를 코드로 옮겨 적게 될 것임. 이미 Shopify에서는 필수가 되었고, Microsoft는 소프트웨어의 1/3이 이런 방식으로 작성됐다고 자랑함. 앞으로 엔지니어링 일자리가 없을 거라면 누가 시간을 들여 배울지도 의문임
    • 주니어에게 하는 추천은 10년째 그대로임. 주말에 SQL 데이터베이스 책 한 권을 읽고, 다음 주말에는 현재 프로젝트에서 쓰는 데이터베이스 책 한 권을 읽으면 됨. 그러면 그 프로젝트의 데이터베이스 전문가가 될 가능성이 큼
    • 몇 년 전 비슷한 상황이 있었고, 지금은 매출 10억 달러 규모인 제품을 Read Committed에서 Read Committed Snapshot으로 바꿔 성능이 크게 좋아졌음
      다만 이 전환 시 주의할 점은, 블로킹 읽기에 의존하는 모든 코드가 깨진다는 것임. 예를 들어 select with exists 같은 코드는 명시적 락이나 다른 방법으로 다시 작성해야 함
  • 예전 회사에서 백업 스크립트의 pg_dump 명령을 바꿔 병렬 작업자(-j 플래그)를 쓰기 시작했을 때, 복원 중 중복 키 오류와 외래 키 제약 오류처럼 불일치를 암시하는 오류가 드물게 보였음
    당시 AWS와 PostgreSQL 메일링 리스트에 보고하려 했지만 쉽게 재현할 수 없어 진전이 없었고, 결국 포기하고 단일 스레드 덤프로 돌아갔음. 그때 본 현상이 이 문제와 관련 있는지 궁금함

    • 단일 인스턴스였는지, 다른 가용 영역에 대기 인스턴스가 있는 한 인스턴스였는지, 아니면 여기서 테스트한 multi-AZ 클러스터였는지 궁금함
  • 이 글을 읽어보면 실제 영향은 같은 행에 쓰기 직후 빠르게 읽기가 일어날 때 오래된 데이터가 반환될 수 있다는 것 같음. 쓰기 트랜잭션이 완료로 표시되지만 multi-AZ RDS 인스턴스의 분산 계층 전체가 완전히 갱신되기 전이라, 같은 행을 즉시 읽으면 행이 아직 없거나 열이 완전히 갱신되지 않아 이전 값이 나올 수 있음
    PostgreSQL의 스냅샷 방식상, 다중 바이트 열 타입의 일부 바이트만 갱신되어 말도 안 되는 값을 읽는다는 뜻은 아닌 것으로 보임
    결국 시간이 지나면 수렴하는 경쟁 조건처럼 보임. 아니면 “long fork”의 나중 트랜잭션들이 정상 상황에서도 영원히 완료되지 않을 수 있다는 뜻으로 읽은 사람이 있는지 궁금함

    • 이건 “최근 트랜잭션 일부를 반영하지 않은 특정 시점의 일관된 스냅샷”이라는 의미의 오래된 데이터만은 아님. 여기서는 보조 노드에 대한 읽기 전용 트랜잭션이 어떤 트랜잭션 T는 관측하면서도, 논리적으로 T보다 먼저 실행됐어야 하는 트랜잭션들을 놓칠 수 있는 상황으로 보임
  • “이 작업은 보상 없이 Jepsen이 독립적으로 수행했다”는 문구는 RDBMS 이해관계자가 좋은 날에도 보고 싶지 않은 내용임. 내부적으로 우려를 담은 이메일이 몇 통 오갔을 듯함. 언제나처럼 aphyr에게 경의를 표함

    • “RDBMS 이해관계자”가 누구를 말하는 거임?
    • 받는 쪽이라면 오히려 기뻐해야 한다고 봄. 전통적으로 Jepsen을 무사히 통과하는 곳은 없지만, Aphyr에게 받는다는 건 진지하게 다뤄지고 있다는 뜻임
  • 이게 multi-instance upstream PostgreSQL 클러스터에서는 문제가 아닌지 완전히 명확하지 않음. AWS가 클러스터 설정에서 뭔가를 하거나, 이 동작을 유발하는 패치를 추가했다고 이해하면 맞는지 궁금함

    • 좋은 질문임. 아직 AWS의 복제 아키텍처를 표준 PostgreSQL로 재구현할 만큼 충분히 이해하지 못함. 단일 노드 PostgreSQL에서는 이 동작이 발생하지 않는 것으로 보이지만, 일부 복제 구성에서는 발생할 수 있음
      PostgreSQL 복제에는 일반적으로 다양한 방식이 있고 결과도 달라짐. 예를 들어 Bin Wang의 Patroni 보고서가 있음: https://www.binwang.me/2024-12-02-PostgreSQL-High-Availabili...
    • 단일 인스턴스 PostgreSQL 클러스터에서는 문제가 아님. 하지만 단일 기본 노드와 스트리밍/물리 복제본으로 구성된 다중 인스턴스 PostgreSQL 클러스터는 영향을 받음
      여기서도 발견한 것은 PostgreSQL이 현재 기본 노드와 복제본 사이에서 일관된 스냅샷 동작을 제공하지 않는다는 점임. 아마 읽기 전용 트랜잭션 T2는 보조 노드에서 실행됐고, 변경 트랜잭션 T1/T3/T4는 기본 노드에서 실행됐을 것임
      배경을 보면, 보조 PostgreSQL 노드의 스냅샷은 어떤 트랜잭션이 보이는지를 정할 때 트랜잭션 지속 순서, 즉 WAL의 커밋 레코드 위치에 의존함. 반면 기본 노드의 가시성 순서는 해당 트랜잭션을 승인한 백엔드가 트랜잭션이 완전히 커밋됐다는 알림을 처음 받은 시점과 그 뒤 커밋 표시를 하는 시점에 의해 결정됨
      기본 노드와 보조 노드 각각에서는 연결된 백엔드 사이의 커밋 순서가 일관되지만, 기본과 보조 사이의 커밋 순서는 다소 달라질 수 있음. 이를 개선하는 작업이 진행 중이지만 아직 매우 진행 중인 단계임
    • “multi instance upstream PostgreSQL 클러스터”가 무엇을 뜻하는지에 달려 있음. PostgreSQL은 기본 인스턴스 장애 조치를 공식 지원하지 않고, 동기화할 수 있는 PostgreSQL 복제 메커니즘만 있음. 그 주변에 직접 도구를 만들어 클러스터를 구성할 수 있고, Patroni가 그런 도구 중 하나임
      AWS는 PostgreSQL을 패치해서 두 인스턴스로 복제하고, 둘 중 하나가 변경을 확인하면 충분하다고 처리하는 듯함. 이 확인이 언제 일어나는지는 공개 정보가 아님
      개인적으로는 PostgreSQL에는 drbd 같은 파일시스템 수준 복제가 더 낫다고 봄. 예전 방식의 AWS Multi-AZ 인스턴스가 아마 이 방식일 것임. 다만 처리량이 낮아지고 보조 인스턴스에서 읽을 수 없음
    • 맞음, 다름. 무엇을 했는지 더 깊게 설명한 영상은 여기 있음: https://youtu.be/fLqJXTOhUg4
      특히 이 지점: https://youtu.be/fLqJXTOhUg4?t=434
  • 제출된 제목은 핵심을 묻고 있음. RDS for PostgreSQL 17.4는 스냅샷 격리를 제대로 구현하지 않음

    • Jepsen 보고서 제목에 HN 사람들이 자주 불만을 갖기 때문에 약간의 맥락이 필요함. Jepsen 보고서는 대개 클라이언트와 긴 협업의 산물이고, 클라이언트는 보고서 제목에 대해 강한 의견을 갖는 경우가 많음
      제목이 시스템에 너무 가혹한지, 너무 우호적인지, 발견한 열몇 개 문제 중 가장 의미 있는 것을 담는지, Jepsen이 데이터베이스 안전성 결과의 정직한 중개자가 되려는 기준에서 공정한지, 10년 뒤 사람들이 계속 링크하지만 최근 버전에는 더 이상 해당하지 않을 때 어떻게 해석될지 같은 논의가 꽤 격렬해질 수 있음
      몇 번의 답답한 시도 끝에 모든 보고서 제목을 “Jepsen: ” 형태로 붙이는 정책으로 이 문제를 피하고 있음. HN이 더 설명적이거나 더 다채로운 링크 텍스트를 원한다면 물론 직접 고르면 됨
    • 이 코멘트도 핵심이 빠졌음. multi-AZ 클러스터에서 그렇다는 것임
      그래도 이건 트랜잭션 보장의 Chuck Norris 같은 Kyle Kingsbury가 쓴 것이니, AWS는 답하거나 해명해야 함. PostgreSQL용 RDS의 두 선택지 중 하나인 multi-AZ 클러스터에만 적용되는 것으로 보여도 마찬가지임. Multi-AZ 배포는 대기 DB 인스턴스가 하나이거나 두 개일 수 있고, 여기서는 두 개의 대기 DB 인스턴스 구성에 관한 것임
      AWS 문서에는 그런 약속이 없음. RDS의 5494쪽짜리 매뉴얼도 각 엔진의 매개변수 문서에서 isolation이나 serializable을 거의 언급할 뿐임
      Multi-AZ 클러스터의 전역 읽기 일관성에 대해서도 없음. 반동기 복제라 writer가 한 standby의 로그 레코드 확인을 기다린다고는 하지만, 두 reader가 서로 다른 스냅샷 위에 있을 수 있음
      [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...
    • 모더레이터에게 이메일을 보내 링크 글에서 그대로 복사한 문구로 바꿔 달라고 요청했음: “Amazon RDS for PostgreSQL multi-AZ clusters violate Snapshot Isolation”
  • 개발자가 스냅샷 격리를 가정했는데 Amazon RDS for PostgreSQL이 실제로는 병렬 스냅샷 격리만 제공한다면, 특히 읽기 복제본 엔드포인트를 쓰는 multi-AZ 구성에서 어떤 안전성 버그나 애플리케이션 수준 버그가 생길 수 있는지 궁금함

    • git push 같은 흐름을 생각해 보면 됨. 트랜잭션을 시작하고 현재 상태를 읽은 뒤 기대한 상태와 맞는지 확인하고, 새 상태를 쓰고, 새 상태 해시와 함께 커밋함. 불운한 상황에서는 어떤 유효한 상태와도 맞지 않는 커밋 해시가 생길 수 있음
      이런 걸 추론하기 어렵다는 사실 자체가 문제를 피하기 어렵게 만듦. 그래서 가장 쉬운 해결책은, 읽기에 조건부인 쓰기라면 “writer 엔드포인트만 사용하면 스냅샷 격리를 회복할 수 있을지도 모른다”에 가까울 것임
      다만 “writer 엔드포인트만 사용”하는 방법이 특히 가용성 손실 상황에서 테스트되지 않은 점은 의외임
    • 게시물 아래에 댓글을 남기는 상황을 생각해 보면 됨. 첫 번째로 댓글을 단 사용자에게 “first commenter badge”를 줘야 한다고 하자
      User1이 댓글을 달고, User2가 댓글을 단 다음, User1이 별도 트랜잭션에서 댓글이 1개뿐이라고 확인해 배지를 받음. User2도 별도 트랜잭션에서 같은 확인을 하고 자기 댓글 1개만 보여 배지를 받을 수 있음
      스냅샷 격리에서는 이게 불가능함. 별도 트랜잭션 중 적어도 하나는 댓글 2개를 봐야 함
      병렬 스냅샷에 관한 원 논문도 읽을 만함: https://scispace.com/pdf/transactional-storage-for-geo-repli...
  • “이 현상은 테스트한 모든 버전, 13.15부터 17.4까지 발생했다”는 문장을 보고, 메이저 버전을 올린 게 잘못된 선택이었나 걱정했는데 그건 아닌 듯함. 이건 회귀가 아니라 기능 요청이거나 오래된 버그에 가까움