バイナリ
ログの内容には更新データのステートメントがあり、レコードに一致しない場合の
DELETE
などで更新済みのステートメントがあります。ステートメントは、変更の内容を説明する
「イベント」
として保存の対象になります。さらに、クエリの更新に要した時間に関する情報も、バイナリ
ログの内容です。
注意:バイナリ ログは、更新ログの代わりになるものです。更新ログは MySQL 5.0 以降では利用できません。バイナリ ログには、更新ログで利用可能だった情報がすべて、より効率的かつトランザクション セーフな内容になっています。トランザクションを行うときは、 MySQL バイナリ ログをバックアックに使用します。更新ログを使用しません。
バイナリ ログの内容は、データ変更に関数ステートメントを含みません。そのため、問題があるクエリの識別などで、すべてのステートメントが必要な場合は、一般クエリ ログを使用します。詳細は 「一般クエリ ログ」 を参照してください。
バイナリ ログの主要目的は、リストア作業中にできるだけデータベースの更新を行う、ということです。バイナリ ログにはバックアップ後のすべての更新情報が入ることになるため、スレーブ サーバに送るステートメントのマスタ記録として、レプリケーションで使用します。詳細は 5章レプリケーション を参照してください。
MySQL Enterprise. バイナリ ログで DDL イベントの大部分をトラックに使用することが可能です。扱いには注意が必要です。 MySQL Network Monitoring and Advisory Service では、バイナリ ログ分析に関する情報を提供しています。詳細は http://www-jp.mysql.com/products/enterprise/advisors.html を参照してください。
バイナリ ログを有効化したサーバを実行すると、パフォーマンスが 1% ほど遅れます。しかし、リストア作業が必要になった場合のバイナリ ログの有用性、レプリケーション セットアップでの利便性を考慮すると、1% の遅れは許容できるものとします。
--log-bin[=
オプションで起動すると、mysqldで、データ更新に関わる
SQL ステートメントのすべてをログ
ファイルに書き込みます。base_name]base_name
の値を指定しない場合、デフォルト名は、-bin
を元にするホスト
マシンの名前になります。ベース名を指定するときに、絶対パスを使用しない場合は、サーバでデータ
ディレクトリにファイルを作成します。できるだけ、ベース名は指定することをお勧めします。その理由に関しては
「Open Issues in MySQL」 を参照してください。
--log-bin=
など、ログ名に拡張子を付ける場合は、その拡張子はサイレントで削除、無視の対象になります。
base_name.extension
mysqld ではバイナリ
ログのベース名で数値の拡張子を付加します。この数値はサーバで新規ログ
ファイルを作成する度に増加し、ファイルの番号が連続する形になります。サーバは起動、そしてログ
フラッシュ毎に、新規のバイナリ ログ
ファイルを作成します。さらにサーバは現行のログ
サイズが max_binlog_size
に到達すると、自動的に新規のバイナリ ログ
ファイルを作成します。大きなトランザクションがあると、バイナリ
ログ ファイルの max_binlog_size
を超えることになるため、1
つのトランザクションで最大値を使い切らないようにする必要があります。
使用しているバイナリ ログ
ファイルの追跡を行うために、mysqld
で、使用があったバイナリ ログ
ファイルのすべての名前を含めた、バイナリ
ログ
インデックスを作成します。デフォルトではバイナリ
ログ
ファイルと同じベース名で、'.index'
という拡張子がつきます。バイナリ ログ
インデックス
ファイルの名前は、--log-bin-index[=
オプションを使用して変更できます。mysqld
が作業中の場合は、このファイルを手動で変更することはしないでください。mysqld
が混乱する原因になります。
file_name]
バイナリ ログ ファイルとインデックス
ファイルへの書き込みは、MyISAM
テーブルへの書き込みと同じ方法で処理します。「How MySQL Handles a Full Disk」
を参照してください。
RESET MASTER
ステートメントでバイナリ ログ
ファイルをすべて削除する場合、または
PURGE MASTER LOGS
でそれらをサブセットする場合は、「RESET 構文」
および 「マスタ サーバをコントロールする SQL ステートメント」
を参照してください。
バイナリ ログは、バックアップでリカバリ作業を行うときに影響があることから、いくつかの制限があります。詳細は 「レプリケーション機能と既知問題」 を参照してください。
トリガや記憶したルーチンに関するバイナリーロギングは、「ストアドルーチンとトリガのバイナリログ」 を参照してください。
次に示すオプションを mysqld で使用して、何をどうバイナリ ログに記録するかを指定します。後続の説明も参考にしてください。
レプリケーションでは、ここで説明するオプションは、マスタからスレーブに送るステートメントに影響します。また、マスタからのステートメントを受けたスレーブが、そのうちの何を実行して、何を無視するかを制御するオプションもあります。その詳細は 「レプリケーションのオプションと変数」 を参照してください。
db_name
などデフォルトのデータベースに関わる更新のバイナリ
ロギングを制限する。(データベースは
USE で選択可能。)
明示的な指定がない限り、デフォルト以外のデータベースは無視の対象。このオプションを使用するときは、デフォルトのデータベースだけが更新の対象であることを確認すること。
これには、例外があり、CREATE
DATABASE、ALTER
DATABASE、DROP DATABASE
などのステートメントを使用する場合は、この限りではない。サーバがそのステートメントで指定するデータベース
(デフォルトのデータベース以外)
によって、ステートメントをログするかどうかを判断する。
期待通りにならない可能性がある例として、サーバを
binlog-do-db=sales
で起動した場合に、USE prices; UPDATE
sales.january SET amount=amount+1000;
を実行すると、このステートメントはバイナリ
ログへの書き込み対象ではない。
複数のデータベースをログするには、複数のオプションを使用のこと。それぞれのデータベースにそれぞれのオプションを使用する。
db_name
などデフォルトのデータベースに関わる更新のバイナリ
ロギングを優先する。(データベースは
USE で選択可能。)
このオプションを使用するときは、デフォルトのデータベースだけが更新の対象であることを確認すること。
--binlog-do-db
同様に、これにも例外があり、CREATE
DATABASE、ALTER
DATABASE、DROP DATABASE
などのステートメントを使用する場合は、この限りではない。サーバがそのステートメントで指定するデータベース
(デフォルトのデータベース以外)
によって、ステートメントをログするかどうかを判断する。
期待通りにならない可能性がある例として、サーバを
binlog-ignore-db=sales
で起動した場合に、USE prices; UPDATE
sales.january SET amount=amount+1000;
を実行すると、このステートメントはバイナリ
ログへの書き込み対象になる。
複数のデータベースを無視するには、複数のオプションを使用のこと。それぞれのデータベースにそれぞれのオプションを使用する。
サーバはバイナリ ログへの更新の処理の仕方
(ログか無視か)
に関するオプションを、次に示すルールに従って評価します。前述の通り、CREATE
DATABASE、ALTER
DATABASE、DROP DATABASE
のステートメントは例外とします。データベースに対する
作成、変更、ドロップ
は、次のルールに従って辿り着きます。
--binlog-do-db または
--binlog-ignore-db
ルールがあるかどうか。
No: バイナリ ログにステートメントを書き込み、終了。
Yes: 次のステップへ進む。
デフォルトのデータベース、USE
で選択しているデータベースがあるかどうか。(--binlog-do-db、--binlog-ignore-db、またはその両方があるため。)
No: ステートメントを書き込まず、終了。
Yes: 次のステップへ進む。
(デフォルトのデータベースがあるので)
--binlog-do-db
ルールがあるかどうか。
Yes:
デフォルトのデータベースは、--binlog-do-db
ルールの適用を受けるかどうか。
Yes: ステートメントを書き込み、終了。
No: ステートメントを書き込まず、終了。
No: 次のステップへ進む。
(--binlog-ignore-db
ルールがあるため、)
--binlog-ignore-db
ルールの適用を受けるかどうか。
Yes: ステートメントを書き込まず、終了。
No: ステートメントを書き込み、終了。
たとえば、--binlog-do-db=sales
だけのオプションで実行していると、スレーブは
sales
とは異なるデータベースのステートメントはバイナリ
ログに書き込みません。つまり、--binlog-do-db
オプションは、「他のデータベースを無視する」
という働きがあります。
レプリケーションでは、バイナリ ログ
ファイルをスレーブで必要としないと確認できるまでは削除しないでください。たとえば、スレーブが
3
日以上遅れることは有り得ない場合、一日に一度、mysqladmin
flush-logs をマスタで実行し、3
日以上経過したログを削除します。ファイルは手動で削除することもできますが、PURGE
MASTER LOGS
の使用をお勧めします。これは、バイナリ ログ
インデックス
ファイルの更新を安全に行えます。(日の引数使用。)
詳細は、「マスタ サーバをコントロールする SQL ステートメント」
を参照してください。
SUPER
権限があるクライアントは、SET
SQL_LOG_BIN=0
ステートメントを使用して独自にステートメントのバイナリ
ログを無効化できます。詳細は
「SET 構文」 を参照してください。
mysqlbinlog ユーティリティを使用して、バイナリ ログ ファイルの内容を表示できます。これは、ログ内のステートメントを再処理するときに活用できます。たとえば、次のように、バイナリ ログから MySQL サーバを更新できます。
shell> mysqlbinlog log_file | mysql -h server_name
mysqlbinlog ユーティリティと、その使用方法については 「mysqlbinlog — バイナリログファイルを処理するためのユーティリティ」 を参照してください。バイナリ ログ ファイルとリレーログ ファイルは同じ形式で書き込みを行うため、mysqlbinlog をリレー ログ ファイルでも使用できます。
バイナリ ロギングはステートメントの完了 (クエリの完了) とともに実行となりますが、その前にロックのリリース、またはコミットを行います。そのため、ログの記録は実行順になります。
非トランザクションの更新は、実行とともに、バイナリ
ログへの保存となります。コミットなしのトランザクション内では、InnoDB
テーブルなど、トランザクションのテーブルに変更を与える
UPDATE、DELETE、INSERT
などの更新は、サーバからの
COMMIT
ステートメントを受けるまでは、キャッシュでの保管になります。その時点で、COMMIT
実行前に mysqld
でトランザクションの内容をバイナリ
ログに書き込みます。トランザクションを扱うスレッドが開始すると、binlog_cache_size
というバッファから、ステートメントのバッファにアロケートします。ステートメントがそのバッファより大きい場合は、スレッドがそのトランザクションを保管する一時テーブルを開きます。スレッドが終了すると、テンポラリ
テーブルは削除になります。
非トランザクションのテーブルへの変更は、ロール
バックが利きません。非トランザクション
テーブルへの変更を含むロール
バックがあるトランザクションの場合は、トランザクション全体が
ROLLBACK
ステートメントでのログになり、そのテーブルへの変更の複製を確実に行い
(請け負い)ます。
Binlog_cache_use
ステータス変数は、(テンポラリファイルとともに)
このバッファを使用したトランザクションの数を表示します。Binlog_cache_disk_use
ステータス変数はそのトランザクション内で一時テーブルを使用する必要があった回数を表示します。この
2 つの変数は、binlog_cache_size
の調整に使用して、一時ファイルの使用を避けるために十分な値を設定します。
max_binlog_cache_size
システム変数は、デフォルトで 4 GB (最大値)
としていますが、複数のステートメントのトランザクションのキャッシュを行うために、合計サイズを制限することができます。トランザクションがこのバイトより大きい場合はロール
バックします。最大値は 4096 です。
バイナリ
ログでは、並列のインサートを、CREATE ...
SELECT または INSERT ... SELECT
ステートメントの通常インサートと置き換えます。これは、たとえば、バックアップ作業中にログを適用して、テーブルの完全コピーを再生できるようにする作用です。
ノート: 古いバージョンの MySQLと MySQL 5.1 とでは、バイナリ ログの形式が異なります。これはレプリケーション効果を改善した結果です。詳細は 「MySQL バージョン間のレプリケーション互換性」 を参照してください。
デフォルトのバイナリ
ログでは、ディクスへのそれぞれの書き込みは非同期です。そのため、MySQL
サーバに限らず、オペレーティング
システムまたはマシンがクラッシュすると、バイナリ
ログの最後のステートメントを失う可能性があります。これを防ぐには、バイナリ
ログへのそれぞれの書き込み
N
をディスクで同期します。それには、sync_binlog
システム変数を使用します。(「システム変数」
を参照のこと。) sync_binlog
での最も安全な値は 1
ですが、これは最も遅くなる値です。sync_binlog
を 1
で設定しても、クラッシュの場合によってテーブルとバイナリ
ログの内容が異なる可能性があります。たとえば、InnoDB
テーブルに対して、COMMIT
ステートメントを MySQL
サーバで処理した場合、トランザクション全体をバイナリ
ログに書き込むことになり、そのトランザクションを
InnoDB
にコミットすることになります。この 2
つの動作を処理している最中にサーバがクラッシュすると、このトランザクションは起動時の
InnoDB にロール
バックしますが、バイナリ
ログでは存在している、ということになります。この問題は
--innodb-safe-binlog
オプションで解決できます。このオプションは、InnoDB
テーブルとバイナリ
ログの内容に整合性を持たせます。(ノート:
MySQL 5.0 以降、--innodb-safe-binlog
は、XA トランザクション
サポートの導入とともに、廃止になりました。)
このオプションでさらに安全性を高めるには、MySQL
サーバを、トランザクション毎にバイナリ
ログと InnoDB
ログを同期してディスクに送るように設定する必要があります。InnoDB
ログはデフォルトで同期化しているため、バイナリ
ログには sync_binlog=1
を使用して同期化します。このオプションの効果としては、クラッシュ後に再起動したときに、ロール
バックしたトランザクションに対して、MySQL
がバイナリ ログから InnoDB
トランザクションのロール
バック返しを行います。これにより、バイナリ
ログが InnoDB
テーブルのデータと完全に一致します。そして、スレーブはマスタと同期化したままであるため、ロール
バックしたステートメントを受けることはありません。
(ノートとして、--innodb-safe-binlog
オプションは、MySQL サーバが
InnoDB 以外のストレージ
エンジンを更新するときにも使用できます。)
InnoDB のクラッシュ
リカバリでは、InnoDB
テーブルに影響があるステートメントとトランザクションだけを、バイナリ
ログから削除します。MySQL サーバがクラッシュ
リカバリ中に、バイナリ
ログが通常より短いと判断する場合には、InnoDB
のトランザクションの中から、成功していないコミットが
1
つ以上あることを示します。つまり、サーバは、The
binary log <name> is shorter than its expected
size というエラー
メッセージを出力します。これは、sync_binlog=1
と指定し、ディスク/ファイル
システムが実際に同期していれば、発生しません。もし、このエラー
メッセージがでり場合には、このバイナリ
ログは未修正のままであるため、レプリケーションを行うときには、マスタ
データのスナップショットを最初からやり直す必要が出てきます。
