RealMySQL 06장 데이터 압축
페이지 압축
페이지 압축은 Transparent Page Compression이라고도 불리는데, MySQL 서버가 디스크에 저장하는 시점에 데이터 페이지가 압축되어 저장되고 반대로 MySQL 서버가 디스크에서 데이터 페이즈를 읽어올 때 압축이 해제되기 때문이다. 즉, MySQL의 내부 코드에서는 압축 여부와 관계없이 투명(Transparent)하게 동작한다. 16KB 데이터 페이지를 압축한 결과가 용량이 얼마나 될지 예측이 불가능한데 적어도 하나의 테이블은 동일한 크기의 페이지(블록)로 통일돼야 한다는 것이다. 그래서 페이지 압축 기능은 운영체제별로 특정 버전의 파일 시스템에서만 지원되는 펀치홀(punch hole) 기능을 사용해야 한다.
1. 16KB 페이지를 압축(압축 결과를 7KB로 가정)
2. MySQL 서버는 디스크에 압축된 결과를 7KB로 기록
3. 디스크에 데이터를 기록한 후, 7KB 이후의 공간 9KB에 대해 펀치 홀(Punch-hole)을 생성
4. 파일 시스템은 7KB만 남기고 나머지 디스크의 9KB 공간은 다시 운영체제로 반납
- Q. 내부 단편화가 발생한다는 뜻인지?
페이지 압축이 가진 문제는 펀치 홀 기능은 운영체제뿐만 아니라 하드웨어 자체에서도 해당 기능을 지원해야 사용 가능하다는 점이다.
또 다른 문제점은 아직 파일 시스템 관련 명령어(유틸리티)가 펀치 홀을 지원하지 못한다는 것이다.
실제 데이터 파일의 크기가 1GB라고 하더라도 "cp"같은 파일 복사 명령 또는 XtraBackup 같은 툴이 파일을 복사하면 펀치 홀이 다시 채워져서 데이터 파일의 크기는 원본 크기인 10GB가 될 수도 있다.
실제로 페이지 압축은 잘 사용되지 않는다. 페이지 압축을 이용하기 위해서는 테이블을 생성하거나 변경할 때 다음과 같이 COMPRESSION 옵션을 지정해야 한다.
create table t1 (c1 INT) compression='zlib';
테이블 압축
테이블 압축은 운영체제나 하드웨어에 대한 제약 없이 사용할 수 있기 때문에 일반적으로 활용도가 높은 편이다. 하지만 테이블 압축도 몇 가지 단점이 있다.
- 버퍼 풀 공간 활용률이 낮음
- 쿼리 처리 성능이 낮음
- 빈번한 데이터 변경시 압축률이 떨어짐
압축 테이블 생성
압축을 사용하려는 테이블이 별도의 테이블 스페이스를 사용해야 한다. 이를 위해서 innodb_file_per_table 시스템 변수가 on으로 설정된 상태에서 테이블이 생성돼야 한다. 테이블 압축을 사용하는 테이블은 다음과 같이 테이블을 생성할 때 ROW_FORMAT=COMPRESSED 옵션을 지정해야 한다.
set global innodb_file_per_table=ON;
create table compressed_table
- Q. 나머지 내용 이해 못함
테이블 압축 방식에서 가장 중요한 것은 원본 데이터 페이지의 압축 결과가 목표 크기(KEY_BLOCK_SIZE)보다 작거나 같을 때까지 반복해서 페이지를 스플릿하는 것이다.
KEY_BLOCK_SIZE 결정
압축 실패율이 3~5% 미만으로 유지할 수 있게 KEY_BLOCK_SIZE를 선택할 수 있게 테스트 해보라고 한다.
압축된 페이지의 버퍼 풀 적재 및 사용
압축된 테이블의 데이터 페이지를 버퍼 풀에 적재하면 압축된 상태와 압축이 해제된 상태 2개 버전을 관리한다. 읽은 상태 그대로의 데이터 페이지 목록을 관리하는 LRU 리스트와 압축된 페이지들의 압축 해제 버전인 Unzip LRU 리스트를 별도로 관리하게 된다. 왜냐면 압축을 해제하는 작업이 CPU를 굉장히 많이 소모하는 작업이기 때문이다.