Загружаем каталог…
Загружаем каталог…
『Real MySQL 8.0』 6장을 읽고, 핵심 개념을 쉽게 이해할 수 있도록 제 방식대로 정리한 글입니다. 📌 들어가기 전에 왜 데이터를 압축할까? 디스크에 저장된 데이터 파일이 커지면 여러 가지 문제가 생깁니다. 문제 설명 쿼리 성능 읽어야 할 데이터가 많아져 디스크 I/O 증가 백업·복구 시간 파일이 클수록 백업과 복구가 오래 걸림 저장 공간 비용 디스크 용량이 많이 필요함 그래서 MySQL은 데이터를 압축해서 저장 하는 방법을 제공합니다. MySQL의 두 가지 압축 방식 방식 다른 이름 한 줄 설명 페이지 압축 Transparent Page Compression 디스크에 쓸 때 압축 , 읽을 때 해제. OS의 펀치 홀 기능에 의존 테이블 압축 - 압축된 페이지를 정해진 크기(KEY_BLOCK_SIZE) 에 맞춰 저장 6.1 페이지 압축 페이지 압축이란? 데이터 페이지를 디스크에 저장하는 순간 압축 하고, 디스크에서 읽어올 때 압축을 해제 합니다. 그래서 버퍼 풀에는 압축이 해제된 상태 로 데이터가 올라옵니다. [쓰기] 버퍼 풀 (16KB, 원본) ──압축──▶ 디스크 (압축된 상태) [읽기] 디스크 (압축된 상태) ──해제──▶ 버퍼 풀 (16KB, 원본) 💡 MySQL 서버 내부에서는 데이터가 압축됐는지 신경 쓰지 않고 똑같이 처리합니다. 그래서 "투명한(Transparent)" 페이지 압축이라고 부릅니다. 문제: 압축 결과의 크기를 예측할 수 없다 16KB 페이지를 압축하면 결과가 7KB가 될지, 10KB가 될지 미리 알 수 없습니다. 그런데 하나의 테이블은 모든 페이지가 같은 크기 여야 관리할 수 있습니다. 페이지 A 압축 → 7KB 페이지 B 압축 → 11KB 페이지 C 압축 → 5KB → 크기가 제각각이면 파일 안에서 페이지 위치를 계산할 수 없음 😵 해결: 펀치 홀 (Punch Hole) 운영체제의 펀치 홀 기능을 이용해 이 문제를 해결합니다. 1 16KB 페이지를 압축 → 결과 7KB 2 디스크에 16KB 크기 그대로 기록 [압축 데이터 7KB][빈 공간 9KB] 3 뒤쪽 빈 공간 9KB에 펀치 홀을 뚫음 [압축 데이터 7KB][🕳️ 9KB] → 파일 시스템은 9KB를 운영체제에 반납 관점 크기 실제 디스크 사용량 7KB MySQL·운영체제가 보는 파일 크기 16KB (압축 데이터 + 펀치 홀 공간) 🧩 비유: 16칸짜리 주차 구역을 그대로 유지하되, 실제로 차를 7칸에만 세우고 나머지 9칸은 "여기는 비어 있음" 이라고 표시해서 다른 사람이 쓰게 돌려주는 것 페이지 압축의 한계 한계 설명 지원 환경 제약 펀치 홀은 운영체제뿐 아니라 하드웨어(파일 시스템) 도 지원해야 함 파일 복사 시 문제 일반적인 파일 복사 명령어는 펀치 홀을 지원하지 않아서, 복사하면 원래 크기(16KB)로 되돌아감 백업 도구 문제 XtraBackup 같은 백업 도구로 백업·복구할 때도 같은 문제가 생길 수 있음 ⚠️ 이런 이유로 페이지 압축은 실무에서 많이 사용되지 않습니다. 사용 방법 -- 테이블 생성 시 페이지 압축 적용 CREATE TABLE t1 (c1 INT) COMPRESSION = 'zlib'; -- 기존 테이블에 페이지 압축 적용 ALTER TABLE t1 COMPRESSION = 'zlib'; OPTIMIZE TABLE t1; -- 기존 데이터에도 압축을 적용하려면 테이블 재구성 필요 COMPRESSION 값 의미 zlib zlib 알고리즘으로 압축 lz4 lz4 알고리즘으로 압축 none 압축하지 않음 6.2 테이블 압축 테이블 압축이란? 운영체제나 하드웨어 제약 없이 사용할 수 있는 압축 방식입니다. 그래서 페이지 압축보다 활용도가 높습니다. 단점도 있다 단점 설명 버퍼 풀 공간 활용률 낮음 버퍼 풀에 압축된 페이지와 해제된 페이지를 둘 다 보관 쿼리 처리 성능 낮음 압축·해제 과정에서 CPU 사용 잦은 변경 시 압축률 저하 데이터가 자주 바뀌면 압축 효율이 떨어짐 6.2.1 압축 테이블 생성 사전 조건 압축 테이블은 별도의 테이블스페이스 를 사용해야 합니다. SHOW GLOBAL VARIABLES LIKE 'innodb_file_per_table'; -- ON 이어야 함 생성 방법 CREATE TABLE compressed_table ( c1 INT PRIMARY KEY ) ROW_FORMAT = COMPRESSED KEY_BLOCK_SIZE = 8; 옵션 설명 ROW_FORMAT = COMPRESSED 압축 테이블로 생성 (생략하면 KEY_BLOCK_SIZE 만 지정해도 자동으로 COMPRESSED 적용) KEY_BLOCK_SIZE 압축된 페이지가 저장될 목표 크기 (KB 단위) 💡 KEY_BLOCK_SIZE 는 1, 2, 4, 8, 16(KB) 중에서 정하며, 기본 페이지 크기(16KB) 기준으로 보통 4KB 또는 8KB 를 사용합니다. InnoDB 페이지 크기가 32KB, 64KB라면 테이블 압축을 사용할 수 없습니다. 압축 과정 (KEY_BLOCK_SIZE = 8KB 예시) 1 16KB 데이터 페이지를 압축 │ ├─ 압축 결과 ≤ 8KB → 그대로 디스크에 저장 ✅ (압축 완료) │ └─ 압축 결과 > 8KB → 원본 페이지를 둘로 나눔 (페이지 스플릿) [8KB] [8KB] │ │ ▼ ▼ 나뉜 페이지 각각에 대해 1부터 다시 반복 ⚠️ 압축 결과가 목표 크기(KEY_BLOCK_SIZE)보다 작아야 저장할 수 있습니다. 목표 크기를 넘으면 페이지 스플릿 이 일어나고, 이게 반복되면 성능이 떨어집니다. 6.2.2 KEY_BLOCK_SIZE 결정 KEY_BLOCK_SIZE 를 너무 작게 잡으면 압축 실패 → 페이지 스플릿 이 자주 발생합니다. 그래서 실제 적용 전에 샘플 데이터로 테스트 해보는 것이 중요합니다. 테스트 방법 -- 1) 인덱스별 압축 통계 수집 활성화 SET GLOBAL innodb_cmp_per_index_enabled = ON; -- 2) KEY_BLOCK_SIZE를 바꿔가며 테스트 테이블 생성 CREATE TABLE employees_comp4k ( emp_no INT NOT NULL, first_name VARCHAR(14) NOT NULL, hire_date DATE NOT NULL, PRIMARY KEY (emp_no), KEY ix_firstname (first_name), KEY ix_hiredate (hire_date) ) ROW_FORMAT = COMPRESSED KEY_BLOCK_SIZE = 4; -- 3) 실제 데이터 일부를 넣어봄 INSERT INTO employees_comp4k SELECT emp_no, first_name, hire_date FROM employees; -- 4) 인덱스별 압축 성공/실패 횟수 확인 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; 컬럼 의미 compress_ops 전체 압축 시도 횟수 compress_ops_ok 압축 성공 횟수 compression_failure_pct 압축 실패율 판단 기준 압축 실패율 = (compress_ops - compress_ops_ok) / compress_ops × 100 💡 일반적으로 압축 실패율이 3~5% 미만 이 되도록 KEY_BLOCK_SIZE 를 선택합니다. 예를 들어 4KB에서 실패율이 높고 8KB에서 낮다면, 8KB 를 선택하는 것이 좋습니다. 그런데 실패율이 전부는 아니다 상황 판단 INSERT만 하는 로그성 테이블 한 번 압축되면 다시 변경되지 않으므로, 실패율이 조금 높아도 압축률이 좋다면 사용 고려 변경이 잦은 테이블 실패율이 낮더라도 압축·해제가 반복되어 CPU 부담 → 압축을 다시 고민 ✅ 압축·해제는 CPU를 사용하는 작업 이라는 점을 함께 고려해야 합니다. 6.2.3 압축된 페이지의 버퍼 풀 적재 및 사용 버퍼 풀에 두 가지 버전을 함께 보관 압축 테이블의 페이지는 버퍼 풀에 이렇게 올라옵니다. ┌─────────────── InnoDB 버퍼 풀 ───────────────┐ │ │ │ [압축된 페이지 8KB] ──해제──▶ [해제된 페이지 16KB] │ │ ▲ ▲ │ │ LRU 리스트 Unzip_LRU 리스트 │ └─────────────────────────────────────────────┘ 리스트 관리 대상 LRU 리스트 압축된 페이지 + 압축 해제된 페이지 모두 Unzip_LRU 리스트 압축 해제된 페이지만 디스크에서 읽어온 압축된 페이지 를 그대로 보관하고, 실제로 데이터를 읽거나 변경하려면 압축을 해제한 페이지 가 필요하기 때문에 둘 다 가지고 있습니다. 이로 인한 문제 문제 설명 메모리 낭비 같은 데이터를 두 가지 형태로 들고 있어서 버퍼 풀 공간을 더 많이 씀 CPU 소모 압축 해제된 페이지를 버렸다가 다시 필요해지면, 또 압축 해제 를 해야 함 InnoDB의 해결 방법: Unzip_LRU 리스트 관리 상황 InnoDB의 동작 버퍼 풀 공간이 부족할 때 압축된 원본은 남기고, Unzip_LRU에서 압축 해제된 버전을 제거 압축된 페이지가 자주 사용될 때 Unzip_LRU에 해제된 페이지를 계속 유지 → 압축·해제 작업 최소화 압축된 페이지가 사용되지 않아 LRU에서 제거될 때 Unzip_LRU에서도 함께 제거 어댑티브(적응형) 알고리즘 InnoDB는 서버 상황을 보고 Unzip_LRU의 비율을 자동으로 조절 합니다. 서버 상황 동작 이유 CPU 사용량이 높음 Unzip_LRU 비율을 높게 유지 압축 해제를 덜 하도록 해서 CPU 절약 디스크 I/O 사용량이 높음 Unzip_LRU 비율을 낮게 유지 버퍼 풀 공간을 더 확보해서 디스크 읽기 감소 🧩 비유 CPU가 바쁠 때: "포장 다시 뜯기 힘드니까, 뜯어놓은 거 그냥 둬" 디스크가 바쁠 때: "창고 공간이 부족하니까, 뜯어놓은 건 치우고 포장된 것만 보관해" 6.2.4 테이블 압축 관련 설정 1 innodb_cmp_per_index_enabled innodb_cmp_per_index_enabled = ON 값 수집되는 통계 ON 인덱스별 압축 성공·실패 횟수 → INNODB_CMP_PER_INDEX OFF 테이블 단위 압축 통계만 수집 → INNODB_CMP 2 innodb_compression_level innodb_compression_level = 6 -- 0 ~ 9, 기본값 6 InnoDB 테이블 압축은 zlib 알고리즘 을 사용하며, 이 값으로 압축률을 정합니다. 값 압축 속도 압축률(저장 공간) CPU 낮을수록 빠름 낮음 (공간 더 사용) 적게 사용 높을수록 느림 높음 (공간 절약) 많이 사용 3 innodb_compression_failure_threshold_pct & innodb_compression_pad_pct_max innodb_compression_failure_threshold_pct = 5 -- 기본값 5(%) innodb_compression_pad_pct_max = 50 -- 기본값 50(%) 동작 방식 테이블 단위 압축 실패율 > innodb_compression_failure_threshold_pct → 압축하기 전에 원본 페이지 끝에 일부러 빈 공간(패딩)을 추가 → 빈 공간은 압축이 매우 잘 되므로 전체 압축률이 올라감 → 압축 결과가 KEY_BLOCK_SIZE보다 작아질 확률 증가 ✅ 설정 의미 innodb_compression_failure_threshold_pct 압축 실패율이 이 값을 넘으면 패딩 추가 시작 innodb_compression_pad_pct_max 패딩 공간은 실패율이 높을수록 늘어나며, 최대 이 비율(%)까지 커질 수 있음 💡 압축 실패로 인한 페이지 스플릿을 줄이기 위해, InnoDB가 스스로 압축 성공률을 높이는 장치 입니다. 4 innodb_log_compressed_pages innodb_log_compressed_pages = ON -- 기본값 ON 서버가 비정상 종료된 뒤 재시작할 때, 압축 알고리즘(zlib)의 버전이 바뀌었더라도 복구가 실패하지 않도록 압축된 데이터 페이지를 그대로 리두 로그에 기록 하는 옵션입니다. 장점 단점 압축 알고리즘을 업그레이드할 때 안전한 복구 보장 데이터 페이지를 통째로 기록하므로 리두 로그 증가량이 커짐 ⚠️ 압축 테이블을 사용 중이라면 리두 로그 공간이 얼마나 빨리 차는지 모니터링해야 합니다. 버퍼 풀에서 더티 페이지가 한꺼번에 많이 기록되는 패턴이라면, 이 옵션을 OFF 로 바꾼 뒤 모니터링해보는 것을 고려할 수 있습니다. ✍️ 마무리 정리 페이지 압축 vs 테이블 압축 항목 페이지 압축 테이블 압축 압축 시점 디스크에 쓸 때 정해진 크기에 맞춰 저장 버퍼 풀 상태 해제된 상태 만 보관 압축 + 해제 둘 다 보관 의존성 OS·하드웨어의 펀치 홀 지원 필요 제약 없음 설정 COMPRESSION = 'zlib' ROW_FORMAT = COMPRESSED , KEY_BLOCK_SIZE 실무 활용 낮음 (파일 복사·백업 문제) 상대적으로 높음 핵심 포인트 6.1 페이지 압축 디스크에 쓸 때 압축하고, 남는 공간은 펀치 홀 로 운영체제에 반납한다. 파일 복사·백업 시 펀치 홀이 사라지는 문제로 잘 쓰이지 않는다. 6.2.1 압축 테이블 생성 innodb_file_per_table = ON 필요 압축 결과가 KEY_BLOCK_SIZE 보다 크면 페이지 스플릿 발생 6.2.2 KEY_BLOCK_SIZE 결정 샘플 데이터로 테스트 후 INNODB_CMP_PER_INDEX 에서 압축 실패율 확인 실패율 3~5% 미만이 기준이지만, 테이블의 변경 빈도도 함께 고려 6.2.3 버퍼 풀 적재 압축 페이지(LRU)와 해제 페이지(Unzip_LRU)를 함께 보관 CPU가 바쁘면 해제 페이지를 유지하고, 디스크가 바쁘면 해제 페이지를 줄이는 적응형 알고리즘 6.2.4 관련 설정 압축 통계( innodb_cmp_per_index_enabled ), 압축률( innodb_compression_level ) 실패율이 높으면 패딩을 추가 해 압축 성공률을 높임 innodb_log_compressed_pages 는 리두 로그 증가량을 함께 모니터링 📚 참고 백은빈, 이성욱, 『Real MySQL 8.0 1권』, 위키북스 MySQL 8.0 Reference Manual - InnoDB Page Compression MySQL 8.0 Reference Manual - InnoDB Table Compression
То, что RADAR обнаружил и классифицировал для этой возможности. Это опубликованный источником текст, а не подтверждение, что предложение ещё действует.
06장. 데이터 압축. 『Real MySQL 8.0』 6장을 읽고, 핵심 개념을 쉽게 이해할 수 있도록 제 방식대로 정리한 글입니다. 📌 들어가기 전에 왜 데이터를 압축할까? 디스크에 저장된 데이터 파일이 커지면 여러 가지 문제가 생깁니다. 문제 설명 쿼리 성능 읽어야 할 데이터가 많아져 디스크 I/O 증가 백업·복구 시간 파일이 클수록 백업과 복구가 오래 걸림 저장 공간 비용 디스크 용량이 많이 필요함 그래서 MySQL은 데이터를 압축해서 저장 하는 방법을 제공합니다. MySQL의 두 가지 압축 방식 방식 다른 이름 한 줄 설명 페이지 압축 Transparent Page Compression 디스크에 쓸 때 압축 , 읽을 때 해제. OS의 펀치 홀 기능에 의존 테이블 압축 - 압축된 페이지를 정해진…
Открыть источник