본문 바로가기

개발기술/데이터베이스

데이터베이스 트랜잭션 개념과 구현 (MYSQL InnoDB)

키워드 : 언두로그, MVCC, 레코드락, 갭락, 넥스트락, 격리수준, 잠금없는일관된읽기

목적 : 애매한 용어들을 명확하게 정의하고자한다.

 

데이터 베이스의 주요 특징 (ACID)

데이터베이스 트랜잭션이 데이터의 신뢰성과 일관성을 보장하기 위한 4가지 특징

  1. Atomicity (원자성):  All or nothing 트랜잭션으로 묶인 작업은 모두 실행되거나 혹은 모두 실행되지 않아야한다.
  2. Consistency (일관성): 트랜잭션 작업의 결과는 항상 일관적이어야한다. 모든 트랜잭션이 종료될 시에는 데이터는 DB의 제약조건을 지키고 있는 상태가 되어야한다.
  3. Isolation (격리성): 프로그램 내에는 여러가지 트랜잭션이 존재하지만 트랜잭션은 다른 트랜잭션과 독립적으로 동작해야한다. 서로 영향을 주지 않도록 고립되어야 합니다. 
  4. Durability (지속성): 트랜잭션이 성공적으로 완료되면 그 변경 사항은 영구적으로 저장되어야한다. 데이터베이스 시스템 장애가 발생하더라도 커밋된 데이터는 모두 로그로 남겨 결국에는 DB에 순차적으로 모두 반영이 되도록 한다.

https://en.wikipedia.org/wiki/ACID

트랜잭션

  • 트랜잭션은 데이터베이스를 대상으로 수행되는 작업 단위. 

MYSQL INNO DB에서의 트랜잭션 기능

  • 트랜잭션은 커밋되거나 롤백될 수 있는 작업의 원자적 단위.
  • 논리적인 작업 셋을 모두 완벽하게 처리하거나, 오류가 발생하여 처리하지 못할 경우 원 상태로 복구해주는 단위.
  • Acid의 All Or Nothing.

트랜잭션의 격리성 

  •  여러 트랜잭션이 동일한 데이터를 동시에 액세스하더라도 서로의 데이터 관측과 작업을 간섭하지 않도록 하는 능력

MYSQL INNO DB : 트랜잭션 격리성 레벨

  • 여러 트랜잭션의 동시작업 환경에서 동시성 성능과 데이터 신뢰성 간의 균형을 조정하는 설정
  • 동시성 성능과 데이터 신뢰성은 Trade-Off 관계임.
  • Acid의 Isolation.

 

트랜잭션, 격리수준, 잠금 개념구분

  • 트랜잭션은 데이터의 정합성을 보장하기 위한 기능. All or nothing, Isolation
  • 트랜잭션 격리수준은 트랜잭션 간의 작업내용을 어느수준으로 공유하고 차단할 것인지 결정하는 레벨
  • 잠금은 여러 컨넥션에서 동시에 동일한 자원을 요청할 경우 순서대로 한시점에서 하나의 컨넥션만 변경할 수 있게 해주는 기능.

 

MySQL InnoDB 트랜잭션 모델

  • 트랜잭션 모델은 트랜잭션(All or Nothing)과 트랜잭션의 격리수준(Isolation)설정이라는 기능을 구현하는 모델
  • InnoDB는 다중버전(Multi-Version) 데이터관리를 통한 스냅샷과 잠금(locking)을 결합하여 구현

InnoDB Multi Versioning

  • 하나의 레코드에 대해 여러 개의 버전이 동시에 관리되는 것을 의미하며, 변경된 데이터의 과거의 버전을 언두로그(Undo Log)에 저장하여 구현됨.
  • Multi Versioning에서 과거의 버전 데이터의 용도는 1. 오류시 트랜잭션 RollBack을 위하여 2. 일관된 읽기를 위한 스냅샷 생성을 위하여 사용된다.

언두로그(Undo Log)

  • DML(Data Manipulation Language : Insert, Update, Delete)로 데이터를 변경했을때 변경되기 전의 데이터를 보관하는 곳

