DBMS/MySQL

InnoDB 개념 정리

반응형

InnoDB 개요


  • 클라이언트의 데이터 읽고 쓰기 요청에 대한 응답은 모두 데이터베이스 캐시(버퍼 풀)를 통해 일어나며, 참조 또는 변경하는 데이터가 버퍼 풀에 없으면 데이터베이스에서 해당 데이터를 패치한다.
  • 클라이언트의 요청이 데이터 변경인 경우 데이터의 변경 작업은 모두 버퍼 풀에서 일어나며, 데이터베이스에 바로 쓰지는 않는다.
  • 참고로, 데이터의 정합성을 보증하기 위해서는 데이터베이스보다 로그를 먼저 갱신해야만 한다.
    • 이러한 이유로 일단 COMMIT을 수행한 데이터는 분실하면 안 되므로 COMMIT이 완료되기 까지 로그 버퍼를 통해 변경 내용을 로그에 기록한다.


Dirty Data

버퍼 풀에 존재하지만 데이터베이스에는 아직 쓰이지 않는 데이터, 즉 Dirty Data는 백그라운드에서 순차적으로 데이터베이스에 기록한다.

Check Point

Dirty Data를 어디까지 데이터베이스에 써내렸는가를 기록하는 처리.

InnoDB의 구조적인 특징


1. 클러스터 인덱스

  • InnoDB는 클러스터 인덱스 구조로, 데이터가 인덱스의 리프 노드에 저장된다. (인덱스에 데이터를 포함하며 즉, 데이터만을 위한 저장 영역이 따로 없다는 의미)
  • 클러스터 인덱스는 같은 크기의 페이지 단위로 관리되어, 루트 노드부터 트리 탐색을 통해 리프 노드까지 찾아간다.
  • 노드 내의 각 엔트리는 양방향 Linked List가 되어 있어 페이지 내 검색은 리스트를 탐색하면서 진행된다.
    • InnoDB는 페이지 안에서 데이터를 정렬하지 않고 빈 공간이 있으면 사용하게 해서 페이지 내부에 행이 순서대로 되어있지 않기 때문에


클러스터 인덱스 장단점

  • 기본 키의 검색 효율이 좋다.
    • 리프 노드까지 도달하고 나면 추가로 데이터 영역에 접근할 필요가 없기 때문
  • 세컨더리 인덱스를 사용한 검색 효율이 좋지 않음.
    • 세컨더리 인덱스의 리프 노드에는 기본 키의 값이 저장되어 있다.
    • 세컨더리 인덱스를 사용한 검색은 세컨더리 인덱스에서 기본 키의 값을 가져온 후 기본 키에서 데이터를 가져오는 흐름으로 일어난다. (한 행을 가져올 때도 인덱스를 두 번 검색하기 때문에)
    • 이러한 배경으로, 세컨더리 인덱스에 접근하는 것만으로 쿼리를 해결할 수 있는 커버링 인덱스로 검색 속도를 큰 폭으로 개선할 수 있다.


2. Redo 로그

  • InnoDB의 로그의 내용은 모두 MTR이라는 단위로 기록된다.
  • MTR은 아주 작은 일련의 데이터 페이지 변경을 기록한 것으로, 재실행하여 같은 조작을 재현할 수 있다.
  • MTR로 생성된 REDO 로그 데이터는 InnoDB 로그 버퍼를 지나 최종적으로 InnoDB 로그 파일에 쓰인다.


3. 더티 페이지의 플러시

MTR을 이용해 복구하려면 두 가지 제약 조건을 만족해야 한다.

  1. 로그 파일이 먼저 디스크에 기록되어야 한다. 복구 시에는 데이터 파일을 읽어 들인 후 로그를 재생한다
    • 로그가 항상 선행되기 때문에, WAL(Write-Ahead-Log)라고 부른다.
  2. 더티 페이지가 남아있는 사이에는 그 페이지를 변경한 MTR이 로그 파일에서 누락되면 안된다는 것.


4. 체크포인트

  • InnoDB는 퍼지라는 체크포인트를 내장하고 있다.
  • 퍼지 체크포인트는 더티 페이지를 조금씩 디스크로 플러시해서 어디까지 플러시 했는지 기록하는 방식이다.
  • InnoDB에서는 LSN(Log Sequence Number)을 이용해 체크 포인트를 로그의 헤더에 기록한다.


5. Double Write

  • InnoDB는 데이터 파일에 쓰기 작업을 두 번 한다.
    • Double Write 버퍼라고 부르는, 데이터 파일에 연결된 2MB 영역에 데이터를 먼저 쓴 후, 실제 데이터 페이지에 쓴다. (참고로 Double Write 버퍼는 메모리가 아니라 파일이다.)
    • 같은 내용을 별도의 영역에 2회에 나누어 쓰는 방법으로 데이터 파일 변경 중에 머신이 손상되어도 데이터 파일의 손상을 막을 수 있다.


6. MVCC와 UNDO 로그

