테마
데이터 압축
압축은 디스크 공간과 I/O(Input/Output, 입출력)를 아끼는 대신, 압축·해제에 CPU를 더 쓰는 선택이다. InnoDB는 데이터를 페이지(page) 단위로 저장하므로 압축도 페이지 단위로 한다. 방식은 페이지 압축(애플리케이션이 신경 쓰지 않아도 엔진이 알아서 하는 투명 압축)과 테이블 압축(KEY_BLOCK_SIZE 지정) 두 가지다.
두 방식
| 페이지 압축 | 테이블 압축 | |
|---|---|---|
| 지정 | 테이블스페이스(tablespace)·테이블 단위 | KEY_BLOCK_SIZE 지정 |
| 동작 | 페이지 통째 압축, 빈 공간 펀치 홀(hole punching) | KEY_BLOCK_SIZE로 압축 페이지 크기 지정 |
| 버퍼 풀(buffer pool) | 압축·비압축 이중 적재 없음 | 두 형태가 함께 올라가 메모리 이중 사용 |
| 파일 | 스파스 파일(sparse file) 지원 파일 시스템 필요 | 일반 파일 시스템 가능 |
- 페이지 압축(Transparent Page Compression): 페이지를 디스크에 쓸 때 압축하고, 압축으로 남은 빈 공간을 잘라낸다. 버퍼 풀에는 압축을 푼 형태 하나만 올라가므로 같은 페이지를 두 형태로 올리는 이중 적재가 없고, 읽기·쓰기 경로가 단순하다. 대신 파일 시스템이 펀치 홀을 지원해야 한다.
- 테이블 압축(table compression): 예전부터 쓰던 전통 방식으로,
ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8처럼 지정한다.KEY_BLOCK_SIZE는 압축된 페이지를 몇 KB로 맞출지 정하는 값이다. 압축률이 좋을 수 있지만, 버퍼 풀에 압축된 형태와 압축을 푼 형태가 함께 올라간다. 또 바뀐 페이지가 정한 크기 안으로 압축되지 않으면(압축 실패) 페이지를 둘로 나누는 페이지 분할(page split)과 재시도 비용이 든다.
페이지 압축을 쓰려면 테이블마다 파일 하나를 두는 file-per-table(테이블별 파일) 테이블스페이스와, 펀치 홀을 지원하는 파일 시스템이 필요하다. 압축 속성을 바꿔도 이미 저장된 페이지는 그대로이므로, 기존 페이지까지 바꾸려면 속성 변경 후 테이블을 재구성해야 한다.
트레이드오프와 판단
- 유리한 경우: 읽기 위주 테이블, 오래 보관만 하는 아카이브성 테이블, 디스크 I/O가 병목인 테이블이다. 디스크 사용량과 백업 크기가 줄어든다.
- 불리한 경우: 쓰기가 잦은 테이블, BLOB(Binary Large Object, 대용량 바이너리 객체) 칼럼에 담은 이미지처럼 이미 압축된 값이 많은 테이블, CPU가 병목인 서버다. 압축·해제 비용이 쓰기 경로에 붙고, 이미 압축된 값은 더 줄지 않기 때문이다.
- 판단은 측정으로 한다. 서버의 메타데이터를 보여 주는
INFORMATION_SCHEMA에서, 전통 테이블 압축은INNODB_CMP·INNODB_CMP_PER_INDEX로 압축 시도·성공 횟수와 걸린 시간을 본다. 페이지 압축은INNODB_TABLESPACES의FILE_SIZE(겉보기 파일 크기)와ALLOCATED_SIZE(실제 디스크 할당량) 차이를 확인한다.
KEY_BLOCK_SIZE는 1·2·4·8·16KB 값을 사용할 수 있지만 InnoDB 페이지 크기와 테이블스페이스 제약을 함께 받는다. 값이 작을수록 한 페이지를 더 작게 눌러 담아야 하므로 재압축·페이지 분할 위험이 커질 수 있다. 그래서 보통 8KB나 4KB부터 측정한다.
면접 포인트
- "두 방식의 차이?" → 투명 페이지 vs KEY_BLOCK_SIZE. 버퍼 풀 이중 적재 유무.
- "언제 쓰나요?" → 읽기 위주·I/O 병목. 쓰기 잦으면 독.
- "효과 측정은?" → INNODB_CMP 성공률·시간. 안 나오면 끈다.