스냅샷

  • MySQL은 '일관된 읽기' 위해서 읽기쿼리의 결과값으로 특정시점의 데이터베이스 상태를 기억하는 스냅샷을 생성한다. 스냅샷은 데이터별 Transaction Id를 기초로하여 어떤 데이터를 조회할지 결정하는 것을 말한다.
    • 만약 스냅샷 생성시점에, 다른 트랜잭션에 의해서 커밋되지 않은 데이터 변경이 생겼다면 언두로그에서 과거 데이터를 찾아서 스냅샷을 생성한다.
    • 스냅샷 생성시점은 read commited 는 조회쿼리 동작시점마다, repeatable read는 트랜잭션 내 첫 조회쿼리 동작시점에 생성
  • 스냅샷은 위와 같이 트랜잭션 ID를 검토하여 데이터를 포함시킬지 결정하기 때문에 lock 없이도 동시성 상황에서 일관된 데이터 읽기가 구현가능하다 ( non-locking read )

 

트랜잭션 격리수준에 따른 MVCC, Lock 동작

 

  • 격리수준은 dirtyread, irrepeatable read, phantomread 이 문제를 해결하는 순서대로 분류가되는데, read uncommitted, read committed, repeatable read, serializable이 있습니다.
  • 각각 mvcc랑 연관관계가 높은데, readuncommitted는 mvcc 스냅샷을 사용하지 않고 read committed는 mvcc 스냅샷으 사용하되 read할때마다 사용하고 repeatableread는 mvcc 스냅샷
  • InnoDB는 다중버전(Multi-Version) 데이터관리를 통한 스냅샷 기능과 잠금 기능(locking)을 결합하여 구현하는데 격리수준에 따라서 두가지 기능의 동작방식이 다르다.
  • 때문에, 격리수준에 따라서 동시에 트랜잭션을 처리하는 역량과 트랜잭션 간 데이터가 간섭되는 정도가 다르다. 

ReadUncommited

  • 스냅샷 : 미사용
  • 읽기작업 Lock기법 : 미사용
  • 발생문제 - Dirty Read : 한 트랜잭션에서 확정/커밋되지 않은 작업이 다른 트랜잭션에서 볼수 있는 현상

  

ReadCommited

  • MVCC : 스냅샷 미사용, 언두로그 사용
  • 읽기작업 Lock기법 : 미사용
  • 해결문제 - Dirty Read : 한 트랜잭션에서 완료/커밋되지 않은 작업이 다른 트랜잭션에서 볼수 있는 현상
    • 해결방안 - 스냅샷을 구성할때, 커밋되지 않은 변경데이터는  언두로그에서 변경 전 데이터를 읽어온다
  • 발생문제 - Non-RepeatableRead : 특정한 레코드를 여러번 조회할때 중간에 다른 트랜잭션이 값을 변경후 commit하면 똑같은 조회를 실행해도 결과값이 달라질 수 있음. 이는 스냅샷이 읽기 조회시마다 새로 생성되기에 발생함.

 

 Repeatable Read

  • MVCC : 트랜잭션 내 최초 데이터 조회시 스냅샷 생성 후 유지
  • 읽기작업 Lock기법 : 일반적으로 미사용, InnoDB LockingRead에서는 적용.
  • 해결문제 - Non-RepeatableRead : 특정한 레코드를 여러번 조회할때 중간에 다른 트랜잭션이 값을 변경후 commit하면 똑같은 조회를 실행해도 결과값이 달라질 수 있음. 이는 스냅샷이 읽기 조회시마다 새로 생성되기에 발생함.
    • 해결방안 -  매 조회쿼리마다 스냅샷을 새로 구성하는 것이 아니라 트랜잭션 내 최초 조회시의 스냅샷을 트랜잭션 동안 유지
  •  발생문제 - PhantomRead : 범위 검색시 다른 트랜잭션에서 수행한 변경 작업에 의해서 레코드가 안보였던 레코드가 보이는 것을말한다. 

 

 

 

Serializable 

  • MVCC : 스냅샷 미사용
  • 읽기작업 Lock기법 : Select문의 MVCC기반의 Non-locking Read를 Locking Read로 변환 적용하여 레코드 및 갭에 S-lock 잠금
  • 해결문제 - PhantomRead: 범위 검색시 다른 트랜잭션에서 수행한 변경 작업에 의해서 레코드가 안보였던 레코드가 보이는 것을말한다. 
    • 해결방안 - 범위조회시 조회된 레코드와 범위(Gap)에 대해서 Lock을 걸어 다른 레코드에서 수정하지 못하도록 함 

 

 

 

 

 

 

 

https://www.aladin.co.kr/shop/UsedShop/wuseditemall.aspx?ItemId=278488709

https://dev.mysql.com/doc/refman/8.4/en/

https://en.wikipedia.org/wiki/Database_transaction