このバグは MySQL Shell 8.0.23 で修正済みです。
前回のエントリーで MySQL Shell の dumpInstance にはバグがあると書きました。 今回は、そのバグについてです。
どんなバグか
バックアップの一貫性が失われるバグです。一貫性が失われるている状態とは、バックアップデータの時間軸がずれていることを指します。 あるレコードは10:00:00の状態だが、別のレコードは10:00:01の状態であるといったケースです。
MySQL Shell 8.0.22 でバグがあることを確認しています(それ以前も同じバグがあるかもしれない、未確認です)
Workaround
このバグには簡単なワークアラウンド(回避策)があります。 プロシージャとファンクションをバックアップ対象外にします。 MySQL Shell でバックアップを取っている人はこのオプションを設定しましょう。
util.dumpInstance("mydump", {routines:false});
このバグはMySQL Shellのバグです。mysqldumpやxtrabackupやら他の方法のバックアップには影響ありません(ご安心ください)。
再現方法
簡単に再現します。このような2つのテーブルにINSERTするトランザクションを連続して実行しながら dumpInstance でバックアップを取ります。
BEGIN INSERT INTO db1.t1 (c) VALUES() INSERT INTO db2.t1 (c) VALUES() COMMIT
# 運が良いと再現しないので何度もバックアップします mysqlsh> \py mysqlsh> for i in range(10): util.dump_instance('/tmp/bk%s' % i, compression='none')
一貫性が正しく保たれていれば、生成されたバックアップの db1.t1
と db2.t1
の件数が一致するはずです。
しかし、ズレたバックアップが生成されてしまいます。。。
$ tail -n3 bk5/db*@t1*tsv | less ==> bk5/db1@t1@@0.tsv <== 2222 2223 2224 ==> bk5/db2@t1@@0.tsv <== 2221 2222 2223
バグの原因
MySQL Shellの dumpInstance は、FLUSH TABLES WITH READ LOCK
か LOCK TABLES
で静止点を設け、その間に各Dumpスレッドが、トランザクションを開始します。
各ダンプスレッドが静止点から開始したトランザクションを使って、データをSELECTすることで一貫性を保ったバックアップを生成する仕組みです。
よくよく調べると、一部のダンプスレッドではトランザクションを開始したあと、プロシージャをバックアップするため、mysql.proc
テーブルのロックをとりに行ってました。
LOCK TABLES は暗黙的にトランザクションをコミットします。これによって特定のダンプスレッドだけ静止点からずれたデータをダンプしてしまう状態になってしまっていました。
ということで、バグレポを上げています。気になる人は Subscribe しておくと良いでしょう。
MySQL Bugs: #101410: mysqlsh dumpInstance backup consistency is broken