MySQL에서의 데이터 압축 기술
들어가며
데이터베이스에서는 대량의 데이터가 저장되고 검색되기 때문에 효율적인 데이터 관리가 필수적입니다. 이에 따라 데이터 압축은 저장 공간을 절약하고 데이터베이스 성능을 향상하는 데 중요한 역할을 합니다. MySQL 서버에서는 페이지 압축과 테이블 압축 두가지의 방식이 존재합니다.
페이지 압축이란
페이지 압축이란 "Transparent Page Compression" 이라 불린다. MySQL 서버가 디스크에 저장하는 시점에 압축되며, 데이터를 읽어올 때 압축이 해제되는 형식이다. 즉 버퍼풀에 데이터 페이지가 적재되면 InnoDB스토리지 엔진은 압축이 해제된 상태로만 데이터를 관리한다. 그래서 MySQL 서버 내부 코드에서는 압축 여부와 관계없이 "투명(Transparent)"하게 작동한다.
- 16KB 페이지를 압축(압축 결과를 7KB로 가정)
- MySQL 서버는 디스크에 압축도딘 결과를 7KB로 기록(7KB에 9KB의 빈데이터 저장)
- 기록한 후, 7KB 이후의 공간 9KB에 대해 펀치 홀(Punch_hole)을 생성
- 나머지 9KB 공간은 운영체제한테 반납
하지만 MySQL서버의 페이지 압축의 펀치 홀이라는 기능은 운영체제뿐만 아니라 하드웨서 자체에서도 기능을 지원해야 사용가능하다. 이러한 이유로 잘 사용하지 않는다.
페이지 압축 SQL문
#테이블 생성시
create table ex (ex int) compression="zlib";
#테이블 변경시
alter t able ex compression="zlib";
optimize table ex;
테이블 압축이란?
운영체제나 하드웨어에 대한 제약 없이 사용할 수 있고, InnoDB 스토리지 엔진에서 제공하는 기증으로 이를 통해 테이블과 인텍스 데이터를 압축하여 디스크 공간을 절약하고 I/0 작업을 줄일 수 있다.
단점
버퍼 풀 공간 활용이 낮음
쿼리 처리 성능이 낮음
번번한 데이터 변경 시 압축률이 떨어짐
압축 테이블 생성 방법
압축 테이블을 사용하기 위해서는 innodb_file_per_table시스템 변수가 ON이 되어 있는 상태에서 사용이 가능하다. 그리고 테이블 생성 시에 ROW_FORMAT=COMPRESSED 옵션을 명시해줘야 한다. 또한 KEY_BLOCK_SIZE 옵션을 이용해 압축된 페이지의 타깃 크기를 명시하는데 2N으로만 생성할 수 있다. 만약 저장 크기가 8KB라면 2KB, 4KB만 설정가능 하다.
테이블생성방법
#KEY_BLOCK_SIZE를 4KB 바이트로 설정한 테이블 생성
create table employess_comp4k (
...
)row_format=compressed key_block_size=4;
#KEY_BLOCK_SIZE를 8KB 바이트로 설정한 테이블 생성
create table employess_comp4k (
...
)row_format=compressed key_block_size=8;
조회
#INSERT문을 실행하기전에 시스템 변수를 ON으로해놔야 실행,성공횟수를 볼수있다.
SET global innodb_cmp_per_index_enabled=on;
위에 명령어를 통해서 테이블 압축을 사용할 수 있다.
압축 페이지의 버퍼 풀 적재 및 사용
InnoDB 스토리지 엔진은 디스크에서 읽은 상태 그대로의 데이터 페이지 목록을 관리하는 LRU 리스트와 압축된 페이지들의 압축 해제 버전인 Unzip_LRU리스트를 별도로 관리한다.
하지만 이렇게 관리하면 동시에 버퍼풀 공간을 이중으로 사용함으로써 메모리를 낭비하는 효과를 가진다. 이런 문제점을 보안하기 위해서 Unzip_LRU 리스트를 별로도 관리하다 MySQL 서버로 유입되는 요청 패턴이 때라 적절한 처리를 다음과 같이 수행해야 한다.
- 공간이 필요한 경우에는 LRU 리스트는 원본데이터를 유지하고 Unzip_LRU리스트는 해제된 버전을 제거해서 버퍼풀 공간을 확보한다.
- 압축된 데이터를 자주 사용할 경우에는 Unzip_LRU 리스트에 압축 해제된 페이지를 계속 유입하면서 압축 및 압축 해제 작업을 최소화한다.
- 사용되지 않을 데이터는 LRU , Unzip_LRU리스트 모두 함께 제거한다.
압축 테이블 관련 설정
- Innodb_cmp_per_index_enalbed : 테이블 압축이 사용된 테이블의 모든 인덱스별로 압축 성공 및 압축 실행 횟수를 설정
- innodb_compression_level : MySQL InnoDB 스토리지 엔진에서 사용되는 데이터 압축 수준을 지정하는 설정입니다. 낮을수록 압축률이 낮아 CPU 사용량을 줄어들고, 높을수록 압축량이 높아져 CPU사용량을 증가한다.
- innodb_compression_failure_threshold_pct : 데이터 압축 작업 중 실패한 비율을 나타내는 임계값 설정
- innodb_compression_pad_pct_max : 압축에 사용되는 패딩(padding) 비율의 최댓값을 설정
- 패딩이란 압축된 데이터의 크기를 일정하게 유지하기 위해 추가되는 비트.
- innodb_compressed_pages : 비정상적으로 종료됐다가 재시작하는 경우 복구과정이 실패하지 않도록 로그에 기록한다.
참고
'MySQL' 카테고리의 다른 글
[MySQL] [1]인덱스(Index)란-B-Tree? (0) | 2024.02.08 |
---|---|
[MySQL] 데이터 암호화란? (2) | 2024.01.27 |
[MySQL] MySQL의 트랜잭션과 잠금 (1) | 2024.01.26 |
[MySQL] 사용자 및 권한 (1) | 2024.01.05 |
[MySQL] 시스템 변수 (1) | 2024.01.05 |