[MySQL] InndoDB - Undo Log

■ Undo Log?

임시 테이블 스페이스에있는 언두 로그는 사용자 정의 임시 테이블의 데이터를 수정하는 트랜잭션에 사용됩니다. 실행 취소 로그 레코드의 집합으로 Transaction 실행후 Rollback Undo Log 참조해 이전 데이터로 복구할수 있도록 로깅 해놓은 영역입니다. 서버가 실행되는 동안 롤백에만 사용됩니다. 유형의 실행 언두 로그는 재실행 로깅 I/O 피함으로써 성능을 향상시킵니다.

트랜잭션이 데이터를 항상 테이블 인덱스 또는 데이터(버퍼 또는 실제 파일) 데이터를 삽입합니다. 개인 복사본이 생성되지 않습니다. 활성 XtraDB/InnoDB 트랜잭션에 의해 수정되는 이전 버전의 데이터는 실행 취소 로그에 저장됩니다. 그런 다음 원본 데이터를 복원하거나 일관된 읽기로 있습니다.

 

언두 로그(실행 취소 로그) 단일 읽기-쓰기 트랜잭션과 관련된 언두 로그 레코드의 모음입니다. 실행 언두로그 레코드에는 트랜잭션에 의한 최신 변경 사항을 클러스터형 인덱스 레코드로 실행을 취소하는 방법에 대한 정보가 포함되어 있습니다. 다른 트랜잭션이 일관된 읽기 작업의 일부로 원래 데이터를 보아야하는 경우 수정되지 않은 데이터는 언두 로그 레코드에서 검색됩니다. 언두 로그는 롤백 세그먼트 내에 포함 실행 취언두 로그 세그먼트 내에 있습니다. 롤백 세그먼트는 시스템 테이블 스페이스, 언두 테이블 스페이스 임시 테이블 스페이스에 있습니다.

 

 

언두 테이블스페이스에는 클러스터형 인덱스 레코드에 대한 트랜잭션의 최신 변경 사항을 실행 취소하는 방법에 대한 정보가 포함된 레코드 모음인 언두 로그가 포함되어 있습니다.

언두 로그는 기본적으로 시스템 테이블스페이스에 저장되지만 대신 하나 이상의 실행 취소 테이블스페이스에 저장할 있습니다. 실행 취소 테이블스페이스를 사용하면 테이블스페이스에서 언두 로그에 필요한 공간을 줄일 있습니다. 언두 로그에 대한 I/O 패턴은 언두 테이블스페이스를 SSD 스토리지를 권장합니다. 빠르게 언두로그에 대해 언두로그가 작성되거나 롤백될때 그만큼 빠르게 처리될 있습니다.

InnoDB 사용하는 언두 테이블스페이스의 수는 innodb_undo_tablespaces 옵션에 의해 제어됩니다. 옵션은 MySQL 인스턴스를 초기화할 때만 구성할 있습니다. 나중에 변경할 없습니다.

 

정리하면 주요 용도는 다음과 같습니다.

위에서 언급한 트랜잭션의 롤백 대비용입니다. 언두로그를 이용해서 트랜잭션을 복구 있습니다.

트랜잭션의 격리 수준을 유지하면서 높은 동시성을 제공하는 사용됩니다. 특히 Repeatable Read, Read Commit에서 언두로그를 이용해서 격리수준에 맞는데 데이터를 리턴합니다.

 

참고

innodb_undo_tablespaces 옵션은 8.0에서 제거됩니다. 언두 테이블스페이스 해당 테이블스페이스 내의 개별 세그먼트는 삭제할 없습니다. 그러나 언두 테이블스페이스에 저장된 언두 로그는 잘릴 있습니다.

 

■ Undo Log 아키텍쳐

 

undo log 저장되는 아키텍쳐

 

Undo Log 구현 정보

Undo Log 레코드에는 실제 변경되는 컬럼의 이전값과 PK 값만 저장이 됩니다. 그리고 언두로그 레코드에는 트랜잭션에 의한 최신 변경 사항을 클러스터형 인덱스 레코드로 실행을 취소하는 방법에 대한 정보가 포함되어 있습니다.

먼저 버퍼풀의 데이터가 변경이 되기 시작하면 언두로그 영역에 반영되기 시작하는데 먼저 데이터 변경뿐만이 아니라 인덱스의 변경도 필요하게 됩니다. 그래서 인서트 버퍼라는 곳에서 먼저 데이터와 인덱스가 처리됩니다. 그리고 일정크기로 변경전 데이터를 버퍼에 모으게 됩니다. 이곳은 메모리 영역입니다.

