MySQL 8.0 リファレンスマニュアル


15.9.2 InnoDB ページ圧縮

InnoDB では、file-per-table テーブルスペースに存在するテーブルのページレベルの圧縮がサポートされます。 この機能は、透過的ページ圧縮と呼ばれます。 ページ圧縮を有効にするには、CREATE TABLE または ALTER TABLECOMPRESSION 属性を指定します。 サポートされている圧縮アルゴリズムには、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 倍です。 次のテーブルに、クラスタサイズとその圧縮単位を示します:

表 15.14 Windows NTFS クラスタのサイズと圧縮単位

クラスタサイズ 圧縮単位
512 バイト 8 KB
1 KB 16 KB
2 KB 32 KB
4 KB 64 KB

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.ibd は明らかなファイルサイズ (FILE_SIZE と同等) をバイト単位で表示します。 ディスクに割り当てられている実際の領域の量 (ALLOCATED_SIZE と同等) を表示するには、du --block-size=1 tablespace_name.ibd を使用します。 --block-size=1 オプションは、割り当てられた領域をブロックではなくバイト単位で出力するため、ls -l 出力と比較できます。

SHOW CREATE TABLE を使用して、現在のページ圧縮設定 (ZlibLz4 または 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 および書込み増幅が増加する可能性があります。


関連キーワード:  InnoDB, 圧縮, テーブル, ページ, サイズ, TABLE, スペース, 構成, SCHEMA, INFORMATION