データベースのダウンタイムのリスクを減らしてスキーマ変更することができる 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
などを実行して、任意の時間にテーブルをリネームすることができます。
深夜に開始して、深夜にリネームしたいという需要はあると思うので、ぜひご活用ください。