[PostgreSQL] Vacuum의 마지막 수수께끼였던 FrozenXID에 대한 고찰

Vacuum을 연구함에 있어서 FrozenXID는 풀리지 않던 마지막 숙제였습니다.

Anti-Wraparound Vacuum 수행 시에 XMIN 값을 FrozenXID로 변경할까?

 

만일 그렇다면 대량의 리두가 발생할 텐데, 과연 그렇게 비효율적인 처리를 수행할 것인가? 하는 의문인 것이죠.  그렇다고, 현재의 PostgreSQL의 구조상으로는 딱히 다른 방법이 있을 것 같지도 않았습니다. 9.6 버전에서 50억 가까운 트랜잭션을 발생시킨 후에도 XMIN 값이 변경되지 않는 것을 확인했습니다. 9.4, 9.5에서도 동일한 테스트를 해본 결과 역시 XMIN 값이 변경되지 않는 것을 확인했습니다. 여기까지 테스트한 후에 약간의 멘붕이 왔습니다. 대부분의 문서, 심지어 매뉴얼까지도 Anti-Wraparound Vacuum 수행 시에는 XMIN 값을 FrozenXID(2)로 replace 한다고 되어있기 때문입니다.

테스트를 접을까 하다, 마음을 가다듬고 9.1부터 다시 테스트를 시작해보기로 했습니다. 수행 결과, 9.1, 9.2, 9.3까지는 Anti-Wraparound Vacuum 수행 후에 실제로 XMIN 값을 FrozenXID인 2로 변경하는 것을 확인했습니다. 그리고 뒤 늦은 구글링 검색 결과, 9.4부터는 XMIN 값을 FrozenXID로 변경하지 않고, Flag로 처리한다는 사실을 발견했습니다 (좀 더 일찍 발견했다면 일주일 이상 삽질을 하지 않았을 텐데요. 하지만 좋은 경험이었습니다)

Note
PostgreSQL은 XID를 Permanent XID와 Normal XID로 구분합니다. 또한 Permanent XID는 Bootstrap XID (initdb시의 할당되는 XID임. 값은 1)와 FrozenXID (2)로 구분됩니다. 즉, 일반 트랜잭션의 시작 XID는 3부터입니다. 따라서 XMIN 값을 FrozenXID(2)로 변경하면, 해당 레코드는 항상 “Visible”한 상태가 됩니다.

하지만 Anti-Wraparound Vacuum 시에 XMIN 값을 실제로 변경하던, Flag를 변경하던 간에 레코드에 변경이 발생하게 되고 이로 인해 WAL 로그가 발생합니다. 즉, Vacuum 수행 시에 WAL 로그가 발생하는 것은 이와 같이 Anti-Wraparound Vacuum에 의해서 테이블 내의 변경이 발생하는 경우라고 보면 됩니다.
이상으로 베큠에 대한 정리를 마무리하도록 하겠습니다.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s