데이터베이스

[데이터베이스] MySql InnoDB의 버퍼 풀(Buffer Pool)과 언두로그(Undo log)

딘딘은딘딘 2024. 12. 20. 18:43
반응형

MySQL의 InnoDB는 내부 구조와 프로세스가 매우 복잡해 우선 MVCC를 이해하기 위해 버퍼 풀과 언두로그에 대한 간단한 정리이다. 

 

버퍼 풀(Buffer Pool)

버퍼 풀은 MySQL InnoDB 스토리지 엔진에서 성능을 최적화하기 위해 사용하는 메모리 영역으로. 디스크 I/O를 최소화하고, 데이터와 인덱스에 빠르게 접근할 수 있도록 설계되어 InnoDB 스토리지 엔진의 가장 핵심적인 부분이다. 이런 특징 때문에 데이터베이스에서 자주 읽고 쓰는 데이터를 메모리에 캐싱하여 디스크 접근 시간을 줄이고 성능을 향상시킬 수 있다.

 

InnoDB 스토리지 엔진의 구조


 * 주요 기능

  1. 데이터 및 인덱스 캐싱:
    • 자주 사용되는 데이터 페이지와 인덱스를 메모리에 저장해 디스크 I/O를 줄이고 빠른 데이터 접근을 가능하게 한다.
  2. 쓰기 지연(Write Buffering):
    • 데이터 변경 작업은 디스크에 바로 기록되지 않고, 버퍼 풀에 저장된 후 특정 조건에 따라 디스크로 기록된다.(지연 쓰기).
  3. 프리페치(Pre-fetching):
    • 쿼리 패턴에 따라 데이터를 미리 읽어들여 성능을 최적화한다.
    • 순차적으로 데이터를 읽는 경우, 다음 데이터를 미리 버퍼 풀에 로드한다.
  4. LRU 알고리즘 관리:
    • 메모리를 효율적으로 사용하기 위해 Least Recently Used (LRU) 알고리즘을 활용해 오래 사용되지 않은 페이지를 제거하고 새로운 데이터를 로드한다.
  5. 트랜잭션 지원:
    • 언두 로그(Undo Log)와 연계하여 데이터 일관성과 복구를 보장하며, 트랜잭션 롤백을 지원.

* 버퍼 풀의 구조

1) LRU 리스트

  • 자주 사용되는 페이지를 유지하고, 오래 사용되지 않은 페이지는 교체할 때 가장 먼저 제거하는 리스트
  • 동작 방식:
    • 새로 로드된 페이지는 리스트의 중간 위치에 삽입된다.
    • 최근 사용된 페이지는 리스트의 앞으로 이동한다.
    • 공간이 부족하면 리스트의 뒷부분 페이지가 제거된다.

2) 프리 리스트(Free List)

  • 사용되지 않는 빈 페이지들의 목록입니다. 새로운 데이터 페이지를 로드할 때 여유 공간을 제공.
  • 동작 방식:
    • 사용 가능한 페이지가 부족하면 디스크에서 공간을 확보해 리스트에 추가.

3) 플러시 리스트(Flush List)

  • 설명: Dirty Page 목록. 디스크에 기록해야 할 페이지를 추적한다.
  • 동작 방식:
    • Dirty Page는 일정 주기나 조건(버퍼 풀이 가득 찼을 때 등)에 따라 디스크로 기록됨.

4) Dirty Page

  • 설명: 변경되었으나 아직 디스크에 기록되지 않은 페이지.
  • 중요성: 쓰기 작업을 지연시키고 디스크 I/O를 줄이는 핵심 요소

5) 언두 로그 캐싱

  • 설명: 데이터 변경 전의 상태를 기록하며, 트랜잭션 롤백 및 읽기 일관성을 위해 사용된다
  • 동작 방식:
    • 버퍼 풀에 언두 로그 페이지가 캐싱된다.

* 각 구조별 설명

1) LRU 리스트

  • 목적: 메모리를 효율적으로 관리하고 디스크 접근을 줄이기 위해 자주 사용되는 데이터를 유지한다.
  • 삽입 규칙: 새로 로드된 페이지는 중간 위치에 삽입하여 자주 사용되는 데이터가 LRU 리스트의 상단에 유지되도록 한다.

2) 프리 리스트

  • 목적: 새 데이터를 로드할 때 사용할 수 있는 공간을 제공.
  • 재활용: 디스크로 기록된 페이지는 다시 프리 리스트에 추가되어 재사용된다.

