pt-online-schema-changeでrebuild_constraint時に"child_table has no foreign key constraints referencing _parent_table_old"という警告が出る

事象

pt-online-schema-change 3.0 でALTER対象のテーブルを参照する外部キーが2つ以上ある子テーブルについて、--alter-foreign-keys-method=rebuild_constraintで外部キーの紐付けを直そうとすると、2つ目以降の外部キーに対して表題の警告が出る。

原因

参照のチェック→リビルドの処理フローを制御するループの不備によるバグ。

  • 子テーブルのリストがユニークになっておらず、参照の数だけ子テーブルのリストが膨らんでいる(@$child_tables)
  • 参照の数分警告のチェックが走る
  • 子テーブル1つにつき、全ての外部キー制約(@constraint)のリビルドを行なっている

https://raw.githubusercontent.com/percona/percona-toolkit/3.0/bin/pt-online-schema-change

   CHILD_TABLE:
   foreach my $child_tbl ( @$child_tables ) {
      my $table_def = $tp->get_create_table(
         $cxn->dbh(),
         $child_tbl->{db},
         $child_tbl->{tbl},
      );
      my @constraints = $table_def =~ m/$constraint/g;
      if ( !@constraints ) {
         warn ts("$child_tbl->{name} has no foreign key "
            . "constraints referencing $old_tbl->{name}.\n");
         next CHILD_TABLE;
      }

      my @rebuilt_constraints;
      foreach my $constraint ( @constraints ) {
         PTDEBUG && _d('Rebuilding fk constraint:', $constraint);
     . . .

子テーブルのリストを作るクエリ

   my $sql = "SELECT table_schema, table_name "
           . "FROM information_schema.key_column_usage "
           . "WHERE referenced_table_schema='$tbl->{db}' "
           . "AND referenced_table_name='$tbl->{tbl}'";

対応

処理に影響ないので無視しても良いが、修正するなら下のような感じ?

  • 子テーブルのリストをユニークにする
  • 同じ要素について2周目以降はスキップする
  • 制約のリビルドは最初に見つけた一件のみに対して行うようにする

2017/10/18 追記

バグ報告しました bugs.launchpad.net