myisampack で見る PARTITION と MRG_MyISAM のちがい

ちょっとマイナーな話だけど、(MyISAMでの) PARTITION と MRG_MyISAM (マージテーブル) の違いとして、一部だけ myisampack ができるかどうか、があるようです。一部だけというのは、内容が確定した各パーティションなりマージ元のテーブルなりだけを myisampack する、ということです。

MRG_MyISAM の場合

DROP TABLE IF EXISTS aho1, aho2, aho;
CREATE TABLE aho1 (
    id      int not null auto_increment,
    val     int not null,
    primary key (id),
    key (val, id) 
) ENGINE=MyISAM;
CREATE TABLE aho2 (
    id      int not null auto_increment,
    val     int not null,
    primary key (id),
    key (val, id) 
) ENGINE=MyISAM;
CREATE TABLE aho (
    id      int not null auto_increment,
    val     int not null,
    key (id),
    key (val, id) 
) ENGINE=MRG_MyISAM UNION=(aho1, aho2);

こんな感じで作って、

% myisampack aho1.MYI
% myisamchk -rq --sort-index --analyze aho1.MYI
% mysqladmin -uhoge -pfuga -S/tmp/mysql5.1.sock flush-tables

としてあげます。ちなみに flush 忘れると、 marked as crashed になって myisamchk -r しても "aho1.MYI gave error 127 on open" なんて言われて復旧できなくなったりするので注意です。

これで

mysql> insert into aho set val = 1;
ERROR 1036 (HY000): Table 'aho' is read only
mysql> insert into aho1 set val = 1;
ERROR 1036 (HY000): Table 'aho1' is read only
mysql> insert into aho2 set val = 1;
Query OK, 1 row affected (0.00 sec)

と、それなりに意図した動きをしてくれます。

PARTITION の場合

やることはMRGとほとんど同じなので準備は省略で、結果だけ。

mysql> insert into aho set val = 1;
ERROR 1036 (HY000): Table 'aho' is read only

一部のパーティションが read only になれば全体として read only になるようでした。そのこと自体はマージテーブルと同じですが、マージテーブルの場合は (上の aho2 のように) 直接マージ元テーブルを指定すれば insert することができます。パーティションの場合は hash にしても range にしても read only になってしまうのでした。

当然といえば当然な結果なので、パーティションのバグとか言うつもりはなくて、そういう違いで用途が変わります、ということだと思います。だったらもっとマージテーブルの開発が盛り上がってくれてもいいのにな、って話はありますね。ファイルハンドル増えすぎ問題も変わんないでしょうし。補足を上に書きました。

ただ、不安はあるようです。ちょっと古いバグですけど、物理的に別のディスクだとうまくいかないそうで。openのまんまだけど、どうなるのかな。