pt-online-schema-changeで任意の時間にswap tableしたい

データベースのダウンタイムのリスクを減らしてスキーマ変更することができる pt-online-schema-change(pt-osc) ですが、トリガーの設置時や、テーブルのリネーム時にロックを取るという挙動があり、トランザクションの多い時間帯に実行すると、意図しない動作をすることがあります。

これを避けるためになるべく、トランザクションの少ない時間に実行したいのですが、開始は自分でコントロールできるが、終了時間はコントロールできない問題がありました。これを解決するために、プラグイン機構を利用して、wait fileが存在しない場合、テーブルのリネームを待つようにしました。

package pt_online_schema_change_plugin;

use strict;

sub new {
   my ($class, %args) = @_;
   my $self = { %args };
   return bless $self, $class;
}

sub before_swap_tables {
    my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time);
    my $yyyymmdd = sprintf("%04d%02d%02d", $year + 1900, $mon + 1, $mday);
    my $f = "/tmp/$yyyymmdd\_swap_table";
    print "waiting $f is located";
    until(-e $f) {
      sleep 10
    }
}
1;

これを実行時にこのように渡してやります。

pt-online-schema-change \
--host=your-master \
--check-slave-lag=your-replica \
--recursion-method=none \
--execute D=yourdb,t=your_table \
--alter  "ADD INDEX index_your_index (your_column)"
--alter-foreign-keys-method=rebuild_constraints \
--no-drop-old-table \
--progress=time,5 \
--plugin ./wait_swaptable.pl # pluginとしてファイルで渡す

このようにすると、

Copying `your_db`.`your_table`:  99% 00:03 remain
Copying `your_db`.`your_table`:  99% 00:00 remain
2023-01-05T17:24:59 Copied rows OK.
waiting /tmp/20230105_swap_table is located

こんな感じでsleepしてくれるので、touch /tmp/20230105_swap_table などを実行して、任意の時間にテーブルをリネームすることができます。

深夜に開始して、深夜にリネームしたいという需要はあると思うので、ぜひご活用ください。