3) 플러시 리스트

  • 목적: Dirty Page를 디스크에 기록할 시점을 관리.
  • 플러시 트리거:
    • 시스템이 종료될 때.
    • 메모리가 부족할 때.
    • 주기적인 체크포인트 작업에서 실행.

4) Dirty Page

  • 상태: 데이터가 변경되었으나 디스크에 기록되지 않은 상태.
  • 관리 방법: 변경된 페이지는 Dirty Page로 표시되며, 플러시 작업을 통해 디스크로 기록된다.

5) 언두 로그

  • 목적: 데이터 변경 전 상태를 저장하여 트랜잭션 롤백 및 MVCC(다중 버전 동시성 제어)를 지원.
  • 버퍼 풀과의 관계: 언두 로그 페이지도 버퍼 풀에 캐싱되어 빠르게 접근 가능.

* 버퍼 풀 작동 방식

  1. 읽기 작업:
    • 데이터 요청이 들어오면 먼저 버퍼 풀에서 해당 데이터 페이지를 검색
    • 버퍼 풀에 데이터가 없을 경우, 디스크에서 데이터를 읽어와 버퍼 풀에 저장한다. (LRU 리스트에 삽입).
  2. 쓰기 작업:
    • 데이터 변경은 버퍼 풀에 먼저 기록되며, Dirty Page로 표시됩니다.
    • Dirty Page는 일정 주기나 조건에 따라 플러시 리스트에 추가되고, 디스크에 기록된다.
  3. 공간 확보:
    • 버퍼 풀이 가득 차면 LRU 리스트의 오래된 페이지를 제거하여 공간을 확보한다.
  4. 프리페치(Pre-fetching):
    • 순차적인 쿼리 패턴을 감지하면, 디스크에서 연속된 페이지를 미리 읽어 버퍼 풀에 로드한다.

* 예시

  1. 사용자가 특정 데이터를 요청 하는 경우
    • Step : 데이터가 버퍼 풀에 있는지 확인.
      • 존재하면 → 즉시 데이터 반환.
      • 존재하지 않으면 → 디스크에서 데이터를 읽어 버퍼 풀에 로드한 후 반환.
  2. 사용자가 데이터를 수정 하는 경우
    • Step 1: 수정된 데이터는 버퍼 풀에 저장되며 Dirty Page로 표시.
    • Step 2: 플러시 리스트에 추가되며, 주기적으로 디스크에 기록.
  3. 데이터가 자주 읽히는 경우.
    • Step : 자주 읽히는 데이터는 LRU 리스트 상단에 유지되며, 디스크 접근 없이 메모리에서 제공된다.

 

 

 

언두로그(Undo log)

언두 로그는 데이터 변경 전의 상태(이전 값)를 기록하는 로그입니다. 이는 데이터베이스가 트랜잭션 롤백(rollback)을 수행하거나, 트랜잭션 격리 수준을 보장하기 위해 사용된다.

그리고 언두로그는 데이터 변경 시점에 생성되며, 트랜잭션이 커밋된 이후에는 특정 조건에 따라 삭제 된다.

 

* 언두로그의 주요 역할

  • 롤백 지원
    • 데이터 변경이 완료되기 전에 트랜잭션이 실패하거나 명시적으로 롤백되면, Undo Log를 통해 데이터베이스를 트랜잭션 시작 이전 상태로 되돌리는 역할을 한다.
  • MVCC 구현:
    • 다중 버전 동시성 제어(Multi-Version Concurrency Control)를 위해 이전 데이터를 보관하고 격리수준을 지원한다.
    • SELECT 쿼리와 같은 읽기 작업에서, 트랜잭션 격리 수준을 보장하기 위해 Undo Log를 사용하여 스냅샷을 제공
    • 예를 들어, REPEATABLE READ 격리 수준에서 트랜잭션이 시작된 시점의 데이터를 읽기 위해 언두로그를 활용한다.

* 언두로그의 작동 방식

1) 트랜잭션 시작

  • 트랜잭션이 데이터를 변경하기 전에, InnoDB는 변경 이전 데이터를 언두로그에 기록한다.

2) 데이터 변경

  • 실제 데이터를 변경한 후, 변경 사항은 Redo Log에 기록되어 영구적으로 저장할 준비를 한다.

