バイナリログには、テーブル作成操作やテーブルデータへの変更などのデータベース変更を記述する「イベント」が格納されます。 また、行ベースのロギングが使用される場合を除き、(一致する行のない DELETE
などの) 潜在的に変更を行おうとしたステートメントについてのイベントも格納されます。 バイナリログには、データを更新した各ステートメントに要した時間に関する情報も格納されます。 バイナリログには 2 つの重要な目的があります。
レプリケーションの場合、レプリケーションソースサーバー上のバイナリログは、レプリカに送信されるデータ変更のレコードを提供します。 ソースは、バイナリログに含まれている情報をレプリカに送信します。このレプリカは、それらのトランザクションを再現して、ソースで行われたものと同じデータ変更を行います。 セクション17.2「レプリケーションの実装」を参照してください。
ある特定のデータリカバリ操作には、バイナリログの使用が必要です。 バックアップがリストアされたあと、バックアップが実行されたあとに記録されたバイナリログ内のイベントが再実行されます。 これらのイベントは、データベースをバックアップのポイントから最新の状態に持って行きます。 セクション7.5「Point-in-Time (増分) リカバリ」を参照してください。
バイナリログは、データを変更しない SELECT
や SHOW
などのステートメントでは使用されません。 (問題となるクエリーを特定するなどのために) すべてのステートメントをログに記録するには、一般クエリーログを使用します。 セクション5.4.3「一般クエリーログ」を参照してください。
バイナリロギングを有効にしてサーバーを実行すると、パフォーマンスがいくらか低下します。 ただし、レプリケーションをセットアップでき、リストア操作に対応できるというバイナリログの利点は、一般的にこのパフォーマンスの減少よりも重要です。
バイナリログは、予期しない停止に対して回復性があります。 完全なイベントまたはトランザクションのみがログに記録されたり、または読み戻されたりします。
バイナリログに書き込まれたステートメント内のパスワードは、文字どおりプレーンテキストで発生しないようにサーバーによって書き換えられます。 セクション6.1.2.3「パスワードおよびロギング」も参照してください。
MySQL 8.0.14 からは、バイナリログファイルとリレーログファイルを暗号化できるため、これらのファイルとそれらに含まれる潜在的機密データを、外部の攻撃者による誤用から保護したり、格納されているオペレーティングシステムのユーザーによる不正な表示から保護したりできます。 MySQL サーバーで暗号化を有効にするには、binlog_encryption
システム変数を ON
に設定します。 詳細は、セクション17.3.2「バイナリログファイルとリレーログファイルの暗号化」を参照してください。
次の説明では、バイナリロギングの操作に影響する一部のサーバーオプションおよび変数について記述します。 完全なリストについては、セクション17.1.6.4「バイナリロギングのオプションと変数」を参照してください。
バイナリロギングはデフォルトで有効になっています (log_bin
システム変数は ON に設定されています)。 ただし、バイナリロギングがデフォルトで無効になっているが、--log-bin
オプションを指定して有効にできる場合は、mysqld を使用して、--initialize
または --initialize-insecure
オプションを指定してデータディレクトリを手動で呼び出してデータディレクトリを初期化することは例外です。
バイナリロギングを無効にするには、起動時に --skip-log-bin
または --disable-log-bin
オプションを指定できます。 これらのオプションのいずれかが指定され、--log-bin
も指定されている場合は、後で指定するオプションが優先されます。
--log-slave-updates
および --slave-preserve-commit-order
オプションにはバイナリロギングが必要です。 バイナリロギングを無効にする場合は、これらのオプションを省略するか、--log-slave-updates=OFF
および --skip-slave-preserve-commit-order
を指定します。 --skip-log-bin
または --disable-log-bin
が指定されている場合、MySQL はこれらのオプションをデフォルトで無効にします。 --log-slave-updates
または --slave-preserve-commit-order
を --skip-log-bin
または --disable-log-bin
とともに指定すると、警告またはエラーメッセージが発行されます。
バイナリログファイルのベース名を指定するには、--log-bin[=
オプションを使用します。 base_name
]--log-bin
オプションを指定しない場合、MySQL はバイナリログファイルのデフォルトのベース名として binlog
を使用します。 以前のリリースとの互換性のために、文字列なしまたは空の文字列を指定して --log-bin
オプションを指定した場合、ベース名はホストマシンの名前を使用して
にデフォルト設定されます。 ホスト名が変更された場合でも、同じバイナリログファイル名を簡単に使用できるように、ベース名を指定することをお勧めします (セクションB.3.7「MySQL の既知の問題」 を参照)。 ログ名に拡張子を指定した場合 (host_name
-bin--log-bin=
など)、拡張子は暗黙的に削除されて無視されます。
base_name.extension
mysqld は、バイナリログベース名に数値拡張子を付加してバイナリログファイル名を生成します。 数値はサーバーが新しいログファイルを作成するたびに増加し、順序付きの一連のファイルが作成されます。 サーバーは、次のいずれかのイベントが発生するたびにシリーズに新しいファイルを作成します:
サーバーが起動または再起動されます
サーバーはログをフラッシュします。
現在のログファイルのサイズが
max_binlog_size
に達しました。
大きなトランザクションを使用する場合、トランザクションがひとまとまりでファイルに書き込まれて、複数のファイルに分割されないため、バイナリログファイルが max_binlog_size
を超えることがあります。
使用されたバイナリログファイルを追跡するために、mysqld はバイナリログファイルの名前を含むバイナリログインデックスファイルも作成します。 デフォルトでは、これはバイナリログファイルと同じベース名を持ち、拡張子は'.index'
です。 バイナリログインデックスファイルの名前は、--log-bin-index[=
オプションを使用して変更できます。 mysqld の動作中にこのファイルを手動で変更しないでください。変更すると、mysqld を混乱させることになります。
file_name
]
「バイナリログファイル」という用語は一般的に、データベースイベントを格納する、番号付けされた個々のファイルを指します。 「バイナリログ」という用語は、番号付けされたバイナリログファイルとインデックスファイルのセットをひとまとめにしたものを指します。
バイナリログファイルとバイナリログインデックスファイルのデフォルトの場所は、データディレクトリです。 ベース名に先頭の絶対パス名を追加して別のディレクトリを指定することで、--log-bin
オプションを使用して別の場所を指定できます。 サーバーは、使用されたバイナリログファイルを追跡するバイナリログインデックスファイルからエントリを読み取るときに、エントリに相対パスが含まれているかどうかを確認します。 その場合、パスの相対部分は、--log-bin
オプションを使用して設定された絶対パスに置き換えられます。 バイナリログインデックスファイルに記録された絶対パスは変更されません。このような場合は、新しいパスを使用できるようにインデックスファイルを手動で編集する必要があります。 バイナリログファイルのベース名と指定されたパスは、log_bin_basename
システム変数として使用できます。
MySQL 5.7 では、バイナリロギングが有効になっているときにサーバー ID を指定する必要がありました。そうしないと、サーバーが起動しません。 MySQL 8.0 では、server_id
システム変数はデフォルトで 1 に設定されています。 バイナリロギングが有効になっている場合、このデフォルト ID でサーバーを起動できますが、server_id
システム変数を使用してサーバー ID を明示的に指定しないと、情報メッセージが発行されます。 レプリケーショントポロジで使用されるサーバーの場合、サーバーごとにゼロ以外の一意のサーバー ID を指定する必要があります。
制限付きセッションシステム変数を設定するのに十分な権限を持つクライアント (セクション5.1.9.1「システム変数権限」 を参照) は、SET sql_log_bin=OFF
ステートメントを使用して独自のステートメントのバイナリロギングを無効にできます。
デフォルトでは、サーバーはイベント自体だけでなくイベントの長さもログに記録し、イベントが正しく書き込まれたことを検証するためにこれを使用します。 また、binlog_checksum
システム変数を設定することによって、サーバーがイベントのチェックサムを書き込むようにすることもできます。 バイナリログから読み取る場合、ソースはデフォルトでイベント長を使用しますが、使用可能な場合は、master_verify_checksum
システム変数を有効にすることによってチェックサムを使用するようにできます。 レプリカ上のレプリケーション I/O スレッドは、ソースから受信したイベントも検証します。 slave_sql_verify_checksum
システム変数を有効にすることで、レプリケーション SQL スレッドがリレーログから読み取るときにチェックサムを使用できるようにすることができます。
バイナリログに記録されるイベントの形式は、バイナリロギング形式に依存します。 3 つの形式タイプがサポートされています: 行ベースロギング、ステートメントベースロギングおよび混合ベースロギング。 使用されるバイナリロギング形式は、MySQL のバージョンに依存します。 ロギング形式の一般的な説明については、セクション5.4.4.1「バイナリロギング形式」を参照してください。 バイナリログの形式についての詳細な説明は、「MySQL Internals: The Binary Log」を参照してください。
サーバーは、--binlog-do-db
および --binlog-ignore-db
オプションを評価する際、それが --replicate-do-db
および --replicate-ignore-db
オプションを評価する場合と同じ方法で行います。 これを行う方法については、セクション17.2.5.1「データベースレベルレプリケーションオプションおよびバイナリロギングオプションの評価」を参照してください。
レプリカは、デフォルトで有効になっている log_slave_updates
システム変数を使用して起動されます。つまり、レプリカは、ソースから受信したデータ変更を自身のバイナリログに書き込みます。 この設定が機能するには、バイナリログが有効になっている必要があります (セクション17.1.6.3「Replica Server のオプションと変数」 を参照)。 この設定により、レプリカを他のレプリカのソースとして機能させることができます。
RESET MASTER
ステートメントですべてのバイナリログファイルを削除したり、PURGE BINARY LOGS
でそのサブセットを削除したりすることができます。 セクション13.7.8.6「RESET ステートメント」およびセクション13.4.1.1「PURGE BINARY LOGS ステートメント」を参照してください。
レプリケーションを使用している場合は、レプリカがまだそれらを使用する必要がないことを確認するまで、ソース上の古いバイナリログファイルを削除しないでください。 たとえば、レプリカが 3 日を超えて実行されることがない場合、1 日に mysqladmin flush-logs をソースで実行してから、3 日以上経過したログを削除できます。 ファイルを手動で削除することができますが、PURGE BINARY LOGS
を使用することが推奨され、この操作によってバイナリログインデックスファイルも安全に更新されます (さらに日付引数を使用できます)。 セクション13.4.1.1「PURGE BINARY LOGS ステートメント」を参照してください。
mysqlbinlog ユーティリティーを使用して、バイナリログファイルの内容を表示できます。 これはリカバリ操作のためにログ内のステートメントを再処理するときに役立ちます。 たとえば、次のようにしてバイナリログから MySQL Server を更新できます。
shell> mysqlbinlog log_file | mysql -h server_name
mysqlbinlog は、バイナリログファイルと同じ形式で書き込まれるため、レプリカ上のリレーログファイルの内容を表示するためにも使用できます。 mysqlbinlog ユーティリティーとその使用方法についての詳細は、セクション4.6.8「mysqlbinlog — バイナリログファイルを処理するためのユーティリティー」を参照してください。 バイナリログおよびリカバリ操作の詳細については、セクション7.5「Point-in-Time (増分) リカバリ」を参照してください。
バイナリロギングは、ステートメントまたはトランザクションの完了後すぐに行われますが、すべてのロックがリリースされるかコミットが実行されるよりも前になります。 これにより、ログがコミット順に記録されることが保証されます。
非トランザクションテーブルへの更新は、実行後すぐにバイナリログに格納されます。
コミットなしのトランザクション内では、InnoDB
テーブルなどのトランザクションテーブルを変更するすべての更新 (UPDATE
、DELETE
、INSERT
) は、サーバーによって COMMIT
ステートメントが受け取られるまでキャッシュされます。 その時点で、COMMIT
が実行される前に mysqld はトランザクション全体をバイナリログに書き込みます。
非トランザクションテーブルへの変更はロールバックできません。 ロールバックされるトランザクションに非トランザクションテーブルへの変更が含まれている場合は、非トランザクションテーブルへの変更が確実にレプリケーションされるようにするために、最後に ROLLBACK
ステートメントを使用してトランザクション全体がログに記録されます。
トランザクションを処理するスレッドが開始すると、スレッドは binlog_cache_size
のバッファーをバッファーステートメントに割り当てます。 ステートメントがこれより大きい場合、スレッドはトランザクションを格納する一時ファイルを開きます。 スレッドが終了すると、一時ファイルは削除されます。 MySQL 8.0.17 から、バイナリログの暗号化がサーバー上でアクティブな場合、一時ファイルは暗号化されます。
Binlog_cache_use
ステータス変数は、ステートメントを格納するために、このバッファー (および場合によっては一時ファイル) を使用したトランザクションの数を表示します。 Binlog_cache_disk_use
ステータス変数は、それらのトランザクションのうち、実際に一時ファイルを使用する必要があったものの数を表示します。 これらの 2 つの変数は、一時ファイルの使用を避けるために十分な値になるよう binlog_cache_size
を調整するために使用することができます。
max_binlog_cache_size
システム変数 (デフォルトは最大値の 4G バイト) を使用して、複数ステートメントのトランザクションをキャッシュするために使用する合計サイズを制限することができます。 トランザクションがこのバイト数より大きくなると、失敗してロールバックします。 最小値は 4096 です。
バイナリログおよび行ベースのロギングを使用している場合、並列挿入は CREATE ... SELECT
または INSERT ... SELECT
ステートメントの一般的な挿入に変換されます。 これは、バックアップ操作中にログを適用することでテーブルの正確なコピーを確実に再作成できるようにするために行われます。 ステートメントベースのロギングを使用している場合、元のステートメントがログに書き込まれます。
バイナリログ形式には、バックアップからのリカバリに影響する可能性があるいくつかの既知の制約があります。 セクション17.5.1「レプリケーションの機能と問題」を参照してください。
ストアドプログラムのバイナリロギングは、セクション25.7「ストアドプログラムバイナリロギング」で説明しているように行われます。
MySQL 8.0 のバイナリログ形式は、レプリケーションの機能拡張により以前のバージョンの MySQL とは異なることに注意してください。 セクション17.5.2「MySQL バージョン間のレプリケーション互換性」を参照してください。
サーバーがバイナリログへの書き込み、バイナリログファイルのフラッシュ、またはバイナリログのディスクへの同期を実行できない場合、レプリケーションソースサーバー上のバイナリログに一貫性がなくなる可能性があり、レプリカはソースとの同期を失う可能性があります。 binlog_error_action
システム変数は、バイナリログでこのタイプのエラーが発生した場合に実行されるアクションを制御します。
デフォルト設定の
ABORT_SERVER
では、サーバーはバイナリロギングを停止してシャットダウンします。 この時点で、エラーの原因を特定して修正できます。 再起動時に、予期しないサーバーが停止した場合と同様にリカバリが続行されます (セクション17.4.2「レプリカの予期しない停止の処理」 を参照)。IGNORE_ERROR
の設定では、古いバージョンの MySQL との下位互換性が提供されます。 この設定では、サーバーは進行中のトランザクションを続行し、エラーをログに記録してからバイナリロギングを停止しますが、更新の実行は続行します。 この時点で、エラーの原因を特定して修正できます。 バイナリロギングを再開するには、log_bin
を再度有効にする必要があります。これにはサーバーの再起動が必要です。 このオプションは、下位互換性が必要で、バイナリログがこの MySQL サーバーインスタンスで必須でない場合にのみ使用します。 たとえば、サーバーの断続的な監査またはデバッグにのみバイナリログを使用し、サーバーからのレプリケーションやポイントインタイムリストア操作にはバイナリログを使用しないことがあります。
デフォルトでは、バイナリログは各書き込み (sync_binlog=1
) でディスクに同期されます。 sync_binlog
が有効になっておらず、(MySQL サーバーだけでなく) オペレーティングシステムまたはマシンがクラッシュした場合は、バイナリログの最後のステートメントが失われる可能性があります。 これを回避するには、sync_binlog
システム変数を有効にして、すべての N
コミットグループの後にバイナリログをディスクに同期します。 セクション5.1.8「サーバーシステム変数」を参照してください。 sync_binlog
の最も安全な値は 1 (デフォルト) ですが、これも最も遅くなります。
以前の MySQL リリースでは、sync_binlog
が 1 に設定されていても、クラッシュが発生した場合、テーブルの内容とバイナリログの内容の間に不整合が発生する可能性がありました。 たとえば、InnoDB
テーブルを使用していて、MySQL サーバーが COMMIT
ステートメントを処理する場合、多くの準備済みトランザクションをバイナリログに順番に書き込み、バイナリログを同期してから、トランザクションを InnoDB
にコミットします。 これらの操作の間にサーバーが予期せず終了した場合、トランザクションは再起動時に InnoDB
によってロールバックされますが、バイナリログにはまだ存在します。 このような問題は、XA トランザクションでの双方向コミットの InnoDB
サポートを有効にすることで、以前のリリースで解決されました。 8.0.0 以上では、XA トランザクションでの 2 フェーズコミットの InnoDB
サポートは常に有効です。
XA トランザクションでの双方向コミットの InnoDB
サポートにより、バイナリログファイルと InnoDB
データファイルが確実に同期化されます。 ただし、トランザクションをコミットする前にバイナリログと InnoDB
ログをディスクに同期するように MySQL サーバーを構成する必要もあります。 InnoDB
ログはデフォルトで同期化され、sync_binlog=1
によってバイナリログが確実に同期化されます。 XA トランザクションおよび sync_binlog=1
での双方向コミットに対する暗黙的な InnoDB
サポートの効果は、クラッシュ後の再起動時に、トランザクションのロールバックを実行した後、MySQL サーバーが最新のバイナリログファイルをスキャンしてトランザクション xid
値を収集し、バイナリログファイル内の最後の有効な位置を計算することです。 次に、MySQL サーバーは、バイナリログに正常に書き込まれた準備済みトランザクションを完了し、バイナリログを最後の有効な位置に切り捨てるように InnoDB
に指示します。 これにより、バイナリログに InnoDB
テーブルの正確なデータが反映されるため、レプリカはロールバックされたステートメントを受信しないため、ソースとの同期が維持されます。
バイナリログが、必要な長さよりも短いということを、MySQL Server がクラッシュリカバリ中に検出した場合、正常にコミットされた InnoDB
トランザクションが、少なくとも 1 つバイナリログから欠落していることを示しています。 これは sync_binlog=1
の場合は発生するはずがなく、ディスクまたはファイルシステムは、リクエストされた場合は (されない場合もあります) 実際の同期を実行するため、サーバーは「The binary log
というエラーメッセージを出力します。 この場合、このバイナリログは正しくなく、レプリケーションはソースデータの新しいスナップショットから再開する必要があります。
file_name
is shorter than its expected size」
次のシステム変数のセッション値はバイナリログに書き込まれ、バイナリログの解析時にレプリカによって適用されます:
sql_mode
(NO_DIR_IN_CREATE
モードがレプリケーションされない場合を除きます。セクション17.5.1.39「レプリケーションと変数」を参照してください)foreign_key_checks
unique_checks
character_set_client
collation_connection
collation_database
collation_server
sql_auto_is_null