분산 트랜잭션 관리 방법(1) : Two-phase Commit

김현지·2024년 9월 12일
post-thumbnail

Microservice Architecture에서는 각 마이크로 서비스가 독립적인 데이터베이스를 가진다. 트랜잭션이 발생하면 마이크로 서비스들이 서로 통신하며 여러 데이터베이스에 트랜잭션이 발생하는데, 이렇게 분산 환경에서 여러 시스템에 걸쳐있는 트랜잭션을 분산 트랜잭션이라고 한다. 분산 트랜잭션 또한 일반적인 트랜잭션처럼 ACID 속성을 가져야한다. 분산 트랜잭션을 관리하는 방법에 대해 알아보자.

Two-phase Commit(2PC)

Two-phase Commit, 줄여서 2PC는 분산 트랜잭션을 관리하기 위한 알고리즘으로, 분산 트랜잭션이 모두 commit되거나 모두 rollback되도록 하여 Atomicity(원자성)를 보장한다.

분산 트랜잭션에 참여하는 데이터베이스 노드를 참여자(Participant)라고 부르고, 분산 트랜잭션을 제어할 코디네이터(Coordinator)가 존재한다.

2PC는 두 단계로 이루어진다.

Prepare 단계

  1. 트랜잭션이 시작되면 코디네이터는 모든 참여자에게 prepare 메세지를 보낸다.
  2. 참여자는 prepare 메세지를 받으면 트랜잭션을 실행하고 코디네이터에게 성공하면 yes, 실패하면 no 메세지를 보낸다.

Commit 단계

성공

  1. 코디네이터가 모든 참여자에게 yes 응답을 받으면 모든 참여자에게 commit 메세지를 보낸다.
  2. 참여자는 commit 메세지를 받으면 트랜잭션을 커밋하고 코디네이터에게 ack를 보낸다.

실패

  1. 코디네이터가 한 참여자라도 no 메세지를 받으면 모든 참여자에게 rollback 메세지를 보낸다.
  2. 참여자는 rollback 메세지를 받으면 트랜잭션을 롤백하고 코디네이터에게 ack를 보낸다.

어떻게 ACID를 보장하는가?

  • Atomicity : 코디네이터가 참여자를 조율하여 모든 참여자가 commit 또는 rollback 하도록 만든다.
  • Consistency : 참여자의 데이터베이스에서 제약조건 등에 의해 일관성이 보장된다.
  • Isolation : 참여자의 데이터베이스 격리 수준과 동시성 제어 기법에 의해 격리성이 보장된다.
  • Durability : 참여자의 데이터베이스에서 Redo log와 Undo log를 기록하여 영속성을 보장한다.

Redo log와 Undo log

데이터베이스에서 트랜잭션 관리와 복구를 위해 사용되는 로그. 트랜잭션이 커밋되면 로그는 디스크의 로그 파일에 영구적으로 저장되어 데이터베이스에 장애가 발생하더라도 Durability를 보장할 수 있음.

  • Redo log : 트랜잭션에서 데이터를 변경할 때, 데이터의 변경사항을 기록하는 로그. 데이터베이스에 장애가 발생한 경우에 커밋된 트랜잭션을 복구하는데 사용됨
  • Undo log : 트랜잭션에서 데이터를 변경하기 전, 데이터의 원래 상태를 기록하는 로그. 트랜잭션을 롤백할 때 사용됨.

트랜잭션이 Commit 되는 과정

  1. 트랜잭션 중 데이터 변경 : 트랜잭션 실행 중 데이터가 변경되면, 변경된 데이터는 메모리의 Buffer Cache에 반영되고, Redo log는 메모리의 Redo log Buffer에 반영된다.
  2. 커밋 : 트랜잭션이 커밋되면 Redo log Buffer에 있던 Redo log는 디스크에 기록된다. (다른 조건을 충족하면 트랜잭션 중간에도 기록될 수 있다. 이 시점을 Checkpoint라 한다.)
  3. 변경된 데이터 기록 : Buffer Cache에 존재하는 변경된 데이터는 커밋 시점이 아니라 나중에 디스크에 기록된다.
  4. Redo log로 트랜잭션 복구 : Buffer Cache에 존재하는 변경된 데이터가 디스크에 반영되지 못하고 데이터베이스에 장애가 생기면, Redo log를 이용하여 트랜잭션을 복구한다.

트랜잭션이 커밋되기 전에 장애가 생겨 Buffer Cache와 Redo log Buffer가 모두 사라질 경우? 커밋되지 않은 트랜잭션은 복구하지 않는다. 커밋된 트랜잭션에 한해서만 ACID를 보장한다.

트랜잭션이 Rollback 되는 과정

  1. 트랜잭션 중 데이터 변경 : 트랜잭션 실행 중 데이터가 변경되면, 변경되기 전의 데이터는 Undo log에 기록되어 메모리의 Undo log Buffer에 반영되고, 변경된 데이터는 메모리의 Buffer Cache에 반영된다.
  2. 디스크에 Undo log 기록 : Checkpoint에 Undo log Buffer에 있던 Undo log는 디스크에 기록된다.
  3. 롤백 : 트랜잭션이 롤백되면 Undo log Buffer에 있던 Undo log를 사용하여 Buffer Cache에서 변경된 데이터를 원래 상태로 되돌린다. 또한 디스크에 이미 반영된 변경된 데이터도 Undo log를 사용하여 되돌린다.

XA 프로토콜

XA 프로토콜은 분산 트랜잭션의 처리를 위해 X/Open에서 정의한 표준이다. XA 프로토콜은 Two-phase Commit 알고리즘을 이용하여 분산 트랜잭션을 처리한다.


단점

  • 참여자는 코디네이터에 의존성을 가지고 있기 때문에 코디네이터에 장애가 발생할 경우, 코디네이터가 복구될 때까지 참여자는 prepare 상태에서 계속 대기해야해서 심각한 성능 저하를 일으킨다. (코디네이터는 단일 장애 지점)
  • 참여자에 장애가 발생한 경우에도 코디네이터가 장애가 발생한 참여자의 응답을 계속 기다리며 다른 참여자들이 대기해야해서 성능 저하를 일으킨다.
  • MySQL에서 2PC가 단일 노드의 트랜잭션보다 최대 10배 느리다고 보고되었다.
  • XA 프로토콜을 지원하는 DBMS 간에는 2PC를 이용한 분산 트랜잭션 구현이 가능하지만, XA 프로토콜을 지원하지 않는 NoSQL 같은 DBMS에서는 사용이 불가능하다.
profile
백엔드 개발자😎

0개의 댓글