MySQL 데이터 압축
Post

MySQL 데이터 압축

한줄 정리

페이지 압축은 되도록 지양, 테이블 압축은 꼭 필요하다면 split, 압축 성공률을 개발환경에서 테스트를 해보고 적용하자.

페이지 압축

페이지 압축은 Transparent Page Compression 이라 불리는데, MySQL 서버가 디스크에 저장하는 시점에 테이터 페이지가 압축되어 저장되고, 반대로 MySQL 서버가 디스크에서 데이터 페이지를 읽어올 때,
압축을 해제한다. 즉 버퍼 풀에 데이터 페이지가 한번 적재되면 innoDB 스토리지 엔진은 압축이 해제된 상태로 관리한다. 그래서 MySQL 내부 코드에서는 압축 여부와 관계없이 투명하게 작동한다.
문제는 압축한 결과가 용량이 얼마나 되든 하나의 테이블은 동이한 크기의 페이지로 통일해야한다는 것이다. 그래서 운영체제 별로 지원되는 펀치홀 기능 사용한다.
운영체제별로 상이하여 실무에는 잘 사용되지 않는다.

테이블 압축

테이블 압축은 운영체제나 하드웨어에 대한 제약이 없이 사용할 수 있기 때문에 일반적으로 활용도가 높다.
단점 은 버퍼 풀 공간 활용률이 낮다는 점, 쿼리 처리 성능이 낮다는 점, 빈번한 데이터 변경 시 압축률이 떨어진다는 점이다.

  • 압축 테이블 생성
1
2
3
4
5
6
7
8
9
10
SET GlOBAL innodb_file_per_table = ON;
CREATE TABLE compressed_table
(
  c1 int primary key
)
  ROW_FORMAT = COMPRESSED
  KEY_BLOCK_SIZE = 8
# 압축된 페이지의 타깃 크기(목표 크기) 명시.
# 2n으로 가능 innodb_page_size 16KB 4KB, 8KB 가능
# 페이지 크기가 32KB, 64KB 압축 적용 불가.
  • 목표 크기보다 커지면 split 되서 2개의 페이지에 저장한다.
    16KB -> 8KB 압축, 초과하면 2개의 페이지에, 이하면 그대로 디스크에 저장.

KEY_BLOCK_SIZE 결정

  • 테스트 데이터를 insert 해보면서 압축 횟수, 성공 횟수, 압축 실패율을 조회해서 KEY_BLOCK_SIZE를 결정하자
1
2
3
4
5
6
select table_name,
       index_name,
       compress_ops,
       compress_ops_ok,
       (compress_ops - compress_ops_ok) / compress_ops * 100 as compression_failure_pct
from information_schema.innodb_cmp_per_index;

테이블 압축 관련 설정

  • innodb_cmp_per_index_enabled : 테이블 압축이 사용된 테이블의 모든 인덱스별로 압축 성공 및 압축 실행 횟수 수집. OFF되어 있을 경우, 테이블 단위의 압축 성공 및 압축 실행 횟수만 수집
  • innodb_compression_level : 압축률 설정이 가능하다. 0-9까지 선택할 수 있고 기본값은 6, 값이 작을수록 압축 속도는 빨라지지만 저장공간은 커질 수 있다.
  • innodb_compression_failure_threshold_pct, innodb_compression_pad_pct_max : 193 페이지 참고
  • innodb_log_compressed_pages : 서버가 비정상적으로 종료됐다가 다시 시작되는 경우 압축 알고리즘의 버전 차이가 있더라도 복구 과정이 실패하지 않도록 innoDB 스토리지 엔진은 압축된 데이터 페이지를 그대로 리두 로그에 기록한다. 리두 로그가 커질 수 있어서 OFF로 하고 모니터링 하고 기본값은 ON이여서 되도록이면 ON 유지