Loading...
MySQL 9.5 Reference Manual 9.5의 17.3 InnoDB Multi-Versioning의 한국어 번역본입니다.
아래의 경우에 피드백에서 신고해주신다면 반영하겠습니다.
감사합니다 :)
InnoDB는 멀티버전 스토리지 엔진입니다. 이 엔진은 동시성 및 롤백과 같은 트랜잭션 기능을 지원하기 위해 변경된 row의 이전 버전에 대한 정보를 유지합니다. 이 정보는 롤백 세그먼트라고 하는 데이터 구조 내의 undo 테이블스페이스에 저장됩니다. 자세한 내용은 Section 17.6.3.4, “Undo Tablespaces”를 참조하십시오.
InnoDB는 트랜잭션 롤백에 필요한 undo 작업을 수행하기 위해 롤백 세그먼트에 있는 정보를 사용합니다. 또한 일관된 읽기를 위해 row의 이전 버전을 구성하는 데에도 이 정보를 사용합니다. 자세한 내용은 Section 17.7.2.3, “Consistent Nonlocking Reads”를 참조하십시오.
내부적으로, InnoDB는 데이터베이스에 저장된 각 row에 세 개의 필드를 추가합니다:
6바이트 DB_TRX_ID 필드는 해당 row를 마지막으로 insert 또는 update한 트랜잭션 식별자를 나타냅니다. 또한, 삭제는 내부적으로는 row를 삭제된 것으로 표시하는 특수 비트가 설정된 update로 처리됩니다.
7바이트 DB_ROLL_PTR 필드는 롤 포인터라고 불립니다. 롤 포인터는 롤백 세그먼트에 기록된 undo 로그 레코드를 가리킵니다. row가 update된 경우, undo 로그 레코드는 update되기 전 row의 내용을 재구성하는 데 필요한 정보를 포함합니다.
6바이트 DB_ROW_ID 필드는 새로운 row가 insert될 때 단조 증가하는 row ID를 포함합니다. InnoDB가 클러스터드 인덱스를 자동으로 생성하는 경우, 해당 인덱스는 row ID 값을 포함합니다. 그렇지 않다면, DB_ROW_ID 컬럼은 어떤 인덱스에도 나타나지 않습니다.
롤백 세그먼트의 undo 로그는 insert undo 로그와 update undo 로그로 구분됩니다. insert undo 로그는 트랜잭션 롤백에서만 필요하며, 트랜잭션이 커밋되는 즉시 폐기할 수 있습니다. update undo 로그는 일관된 읽기에도 사용되지만, InnoDB가 스냅샷을 부여한 트랜잭션 중에서 일관된 읽기를 수행할 때 데이터베이스 row의 이전 버전을 구성하기 위해 해당 update undo 로그의 정보가 필요할 수 있는 트랜잭션이 더 이상 존재하지 않을 때만 폐기할 수 있습니다. undo 로그에 대한 추가 정보는 Section 17.6.6, “Undo Logs”를 참조하십시오.
일관된 읽기만 수행하는 트랜잭션을 포함하여, 트랜잭션을 정기적으로 커밋하는 것이 권장됩니다. 그렇지 않으면, InnoDB는 update undo 로그에서 데이터를 폐기할 수 없고, 롤백 세그먼트가 너무 커져서 그 세그먼트가 위치한 undo 테이블스페이스를 가득 채울 수 있습니다. undo 테이블스페이스 관리에 대한 정보는 Section 17.6.3.4, “Undo Tablespaces”를 참조하십시오.
롤백 세그먼트에서 undo 로그 레코드의 물리적 크기는 일반적으로 해당 insert 또는 update된 row의 크기보다 작습니다. 이 정보를 사용하여 롤백 세그먼트에 필요한 공간을 계산할 수 있습니다.
InnoDB 멀티버전 방식에서는 SQL statement로 row를 delete하더라도 데이터베이스에서 해당 row가 즉시 물리적으로 제거되지는 않습니다. InnoDB는 delete를 위해 기록된 update undo 로그 레코드를 폐기할 때에만 해당 row와 그 인덱스 레코드를 물리적으로 제거합니다. 이 제거 작업을 purge라고 하며, 보통 delete를 수행한 SQL statement와 비슷한 수준의 시간만 소요될 정도로 상당히 빠릅니다.
테이블에서 대략 비슷한 속도로 row를 작은 배치 단위로 insert 및 delete하는 경우, purge 스레드가 뒤처지기 시작할 수 있고, 테이블은 모든 “dead” row 때문에 점점 더 커지며, 이로 인해 모든 작업이 디스크 바운드가 되어 매우 느려질 수 있습니다. 이러한 경우, 새로운 row 작업을 제한(throttle)하고, innodb_max_purge_lag 시스템 변수 튜닝을 통해 purge 스레드에 더 많은 리소스를 할당하십시오. 자세한 내용은 Section 17.8.9, “Purge Configuration”을 참조하십시오.
InnoDB 멀티버전 동시성 제어(MVCC)는 세컨더리 인덱스를 클러스터드 인덱스와 다르게 처리합니다. 클러스터드 인덱스의 레코드는 제자리(in-place)에서 update되며, 숨겨진 시스템 컬럼은 이전 버전의 레코드를 재구성할 수 있는 undo 로그 엔트리를 가리킵니다. 클러스터드 인덱스 레코드와 달리, 세컨더리 인덱스 레코드는 숨겨진 시스템 컬럼을 포함하지 않으며 제자리에서 update되지도 않습니다.
세컨더리 인덱스 컬럼이 update될 때, 이전 세컨더리 인덱스 레코드는 삭제 대상으로 표시(delete-mark)되고, 새로운 레코드가 insert되며, 삭제 대상으로 표시된 레코드는 결국 purge됩니다. 세컨더리 인덱스 레코드가 삭제 대상으로 표시되었거나 세컨더리 인덱스 페이지가 더 새로운 트랜잭션에 의해 update되면, InnoDB는 클러스터드 인덱스에서 데이터베이스 레코드를 조회합니다. 클러스터드 인덱스에서 해당 레코드의 DB_TRX_ID가 확인되며, 읽기 트랜잭션이 시작된 이후 레코드가 변경되었다면 undo 로그에서 올바른 버전의 레코드를 가져옵니다.
세컨더리 인덱스 레코드가 삭제 대상으로 표시되었거나 세컨더리 인덱스 페이지가 더 새로운 트랜잭션에 의해 update된 경우, covering index 기법은 사용되지 않습니다. 인덱스 구조에서 값을 반환하는 대신, InnoDB는 클러스터드 인덱스에서 레코드를 조회합니다.
그러나 index condition pushdown (ICP) 최적화가 활성화되어 있고, WHERE 조건의 일부를 인덱스 필드만 사용하여 평가할 수 있는 경우, MySQL 서버는 여전히 WHERE 조건의 이 부분을 스토리지 엔진으로 푸시하여 인덱스를 사용해 평가합니다. 일치하는 레코드가 발견되지 않으면 클러스터드 인덱스 조회는 수행되지 않습니다. 삭제 대상으로 표시된 레코드를 포함해 일치하는 레코드가 발견된 경우, InnoDB는 클러스터드 인덱스에서 해당 레코드를 조회합니다.
17.2 InnoDB and the ACID Model
17.4 InnoDB Architecture