그리고 일정데이터가 모이게 되다가 체크포인트 시점을 만나게 되면 Undo Log 기록이 되게 됩니다. 이곳은 디스크 영역으로 언두로그 파일에 저장됩니다.

그리고 일반 행에는 실행 취소 로그에 있는 동일한 행의 최신 버전에 대한 포인터가 있습니다. 실행 취소 로그의 행에는 이전 버전에 대한 포인터가 포함되어 있습니다(있는 경우). 따라서 수정된 행에는 기록 체인이 있습니다.

 

인서트 버퍼란?

RDBMS에서 레코드가 INSERT 되거나 UPDATE 때는 데이터 파일을 변경하는 작업 아니라 해당 테이블에 포함된 인덱스를 업데이트하는 작업도 필요합니다. 그런데 인덱스를 업데이트하는 작업은 랜덤하게 디스크를 읽는 작업이 필요하므로 테이블에 인덱스가 많다면 작업은 상당히 많은 자원을 소모하게 됩니다. 그래서 InnoDB 변경해야 인덱스 페이지가 버퍼 풀에 있으면 바로 업데이트를 수행하지만, 그렇지 않고 디스크로부터 읽어와서 업데이트해야 한다면 이를 즉시 실행하지 않고 임시 공간에 저장해 두고 바로 사용자에게 결과를 반환하는 형태로 성능을 향상시키게 되는데, 사용하는 임시 메모리 공간을 인서트 버퍼(Insert Buffer) 라고 합니다.

 

트랜잭션이 끝날 때까지 행은 물리적으로 삭제되지 않습니다. 삭제된 경우 복원이 불가능합니다. 따라서 행은 단순히 삭제 표시됩니다.

트랜잭션은 레코드 보기를 사용합니다. 트랜잭션 수준에 따라 보기가 생성되는 방식이 결정됩니다. 예를 들어, READ UNCOMMITTED 커밋되지 않은 경우에도(더티 읽기) 일반적으로 현재 버전의 행을 사용합니다. 다른 격리 수준을 사용하려면 실행 취소 로그에서 가장 최근에 커밋된 버전의 행을 검색해야 합니다. READ COMMITTED 테이블에 대해 다른 뷰를 사용하는 반면 REPEATABLE READ SERIALIZABLE 모든 테이블에 대해 동일한 뷰를 사용합니다.

 

데이터의 글로벌 히스토리 목록도 있습니다. 트랜잭션이 커밋되면 해당 기록이 기록 목록에 추가됩니다. 목록의 순서는 커밋의 시간순입니다.

제거 스레드는 기존 보기에 필요하지 않은 실행 취소 로그의 행을 삭제합니다. 최신 버전이 있는 행과 삭제 표시된 행이 삭제됩니다.

InnoDB 이전 버전을 복원해야 하는 경우 버전을 이전 버전으로 교체하기만 하면 됩니다. 트랜잭션이 행을 삽입하면 이전 버전이 없습니다. 그러나 경우 삽입된 행을 삭제하여 복원할 있습니다.

 

롤백 세그먼트 슬롯

InnoDB 최대 128개의 롤백 세그먼트를 지원하며 32개는 임시 테이블 스페이스에 할당됩니다. 이로 인해 일반 테이블의 데이터를 수정하는 트랜잭션에 할당 수있는 96개의 롤백 세그먼트가 남습니다. innodb_rollback_segments 변수는 InnoDB에서 사용하는 롤백 세그먼트 수를 정의합니다.

 

롤백 세그먼트가 지원하는 트랜잭션 수는 롤백 세그먼트의 언두 슬롯 수와 트랜잭션에 필요한 언두 로그 수에 따라 다릅니다.

 

롤백 세그먼트의 실행 취소 슬롯 수는 InnoDB 페이지 크기에 따라 다릅니다.

 

InnoDB Page Size Number of Undo Slots in a Rollback Segment (InnoDB Page Size / 16)
4096 (4KB) 256
8192 (8KB) 512
16384 (16KB) 1024
32768 (32KB) 2048
65536 (64KB) 4096

 

트랜잭션에는 다음 작업 유형 각각에 대해 최대 4 개의 실행 언두 로그가 할당됩니다.

1. 사용자 정의 테이블에 대한 INSERT 조작

2. 사용자 정의 테이블에 대한 UPDATE DELETE 조작

3. 사용자 정의 임시 테이블에 대한 INSERT 조작

4. 사용자 정의 임시 테이블에 대한 UPDATE DELETE 조작

 

