[DB] MVCC

Daekuen·2023년 8월 3일
0

Database

목록 보기
7/7
post-thumbnail
post-custom-banner

Lock 기법에서는 read/read lock 끼리만 block을 하지 않아, 이 때만 서로 다른 트랜잭션이 동시에 특정 데이터접근이 가능했다.
그러나 트랜잭션 처리량이 적어 성능적인 이슈가 있었고

이를 해결하고자 MVCC가 등장하였다.

Keyword
MVCC, Locking read

MVCC(Multi Version Concurrency Control)

  • 데이터를 읽을떄, 특정시점을 기준으로 가장 최근에 commit된 데이터를 읽는다
    특정시점은 isolation level에 따라 다르다.
  • 데이터 변화(wirte operation)에 대한 이력을 관리한다
    history를 저장하는 추가적인 저장공간이 필요 (굳이 말하자면 단점..?)
  • read-lock과 write-lock끼리 block하지 않는다.
    트랜잭션 처리량 증가로 성능 향상.

isolation level에 따른 MVCC 동작

아래 상황을 살펴보자.

  • x의 초기값은 10이다.
  • tx2에 의해서 x = 50 write 작업이 이루어 졌다. 아직 commit 전이기 때문에 DB 적용 X
  • MVCC는 commit 된 데이터만 읽기 때문에 tx1의 read는 x = 10.
  • 그 후에 tx2에서 commit, DB에 x=50이 적용.

그럼 tx1의 두번째 read는 어떤 값을 읽어올까?
Isolation level에 따라 다르다.

read committed

  • read하는 시간을 기준으로 그전에 commit된 데이터를 읽는다 (x=50)
  • mysql, postgresql 모두 동일

repetable read

  • tx 시작 시간을 기준으로 그전에 commit된 데이터를 읽는다. (x=10)
  • tx1 시작은 commit 전에 이루어졌으므로 x의 초기값을 읽는다.
  • mysql, postgresql 모두 동일

serializable

  • MySQL에서는 MVCC로 동작하기 보다는 lock으로 동작한다.
  • postgreSQL에서는 SSI(Serializable Snapshot Isolation) 기법이 적용된 MVCC로 동작
  • mysql, postgresql 결과는 동일, 동작방식 다름

read uncommitted

  • MVCC는 commit된 데이터를 읽기 때문에, 이 level에서는 보통 MVCC가 적용되지 않는다.
  • postgreSQL에서는 read uncommitted level이 존재하지만 read commited level처럼 동작한다.

MVCC에서 이상현상 해결 방법.

MVCC를 사용할 때도 Lost-update, write-skew와 같은 이상현상이 발생한다.
postgreSQL과 MySQL의 해결방식이 조금은 다른데 알아보도록 하자.

PostgreSQL

Lost-update

PostgreSQL에서는 read committed level에서 Lost-update가 발생한다.

PostgreSQL는 Update에 참여하는 모든 트랜잭션이 repeatable read를 사용할 경우,
Lost-update문제를 해결할 수 있다.

postgreSQL에서는 repeatable read level에서
같은 데이터에 먼저 update한 tx가 commit 되면 나중 tx는 rollback 된다.(first-updater-win)

MYSQL

Lost-update

mysql에서는 lost update를 방지하기 위해서는 repeatable read만 가지고는 해결되지 않는다.
Locking read를 함께 사용해야 한다.

Locking read

  • read를 하면서도 read lock과 함께 write lock도 함께 획득하게 되는 것.
  • sql 쿼리문에 FOR UPDATE를 붙여줌으로 써 Locking read가 적용된다.(exclusive lock 획득)
  • FOR SHARE를 붙여줄 수도 있다.(shared lock 획득)
  • Locking read는 가장 최근의 commit된 데이터를 읽는다.
    isolation level과는 무관.
SELECT balance FROM account WHERE id='x' FOR UPDATE or (FOR SHARE)
  • Lost-update 외에도 write skew 이상 현상이 발생 할 수 있는데

    Repeatable Read 격리 수준에서 write skew를 피하기 위해서는
    MySQL, PostgreSQL Locking Read를 사용해야 한다.

Reference
쉬운코드 - MVCC 1,2 편

profile
오늘보다 나은 내일을 위해 노력하는 개발자.
post-custom-banner

0개의 댓글