PostgreSQLとMySQL(MariaDB)のレプリケーションはいろいろ違うが、ロングトランザクションでの挙動の差は興味深いわりにあまり言及されないので、さくっと書く。
MySQLのレプリケーションはバイナリログベースである。動作は以下のとおり。
- トランザクションがcommitした時にバイナリログが書き込まれる
- それがマスターからスレーブに送信される
- 受信したバイナリログをスレーブがredoする
バイナリログはデータ更新をシリアライズして送信するようなものだから、どうしてもコミット完了後に送信せざるをえない*1。
マスターがトランザクションを完了してからバイナリログが送信され、それをスレーブがredoするので、ロングトランザクションの場合はこんな処理シーケンスになる。
一方、PostgreSQLはWALデータを送信するわけだが、WALデータ送信タイミングは以下の通り:
- トランザクションがcommitかabortしたとき
- WAL writerが周期的(デフォルト200msec)に書き込んだ後
- WAL bufferが溢れたとき
トランザクションがcommitする前であっても、WAL writerプロセスに書き込まれたWALデータが逐次送信されているし、大量に書き込まれてWALbufferが溢れれば200msec以内に送信される。
よって、ロングトランザクションの場合はこんな処理シーケンスになる。
ロングトランザクションの場合はMySQL/MariaDBでスレーブの遅れが顕著に現れるというお話。