Bug #17764 trigger crashes myisam table

http://bugs.mysql.com/bug.php?id=17764
解決済みのバグについて、その発生理由と修正方法を部内勉強会で説明するために調べりんぐ。

再現環境

再現コード

DROP TABLE IF EXISTS t1;
CREATE TABLE `t1` (
  `a` int(11) default NULL,
  `b` int(11) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
;

insert into t1 (a,b) values(1,2),(2,3),(1,2),(2,3),(1,2);

DROP TABLE IF EXISTS t2;
CREATE TABLE `t2` (
  `a` int(11) default NULL,
  `c` int(11) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
;

drop procedure if exists sp1;
delimiter //
create procedure sp1(in v2 INTEGER)
    NOT DETERMINISTIC
    SQL SECURITY DEFINER
    COMMENT ''
BEGIN
  DECLARE total INTEGER;
  select sum(c) into total from t2 where a = v2 group by a;
  update t1 set t1.b = total where t1.a = v2;
END//
delimiter ;

CREATE TRIGGER tr1 AFTER INSERT
ON t2 FOR EACH ROW
  call sp1(NEW.a);

insert into t2 (a,c) values
(1,2),(2,3),(1,2),(2,3),(1,2),(2,3),(1,2),(2,3),(1,2),(2,3),(2,3),(1,2),(2,3);

症状

最後のbulk insert処理でエラーになる。

[test] > insert into t2 (a,c) values
    -> (1,2),(2,3),(1,2),(2,3),(1,2),(2,3),(1,2),(2,3),(1,2),(2,3),(2,3),(1,2),(2,3);
ERROR 1194 (HY000): Table 't2' is marked as crashed and should be repaired

本来は以下ように正常にbulk insertができないといけない。(MySQL 5.0.20以上はこうなってる。)

[test] > insert into t2 (a,c) values
    -> (1,2),(2,3),(1,2),(2,3),(1,2),(2,3),(1,2),(2,3),(1,2),(2,3),(2,3),(1,2),(2,3);
Query OK, 13 rows affected (0.00 sec)
Records: 13  Duplicates: 0  Warnings: 0

要するにこの手順で実行するとテーブルを壊しちゃう。

つまりどういう問題?

通常のbulk insertはできる。でもそのinsert対象のテーブルにtriggerがしかけてある場合、テーブルが壊れるというもの。bulk insert独特の高速化のためのロジックとtriggerが相容れないということ。

修正コード

既に結論がでているので、とりあえず。