본문 바로가기
MySQL별책부록

MySQL Ver. 5.7 InnoDB Transparent Page Compression

by 모모레 2016. 6. 3.

InnoDB에서 페이지에 대한 압축 기능을 제공한 건 InnoDB Plugin for MySQL Ver. 5.1 부터였다. 하지만, 처음에 이 압축기능은 성능도 많이 떨어지고 문제가 많아서 쓰기에 부적합했었다. 버젼이 높아지면서 해당 문제는 조금씩 해결되어 가고 있는데, MySQL Ver. 5.7에서는 어떻게 수정되어 변경되었는지 알아보도록 하자. 


MySQL Ver. 5.7에서는 좀 더 단순하게 구현하려고 노력했다. 그래서 변화된 코드에서는 기본은 localize 즉, 관리 데이터는 로컬에서 처리되게 하고, 기존의 InnoDB 압축 기능과 새 압축 기능이 하나의 인스턴스 안에서 공존하여 사용할 수 있게 하였다. 사용자 입장에서는 자신이 원하는 압축 방법을 사용할 수 있게 제공하고, 가능하면 테이블 별로 설정할 수 있게 제공하게 구현하려고 했다. 


그래서 새롭게 MySQL Ver. 5.7.8 부터 추가된 기능이 Transparent Page Compression 이다. 이 기능은 file-per-table 테이블스페이스에 저장된 InnoDB의 테이블에 대한 페이지 레벨의 압축 기능을 말한다. 이 페이지 압축 기능은 CREATE TABLE/ ALTER TABLE 명령을 통해 활성화 된다. 



쓰기와 읽기에서 Transparent Page Compression은 다음과 같은 로직으로 구현된다. 


Write : Page -> Transform -> Write transformed page to disk -> Punch hole



Read : Page from disk -> Transform -> Original Page


위와 같은 추상화 작업으로 내부적으로 페이지를 어떤 식으로 변환하는지 즉, 어떤 알고리즘을 사용하는 것인지 크게 상관하지 않고 개발 할 수 있게 되었다. 그래서, 새롭게 압축 알고리즘을 추가하는것도 쉽게 가능했다. 

또한, MySQL Ver. 5.7 부터 Page Cleaner Thread를 여러 개 생성하는게 가능해 졌다. 즉, 이미 있는 기능인 멀티 Palge Cleaner Thread 기능으로 인해, 디스크에 쓰기전에 페이지 내용을 변환하는 작업을 해당 스레드에 전가하여 백그라운드로 병렬 처리되게 처리할 수 있게 된 것이다. 반면, 이전의 InnoDB 압축은 사용자 스레드에서 compress/decompress/recompress 명령어를 사용하여 처리되게 구현되었었다. 


[Hole Punching]

사용할 파일 블럭을 미리 할당받아서 사용하는 기능을 말한다.  즉, 디스크에 쓰기 요청을 할때, DB의 Page 사이즈 만큼 미리 할당 받아 놓고 작업을 하는 것이다. DB page의 사이즈와 파일 시스템의 블럭 사이즈는 다르기 때문이다. 그 간극을 줄여서 좀 더 효율적으로 사용할 수 있게 하는 것이 Hole Punching 기능이다.  InnoDB Transparent Page Compression은 해당 기능이 제공되어야 사용이 가능하다. 


여기서 이야기 하는 새롭게 추가된 Transparent Compression 기능을 사용하기 위해서는 OS에서는 sparse files와 hole punching 이라는 기능이 지원되어야 한다. 


[Linux]

리눅스에서 제공하는 파일 시스템에서는 이미 hole punching 기능을 제공하고 있다. XFS(Linux 2.6.38), ext4(Linux 3.0), tmpfs[/dev/shm](Linux 3.5) Btrfs(Linux3.7)에서 지원되고 있다. 


현재 사용가능한 압축 기능은 ZLib와 LZ4 이다. 다음과 같은 문법으로 선택이 가능하다. 


COMPRESSION := ( "zlib" | "lz4" | "none")


테이블을 생성할 때 다음과 같이 생성하면 사용이 가능하다. 


CREATE TABLE T (C INT) COMPRESSION="lz4";


압축을 사용하고 싶지 않은 경우 다음과 같이 ALTER 명령어를 통해 비활성화 할 수 있다. 


ALTER TABLE T COMPRESSION="none";


이때 해당 작업은 메터 데이터 변경만 진행된다. InnoDB의 압축은 페이지 레벨의 속성으로 내부에서 처리되는 것이기 때문이다. 그리고 하나의 테이블 스페이스안에 저장된 페이지들은 여러 다른 압축 알고리즘을 사용해도 상관없다. 만약, 강제적으로 페이지의 내용을 변환하고자 한다면 다음과 같이 해당 테이블을 실행하면 된다. 


OPTIMIZE TABLE T;


이 기능을 사용할 때에는 innodb-page_cleaners 파라메터를 기억해야 한다. 해당 시스템 변수의 값을 기본 값보다 증가시켜야 효과를 느낄 수 있다. 


해당 기능의 모니터링은 information_schema의 INNODB_SYS_TABLESPACES 테이블을 통해 가능하다. 


FS_BLOCK_SIZE : 파일 시스템의 블럭 사이즈 

FILE_SIZE : 파일의 논리적인 크기. 

ALLOCATED_SIZE : 파일시스템에 존재하는 블럭 디바이스에 실제 할당된 사이즈 

COMPRESSION : 사용하는 압축 알고리즘 


제약 사항은 다음과 같다. 

1. Spatial(R-Tree_ 인덱스를 내부적으로 생성하여 관리하는 System Tablespce, General Tablespaces, Undo Tablespaces는 모두 사용할 수 없다. 

2. 파일 시스템에 설정된 블럭 사이즈에 따라 제약 사항이 발생한다. 즉 해당 사이즈에 맞춰서 punch a hole을 하기 때문에 1K로 압축해도 4K로 할당하여 저장한다. 

3.  현재 이기능을 사용하는 파일을 다른 시스템으로 복사할 때, 해당 파일의 사이즈가 더 커질 수 있다. 그래서 다른 시스템으로 복사할 때 주의해야 한다. 예를 들어 rsync를 사용하면 문제없이 복사될 수 있지만, scp를 사용하면 파일의 사이즈가 더 커지게 된다. 

4. ALTER TABLE 명령어를 사용하여 압축 기능을 활성화 해도 씰제 데이터 파일은 변경되지 않는다. 메터 정보만 변경하기 때문이다. 이후에 들어오는 데이터에 대해서만 적용된다. 그러므로, 기존 데이터에도 똑같이 적용되게 하려면 OPTIMIZE TABLE 명령어를 사용하여 변경해 주어야 한다. 

5. punching hole을 하고, release를 할 때 파일 시스템에 단편화가 많이 발생할 수 있다. 그래서 해당 블럭을 관리하는 FS Free list 관리에 오버헤드가 증가할 수 있다. 


다음의 문서에서 더 자세한 내용을 확인할 수 있습니다. 

http://mysqlserverteam.com/innodb-transparent-page-compression/

http://dev.mysql.com/doc/refman/5.7/en/innodb-page-compression.html