필요에 따라 언두 로그가 할당됩니다. 예를 들어, 일반 임시 테이블에서 INSERT, UPDATE DELETE 작업을 수행하는 트랜잭션에는 4개의 언두 로그를 완전히 할당해야합니다. 일반 테이블에서 INSERT 조작 수행하는 트랜잭션에는 단일 언두 로그가 필요합니다.

 

일반 테이블에서 작업을 수행하는 트랜잭션에는 할당된 시스템 테이블 스페이스 또는 언두 테이블 스페이스 롤백 세그먼트에서 언두 로그가 할당됩니다. 임시 테이블에서 작업을 수행하는 트랜잭션에는 할당 임시 테이블 스페이스 롤백 세그먼트의 언두 로그가 할당됩니다.

 

트랜잭션에 할당 언두 로그는 해당 기간 동안 트랜잭션과 연결되어 있습니다. 예를 들어, 일반 테이블에서 INSERT 조작을 위해 트랜잭션에 지정된 언두 로그는 해당 트랜잭션이 수행하는 일반 테이블의 모든 INSERT 조작에 사용됩니다.

 

위에서 설명한 요소를 감안할 다음 공식을 사용하여 InnoDB 지원할 수있는 동시 읽기 / 쓰기 트랜잭션 수를 추정 있습니다.

 

노트

InnoDB 지원할 있는 동시 읽기 / 쓰기 트랜잭션 수에 도달하기 전에 트랜잭션에 동시 트랜잭션 제한 오류가 발생할 있습니다. 트랜잭션에 지정된 롤백 세그먼트에 언두 슬롯이 부족할 발생합니다. 이러한 경우 트랜잭션을 다시 실행합니다.

 

트랜잭션이 임시 테이블에서 작업을 수행할 InnoDB 지원할 수있는 동시 읽기 / 쓰기 트랜잭션 수는 임시 테이블 스페이스에 할당 롤백 세그먼트 (32) 제한됩니다.

+ 트랜잭션이 INSERT 또는 UPDATE 또는 DELETE 작업을 수행하는 경우 InnoDB 지원할 수있는 동시 읽기 / 쓰기 트랜잭션 수는 다음과 같습니다.

(innodb_page_size / 16) * (innodb_rollback_segments-32)

 

+ 트랜잭션이 INSERT UPDATE 또는 DELETE 작업을 수행하는 경우 InnoDB 지원할 수있는 동시 읽기 / 쓰기 트랜잭션 수는 다음과 같습니다.

(innodb_page_size / 16/2) * (innodb_rollback_segments-32)

 

+ 트랜잭션이 임시 테이블에서 INSERT 작업을 수행하는 경우 InnoDB 지원할 수있는 동시 읽기 / 쓰기 트랜잭션 수는 다음과 같습니다.

(innodb_page_size / 16) * 32

 

+ 트랜잭션이 임시 테이블에서 INSERT UPDATE 또는 DELETE 작업을 수행하는 경우 InnoDB 지원할 수있는 동시 읽기 / 쓰기 트랜잭션 수는 다음과 같습니다.

(innodb_page_size / 16/2) * 32

 

 

언두로그 유의 사항

실행 취소 로그가 작동하는 방식을 이해하면 트랜잭션에 미치는 부정적인 영향을 이해하는 도움이 됩니다.

- 트랜잭션은 실행 취소 로그에 여러 개의 이전 버전 행을 생성합니다. 이러한 행은 다른 트랜잭션에 필요하기 때문에 아마도 오랜 시간 동안 필요할 것입니다. 이러한 트랜잭션은 수정된 행을 많이 생성하므로 일종의 조합 폭발이 관찰될 있습니다. 따라서 실행 취소 로그에는 많은 공간이 필요합니다.

- 트랜잭션은 기록 목록에 있는 매우 오래된 버전의 행을 읽어야 있으므로 성능이 저하됩니다.

물론 읽기 전용 트랜잭션은 실행 취소 로그에 많은 항목을 기록하지 않습니다. 그러나 기존 항목의 제거가 지연됩니다.

또한 트랜잭션이 길면 교착 상태가 발생할 가능성이 높지만 문제는 실행 취소 로그와 관련이 없습니다.

 

DBMS 단독으로 처리되는 시스템이 아닌 여러 세션이 동시에 접속되어 운영되는 시스템이기 때문에 대량의 트랜잭션이 오래 수행이 되면 그만큼 언두로그를 크게 차지하게 됩니다.

