InnoDB
では、file-per-table テーブルスペースに存在するテーブルのページレベルの圧縮がサポートされます。 この機能は、透過的ページ圧縮と呼ばれます。 ページ圧縮を有効にするには、CREATE TABLE
または ALTER TABLE
で COMPRESSION
属性を指定します。 サポートされている圧縮アルゴリズムには、Zlib
および LZ4
があります。
サポートされるプラットフォーム
ページ圧縮には、スパースファイルおよびホールパンチのサポートが必要です。 ページ圧縮は、NTFS を使用する Windows、およびカーネルレベルでホールパンチングサポートが提供される MySQL-supported Linux プラットフォームの次のサブセットでサポートされます:
RHEL 7 およびカーネルバージョン 3.10.0-123 以降を使用する派生ディストリビューション
OEL 5.10 (UEK2) カーネルバージョン 2.6.39 以上
OEL 6.5 (UEK3) カーネルバージョン 3.8.13 以上
OEL 7.0 カーネルバージョン 3.8.13 以上
SLE11 カーネルバージョン 3.0-x
SLE12 カーネルバージョン 3.12-x
OES11 カーネルバージョン 3.0-x
Ubuntu 14.0.4 LTS カーネルバージョン 3.13 以上
Ubuntu 12.0.4 LTS カーネルバージョン 3.2 以上
Debian 7 カーネルバージョン 3.2 以上
特定の Linux ディストリビューションで使用可能なすべてのファイルシステムでホールパンチがサポートされていない場合があります。
ページ圧縮の仕組み
ページが書き込まれると、指定された圧縮アルゴリズムを使用して圧縮されます。 圧縮されたデータはディスクに書き込まれ、ホールパンチングメカニズムによってページの最後から空のブロックが解放されます。 圧縮に失敗すると、データはそのまま書き出されます。
Linux の穴パンチサイズ
Linux システムでは、ファイルシステムのブロックサイズはホールパンチに使用される単位サイズです。 したがって、ページ圧縮は、InnoDB
ページサイズからファイルシステムのブロックサイズを引いたサイズ以下のサイズにページデータを圧縮できる場合にのみ機能します。 たとえば、innodb_page_size=16K
でファイルシステムのブロックサイズが 4K の場合、ホールパンチを可能にするには、ページデータを 12K 以下に圧縮する必要があります。
Windows でのホールパンチングサイズ
Windows システムでは、疎ファイルの基盤となるインフラストラクチャは NTFS 圧縮に基づいています。 ホールパンチングサイズは NTFS 圧縮ユニットで、NTFS クラスタサイズの 16 倍です。 次のテーブルに、クラスタサイズとその圧縮単位を示します:
Windows システムでのページ圧縮は、ページデータを InnoDB
ページサイズから圧縮単位サイズを引いた値以下のサイズに圧縮できる場合にのみ機能します。
NTFS クラスタのデフォルトサイズは 4KB で、圧縮単位のサイズは 64KB です。 つまり、デフォルトの Windows NTFS 構成では、最大 innodb_page_size
も 64KB であるため、ページ圧縮にメリットはありません。
ページ圧縮を Windows で機能させるには、ファイルシステムを 4K より小さいクラスタサイズで作成し、innodb_page_size
を圧縮ユニットの 2 倍以上のサイズにする必要があります。 たとえば、ページ圧縮が Windows で機能するようにするには、512 バイト (圧縮単位は 8KB) のクラスタサイズでファイルシステムを構築し、16K 以上の innodb_page_size
値で InnoDB
を初期化します。
ページ圧縮の有効化
ページ圧縮を有効にするには、CREATE TABLE
ステートメントで COMPRESSION
属性を指定します。 例:
CREATE TABLE t1 (c1 INT) COMPRESSION="zlib";
ALTER TABLE
ステートメントでページ圧縮を有効にすることもできます。 ただし、ALTER TABLE ... COMPRESSION
ではテーブルスペース圧縮属性のみが更新されます。 新しい圧縮アルゴリズムの設定後に発生したテーブルスペースへの書込みでは新しい設定が使用されますが、新しい圧縮アルゴリズムを既存のページに適用するには、OPTIMIZE TABLE
を使用してテーブルを再構築する必要があります。
ALTER TABLE t1 COMPRESSION="zlib";
OPTIMIZE TABLE t1;
ページ圧縮の無効化
ページ圧縮を無効にするには、ALTER TABLE
を使用して COMPRESSION=None
を設定します。 COMPRESSION=None
の設定後に発生するテーブルスペースへの書込みでは、ページ圧縮は使用されなくなりました。 既存のページを解凍するには、COMPRESSION=None
の設定後に OPTIMIZE TABLE
を使用してテーブルを再構築する必要があります。
ALTER TABLE t1 COMPRESSION="None";
OPTIMIZE TABLE t1;
ページ圧縮メタデータ
ページ圧縮メタデータは、INFORMATION_SCHEMA.INNODB_TABLESPACES
テーブルの次のカラムにあります:
FS_BLOCK_SIZE
: ホールパンチングに使用される単位サイズであるファイルシステムのブロックサイズ。FILE_SIZE
: 圧縮解除されたファイルの最大サイズを表す、ファイルの見かけ上のサイズ。ALLOCATED_SIZE
: ファイルの実際のサイズ。これは、ディスクに割り当てられた領域の量です。
Unix に似たシステムでは、ls -l
は明らかなファイルサイズ (tablespace_name
.ibdFILE_SIZE
と同等) をバイト単位で表示します。 ディスクに割り当てられている実際の領域の量 (ALLOCATED_SIZE
と同等) を表示するには、du --block-size=1
を使用します。 tablespace_name
.ibd--block-size=1
オプションは、割り当てられた領域をブロックではなくバイト単位で出力するため、ls -l
出力と比較できます。
SHOW CREATE TABLE
を使用して、現在のページ圧縮設定 (Zlib
、Lz4
または None
) を表示します。 テーブルには、異なる圧縮設定を持つページが混在する場合があります。
次の例では、employees テーブルのページ圧縮メタデータが INFORMATION_SCHEMA.INNODB_TABLESPACES
テーブルから取得されます。
# Create the employees table with Zlib page compression
CREATE TABLE employees (
emp_no INT NOT NULL,
birth_date DATE NOT NULL,
first_name VARCHAR(14) NOT NULL,
last_name VARCHAR(16) NOT NULL,
gender ENUM ('M','F') NOT NULL,
hire_date DATE NOT NULL,
PRIMARY KEY (emp_no)
) COMPRESSION="zlib";
# Insert data (not shown)
# Query page compression metadata in INFORMATION_SCHEMA.INNODB_TABLESPACES
mysql> SELECT SPACE, NAME, FS_BLOCK_SIZE, FILE_SIZE, ALLOCATED_SIZE FROM
INFORMATION_SCHEMA.INNODB_TABLESPACES WHERE NAME='employees/employees'\G
*************************** 1. row ***************************
SPACE: 45
NAME: employees/employees
FS_BLOCK_SIZE: 4096
FILE_SIZE: 23068672
ALLOCATED_SIZE: 19415040
employees テーブルのページ圧縮メタデータは、明らかなファイルサイズが 23068672 バイトで、実際のファイルサイズ (ページ圧縮あり) が 19415040 バイトであることを示しています。 ファイルシステムのブロックサイズは 4096 バイトで、ホールパンチに使用されるブロックサイズです。
ページ圧縮を使用したテーブルの識別
ページ圧縮が有効になっているテーブルを識別するには、COMPRESSION
属性で定義されているテーブルの INFORMATION_SCHEMA.TABLES
CREATE_OPTIONS
カラムをクエリーします:
mysql> SELECT TABLE_NAME, TABLE_SCHEMA, CREATE_OPTIONS FROM INFORMATION_SCHEMA.TABLES
WHERE CREATE_OPTIONS LIKE '%COMPRESSION=%';
+------------+--------------+--------------------+
| TABLE_NAME | TABLE_SCHEMA | CREATE_OPTIONS |
+------------+--------------+--------------------+
| employees | test | COMPRESSION="zlib" |
+------------+--------------+--------------------+
SHOW CREATE TABLE
では、COMPRESSION
属性も表示されます (使用されている場合)。
ページ圧縮の制限事項と使用上のノート
ファイルシステムのブロックサイズ (または Windows の場合は圧縮単位サイズ) * 2 >
innodb_page_size
の場合、ページ圧縮は無効になります。システムテーブルスペース、一時テーブルスペースおよび一般テーブルスペースを含む共有テーブルスペースに存在するテーブルでは、ページ圧縮はサポートされていません。
undo ログテーブルスペースではページ圧縮はサポートされていません。
redo ログページでは、ページ圧縮はサポートされていません。
空間インデックスに使用される R ツリーページは圧縮されません。
圧縮テーブル (
ROW_FORMAT=COMPRESSED
) に属するページはそのまま残ります。リカバリ中、更新されたページは圧縮されていない形式で書き出されます。
使用された圧縮アルゴリズムをサポートしていないサーバーにページ圧縮テーブルスペースをロードすると、I/O エラーが発生します。
ページ圧縮をサポートしていない以前のバージョンの MySQL にダウングレードする前に、ページ圧縮機能を使用するテーブルを解凍します。 テーブルを解凍するには、
ALTER TABLE ... COMPRESSION=None
およびOPTIMIZE TABLE
を実行します。ページ圧縮されたテーブルスペースは、使用された圧縮アルゴリズムが両方のサーバーで使用可能な場合、Linux サーバーと Windows サーバーの間でコピーできます。
ページ圧縮されたテーブルスペースファイルをあるホストから別のホストに移動する際にページ圧縮を保持するには、スパースファイルを保持するユーティリティが必要です。
NVMFS はパンチ穴機能を利用するように設計されているため、NVMFS を搭載した Fusion-io ハードウェアでは、他のプラットフォームよりも優れたページ圧縮を実現できます。
InnoDB
ページサイズが大きく、ファイルシステムのブロックサイズが比較的小さいページ圧縮機能を使用すると、書込み増幅が発生する可能性があります。 たとえば、ファイルシステムのブロックサイズが 4KB の 64KB の最大InnoDB
ページサイズでは、圧縮が改善されますが、バッファプールに対する需要が増加し、I/O および書込み増幅が増加する可能性があります。