MySQL - MyISAM, InnoDB, Memory 스토리지 엔진 비교

청포도봉봉이·2025년 1월 11일
1

DataBase

목록 보기
3/3

MyISAM 스토리지 엔진

키 캐시

InnoDB의 버퍼 풀과 비슷한 역할을 하는 것이 MyISAM의 키 캐시(Key cache, 키 버퍼라고도 불림)다.

하지만 이름 그대로 MyISAM 키 캐시는 인덱스만을 대상으로 작동하며, 또한 인덱스의 디스크 쓰기 작업에 대해서만 부분적으로 버퍼링 역할을 한다.

키 캐시가 얼마나 호율적으로 작동하는지는 다음 수식으로 확인할 수 있다.

키 캐시 히드율(Hit rate) = 100 - (Key_reads / Key_read_request * 100)

Key_reads: 인덱스를 디스크에서 읽어 들인 횟수를 저장하는 상태 변수
Key_read_request: 키 캐시로부터 인덱스를 읽은 횟수를 저장하는 상태 변수

메뉴얼에서는 일반적으로 키 캐시를 이용한 쿼리의 비율(히트율, Hit rate)을 99% 이상으로 유지하라고 권장한다. 히트율이 99% 미만이라면 키 캐시를 조금 더 크게 설정하는 것이 좋다.

운영체제의 캐시 및 버퍼

MyISAM 테이블의 인덱스는 키 캐시를 이용해 디스크를 검색하지 않고도 충분히 빠르게 검색할 수 있다.

하지만 MyISAM 테이블의 데이터에 대해서는 디스크로부터의 I/O를 해결해 줄 만한 어떠한 캐시나 버퍼링 기능이 없다. 그래서 MyISAM 테이블의 데이터 읽기나 쓰기 작업은 항상 운영체제의 디스크 읽기 또는 쓰기 작업으로 요청될 수 밖에 없다.

물론 대부분의 운영체제에는 디스크로부터 읽고 쓰는 파일에 대한 캐시나 버퍼링 메너니즘이 있기 때문에 MySQL 서버가 요청하는 디스크 읽기 작업을 위해 매번 디스크의 파일을 읽지는 않는다.

만약 전체 메모리가 8GB인데 MySQL이나 다른 애플리케이션에서 메모리를 모두 사용해 버린다면 운영체제가 캐시 용도로 사용할 수 있는 메모리 공간이 없어진다. 이런 경우에는 MyISAM 테이블의 데이터를 캐시하지 못하며, 쿼리 처리가 느려진다.

MyISAM이 주로 사용되는 MySQL에서 일반적으로 키 캐시는 최대 물리 메모리의 40% 이상을 넘지 않게 설정하고, 나머지 메모리 공간은 운영체제가 자체적인 파일 시스템을 위한 캐시 공간을 마련할 수 있게 해주는 것이 좋다.

데이터 파일과 프라이머리 키(인덱스) 구조

InnoDB 스토리지 엔진을 사용하는 테이블은 프라이머리 키에 의해서 클러스팅되어 저장되는 반면, MyISAM 테이블은 프라이머리 키에 의한 클러스팅 없이 데이터 파일이 힙(Heap) 공간처럼 활용된다.

즉 MyISAM 테이블에 레코드는 프라이머리 키 값과 무관하게 INSERT되는 순서대로 데이터 파일에 저장된다. 그리고 저장되는 레코드는 모두 ROWID라는 물리적인 주솟값을 가지는데, 프라이머리 키와 세컨더리 인덱스는 모두 데이터 파일에 저장된 레코드의 ROWID 값을 포인터로 가진다.

MyISAM 테이블의 ROWID는 가변 길이와 고정 길이의 두 가지 방법으로 저장될 수 있다.

  • 고정 길이 ROWID
    자주 사용되지는 않지만 MyISAM 테이블을 생성할 때 MAX_ROWS 옵션을 사용할 수 있는데, 이 옵션을 명시하면 MySQL 서버는 최대로 가질 수 있는 레코드가 한정된 테이블을 생성한다.

  • 가변 길이 ROWID
    MyISAM 테이블을 생성할 때 MAX_ROWS 옵션을 설정하지 않으면 MyISAM 테이블의 ROWID는 최대 myisam_data_pointer_size 시스템 변수에 설정된 바이트 수만큼의 공간을 사용할 수 있다.




InnoDB 스토리지 엔진

버퍼 풀 (Buffer Pool)

InnoDB의 가장 핵심적인 부분으로, 디스크에서 읽은 데이터 페이지를 캐시하는 메모리 공간이다. 이는 MySQL 성능에 직접적인 영향을 미치는 매우 중요한 구성요소다.

버퍼 풀의 주요 기능

  • 테이블 데이터와 인덱스 데이터 캐시
  • 변경된 데이터를 일괄 처리하기 위한 버퍼링
  • Insert Buffer를 통한 인덱스 페이지 변경 버퍼링
  • 잠금이나 트랜잭션 정보를 포함한 내부 데이터 자료구조 보관

버퍼 풀의 효율성은 다음 수식으로 확인할 수 있다.