일관된 읽기를 최신 데이터로만 실행하려면 참조 또는 변경할 행 전체에 잠금을 걸어야 하므로 오버헤드가 커지게 된다.

  • 이러한 문제를 해결하기 위해 InnoDB에서는 REPEATABLE-READ 격리 레벨을 실현하기 위해 MVCC 시스템을 도입했다.

InnoDB에서는 REPEATABLE-READ와 READ-COMMITED MVCC가 이뤄진다.

  • READ-UNCOMMITED와 SERIALIZABLE은 UNDO 로그를 참조하지 않는다.
  • READ-UNCOMMITED더티 상태가 되어도 최신 데이터를 읽음.
  • SERIALIZABLE전체 행 접근으로 락을 걸기 때문에 역시나 최신의 데이터만 참조하면 된다.

MVCC (Multi Version Concurrency Control)

  • 과거 버전의 데이터를 보여줌으로써 트랜잭션에 일관된 데이터를 참조할 수 있게 하는 것이다.
  • 어떤 행이 변경된 경우, 이미 실행하고 있던 트랜잭션이 그 행 데이터를 참조하려면 최신 데이터가 아닌 변경 전의 데이터를 참조하게 하는 것이다.
  • 이로써 과거 버전의 데이터를 참조하게 하면 트랜잭션 시작 시의 데이터를 일관되게 제공할 수 있고, 행에 잠금을 걸 필요가 없어 병렬 처리가 개선된다.

Undo 로그

  • 행 데이터가 변경되면 일단 그 데이터를 UNDO 로그 영역으로 복사한다.
  • 각각의 행에는 롤백 포인터라는 레코드가 있어서 보내진 UNDO 레코드를 참조한다.


7. 퍼지 처리

  • UNDO 레코드는 갱신될 때마다 증가하기 때문에 그냥 두면 계속 늘어난다.
  • 새로운 행 데이터를 쓴 트랜잭션이 COMMIT 하기 전에 실행하기 시작한 트랜잭션이 종료하게 되면 과거 버전을 참조할 필요도 없어지므로 UNDO 레코드도 삭제할 수 있게 된다.
  • 퍼지 스레드백그라운드에서 UNDO 레코드를 순차적으로 삭제한다.

추가적으로 퍼지 스레드는 삭제가 끝났다고 체크된 행을 실제로 삭제하는 역할도 수행한다.

  • DELETE로 행을 삭제하면, 삭제되기 전의 데이터를 참조하는 트랜잭션이 있을지 모르기 때문에 데이터 페이지에서 행을 바로 삭제하는 것이 아니라 삭제가 완료되었다는 마크만 붙인다.
  • 행을 참조하는 트랜잭션이 없으면, 퍼지 스레드가 행의 삭제와 UNDO 레코드를 삭제한다.


8. Non Locking Read와 Locking Read

  • InnoDB에서 MVCC는 Non Locking Read로만 사용된다는 점을 주의해야 한다.

Lost Update (변경 유실)

  • 이러한 특징으로 변경 유실 등 문제가 발생할 수 있는데, SELECT FOR UPDATE or SELECT LOCK IN SHARE MODELocking Read 옵션으로 최신 데이터에 접근하는 동시에 락을 획득해야 한다.'

Locking Read에 대한 자세한 내용은 아래를 참고.

 

[Real MySQL 정리] 12장. 쿼리 종류별 잠금 (1) InnoDB의 기본 잠금 방식

먼저 트랜잭션이란 논리적인 작업셋의 완전성을 보장하기 위한 기능이고, 잠금이란 동시성을 제어하기 위한 기능이라고 할 수 있습니다. 1. InnoDB의 기본 잠금 방식 MySQL에서 일반적으로 사용 가

willseungh0.tistory.com

성능 튜닝의 기본


버퍼 풀의 크기

  • 버퍼 풀은 데이터 파일과 로그 파일이 기록되는 순서를 조정하기 위한 버퍼이지만, 디스크 액세스를 줄이기 위한 캐시의 역할도 하고 있다.
  • 버퍼 풀이 크면 클수록 데이터를 참조할 때 불필요한 파일 접근이 줄어 성능 향상에 도움이 된다.
  • 튜닝 이론상으로는 다른 버퍼에 배정해야 하는 메모리를 제외하고는 버퍼 풀의 크기가 최대가 되도록 메모리를 할당하는 것이 좋다.


로그 크기

  • InnoDB의 로그 파일은 크기가 고정되어 있어 같은 영역을 몇 번이고 다시 사용한다.
  • 로그 파일을 다 사용하고 새롭게 REDO 로그 (MTR)를 생성하려면 오래된 더티 페이지가 플러시 되어 체크포인트가 생성될 때까지 기다려야 한다.
  • 충분히 큰 로그를 갖게 해서 느린 플러시를 미룰 수 있다.
  • 하지만 REDO 로그의 크기가 커지게 되면 복구 시간도 길어지는 부작용이 생긴다.
  • 더티 페이지는 버퍼 풀보다 클 수 없으므로 버퍼 풀 이상으로 REDO 로그를 크게 설정해도 의미가 없다.
반응형