Search
Duplicate
📒

[Database Study] 03-4. MVCC와 데이터베이스가 트랜잭션을 지원하는 방법과 동작 과정

상태
수정중
수업
Database Study
주제
Transaction
4 more properties
참고

MVCC(다중 버전 동시성 제어)

NOTE
동시 접근을 허용하는 데이터베이스에서 동시성을 제어하기 위해 사용하는 방법!
InnoDB 스토리지 엔진 아키텍쳐
데이터베이스를 사용하는 가장 큰 이유 중 하나는 바로 트랜잭션 때문이다.
하지만 모든 DBMS가 트랜잭션 기능을 제공하지 않는다.
대표적으로 MySQL의 스토리지 엔진중 하나인 MyISAM
MySQL의 InnoDB레코드 단위까지의 트랜잭션 지원
레코드 수준의 트랜잭션을 지원하기 위해서 InnoDB는 MVCC를 사용한다.
MVCC → 동시성을 제어하기 위해 사용하는 방법 중 하나.
스냅샷을 통해 하나의 레코드에 여러 버전이 관리가 된다.
데이터에 대한 변경이 완료(Commit)되기 전까지의 변경 사항은 다른 사용자가 볼 수 없도록 할 수 있다.
MVCC를 사용하는 이유는 락을 사용하지 않기 위해서이다.
락을 사용하는건 동시성 제어에서 가장 기본적인 방법이다.
하지만 락은 동시성을 떨어트리므로, MVCC를 통해 보완한다.

버퍼풀(Buffer Pool)

NOTE
스토리지 엔진의 핵심 부분으로, 디스크에 저장된 테이블과 인덱스 정보(엄밀히는 페이지)를 캐시해두는 공간이다!
캐싱을 통한 읽기 성능 향상
데이터를 임시 저장하는 메모리 공간이다
읽기 작업시에 디스크 읽기 횟수를 줄여 성능을 높인다.
쓰기 지연을 통한 쓰기 성능 향상
여러 건의 디스크 쓰기를 한 번에 처리할 수 있는 역할을 한다.
쓰기 작업을 매번 따로 수행하면 데이터 처리할 위치를 찾아야하는 랜덤 I/O가 발생하지만, 버퍼풀을 사용하면 일괄처리를 해서 I/O를 줄여 성능이 올라간다.

버퍼 vs 캐시

버퍼
데이터를 전송하는 상호간의 장치간의 속도차이로 고속의 장치가 기다리는 현상을 줄여주는 방식
ex) 프린트를 인쇄한다고 할 떄, 버퍼가 없다면 컴퓨터는 모든 페이지를 인쇄하기 전까지 기다린다.
버퍼를 사용하면 컴퓨터는 버퍼로 데이터를 보내고, 프린터는 컴퓨터로 데이터를 받지않고 버퍼를 통해서 받는다.
데이터의 손실을 막기 위해서도 사용한다.
캐시
속도가 다른 두 기기간의 병목 현상을 완화해주는 장치다.
고속의 기기에 대해 미리 데이터를 받아두고 저속의 기기까지 거치지않고 데이터를 가져온다.

Undo Log

NOTE
MySQL이 트랜잭션과 격리 수준을 보장하기 위해 백업해둔 변경 전의 데이터!
트랜잭션 보장
트랜잭션이 롤백되면 변경된 데이터를 백업된 이전으로 복구 시킨다.
격리수준 보장
특정 커넥션에서 데이터를 변경하는 도중에 다른 커넥션에서 데이터를 조회하면 격리 수준에 맞는 데이터를 반환한다.
데이터베이스는 커밋 여부와 무관하게 실제 데이터와 버퍼풀(메모리)의 내용을 변경한다.
그리고 언두 영역에는 변경적의 값을 백업해두다가 커밋되면 현재 상태를 유지하고, 롤백되면 백업데이터로 복구한다.
이러한 방식 때문에 아래와 같은 상황은 좋지않다.
대량의 트랜잭션을 변경/삭제 하는 경우(변경/삭제 마다 언두로그도 복사되므로)
트랜잭션을 오래 유지하는 경우(계속해서 로그가 쌓이므로)

Redo Log

NOTE
트랜잭션 ACID중에서 D에 가장 밀접하게 연관되어 있다!
커밋됐지만 데이터 파일에 기록되지 않은 데이터
롤백됐지만 데이터 파일에 이미 기록된 데이터
데이터 변경 내용을 리두 로그로 기록하고, 이를 통해 MySQL 서버가 비정상적으로 종료됐을 때 일관된 데이터를 가지도록 한다.

데이터베이스가 트랜잭션을 지원하는 방법과 동작 과정

트랜잭션

NOTE
잠금이 존재하는 이유 ⇒ 동시성을 제어하기 위함 트랜잭션이 존재하는 이유 ⇒ 데이터의 정합성을 보장하기 위함
트랜잭션은 계좌 이체처럼 여러 작업들로 묶이는 하나의 논리적인 작업을 완벽하게 처리한다.
만약 문제가 있다면 일부 작업만 적용되는 부분 업데이트 문제를 해결해준다.
트랜잭션은 하나의 논리적인 작업 자체가 완전히 적용(Commit) 되거나 아무것도 적용되지 않음(Rollback)을 보장해준다.

트랜잭션의 동작 과정 예시

NOTE
격리수준 READ_COMMITED인 경우 데이터의 변경을 어떻게 처리하는지 알아보자!
INSERT INTO member(id, name, area) VALUES (1, "MangKyu", "서울");
SQL
복사
데이터를 추가
INSERT문이 실행되면 버퍼풀과 디스크에 각각 저장된다.
START TRANSACTION; UPDATE member SET area = "경기" WHERE id = 1;
SQL
복사
UPDATE로 데이터 갱신
버퍼풀 → 데이터 갱신 Undo log → 이전 데이터
디스크는 백그라운드 쓰레드에 의해서 처리가 되므로 시점에 따라 생산되지 않았을 수도 있다.
하지만 MySQL은 ACID를 보장하므로 일반적으로는 버퍼풀과 동일하다고 보면된다.
MVCC를 통해 동일한 레코드가 여러 버전으로 관리되고 이를 통해 커밋 이전의 데이터 읽기, 롤백 등이 가능해졌다!
그렇다면 아직 커밋 또는 롤백이 되지 않은 경우 데이터를 조회하면 어떤 데이터가 조회되는가?
이는 격리 수준에 따라 다르다.
READ UNCOMMITED
커밋 여부와 무관하게 버퍼풀의 데이터를 반환
READ COMMITED, REPETABLE READ, SERIALIZABLE
백업된 언두 영역의 데이터를 반환한다.