버퍼 풀 히트율 = 100 - (Innodb_buffer_pool_reads / Innodb_buffer_pool_read_requests * 100)

일반적으로 99% 이상의 히트율을 유지하는 것이 권장되며, 이보다 낮다면 버퍼 풀 크기를 늘리는 것이 좋다. innodb_buffer_pool_size 파라미터로 크기를 설정할 수 있으며, 보통 전체 메모리의 50-80%를 할당한다.

체인지 버퍼 (Change Buffer)

보조 인덱스의 변경 작업을 즉시 실행하지 않고 버퍼링하는 공간이다. 이를 통해 인덱스 페이지의 디스크 I/O를 줄일 수 있다.

주요 특징

  • INSERT, UPDATE, DELETE 작업 시 사용
  • 프라이머리 키나 유니크 인덱스에는 적용되지 않음
  • 체인지 버퍼의 내용은 백그라운드 스레드에 의해 실제 디스크에 적용됨

리두 로그 (Redo Log)

데이터베이스 장애 발생 시 복구를 위해 사용되는 로그다.

주요 특징

  • 순환 큐 방식으로 동작
  • 트랜잭션의 ACID 중 Durability를 보장
  • innodb_log_file_size로 크기 설정
  • 작은 로그 파일은 잦은 체크포인트를 유발할 수 있음

언두 로그 (Undo Log)

트랜잭션의 롤백이나 MVCC를 구현하기 위해 사용되는 로그다.

주요 기능

  • 트랜잭션 롤백 시 데이터 복구
  • 격리 수준에 따른 일관된 읽기 제공
  • MVCC를 통한 동시성 제어

어댑티브 해시 인덱스 (Adaptive Hash Index)

자주 읽히는 데이터에 대해 자동으로 생성되는 해시 인덱스다.

특징

  • B-Tree 검색 시간을 줄여줌
  • 메모리를 추가로 사용
  • innodb_adaptive_hash_index 파라미터로 활성화/비활성화 가능

이중 쓰기 버퍼 (Double Write Buffer)

데이터 페이지 쓰기 작업 중 운영체제가 크래시되는 경우를 대비한 안전장치다.

동작 방식

  1. 변경된 페이지를 이중 쓰기 버퍼에 기록
  2. 이중 쓰기 버퍼의 내용을 실제 데이터 파일에 기록
  3. 크래시 발생 시 이중 쓰기 버퍼의 내용을 이용해 복구

데이터 파일과 클러스터링 인덱스

InnoDB 테이블은 프라이머리 키를 기준으로 클러스터링되어 저장된다.

클러스터링 인덱스의 특징

  • 프라이머리 키 순서대로 데이터가 정렬되어 저장
  • 프라이머리 키 검색이 매우 빠름
  • 연관된 레코드들이 물리적으로 가까이 저장됨
  • 범위 검색 성능이 좋음

트랜잭션과 잠금

InnoDB는 트랜잭션을 완벽하게 지원하는 스토리지 엔진이다.

트랜잭션 관련 주요 기능

  • ACID 속성 보장
  • 4가지 트랜잭션 격리 수준 지원 (READ UNCOMMITTED, READ COMMITTED, REPEATABLE READ, SERIALIZABLE)
  • 레코드 기반의 잠금 제공
  • 데드락 감지 및 해결

잠금의 종류

  • 레코드 락: 개별 레코드에 대한 잠금
  • 갭 락: 레코드 사이의 간격을 잠그는 것
  • 넥스트 키 락: 레코드 락과 갭 락을 합친 것
  • 자동 증가 락: AUTO_INCREMENT 칼럼을 위한 특별한 잠금

이러한 다양한 기능들로 인해 InnoDB는 MySQL에서 가장 널리 사용되는 스토리지 엔진이 되었으며, 특히 트랜잭션이 필요한 웹 애플리케이션이나 높은 동시성이 요구되는 서비스에 적합하다.




Memory 스토리지 엔진

메모리 구조

Memory 스토리지 엔진은 모든 데이터를 메모리에 저장하는 특징이 있다. 디스크 I/O가 발생하지 않아 매우 빠른 읽기/쓰기가 가능하다. 하지만 MySQL 서버가 재시작되면 모든 데이터가 사라진다.

해시 인덱스

Memory 테이블의 기본 인덱스 타입은 해시 인덱스다. 해시 인덱스는 등호(=) 비교에서 매우 빠른 성능을 보이지만, 범위 검색이나 정렬에는 적합하지 않다. 필요한 경우 BTREE 인덱스도 사용할 수 있다.

용도와 제약사항

Memory 테이블의 주요 용도

  • 임시 데이터의 저장
  • 빠른 룩업 테이블
  • 세션 데이터 저장

Memory 엔진의 제한사항

  • VARCHAR를 포함한 가변 길이 칼럼을 CHAR로 저장
  • BLOB이나 TEXT 타입 사용 불가
  • 트랜잭션을 지원하지 않음

이러한 특성으로 인해 Memory 스토리지 엔진은 주로 조회가 빈번하고 데이터의 영구 저장이 필요없는 임시 테이블용도로 사용된다.

profile
서버 백엔드 개발자

0개의 댓글