앞선 포스팅에서 트랜잭션에 대해 알아보았습니다.
이 포스팅에서는 트랜잭션의 내부 매커니즘에 대해서 알아보겠습니다.
우선 Redo Log부터 알아보겠습니다!!!
Redo Log란 DB 장애발생시 복구에 사용되는 Log
더 정확하게 설명하자면 MySQL 장애 시 Buffer pool에 저장되어 있던 데이터의 유실을 방지(데이터 복구)하기 위해 사용된다.
Redo Log를 설명하려면 우선 InnoDB Buffer Pool에 대해 이해해야 합니다. Buffer Pool은 InnoDB 엔진이 Table Caching 및 Index Data Caching을 위해 이용하는 메모리 공간이다. 다시 말해, Buffer Pool 크기(메모리 공간)이 클수록 상대적으로 캐싱되는 데이터의 양이 늘어나기 때문에 Disk에 접근하는 횟수가 줄어들고, 이것은 DB의 성능 향상으로 이어진다.
하지만, Buffer Pool은 메모리 공간이기 때문에 MySQL 장애 발생시 Buffer Pool에 있는 내용은 사라지게 된다. 이것은 ACID를 보장할수 없게 되고, 다시 해석하면 장애를 복구하더라도 데이터는 복구될 수 없다는 것을 의미한다.
위 그림은 MySQL의 Commit 실행과정이다.
실제 DB에서 Commit이 발생하면 바로 디스크 영역(Table Space)으로 들어가는 것이 아닌 메모리 영역(Buffer Poll & Log Buffer)에 들어가는 것을 확인할 수 있다.(DISK I/O 절약)
Redo Log가 무엇이고 왜 쓰는지 까지 알아보았습니다. 그렇다면 Redo Log는 항상 쓰이는 것일까요? 정답은 항상 쓰이진 않습니다.
Redo Log에 기록할 때는 데이터 변경이 있을 시 입니다. DML, DDL, TCL 작업 등 DATA 변경이 일어나는 모든 것을 기록합니다.(SELECT문은 데이터 변경 x)
DML(Data Manipulation Language)
: 정의된 데이터베이스에 입력된 데이터를 조회하거나 수정하거나 삭제하는 등의 역할을 하는 언어.
DDL(Data Definition Language)
: 데이터베이스를 정의하는 언어
TCL(Transaction Control Language)
: COMMIT, ROLLBACK
방금전까지 Redo Log를 설명했는데 무슨 또 Redo Log File? 하실 수 있지만 여태까지 말한 것은 메모리 영역인 Redo Log Buffer에 저장되는 부분을 설명한 것입니다. Redo Log Buffer 또한 메모리영역이니 장애가 발생한다면 사라지겠죠?그렇다면 어떻게 이것으로 복구한다는거야? 생각하실 수 있습니다. 그것은 바로 Redo Log File로 복구하는 것입니다!!
참 복잡합니다.. 하지만 우리는 할 수 있습니다.
자 이제 Redo Log File에 대해 파고들어보겠습니다.
방금 Log Buffer는 메모리 영역이라고 했습니다. 메모리 영역이라는 것은 용량이 제한적이라는 뜻입니다. 용량이 제한적이기 때문에 Checkpoint 이벤트 발생시점에 Redo Log Buffer에 있던 데이터들을 Disk에 File로 저장하게 됩니다. 이 파일을 Redo Log File라고 부릅니다.
Redo Log File은 두 개의 파일로 구성되는데, 하나의 파일이 가득차면 log switch가 발생하며 다른 파일에 쓰게됩니다. log switch가 발생할 때마다 Checkpoint 이벤트도 발생하는데, 이때 InnoDB Buffer Pool Cache에 있던 데이터들이 백그라운드 스레드에 의해 디스크에 기록됩니다.
정리하겠습니다.
Checkpoint 이벤트가 발생하기 전 장애가 발생한다면 Buffer Pool에 있던 데이터들은 유실되지만 마지막 Checkpoint가 수행된 시점(=log swtich)까지의 데이터가 Redo Log File로 남아있기 때문에 이 파일을 사용하여 데이터를 복구할 수 있습니다.
말로만 들으면 이해가 잘 되지 않으니 그림으로 보겠습니다.
사진에 오탈자가 있음. 3. Redo Log Buffer -> Redo Log File로 바꿔서 이해하기 바람
선 로그 기법(Log Ahead)
: 데이터 변경 작업 시 데이터 변경에 대한 내용을 Redo Log Buffer에 미리 저장
Redo Log에 대해서는 내용이 너무 길어지기 때문에 딱 여기까지만 알아보겠습니다.
넌 또 뭐냐..
정의부터 살펴보자
실행 취소 로그 레코드의 집합으로 트랜잭션 실행 후 Rollback 시 Undo Log를 참조해 이전 데이터로 복구할 수 있도록 로깅 해놓은 영역이다.
작업 수행 중에 수정된 페이지들이 버퍼 관리자의 버퍼 교체 알고리즘에 따라서 디스크에 출력될 수 있다. 버퍼 교체는 전적으로 버퍼의 상태에 따라 결정되며, 일관성 관점에서 봤을 때는 임의의 방식으로 일어나게 된다. 즉 아직 완료되지 않은 트랜잭션이 수정한 페이지들도 디스크에 출력될 수 있으므로, 만약 해당 트랜잭션이 어떤 이유든 정상적으로 종료될 수 없게 되면 트랜잭션이 변경한 페이지들은 원상 복구되어야 한다. 이러한 복구를 UNDO라고 한다.
-- 데이터 INSERT
INSERT INTO member(m_id, m_name, m_area) VALUES (12, '홍길동', '서울');
COMMIT;
-- 데이터 UPDATE
UPDATE member SET m_area='경기' WHERE m_id=12;
Undo Log도 Redo Log와 마찬가지로 Log Buffer에 기록됩니다. Undo Recodrs영역에 기록되는 것입니다. 저장되는 데이터는 PK값과 변경되기 전의 데이터 값입니다.
이제 메모리 영역에서 어떻게 디스크 영역으로 저장되는 것인지 알아보겠습니다.
Redo Log가 트랜잭션 커밋과 Checkpoint시 디스크에 기록 되지만, Undo Log는 Checkpoint시 디스크에 기록됩니다.
위 sql코드와 그림을 보면 update쿼리가 실행되면 (commit/rollback 전) InnoDB buffer pool에 캐싱된 데이터는 update한 정보로 수정됩니다. 데이터를 수정함과 동시에 rollback을 대비하기 위해, 업데이트 전의 데이터를 undo records로 기록하는것입니다.
너무 긴 트랜잭션
: 하나의 트랜잭션이 너무 길어지게 되면(다른 트랜잭션들에 의해 지속적인 checkpoint가 발생하기 때문에 redo / undo log가 지속적으로 파일에 쓰여지게 되고 심각한 경우 disk 100% 사용까지도 가능해진다.
rollback은 무거운 작업
rollback은 결국 수 많은 undo log 정보를 참조하여 기존의 레코드로 정보를 리턴하는 작업입니다. 즉, 트랜잭션이 길면 길수록 undo log에 써진 내용이 많아 rollback 작업은 무거워질수 밖에 없습니다.
쉽게 생각하면
: Redo 로그 (변경 후의 값을 기록) forwarding
: Undo 로그 (변경 전의 값을 기록) backing
참조:
Mysql-Redo-Log-란
Redo Log 원리
Redo Log & Redo Log Buffer
DBMS는 어떻게 트랜잭션을 관리할까?
로그 기록자 백그라운드 프로세스
Real MariaDB
Undo Log
읽어보면 도움될 내용:
Mysql Redo
중국 리두 로그
Redo Log 관리 하기
에이든의 트랜잭션 메커니즘 Youtube
innodb redo log
글 재미있게 잘 쓰셨네요 감사합니다!