본문 바로가기
MySQL Internal/InnoDB Internal

InnoDB의 rollback segment에 대한 구조 설명에 관한 문서

by 모모레 2014. 1. 20.

-참고-

이 글은 다음의 영문글을 번역한 겁니다.

번역오류가 있다면 알려주세요

전 영어 번역 전문가는 아니라서요...^^;

https://blogs.oracle.com/mysqlinnodb/entry/better_scalability_with_multiple_rollback



By Calvin Sun


1. Background

고질적인 문제였던 버그#26590에 대한 이야기 이다. - MySQL은 현재 사용하는 트랜잭션의 갯수로 1023보다 더 많은 트랜잭션을 사용할 수가 없다. 실질적으로 InnoDB에서 현재 동시에 update에 사용하는 트랜잭션의 수가 1024 limit을 사용하고 있다는 것이다. 왜 이 수인가?

1024는 하나의 rollback segment header page의 undo log list slot의 총 숫자이다. 이전의 InnoDB에서는 하나의 인스턴스에서 하나의 rollback segment header page만 생성이 가능했다. rollback segment의 header page는 system header page에 위치하고 있고, 그것은 단지 128개의 rolback segment만을 위한 공간으로 결국 1024 제약조건이 되는 것이다. rollback segment header의 각각의 slot은 {space_id, page_no}의 묶음의 array로 되어있는데, 이것은 uint32_t 타입으로 되어있다. space id는 "unused"로 되어있고, space id는 tablespace 0인 system tablespace를 가르키고 있다. 

Now, onto the rollback segmgnet header page. 이 페이지는 rollback segment header를 포함하고 있다. (자세한 내용은 이 블로그의 주제를 벗어 나므로.. 대충 넘어간다.) 여기에는 1024 UNDO Slot의 array가 따른다. 각각의 slot은 UNDI log의 파일 base의 linked list의 기본 노드가 된다. file base list의 각 노드는 UNDO log record를 포함한다. 이때 UNDO log record는 트랜잭션에 의해 수정된 데이터를 포함한다. 하나의 UNDO log node는 여러 다른 트랜잭션의 UNDO entries를 포함할 수 있다.


2. Performance ramifications

트랜잭션은 시작할 때 수정작업을 위한 rollback segment를 할당받는다. 여러 트랜잭션들은 같은 rollback segment를 할당 받을 수 있다. 하지만, 단지 하나의 트랜잭션만 UNDO slot 에 수정작업을 할 수 있다. This should make clear where the 1024 limit comes from. 각각의 rollback segment는 그 자신의 mutex에 의해 보호된다. 우리가 하나의 rollback segment를 가지고 있을 때, 이 rollback segment mutex는 high contention mutex가 될 수 있다.


3. Requirements

파일 포맷의 하위 호환성은 InnoDB에서는 굉장히 심각하게 받아들여질 수 있다. InnoDB는 항상 128 page를 모두 고갈시킬 수 있는 능력을 가지고 있다. 그러나, 그것을 수정하기 전에 InnoDB는 단지 하나의 rollback segment만을 생성하였다. 우리는 Old version의 InnoDB의 소스 변경없이 하위 호환성을 변경하여 여러개의 rollback segment를 만드는 것으로 해결을 하려고 하였다. The 128 Limit is a result of the latter. 256 개의 rollback segment를 위한 공간이 있는 동안, InnoDB는 그 필드로 부터 단지 7 bit만 사용하면 된다. 그래서 우리는 현재 128개로 충분하지만, 256개의 rollback segment를 사용할 수 있게 수정했다. There are other scalability issues that need to be addressed first before 128k concurrent transactions will become an issue.


4. The solution

하위 호환성을 유지하기 위해, 새로 추가되는 rollback segment는 double write buffer 후에 생성한다. 우리는 256이 아니라 128개의 rollback segement의 총 수를 유지한다. 그리고, 나머지 slot은 NULL로 설정해 놓는다. 이것은 old version과의 호환성 때문이다. 이것은 InnoDB oldversion에서 추가적인 rollback segment로 부터 이득이 있을 수 있음을 의미한다. 만약 새버젼에서 추가적인 rollback segment를 사용하고자 했다가 다시 old version으로 가기로 했다더라도, 문제가 되지 않을 것이다. 이 수정사항을 포함한 새로운 InnoDB는 현재 인스턴스에서 innodb_force_recovery flag를 설정하지 않고, 추가적인 segment를 생성할 수 있을 것이다.  그리고, 정상적으로 shutdown 될 것이다. 추가적인 segment는 새로운 인스턴스를 생성할 때 기본적으로 생성될 것이다. 



여기서 내가 번역을 통해 알고 싶었던 것은 버그의 내용 보다는 다음의 내용이다. 


InnoDB는 하나의 rollback segment header page를 생성하고,

그 페이지에서 rollback segment header를 관리한다.

여기에는 1024개의 undo slot이 존재하고,

각 slot은 파일 기반의 undo log의 linked list의 base node가 된다.

파일 기반의 node list는 undo log record를 포함하고 있고,

그 undo log record는 트랜잭션에서 사용하는 데이터의 변경 내역을 가지고 있다.

각각의 undo log node는 여러 트랜잭션에서 사용하는 undo entries를 포함할 수 있다. 

그리고 사용가능한 rollback segment는 총 128개 이다.

추가적으로 생성하여 사용가능한 rollback segment  갯수는 256개 이다.


내가 해석한게 맞나 몰겠네....흠냐........