1. 트랜잭션 시작 (처음으로 트랜잭션 시작)
- 이 트랜잭션에 트랜잭션 ID(TRX_ID)를 할당한다. 트랜잭션 ID는 시스템 테이블 스페이스의 TRX_SYS 페이지에서 가장 큰 트랜잭션 ID필드에 기록될 수 있다.
- 시스템 테이블 스페이스의 TRX_SYS 페이지에서 가장 큰 트랜잭션 ID 필드가 업데이트되면 업데이트가 Redo Log에 기록된다.
- 할당된 TRX_ID를 기반으로 read view를 만든다.
2. 레코드 수정 (한번에 하나의 레코드 행만 수정됨)
2-1. Undo Log 로그 공간 할당
2-2. 수정전 값을 Undo Log 로그에 복사 (실제 변경되는 컬럼의 이전 값과 PK 값만 저장)
2-3. 버퍼풀 데이터 페이지의 변경 대상 레코드의 메타 정보중에서 Roll-Point 값을 2-2에서 생성된 Undo Log의 주소 값으로 저장
2-4. 버퍼풀 데이터 페이지의 변경 대상 레코드의 컬럼 값을 새로운 값으로 변경하고, 변경되는 컬럼의 이후 값과 데이터 페이지 주소 및 Offset을 Redo 로그에 저장. 롤백 세그먼트 포인터는 Undo Log에 있는 레코드의 이전 버전을 가리킨다.
2-5. 변경되는 컬럼을 이용한 인덱스가 있을 경우 인덱스의 값 변경
해당 인덱스 페이지가 버퍼풀에 없으면 Insert Buffer에 임시 저장한다.
- 인덱스 페이지는 단순히 기존 인덱스 키를 덮어쓰기 하는 것이 아니라, 기존 인덱스 키는 그대로 보존하고 새로운 키 값을 추가한다.
- 인덱스 키 하나는 트랜잭션 가시성에 관계없이 모든 값들을 다 가지고 있게된다.
(변경 전/후의 레코드 포인터 모두 가지고 있다.)
3. 다른 트랜잭션은 어떻게 되나요?
- 레코드가 수정되면 커밋되지 않더라도 다른 트랜잭션도 해당 트랜잭션 격리 수준에 따라 수정된 레코드를 볼 수 있다.
- RU 격리 수준인 경우 색인 페이지를 사용하여 최신 버전 기록을 읽는다.
- RC 격리 수준인 경우 가정 최근에 제출된 레코드 버전 검색
- RR 격리 수준인 경우 read view에 해당하는 레코드 버전을 찾는다.
- 최신 버전 레코드보다 오래된 버전 레코드를 읽기 위해 인덱스 페이지를 사용해야하는 경우, 이전 버전 레코드를 다시 빌드하려면 Undo Log 를 사용해야한다.
4. 트랜잭션 커밋
- 트랜잭션에 해당하는 Undo Log 페이지는 "purge"로 설정된다.
- Undo Log 페이지는 다른 트랜잭션에서 더이상 참조되지 않을때 지을 수 있다.
- Redo Log 버퍼가 디스크의 로그 파일로 기록된다.
- 디스크 플러시 여부는 innodb_flush_log_at_trx_commit 시스템 변수 값에 따라 다르다.
- Redo Log의 더티페이지가 로그 파일에 기록되기 전에 이 더티 페이지를 만든 LSN 이전의 LSN의 Read Log는 반드시 먼저 디스크에 기록되어야 한다.
5. 백그라운드 스레드가 다른 트리거 매카니즘에 따라 지속적으로 새로고침을 트리거함
- 가장 오래된 더티 페이지를 찾아서 플러시 배치에 추가한다.
- 플러시 배치는 최신 LSN 번호가 리두 로그에 기록되고 배치되었는지 확인한다.
- duble write가 활성화 된 경우 더티 페이지는 먼저 duble write 버퍼로 플러시 되고 동기화를 기다린다.
- 버퍼풀의 각 더티 페이지를 최종 목적지 (테이블 스페이스 파일)에 쓴다.
6. 정기적으로 체크 포인트 수행
- 체크 포인트보다 오래된 더티 페이지(체크 포인트 LSN보다 작은)가 테이블 스페이스 파일로 기록됐는지 확인한다. 체크 포인트 LSN보다 큰 더티 페이지가 있는 경우 더티 페이지가 즉시 데이터 파일로 기록된다.
- 체크 포인터로 인해 디스크에 기록되는 데이터가 모두 Commit된 데이터가 아닐 수 있다.
7. 백그라운드 스레드 제거
- 백그라운드 스레드는 Undo Log 및 히스토리 연결 목록을 포함하여 필요에 따라 주기적으로 지속적으로 제거를 실행함
- 각 롤백 세그먼트에서 더이상 필요하지 않은 가장 오래된 Undo Log를 찾는다.
- 실제로 인덱스에서 삭제 표시가 있는 레코드를 삭제한다.
- Undo Log 페이지 해제
참고
https://www.programmersought.com/article/49353530904/
http://intomysql.blogspot.com/2010/12/innodb-redoundo.html
'MySQL' 카테고리의 다른 글
Hash join in MySQL 8 (0) | 2021.06.25 |
---|---|
Redo Log (0) | 2021.06.25 |
OPTIMIZE TABLE Statement (0) | 2021.06.18 |
ANALYZE TABLE Statement (0) | 2021.06.17 |
GTID - 트랜잭션 건너뛰기 (0) | 2021.06.13 |