3) 롤백 발생 시

  • 트랜잭션이 실패하거나 롤백되면, 언두로그를 참조하여 데이터 변경을 되돌린다.

4) MVCC 동작

  • 다른 트랜잭션에서 언두로그를 참조해 데이터 변경 이전의 스냅샷을 읽어온다. 이는 읽기 작업이 데이터 변경 작업과 충돌하지 않도록 보장하는 역할을 한다.

* Insert Undo Log와 Update Undo Log

 

  • Insert Undo Log
    • 새로운 레코드 삽입 작업의 언두 로그
    • 트랜잭션 롤백에만 사용되고, MVCC에는 사용되지 않는다.
    • 트랜잭션이 커밋되면 즉시 삭제됨
  • Update Undo Log
    • 기존 레코드 변경 작업의 언두 로그
    • 롤백뿐만 아니라 MVCC 스냅샷 제공에도 사용된다.
    • 트랜잭션이 커밋되더라도, 다른 트랜잭션에서 참조 중인 경우 삭제되지 않는다.

 


* 언두로그의 생성과 삭제 시점

  • 생성시점
    • 언두로그는 데이터 변경 시점에 생성된다.
    • 트랜잭션이 데이터를 수정하려고 하면, InnoDB는 변경 이전 데이터를 언두로그에 기록한다.
    • 이는 롤백 시 데이터 복구 및 MVCC를 지원하기 위해 필요한 과정이다.
    • 예시) 만약 employees 테이블의 id가 1인 salary 컬럼의 값이 3000이라고 했을때 UPDATE문이 실행되며 데이터가 변경되는 시점에 언두로그에는 변경 전 데이터인  salary가 3000인 값이 기록된다.
UPDATE employees SET salary = 5000 WHERE id = 1;

 

  • 삭제 시점
    • 트랜잭션이 커밋된 경우
      • Insert Undo Log
        • Insert된 데이터는 커밋되면 다른 트랜잭션에서 읽을 필요가 없기 때문에 Insert 작업과 관련된 언두로그는 커밋 후 바로 삭제된다.
      • Update Undo Log
        • MVCC를 위해 다른 트랜잭션이 해당 Undo Log를 참조할 수 있기 때문에 Update 작업과 관련된 언두로그는 참조 중인 트랜잭션이 없을 때 삭제된다.
        • Ex) 트랜잭션 A가 커밋되었지만, 트랜잭션 B가 아직 A의 이전 데이터를 읽고 있다면 해당 언두로그는 삭제되지 않는다.
    • 트랜잭션이 롤백된 경우
      • 롤백 시 언두로그를 사용해 데이터를 변경 이전 상태로 복원한다.
      • 복원 작업이 완료되면 해당 언두로그는 삭제됨.
    • 참조가 끝난 경우
      • 트랜잭션이 커밋되었더라도, 다른 트랜잭션이 언두로그를 참조하고 있다면 삭제되지 않는다.
      • 침조 중인 모든 트랜잭션이 종료되면 언두로그는 삭제된다.

* InnoDB Purge Thread

  • InnoDB Purge Thread는 MySQL의 InnoDB 스토리지 엔진에서 MVCC 및 트랜잭션 롤백을 지원하기 위해 사용된 언두로그와 애플리케이션에서 더 이상 필요하지 않은 이전 데이터를 정리하는 백그라운드 작업 스레드이다.
  • 백그라운드에서 Purge Thread를 통해 더 이상 참조되지 않는 언두로그를 자동으로 삭제하는 역할을 한다. 즉, 자동으로 테이블 스페이스를 최적화 하는 기능이라고 보면 된다.

 

* 언두로그(Undo Log)와 리두로그(Redo Log)의 차이

언두로그와 리두로그는 모두 트랜잭션과 데이터 무결성을 유지하는 데 중요한 역할을 하지만, 목적과 사용 방식이 다르고 아래와 같이 정리할 수 있다.

특징 언두로그(Undo Log) 리두로그(Redo Log)
목적 데이터 변경 이전 상태 복구 데이터 변경을 영구적으로 디스크에 반영
용도 롤백 및 MVCC 충돌 복구 및 커밋된 변경 사항 저장
기록 시점 트랜잭션 시작 전에 기록 데이터 변경 후 기록
삭제 시점 참조가 끝나면 삭제 체크포인트 이후 삭제

 

반응형