パーティショニング機能
MySQL 5.1ではパーティショニング機能が実装されているのですが、そのおさらいをするぜ。(`・ω・´)
パーティショニング機能の利用可否確認。
[test] > show variables like '%partition%'; +-------------------+-------+ | Variable_name | Value | +-------------------+-------+ | have_partitioning | YES | +-------------------+-------+ 1 row in set (0.00 sec)
SQL構文。CREATE TABLEのtable optionの後につける。ALTER TABLEでもつかえる。
partition_options: PARTITION BY [LINEAR] HASH(expr) | [LINEAR] KEY(column_list) | RANGE(expr) | LIST(expr) [PARTITIONS num] [SUBPARTITION BY [LINEAR] HASH(expr) | [LINEAR] KEY(column_list) [SUBPARTITIONS num] ] [(partition_definition [, partition_definition] ...)] partition_definition: PARTITION partition_name [VALUES {LESS THAN (expr) | MAXVALUE | IN (value_list)}] [[STORAGE] ENGINE [=] engine_name] [COMMENT [=] 'comment_text' ] [DATA DIRECTORY [=] 'data_dir'] [INDEX DIRECTORY [=] 'index_dir'] [MAX_ROWS [=] max_number_of_rows] [MIN_ROWS [=] min_number_of_rows] [TABLESPACE [=] (tablespace_name)] [NODEGROUP [=] node_group_id] [(subpartition_definition [, subpartition_definition] ...)] subpartition_definition: SUBPARTITION logical_name [[STORAGE] ENGINE [=] engine_name] [COMMENT [=] 'comment_text' ] [DATA DIRECTORY [=] 'data_dir'] [INDEX DIRECTORY [=] 'index_dir'] [MAX_ROWS [=] max_number_of_rows] [MIN_ROWS [=] min_number_of_rows] [TABLESPACE [=] (tablespace_name)] [NODEGROUP [=] node_group_id]
こんな感じで作る。年ごとに別のパーティションにする場合。パーティションの判定に使用するカラムは主キーあるいはその一部である必要がある。
[test] > CREATE TABLE t1 (c1 INT, c2 DATE, c3 VARCHAR(255), PRIMARY KEY(c1,c2)) -> PARTITION BY RANGE (YEAR(c2)) ( -> PARTITION p2004 VALUES LESS THAN (2005), -> PARTITION p2005 VALUES LESS THAN (2006), -> PARTITION p2006 VALUES LESS THAN (2007), -> PARTITION p2007 VALUES LESS THAN (2008) -> ); Query OK, 0 rows affected (0.00 sec)
このとき、生成されるファイルは以下。
mir@t43:/usr/local/mysql/data/test$ ll 合計 32 -rw-rw---- 1 mir mir 0 2007-02-08 14:35 t1#P#p2004.MYD -rw-rw---- 1 mir mir 1024 2007-02-08 14:35 t1#P#p2004.MYI -rw-rw---- 1 mir mir 0 2007-02-08 14:35 t1#P#p2005.MYD -rw-rw---- 1 mir mir 1024 2007-02-08 14:35 t1#P#p2005.MYI -rw-rw---- 1 mir mir 0 2007-02-08 14:35 t1#P#p2006.MYD -rw-rw---- 1 mir mir 1024 2007-02-08 14:35 t1#P#p2006.MYI -rw-rw---- 1 mir mir 0 2007-02-08 14:35 t1#P#p2007.MYD -rw-rw---- 1 mir mir 1024 2007-02-08 14:35 t1#P#p2007.MYI -rw-rw---- 1 mir mir 8608 2007-02-08 14:35 t1.frm -rw-rw---- 1 mir mir 44 2007-02-08 14:35 t1.par
それぞれのパーティションにデータが入る。パーティションの定義範囲外の値はINSERTできない。
[test] > insert into t1 values (10, "2004-12-20", "hogehoge"); Query OK, 1 row affected (0.00 sec) [test] > insert into t1 values (14, "2006-03-21", "fugafuga"); Query OK, 1 row affected (0.01 sec) [test] > insert into t1 values (20, "2008-02-28", "murimuri"); ERROR 1513 (HY000): Table has no partition for value 2008
ちゃんと当該パーティションだけがサイズが増えている。
mir@t43:/usr/local/mysql/data/test$ ll 合計 40 -rw-rw---- 1 mir mir 24 2007-02-08 14:38 t1#P#p2004.MYD -rw-rw---- 1 mir mir 2048 2007-02-08 14:38 t1#P#p2004.MYI -rw-rw---- 1 mir mir 0 2007-02-08 14:35 t1#P#p2005.MYD -rw-rw---- 1 mir mir 1024 2007-02-08 14:35 t1#P#p2005.MYI -rw-rw---- 1 mir mir 24 2007-02-08 14:39 t1#P#p2006.MYD -rw-rw---- 1 mir mir 2048 2007-02-08 14:39 t1#P#p2006.MYI -rw-rw---- 1 mir mir 0 2007-02-08 14:35 t1#P#p2007.MYD -rw-rw---- 1 mir mir 1024 2007-02-08 14:35 t1#P#p2007.MYI -rw-rw---- 1 mir mir 8608 2007-02-08 14:35 t1.frm -rw-rw---- 1 mir mir 44 2007-02-08 14:35 t1.par
2004年のデータが不要になったのでパーティションごと消す。
[test] > ALTER TABLE t1 DROP PARTITION p2004; Query OK, 0 rows affected (0.01 sec) Records: 0 Duplicates: 0 Warnings: 0
ファイルが消えている。
mir@t43:/usr/local/mysql/data/test$ ll 合計 32 -rw-rw---- 1 mir mir 0 2007-02-08 14:35 t1#P#p2005.MYD -rw-rw---- 1 mir mir 1024 2007-02-08 14:35 t1#P#p2005.MYI -rw-rw---- 1 mir mir 24 2007-02-08 14:39 t1#P#p2006.MYD -rw-rw---- 1 mir mir 2048 2007-02-08 14:42 t1#P#p2006.MYI -rw-rw---- 1 mir mir 0 2007-02-08 14:35 t1#P#p2007.MYD -rw-rw---- 1 mir mir 1024 2007-02-08 14:35 t1#P#p2007.MYI -rw-rw---- 1 mir mir 8608 2007-02-08 14:42 t1.frm -rw-rw---- 1 mir mir 40 2007-02-08 14:42 t1.par
2008年対応をするため、パーティションを追加する。
[test] > ALTER TABLE t1 ADD PARTITION (PARTITION p2008 VALUES LESS THAN (2009)); Query OK, 0 rows affected (0.01 sec) Records: 0 Duplicates: 0 Warnings: 0
ファイルが増えている。
mir@t43:/usr/local/mysql/data/test$ ll 合計 36 -rw-rw---- 1 mir mir 0 2007-02-08 14:35 t1#P#p2005.MYD -rw-rw---- 1 mir mir 1024 2007-02-08 14:35 t1#P#p2005.MYI -rw-rw---- 1 mir mir 24 2007-02-08 14:39 t1#P#p2006.MYD -rw-rw---- 1 mir mir 2048 2007-02-08 14:42 t1#P#p2006.MYI -rw-rw---- 1 mir mir 0 2007-02-08 14:35 t1#P#p2007.MYD -rw-rw---- 1 mir mir 1024 2007-02-08 14:35 t1#P#p2007.MYI -rw-rw---- 1 mir mir 0 2007-02-08 14:46 t1#P#p2008.MYD -rw-rw---- 1 mir mir 1024 2007-02-08 14:46 t1#P#p2008.MYI -rw-rw---- 1 mir mir 8608 2007-02-08 14:46 t1.frm -rw-rw---- 1 mir mir 44 2007-02-08 14:46 t1.par
今度は2008年のデータも入る。
[test] > insert into t1 values (20, "2008-02-28", "murimuri"); Query OK, 1 row affected (0.00 sec)
ストレージエンジンをMyISAMからInnoDBへ変えることもできる。
[test] > ALTER TABLE t1 ENGINE = INNODB; Query OK, 2 rows affected (0.01 sec) Records: 2 Duplicates: 0 Warnings: 0
当然、ibdata1に入るのでfrmファイルとparファイル以外は消える。
mir@t43:/usr/local/mysql/data/test$ ll 合計 16 -rw-rw---- 1 mir mir 8608 2007-02-08 14:48 t1.frm -rw-rw---- 1 mir mir 44 2007-02-08 14:48 t1.par
innodb_file_per_tableをONにしていると、ファイルが分割される。
mir@t43:/usr/local/mysql/data/test$ ll 合計 416 -rw-rw---- 1 mir mir 98304 2007-02-08 14:55 t1#P#p2004.ibd -rw-rw---- 1 mir mir 98304 2007-02-08 14:55 t1#P#p2005.ibd -rw-rw---- 1 mir mir 98304 2007-02-08 14:55 t1#P#p2006.ibd -rw-rw---- 1 mir mir 98304 2007-02-08 14:55 t1#P#p2007.ibd -rw-rw---- 1 mir mir 8608 2007-02-08 14:55 t1.frm -rw-rw---- 1 mir mir 44 2007-02-08 14:55 t1.par
話は戻って、myisamであれば、データファイルとインデックスファイルの場所を以下のようにあとから移動が可能。
[test] > ALTER TABLE t1 REORGANIZE PARTITION p2007 INTO (PARTITION p2007 VALUES LESS THAN (2008) DATA DIRECTORY = '/tmp/mysql' INDEX DIRECTORY = '/tmp/mysql' );
もちろん、CREATE TABLE時の指定も可能。
単にmvしてln -sしただけっぽい。ということは手動symlinkもokかも。
mir@t43:/usr/local/mysql/data/test$ ll 合計 28 -rw-rw---- 1 mir mir 0 2007-02-08 15:06 t1#P#p2004.MYD -rw-rw---- 1 mir mir 1024 2007-02-08 15:06 t1#P#p2004.MYI -rw-rw---- 1 mir mir 0 2007-02-08 15:06 t1#P#p2005.MYD -rw-rw---- 1 mir mir 1024 2007-02-08 15:06 t1#P#p2005.MYI -rw-rw---- 1 mir mir 0 2007-02-08 15:06 t1#P#p2006.MYD -rw-rw---- 1 mir mir 1024 2007-02-08 15:06 t1#P#p2006.MYI lrwxrwxrwx 1 mir mir 25 2007-02-08 15:06 t1#P#p2007.MYD -> /tmp/mysql/t1#P#p2007.MYD lrwxrwxrwx 1 mir mir 25 2007-02-08 15:06 t1#P#p2007.MYI -> /tmp/mysql/t1#P#p2007.MYI -rw-rw---- 1 mir mir 8608 2007-02-08 15:06 t1.frm -rw-rw---- 1 mir mir 44 2007-02-08 15:06 t1.par mir@t43:/usr/local/mysql/data/test$ ll /tmp/mysql/ 合計 4 -rw-rw---- 1 mir mir 0 2007-02-08 15:06 t1#P#p2007.MYD -rw-rw---- 1 mir mir 1024 2007-02-08 15:06 t1#P#p2007.MYI
で、そろそろ長くなってきたので最後ですが、現時点のver5.1.14-betaでの主な制約
- InnoDBの外部キーは使用できない
- MERGEは使用できない
- FULLTEXTインデックスは使用できない
http://dev.mysql.com/doc/refman/5.1/en/partitioning-limitations.html
え、え、えええぇぇぇぇ! orz.. FULLTEXTだめっすか。しかしまあそのうち対応してくれるでせう。