MySQLにはHANDLER構文というものがあります。 (Handler Socketとはまた別の話。)
MySQL :: MySQL 5.1 リファレンスマニュアル (オンラインヘルプ) :: 8.2.4 HANDLER 構文
この構文がサポートしているのはMyISAM,InnoDBだけなので使う際は注意が必要です。
CREATE TABLE IF NOT EXISTS tweet ( tid INT(10) AUTO_INCREMENT, body VARCHAR(255), PRIMARY KEY (tid) )Engine=InnoDB;
INSERT INTO tweet (body) VALUES ('hoge'); INSERT INTO tweet (body) VALUES ('foo'); INSERT INTO tweet (body) VALUES ('bar'); INSERT INTO tweet (body) VALUES ('ham'); INSERT INTO tweet (body) VALUES ('spam'); INSERT INTO tweet (body) VALUES ('egg');
% mysql -uroot -Dfoo < tweet.sql % mysql -uroot -Dfoo < sample_data.sql
こんな感じでテーブルとサンプルデータを投入してちょっと動かしてみましょう。
# まず、テーブルをオープン mysql> HANDLER tweet open; Query OK, 0 rows affected (0.00 sec) # データを取得します。 デフォルトではPKでソートされた順番に取得します。 mysql> HANDLER tweet READ NEXT; +-----+------+ | tid | body | +-----+------+ | 1 | hoge | +-----+------+ 1 row in set (0.00 sec) # LIMIT句で取得する件数を指定もできます。 mysql> HANDLER tweet READ NEXT LIMIT 3; +-----+------+ | tid | body | +-----+------+ | 2 | foo | | 3 | bar | | 4 | ham | +-----+------+ 3 rows in set (0.00 sec) mysql> HANDLER tweet READ NEXT LIMIT 5; +-----+------+ | tid | body | +-----+------+ | 5 | spam | | 6 | egg | +-----+------+ 2 rows in set (0.00 sec) # 最後までいくと Emptyを返します。 mysql> HANDLER tweet READ NEXT; Empty set (0.00 sec) # テーブルをクローズ mysql> HANDLER tweet CLOSE; Query OK, 0 rows affected (0.00 sec)
ただし、HANDLER構文はSELECT文のように取得するカラムは選べません。
さて、なんでハマったかという本題からずれているので戻します。
こんなテーブルを作ってみました。
CREATE TABLE IF NOT EXISTS tweet ( tid INT(10) AUTO_INCREMENT, body VARCHAR(255), PRIMARY KEY (tid) )Engine=InnoDB; ALTER TABLE tweet PARTITION BY KEY(tid) PARTITIONS 4;
すると、こんなエラーが・・・。
mysql> HANDLER tweet open; ERROR 1031 (HY000): Table storage engine for 'tweet' doesn't have this option
なんでかなって考えたら、テーブルファイルの構造がパーティションによって変更を受けるのが原因のような気がしている。
パーティションしてない場合のデータファイルはこう。
% sudo ls -lh /var/lib/mysql/foo -rw-rw---- 1 mysql mysql 65 9月 24 09:58 2012 db.opt -rw-rw---- 1 mysql mysql 8.4K 9月 30 17:31 2012 tweet.frm
パーティションしている場合のデータファイルはこう。
% sudo ls -lh /var/lib/mysql/foo -rw-rw---- 1 mysql mysql 65 9月 24 09:58 2012 db.opt -rw-rw---- 1 mysql mysql 8.4K 9月 30 17:24 2012 tweet.frm -rw-rw---- 1 mysql mysql 32 9月 30 17:24 2012 tweet.par
テーブル名.parが増えているのでその辺が悪いのかなって思ってる。
まとめ、テーブルパーティションする可能性がある場合はHANDLER構文を使ってはダメです。
SELECT構文で簡単に書き直せるので使っている場合は今からでも書き直しましょう。