免責事項
この記事はSujatha Sivakumar氏によるMySQL High Availabilityの投稿「Replication Defaults in MySQL-5.7.7」(2015/7/8)をユーザが翻訳したものであり、Oracle公式の文書ではありません。
コミュニティーのフィードバックにもとづいて、MySQL 5.7.7のリリースの一部として、レプリケーション機能のデフォルト値という観点でいくつかの改善が行われた。これはMySQLのレプリケーションをより安全に、かつより使いやすくするだろう。
このブログはこれらのデフォルト値の変更についての情報を提供することを目的としており、簡単にその長所を説明する。
1) 単純化されたGTIDリカバリがデフォルトで有効化されるようになった
binlog_gtid_simple_recovery=TRUEがデフォルトとなった。
この変数はMySQLが起動されたり再起動された時に、GTIDを検索する最中にどのようにバイナリログファイルが繰返し利用されるかを制御する。 このオプションをTRUEにすることでリカバリの性能は向上する。このオプションによりサーバーの起動とバイナリログのパージが高速になる。 このパラメータが有効化されたときは、一番古い、そして一番新しいログファイルだけを開き、gtid_purgedとgtid_executedが、これらのファイルのprevious_gtid_log_eventまたはgtid_log_eventから計算される。
MySQL 5.6でこのオプションをTRUEにすると性能が良くなるが、いくつかの特異なケースで、バイナリログ中のgtidのセットの計算が不正確になる可能性がある。このオプションをFALSEにすると常に正確な結果となる。
MySQL 5.7.7では、速度と安全性のトレードオフがほとんどなくなった。このオプションをTRUEにするといくつかの特異なケースを除き、いつも正確な値を返すようになった。
特異なケースとしては下記があげられる。
- 最新のバイナリログがMySQL 5.7.5以降で生成されており、gtid_modeがいくつかのバイナリログでONとなっているが、最新のバイナリログではOFFとなっている
- SET GTID_PURGED文はMySQL 5.7.7以前で問題があり、SET GTID_PURGEDがまだパージされていないときにアクティブになったバイナリログ
従って、より高速なオプションは大抵の場合よりよい選択肢であり、デフォルトのモードとなった。
この機能がOFFになると、リカバリの最中でgtid_executedを初期化するために、最新のファイル以降の全てのバイナリログが検査され、またgtid_purgedを初期化する為に一番古いバイナリログから最新のログファイルまでの全てのバイナリログが検査される。これは潜在的に長い時間がかかりうる。
2) 行ベースのバイナリログ形式がデフォルトとなった
binlog-format=ROWがデフォルトとなった。
http://dev.mysql.com/doc/refman/5.7/en/replication-options-binary-log.html#sysvar_binlog_format
バイナリログがONでバイナリログ形式がROWモードで運用している際には、各テーブルの行に対する変更がバイナリログに記録される。それからこれらがスレーブ側に適用される。これはSTATEMENT形式を利用している場合とは異なり、STATEMENT形式ではバイナリログにSTATEMENTs(SQL文)を記録し、これがスレーブで再実行される。
全ての種類の変更を複製できるので、これが最も安全なレプリケーション形式である。あるSQL文では、ステートメントベースレプリケーションに比べ、行のロックが少なくてすむようになる。以前のSTATEMENTオプションでは非決定的なSQL文がスレーブでマスターと異なる結果となりえる。
3) binlog_error_action=ABORT_SERVERがデフォルトとなった
binlog_error_action
は、サーバーがバイナリログを書込めないときにどうすべきかを制御するものだ。
binlog_error_action=ABORT_SERVERに設定すると、サーバーはディスクフルまたは、ファイルシステムがリードオンリーとなった場合などの場合と同様にfatalエラーを出して異常終了する。 ABORT_SERVERオプションをつければ、バイナリログおよびスレーブは安全となる為、デフォルトの値を変更した。
以前のデフォルトであったbinlog_error_action=IGNORE_ERRORでは、MySQLサーバーがバイナリログを書込めないエラーが発生した場合、エラーログにある適切なエラーメッセージを書込み、バイナリログを無効化する。サーバーはバイナリログを無効化した状態で動作を継続する点に注意してほしく、このようにしてスレーブがエラーが起きた後の変更が適用できなくなる。
4) クラッシュセーフなバイナリログがデフォルトとなった
sync_binlog変数によってバイナリログがクラッシュセーフとなるかどうかが制御される。この変数は、バイナリログをディスクに同期する前の、バイナリログのコミットグループ数を指定する。
http://dev.mysql.com/doc/refman/5.7/en/replication-options-binary-log.html#sysvar_sync_binlog
sync_binlog=1では、全てのトランザクションがコミットされる前にバイナリログに同期される。従って、予期せぬ再起動が起こったとしても、バイナリログにないトランザクションは、どれをとっても準備完了状態となっているに過ぎない。サーバーの自動リカバリの時にこれらのトランザクションをロールバックする。これはバイナリログからロストするトランザクションはないことを保証し、従ってこれが最も安全なオプションである。実際のところ、これはfsyncが呼び出される総数を増やすが、MySQL 5.6からは、サーバーはトランザクションおよびそれらのfysncをグループ化し、パフォーマンスへの影響を最小化する。
sync_binlog=0では、MySQLサーバーによってバイナリログがディスクに同期されることはなく、この場合はサーバーはバイナリログの内容のフラッシュをOS任せにし、他のファイルをその時々でフラッシュするときにフラッシュされる。このようにして、電源故障やOSのクラッシュが起きた場合、いくつかのトランザクションはサーバーがコミットしているが、バイナリログが同期されていないことが起こりうる。そうするとリカバリ処理でこれらのトランザクションをリカバリすることは出来ず、バイナリログからも失われているだろう。
このようにして、新しいsync_binlog=1はより安全である。
5) slave_net_timeoutのデフォルトの値が小さくなった
slave_net_timeout
は、スレーブがコネクションが切断されたり、読込みが中断されたりして再接続する前に、マスタからのデータを待ち受ける秒数を表す。この変数はマスターとスレーブの間のハートビートの頻度にも影響を与える。ハートビートの間隔はデフォルトで、slave_net_timeoutを2で割った値であるためだ。
新しいデフォルト値は、以前のデフォルト値が3600秒であるのに対し、slave_net_timeout=60である。古い設定では、一時的なネットワーク遅延によって大きなレプリケーション遅延が発生しうる。
6) @@session.gtid_executedは廃止予定となった
@@global.gtid_executed
変数はバイナリログの記録されている全てのトランザクションセットの情報を保持している。
http://dev.mysql.com/doc/refman/5.7/en/replication-options-gtids.html#sysvar_gtid_executed
セッションのスコープで使われた場合は、この変数はトランザクションキャッシュに書込まれたトランザクションセットの情報を保持する。具体的には、SESSION.GTID_EXECUTEDは、GTID_NEXTがUUID:NUMBERの形式をしており、少なくとも1つのDMLが実行されたがコミットされていない場合、UUID:NUMBERに等しい。GTID_NEXTが他の値に設定されたとき、SESSION.GTID_EXECUTEDは空白文字となる。MySQL 5.7.7ではこのセッションスコープの変数が使われた時に警告を出力するようになった。グローバルスコープの変数である@@global.gtid_executedには何の変更もない。@@global.gtid_executedは頻繁に使われている一方で、ユーザーがglobal
キーワードをつけ忘れた時に正しくない値を示すセッション変数を参照できてしまう。混乱を防ぐ為にセッション変数は廃止予定となった。また、このセッション変数がいくつかの用途で非常に有用であることが知られていないため、廃止予定となった。