MySQL 의 InnoDB 는 트랜잭션을 제공하여 데이터의 원자성을 유지한다. 트랜잭션 도중 에러가 발생하면 변경되기 이전의 데이터로 롤백한다. 또한 다른 트랜잭션에서 데이터를 변경하고 있다고 하더라도 변경되지 않은 데이터를 조회할 수 있다. 이러한 롤백 및 다른 트랜잭션과의 격리를 제공할 수 있도록 도와주는 것이 언두로그이며, 언두로그를 관리하는 방식을 MVCC 라고 부른다.

Undo Log

트랜잭션을 관리하기 위해 변경되기 전의 데이터를 관리하는 데이터이다. 트랜잭션 내에서 데이터를 변경하면 변경되기 전의 데이터를 언두로그 영역에 저장한다. 이는 트랜잭션에서 에러가 발생하여 롤백을 하거나, 다른 트랜잭션에서 데이터 조회 시 커밋되기 전의 데이터를 조회할 때 이용한다.

언두로그는 개발자에게 편의성을 제공하지만 주의해야 할 점이 있다. 트랜잭션 내에서의 데이터 변경 사항을 모두 보유하고 있기 때문에 한 트랜잭션 내에서 크기가 매우 큰 데이터를 변경할 경우 동일한 크기의 언두로그가 생성된다. 언두로그의 데이터가 사라지기 전까지는 거대한 크기의 데이터를 보유하고 있는 셈이다.

혹은 트랜잭션의 시간이 매우 길어지면 문제가 발생할 수도 있다. 격리 수준을 보장하기 위해 가장 오랜된 트랜잭션을 기준으로 트랜잭션 이후에 발생한 트랜잭션들의 언두로그는 모두 보존한다. 가장 오래된 트랜잭션에서 어떤 데이터에 접근할지 알 수 없기 때문에 트랜잭션이 시작되었던 시점의 데이터를 기억해야하기 때문이다. 언두로그는 해당 영역을 필요로 하는 트랜잭션이 없을 때야 비로소 삭제된다.

언두로그 영역도 결국은 데이터이기 때문에 DB 서버의 데이터 사용량이 급격하게 늘어날 수 있으므로 모니터링을 통해서 관리하는 과정이 필요하다.

MVCC(Multi Version Concurrency Control)

MVCC 의 ‘멀티 버전’ 은 하나의 레코드에 대해 여러 개의 버전으로 관리되고 있다는 의미이다. 트랜잭션을 관리하기 위해 MySQL 에서는 언두로그 방식을 택했다. 실제로 저장되는 디스크(및 메모리) 의 데이터 말고도 언두로그 영역에서 동일한 데이터를 관리하여 최소 두 곳 이상에서 관리하고 있는 셈이다.

트랜잭션의 격리 수준이 READ_UNCOMMITTED 일 경우 실시간으로 데이터의 변경이 반영되는 InnoDB 버퍼 풀을 읽어온다. 즉, 트랜잭션에서 커밋 되기 전의 데이터를 조회한다. READ_COMMITTED 또는 그 이상의 수준일 경우 언두로그 영역의 데이터를 읽어온다. 언두로그 영역의 데이터를 읽음으로써 커밋이 반영된 데이터만을 읽을 수 있게 된다.