728x90
글의 내용은 Real MySQL 8.0 책을 참고하였습니다.
DBMS들이 데이터 압축을 사용하는 이유
- 디스크에 저장된 데이터 파일의 크기는 쿼리 처리 성능과 직결되며, 백업 및 복구 시간과도 밀접하게 연관된다.
- 데이터 파일의 크기가 커질수록
- 쿼리 처리를 위해 많은 데이터 페이지를 InnoDB 스토리지 엔진 버퍼풀로 읽어들여야할 수 있고
- 새로운 페이지가 버퍼풀로 적재될 때 더티 페이지가 더 자주 디스크로 기록되어야 함 (Disk IO 증가)
- 이런 문제점 때문에 많은 DBMS는 데이터 압축 기능을 사용한다.
- MySQL 서버에서는 테이블압축과 페이지 압축 기능을 제공한다.
MySQL 페이지 압축(많이 사용 x)
- MySQL 서버가 디스크에 저장하는 시점에 데이터 페이지가 압축되어 저장되고, 디스크에서 데이터 페이지를 읽어올 때 압축이 해제되는 방식이다.
- InnoDB 스토리지 엔진 버퍼 풀에 데이터페이지가 한 번 적재되면, 압축이 해제된 상태로만 데이터 페이지를 관리한다.
- 하지만 데이터 페이지를 압축한 결과 용량을 예측할 수 없음
- 적어도 하나의 테이블은 동일한 크기의 페이지로 통일되도록 해야한다.
- 이를 위해 펀치 홀 기능을 사용한다
- 특정 테이블에 대해 페이지 크기를 유지하면서도, 압축된 다양한 크기의 데이터 페이지를 디스크에 저장하여 공간을 절약한다.
펀치 홀 기능
- 압축 데이터 뒤에 빈 데이터공간(펀치홀)을 생성하고, 저장 후 빈 데이터 공간을 OS에 반납하는 방식이다.
문제점
- 펀치 홀 기능은 OS 뿐만 아니라 HW자체에서도 해당 기능을 지원해야 사용이 가능하다
- 하지만 파일 시스템 관련 명령어(유틸리티)가 펀치 홀을 지원하지 못한다.
- MySQL 서버의 데이터 파일은 백업 및 복구 과정에서 데이터 파일 복사과정이 실행되는데, 많은 파일 관련 유틸리티들을 사용한다
- 펀치홀이 제 기능을 하지 못하는 경우도 발생할 수 있다.
- 그래서 실제로 페이지 압축을 많이 사용하지 않는다.
테이블 압축
- OS나 HW에 대한 제약없이 사용할 수 있기 때문에 일반적으로 활용도가 높다
- 압축 테이블을 생성하여 데이터 페이지를 압축한다.
- 별도의 테이블 스페이스를 사용하여 테이블을 생성함
- KEY_BLOCK_SIZE 옵션으로 압축된 페이지의 타깃 크기를 명시해준다
- 목표 크기를 잘못 설정하면 MySQL 서버의 처리 성능이 급격히 떨어질 수 있다
- 압축 적용하는 방법
- 16KB 데이터 페이지 압축 시(KEY_BLOCK_SIZE = 8)
- 압축 된 결과가 8KB 이하이면 그대로 디스크 저장
- 초과 시 원본 페이지를 스플릿해서 2개의 페이지에 8KB씩 저장
- 계속 반복 수행
- 테이블 압축 실패율과 데이터의 조회가 빈번한지 여부에 따라 압축을 고려하면 좋음
- 샘플 데이터 사용하여 적절한지 판단
- 테이블 압축은 zlib을 이용해 압축하는데, 이 알고리즘은 많은 CPU 자원을 소모한다
- InnoDB 스토리지 엔진은 압축된 테이블의 데이터 페이지를 버퍼 풀에 적재하면 압축된 상태와 압축이 해제된 상태 2개의 버전을 관리한다.
- 압축된 버전 데이터 페이지 목록을 관리하는 LRU 리스트
- 압축 해제된 페이지들을 관리하는 Unzip_LRU 리스트
- Unzip_LRU리스트는 압축이 적용되지 않은 테이블의 데이터 페이지는 가지지 않고, 압축이 적용된 테이블에서 읽은 데이터 페이지만 관리한다.
테이블 압축의 단점
- 버퍼 풀 공간 활용률이 낮음
- 쿼리 처리 성능이 낮음
- 빈번한 데이터 변경 시 압축률이 떨어짐
- InnoDB 스토리지 엔진은 압축된 테이블에 대해서 버퍼 풀의 공간을 이중으로 사용한다 -> 메모리 낭비 효과
- 압축된 페이지에서 데이터를 읽고 변경할 때 압축을 해제하는데, 이는 CPU를 많이 소모한다
- 위 두 가지의 단점을 보완하기 위해 Unzip_LRU 리스트를 별도로 관리하고 있다가, MySQL 서버로 유입되는 요청 패턴에 따라 다음과 같은 처리를 수행한다.
- InnoDB 버퍼 풀 공간이 필요한 경우: LRU 리스트에서 원본 데이터 페이지는 유지, Unzip_LRU리스트에서는 제거
- 압축된 데이터 페이지가 자주 사용되는 경우: Unzip_LRU 리스트에 압축 해제된 페이지를 계속 유지하면서 압축, 압축해제 작업 최소화
- 압축된 데이터 페이지가 사용되지 않아 LRU 리스트에서 제거되는 경우: Unzip 리스트에서도 함께 제거
- 압축 해제된 버전의 데이터페이지를 적절 수준으로 유지하기 위해 어댑티브 알고리즘을 사용한다
- CPU 사용량 ↑ 서버: 압축해제 피하기 위해 Unzip_LRU 리스트 비율 높여서 유지
- Disk IO 사용량 ↑ 서버: 가능하면 Unzip_LRU리스트 비율 낮춰서 InnoDB 버퍼풀 공간을 확보하도록 작동
간단 요약
- 디스크에 저장된 파일의 크기는 쿼리성능과 백업/복구 시간에 영향을 미친다
- 그래서 많은 DBMS들은 데이터 압축 기능을 제공하고, MySQL은 테이블 압축과 페이지 압축을 제공한다
- 페이지 압축은 펀치홀 기능을 사용해야하기 때문에 많이 사용되지 않는다
- 테이블 압축은 OS나 HW에 대한 제약없이 사용가능하지만, 단점이 존재
- 테이블 압축 시 타깃 페이지 크기를 잘 명시해야 효율이 좋다
- 반복 스플릿 작업으로 타깃 페이지를 저장하기 때문에, 서버의 처리 성능을 잘 고려해서 설정해야함
- 테이블 압축 시 압축된 상태, 압축해제된 상태(Unzip_LRU 리스트)를 관리한다
- 메모리 낭비 효과와 압축해제 시 CPU를 많이 소모하는 단점을 줄이기 위해 요청에 따라 리스트에서 제거하는 작업을 수행한다
- 그리고 Unzip_LRU리스트 데이터 페이지를 적절한 수준으로 유지하기 위해 어댑티브 알고리즘을 사용한다
- CPU사용량이 높은 서버, Disk IO 사용량이 높은 서버에 따라 Unzip_LRU 리스트 비율을 조절
728x90
'database > MySQL' 카테고리의 다른 글
[MySQL] 풀 테이블 스캔 (0) | 2024.02.17 |
---|---|
[MySQL] Unique index와 Primary key 차이 (1) | 2024.02.12 |
workbench 프로그램 안켜지는 문제 (0) | 2023.09.09 |
[sql] 제약조건(NOT NULL, UNIQUE, PRIMARY KEY, FOREIGN KEY) (2) | 2023.02.12 |
MySQL Workbench 8.0.29 설치하기(Windows x86, 64-bit) (5) | 2022.07.07 |