免責事項
この記事はKevin Lewis氏によるMySQL Server Blogの投稿「General Tablespaces in MySQL 5.7 – Details and Tips」(2016/3/23)をユーザが翻訳したものであり、Oracle公式の文書ではありません。
※ 訳注: Tablespaceの日本語訳について: 記事タイトル以外はMySQLのマニュアルに倣い「表領域」ではなく「テーブルスペース」の表記としています。
MySQL 5.7のInnoDBで、一般テーブルスペースの作成および複数のテーブルへの割り当てが初めてできるようになりました。一般テーブルスペースはシステムの任意の場所に配置でき、圧縮テーブルのブロックサイズにkey_block_size
を利用できるように、通常より小さなブロックサイズを指定することもできます。
新しいテーブルスペースは、次のようにして作成することができます。
CREATE TABLESPACE new ADD DATAFILE 'newdata.ibd' BLOCK_SIZE=16k;
現在のinnodb-page-size
が16KBであれば、BLOCK_SIZE句の付与は任意となります。
データファイル名について
.ibd 拡張子がファイル名に付与されます。InnoDBが.ibdで終わるファイル名のみ受け付けているため、これは必須となります。つまり、ファイル名は単にADD DATAFILEの後に指定できるならば何でも良いというわけではなく、システムテーブルスペース以外のInnoDBのデータファイルが認識しやすくなるように.ibdで終わるというルールにも沿う必要があることがわかります。
上記のデータファイルにパスがついていないのも重要です。このような相対パスは設定ファイル中のdatadirからの相対的なパスとなります。これはシステムテーブルスペースおよびログファイルと同じ場所となります。
システムの他の場所にファイルを作成する為に、絶対パスも指定できます。一般テーブルスペースの場所については、2つの制約があります。
- ルートディレクトリには設置できません。設計エンジニアがこれは禁止した方がよかろうと考えたためです。これは主にunixの観点ですが、Windowsでも一般的にはこのようにした方がよいでしょう。
- 一般テーブルスペースのデータファイルはdatadir下のディレクトリには置けません。これはfile-per-tableモードのテーブルスペースのデータファイルの場所であるためです。MySQLでは伝統的にdatadir下のディレクトリにはデータベースやスキーマ関連のファイルを置きます。これらのデータファイルやディレクトリは
innodb-file-per-table
がONのときはテーブル作成時に自動的に作成されます。ファイル名はテーブル名に.ibd拡張子が付与したものとなります。
file-per-tableモードのデータファイルと同一名称のデータファイルのテーブルスペースを作ることもできます。例えば次の通りです。
CREATE DATABASE new;
SET SESSION innodb_file_per_table=ON;
CREATE TABLE new.new (a INT) engine=InnoDB;
CREATE TABLESPACE new ADD DATAFILE 'new.ibd' engine=InnoDB;
new.ibdという名称の2つのファイルが作成されます。一般テーブルスペースのデータファイルはdatadir直下に、そしてfile-per-tableモードのデータファイルはdatadir下のnewディレクトリ下に配置されます。
しかしアドバイスとしては、、、全データベースオブジェクトでユニークになるよう名前を付与してください。InnoDBの将来のバージョンでは、上記のような似たデータファイル名は禁止されるかもしれませんし、一般テーブルスペースをデータベースに関連付ける際に何らかの競合を引き起こすかもしれません。異なるオブジェクトには異なる名称を付与し、競合が発生する可能性を回避するのがよいでしょう。
一般テーブルスペースのポータビリティー
file-per-tableモードのテーブルスペースは次の手順に従って他のシステムに移動することができます:http://dev.mysql.com/doc/refman/5.7/en/tablespace-copying.html
ドキュメント中の手法では次のコマンドを利用しています。
ALTER TABLE t1 DISCARD TABLESPACE;
ALTER TABLE t1 IMPORT TABLESPACE;
DiscardとImportはシステムテーブルスペースではサポートされてきませんでした。5.7の一般テーブルスペースでもこれはサポートされません。これは一般テーブルスペースがシステムテーブルスペースと同様に複数のテーブルで共有可能であり、他のシステムにデータファイルを移動するのが容易ではないためです。
テーブルのテーブルスペースを選択する
テーブルは、CREATE TABLE
あるいはALTER TABLE
文でTABLESPACE
句を利用することで、一般テーブルスペース 、file-per-tableモードのテーブルスペース、システムテーブルスペースで作成および変更ができます。
これにより明示的にテーブルにテーブルスペースを選択できるようになり、テーブルを移動することができるようにもなります。ALTER TABLE
構文でTABLESPACE
句を使うことで、任意のテーブルスペースの任意のテーブルを他のテーブルスペースに移動することができます。これは初めてテーブルをシステムテーブルスペースに移動できるようになったということになります。また、innodb-file-per-tableの設定とは関係なしにfile-per-tableを選択できるということになります。
つまり、次のようなクエリを発行したとすると、
SET SESSION innodb_file_per_table=OFF;
CREATE TABLE t1 (a INT) TABLESPACE=innodb_file_per_table engine=InnoDB;
テーブルは、そのテーブルのfile-per-tableモードのテーブルスペースで作成されることになります。
同じようにして、システムテーブルスペースを指定してテーブルを作成することもできます。
SET SESSION innodb_file_per_table=ON;
CREATE TABLE t1 (a INT) TABLESPACE=innodb_system engine=InnoDB;
テーブルスペース名はSQLの識別子
これらの例にみられるテーブルスペース名の前後には引用符(クォート)がありません。テーブルスペース名はSQLの識別子であるためです。この事実からこの名前をバッククォート(`)で囲むこともでき、常に大文字小文字を区別して評価されることがわかります。
※訳注: 識別子の修飾子/識別子の大文字と小文字の区別参照。
つまり、次のように同一名で大文字小文字が異なる複数のテーブルスペースが作成可能であるということになります。
CREATE TABLESPACE new ADD DATAFILE 'new1.ibd';
CREATE TABLESPACE New ADD DATAFILE 'new2.ibd';
CREATE TABLESPACE NEW ADD DATAFILE 'new3.ibd';
再度となりますが、大文字小文字だけが異なる同一名称のテーブルスペースは作らないようにしてください。
予約テーブルスペース名
特別な意味を持つ「予約」テーブルペースが3つあります。2つはこれまでにご紹介しています。
- innodb_file-per-table
- innodb_system
- innodb_temporary
5.7では最初の2つをご紹介したようにして利用することができます。3つ目は利用できません。テーブルを一時テーブルスペースに置くためにTABLESPACE=innodb_temporary
は使えません。CREATE TEMPORARY TABLE ...;
をご利用ください。
3つのテーブルスペースは大文字小文字を区別するため、次のクエリが発行可能です。
CREATE TABLESPACE `InnoDB_System` ADD DATAFILE 'innodb_system.ibd';
しかし、再度となりますが、決してこの方法を使わないでください。 テーブルスペースはユニークになるようにすべきです。
まとめ
このディスカッションによってMySQL 5.7の一般テーブルスペースの理解の助けになればと思います。将来のリリースで、テーブルスペースの機能はいくつか追加されます。