Mroongaのラッパーモードは「データは任意のストレージエンジンに」「転置索引はGroonga上に」作るモードであって、飽くまでGroonga上ではトランザクションは利きません。つまり、こういうことが起こる。
mysql56> CREATE TABLE t1 (num int, val varchar(32), primary key(num), fulltext key(val)) Engine= Mroonga COMMENT= 'engine "innodb"'; Query OK, 0 rows affected (0.09 sec) mysql56> INSERT INTO t1 VALUES (1, 'yoku0825'); Query OK, 1 row affected (0.01 sec) mysql56> SELECT * FROM t1; +-----+----------+ | num | val | +-----+----------+ | 1 | yoku0825 | +-----+----------+ 1 row in set (0.01 sec) mysql56> SELECT * FROM t1 WHERE match(val) against('yoku'); +-----+----------+ | num | val | +-----+----------+ | 1 | yoku0825 | +-----+----------+ 1 row in set (0.00 sec) mysql56> START TRANSACTION; Query OK, 0 rows affected (0.00 sec) mysql56> UPDATE t1 SET val= 'updated' WHERE num= 1; Query OK, 1 row affected (0.00 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql56> SELECT * FROM t1; +-----+---------+ | num | val | +-----+---------+ | 1 | updated | +-----+---------+ 1 row in set (0.00 sec) mysql56> SELECT * FROM t1 WHERE match(val) against('yoku'); Empty set (0.00 sec) mysql56> SELECT * FROM t1 WHERE match(val) against('update'); +-----+---------+ | num | val | +-----+---------+ | 1 | updated | +-----+---------+ 1 row in set (0.00 sec) mysql56> ROLLBACK; Query OK, 0 rows affected (0.01 sec) mysql56> SELECT * FROM t1; +-----+----------+ | num | val | +-----+----------+ | 1 | yoku0825 | +-----+----------+ 1 row in set (0.00 sec) mysql56> SELECT * FROM t1 WHERE match(val) against('yoku'); Empty set (0.00 sec) mysql56> SELECT * FROM t1 WHERE match(val) against('update'); +-----+----------+ | num | val | +-----+----------+ | 1 | yoku0825 | +-----+----------+ 1 row in set (0.00 sec)
飽くまで転置索引は既に更新されていて、ROLLBACKが利くのは「データの格納されているInnoDB部分」だけ。この状態を解消するには、転置索引を作り直してやるしかない(と思う)
mysql56> ALTER TABLE t1 DISABLE KEYS; Query OK, 0 rows affected (0.00 sec) mysql56> ALTER TABLE t1 ENABLE KEYS; Query OK, 0 rows affected (0.06 sec) mysql56> SELECT * FROM t1 WHERE match(val) against('yoku'); +-----+----------+ | num | val | +-----+----------+ | 1 | yoku0825 | +-----+----------+ 1 row in set (0.01 sec) mysql56> SELECT * FROM t1 WHERE match(val) against('update'); Empty set (0.00 sec)
飽くまで「こういうもの」として考えておかないと、ヒットする/しないがシビアなところだと失敗するかも知れません。基本的に俺はストレージモード推しです。
なお、「(パラメーターによるけど)InnoDBのトランザクション機能でデータ部分は保護される」のは事実なので、クラッシュしてGroonga部分が壊れても(ストレージモードだとここでバックアップからリストアコース)データ部分はリストアする必要がなく、転置索引さえ再作成すればOK、というのはありますね。転置索引に比べてデータ部分が十分大きい場合には、リカバリーの時間短縮と考えられるかも知れません(ちゃんと計ってない)
誰か計ったら教えてください :)
【2014/04/16 10:16】
中の人が教えてくだれました :)
@yoku0825 「転置索引を作り直してやるしかない」のはその通りです!(自分で元の値を入れなおすというのもあるけど現実的じゃない。)「リカバリーの時間短縮」もその通りです!しかも、静的インデックス構築モードになるので1つずつインデックスを構築するより10倍くらい速いです!
— す (@ktou) April 16, 2014
ありがとうございます。
0 件のコメント :
コメントを投稿