또한 대량의 트랜잭션으로 인해 여러 세션이 대기하게 되면 그만큼 언두로그를 사용하게 됩니다. 이렇게 되면 결국 할당된 크기의 언두로그가 가득차게 되어 시스템이 멈추게 되거나 롤백을 시도하게 됩니다.

 

특히 롤백은 굉장히 무거운 작업입니다. 리두로그와 언두로그를 사용하여 데이터를 이전상태로 되돌려야 합니다. 예를들어 1시간동안실행되어던 트랜잭션이 롤백된다면 그만큼 시간이 소요됩니다. 그렇기에 언두로그가 차지 않도록 모니터링 되야 합니다.

 

■ Undo Log 설정방법

언두 로그는 오류 로그나 느린 쿼리 로그와 같이 일반적인 의미의 디스크에서 있는 로그 파일이 아니라 저장 영역입니다.

5.6 이하세어는 Undo tablespace 관리를 하지만 5.7 이상부터는 별도의 언두로그 파일이 관리를 합니다. 보통 ibdata1 생성이 됩니다.

실행 취소 로그의 삽입 또는 업데이트 부분을 롤백 세그먼트라고 합니다. innodb_undo_logs 시스템 변수는 트랜잭션당 사용할 롤백 세그먼트 수를 지정합니다.

관련된 innodb_available_undo_logs 상태 변수는 사용 가능한 InnoDB 실행 취소 로그의 수를 저장합니다.

 

innodb-rollback-segments

Command-Line Format --innodb-rollback-segments=#
시스템 변수 innodb_rollback_segments
범위 글로벌
동적여부 가능
유형 정수형
기본값 128
최소값 1
최대값 128

 

실행 취소 레코드를 생성하는 트랜잭션에 대해 InnoDB에서 사용하는 롤백 세그먼트의 수를 정의합니다. 롤백 세그먼트가 지원하는 트랜잭션 수는 InnoDB 페이지 크기와 트랜잭션에 할당된 실행 취소 로그 수에 따라 다릅니다.

 

하나의 롤백 세그먼트는 항상 시스템 테이블스페이스에 할당되고 32개의 롤백 세그먼트는 임시 테이블에서 사용하도록 예약되어 임시 테이블스페이스(ibtmp1) 상주합니다. 추가 롤백 세그먼트를 할당하려면 innodb_rollback_segments 33보다 값으로 설정해야 합니다. 별도의 실행 취소 테이블스페이스를 구성하면 시스템 테이블스페이스의 롤백 세그먼트가 비활성화됩니다.

innodb_rollback_segments 32 이하로 설정되면 InnoDB 하나의 롤백 세그먼트를 시스템 테이블스페이스에 할당하고 32 임시 테이블스페이스에 할당합니다.

innodb_rollback_segments 32보다 값으로 설정되면 InnoDB 하나의 롤백 세그먼트를 시스템 테이블스페이스에 할당하고 32 임시 테이블스페이스에 할당하고 추가 롤백 세그먼트를 할당하여 존재하는 경우 실행 취소 테이블스페이스에 할당합니다. 실행 취소 테이블스페이스가 없으면 시스템 테이블스페이스에 추가 롤백 세그먼트가 할당됩니다.

InnoDB에서 사용하는 롤백 세그먼트의 수를 늘리거나 줄일 있지만 시스템에 물리적으로 존재하는 롤백 세그먼트의 수는 결코 줄어들지 않습니다. 따라서 낮은 값으로 시작하여 필요하지 않은 롤백 세그먼트를 할당하지 않도록 점차적으로 값을 늘릴 있습니다. innodb_rollback_segments 기본값과 최대값은 128입니다.

 

관련 링크 :

https://myinfrabox.tistory.com/49

 

[MySQL][InnoDB] Double Write buffer, Undo Log, Redo Log

■ Doublewrite Buffer 이중 쓰기 버퍼는 InnoDB 데이터 파일의 적절한 위치에 페이지를 쓰기 전에 InnoDB가 버퍼 풀에서 플러시 된 페이지를 쓰는 저장 영역입니다. 페이지 쓰기 도중에 운영 체제, 스토

myinfrabox.tistory.com

 

참고 링크 :

https://devlog-wjdrbs96.tistory.com/368

https://dev.mysql.com/doc/refman/5.7/en/innodb-undo-logs.html

https://dus815.tistory.com/entry/Mysql-Undo-Log-%EB%9E%80?category=580433

https://mariadb.com/kb/en/innodb-undo-log/

 

 

도움이 되셨다면 광고클릭 한번 부탁드립니다.

댓글(0)

Designed by JB FACTORY