profile image

L o a d i n g . . .

728x90

INSERT, UPDATE, DELETE 등의 DML이 수행될 때 디스크상의 데이터 파일에 변경사항을 즉시 반영하는 것은 성능에 부정적인 영향을 미칠 수 있습니다. 이는 변경해야 하는 데이터 파일이 디스크에 랜덤 하게 위치하기 때문입니다. MySQL은 리두 로그와 체크포인트를 활용해 변경사항을 일괄적으로 처리해 성능을 최적화합니다. 

 

Redo Log 

트랜잭션은 ACID 속성을 지니고 있습니다. ACID를 풀이하면 다음과 같습니다. 

  • A(Atomicity): 원자성을 의미합니다. 트랜잭션으로 묶인 작업은 모두 성공하거나 모두 실패해야 한다는 속성입니다. 
  • C(Consistency): 트랜잭션에 의해 조작된 데이터는 일관성을 유지할 수 있음을 의미합니다. 주의할 점은 데이터의 일관성을 유지하기 위해서는 트랜잭션뿐 아니라 애플리케이션 레벨에서 데이터 일관성을 보존하기 위한 작업이 필요하다는 점입니다. 
  • I(Isolation): 동시에 실행되는 트랜잭션이 서로 영향을 주지 않고 독립적으로 실행된 것과 동일한 결과를 보장하는 트랜잭션의 속성입니다. Isolation level에 따라 트랜잭션 간 미치는 영향의 정도를 조절할 수 있습니다. 
  • D(Durability): 트랜잭션으로 인한 변경사항은 커밋 이후 저장소에 영구적으로 저장됨을 보장하는 속성입니다. 

트랜잭션이 커밋되는 시점마다 버퍼 풀의 더티 페이지를 데이터 파일에 바로 기록하는 것은 성능적으로 좋지 않습니다. 디스크에 랜덤 액세스가 발생하여 처리 속도가 저하될 수 있기 때문입니다. InnoDB는 트랜잭션의 Durability 속성을 보장하면서도 디스크에 변경사항을 일괄적으로 반영하기 위해 리두 로그를 활용합니다.

트랜잭션의 변경사항은 우선 버퍼 풀에 기록되며, 트랜잭션 커밋 시점에 디스크에 반영되어야 합니다. InnoDB는 변경사항을 데이터 파일에 바로 반영하는 대신, 리두 로그에 우선 추가합니다. 이후 체크포인트를 수행하여 변경사항을 데이터 파일에 반영합니다.

버퍼 풀에 로드된 페이지 중 변경됐지만 아직 디스크로 플러시 되지 않은 페이지를 더티 페이지(dirty page)라고 부릅니다. 

 

Checkpoint 

InnoDB는 체크포인트를 통해 버퍼 풀의 더티 페이지를 디스크의 데이터 파일에 일괄적으로 반영합니다. 그러나 모든 더티 페이지를 한 번에 디스크로 반영하면 어떻게 될까요? 더티 페이지의 수가 많으면 체크포인트 수행 시간이 길어지고, 이는 클라이언트 요청을 처리하는데 영향을 줄 수 있습니다. 이를 방지하기 위해 InnoDB는 퍼지 체크포인팅(fuzzy checkpointing) 기법을 사용합니다. 이 기법은 체크포인트를 더 작은 단위로 분할하여 수행함으로써 클라이언트 요청을 처리하는데 미치는 영향을 최소화합니다.

 

Redo Log & Checkpoint

리두 로그와 체크포인트에 대해 살펴봤으니 그 다음으로는 클라이언트의 쓰기 요청이 디스크의 데이터 페이지에 반영되는 전체적인 흐름을 살펴보겠습니다. 

Redo Log & Checkpoint

  1. 클라이언트는 DML 요청을 보냅니다. 
  2. 변경이 필요한 데이터를 포함한 버퍼 풀 페이지를 업데이트합니다. 
  3. 변경사항을 로그 버퍼에 기록합니다.
  4. 로그 버퍼에 저장된 변경사항은 innodb_flush_log_at_trx_commit 설정에 따라 리두 로그에 플러시 됩니다.
  5. 주기적인 체크포인트를 통해 버퍼 풀의 더티 페이지가 디스크에 플러시 됩니다.

innodb_flush_log_at_trx_commit 설정은 트랜잭션의 Durability와 InnoDB의 I/O 성능을 조절하기 위한 설정으로, 0, 1, 2 중 하나의 값을 선택할 수 있으며, 기본값은 1입니다.

  • 0: 1초 주기로 로그 버퍼의 변경사항이 디스크로 플러시 됩니다. 디스크로 플러시 되지 않은 변경사항은 트랜잭션 커밋이 완료됐더라도 유실될 수 있습니다.
  • 1: 트랜잭션이 커밋되는 시점에 로그 버퍼의 변경사항을 디스크로 플러시 합니다. 변경사항 유실을 방지하기 위해서는 "innodb_flush_log_at_trx_commit = 1"을 사용하도록 권고하고 있습니다.
  • 2: 트랜잭션이 커밋되는 시점과 1초 주기로 로그 버퍼의 변경사항을 디스크로 플러시 합니다.
728x90
복사했습니다!