概要
MySQLのレプリケーションは、ソースサーバのデータを1つ以上のレプリカサーバに複製する機能である。
ソースサーバのデータ変更がバイナリログに記録され、レプリカサーバがこれを取得して実行することで、データの同期が実現される。
レプリケーションの主な用途は、読み取りスケーリング (レプリカへの読み取り分散)、バックアップ (レプリカからのバックアップ取得)、災害対策 (地理的に分散したレプリカ配置)、高可用性構成 (フェイルオーバー) である。
MySQL 8.0以降では、デフォルトでバイナリロギングが有効になっており、レプリケーション構成が容易である。
また、MySQL 8.0.26以降では、用語がmaster / slave から source / replicaに変更され、MySQL 8.4ではCHANGE MASTER TO等の旧構文が完全削除された。
レプリケーション方式には、位置ベースレプリケーション (バイナリログファイル名と位置で同期) と GTIDレプリケーション (グローバルトランザクション識別子で同期) の2種類がある。
現在の推奨はGTIDレプリケーションであり、フェイルオーバーやトポロジ変更が容易になる。
半同期レプリケーションを使用することで、少なくとも1つのレプリカへのデータ転送を保証し、データ損失のリスクを低減できる。
レプリケーションの設定には、ソースサーバとレプリカサーバの両方での設定変更、レプリケーション用ユーザの作成、バイナリログ形式の選択が必要である。
認証に関しては MySQL - 認証プラグイン、レプリケーション通信の暗号化については MySQL - SSL TLS接続、設定パラメータの詳細は MySQL - 設定ファイル を参照すること。
レプリケーションのアーキテクチャ
MySQLレプリケーションは、ソースサーバとレプリカサーバ間でのデータ同期を実現する仕組みである。
基本的には、ソースサーバの変更をバイナリログに記録し、レプリカサーバがこれを取得して実行する方式である。
基本的な仕組み
レプリケーションの基本的な流れを以下に示す。
- ソースサーバがデータベース変更をバイナリログに記録
- INSERT, UPDATE, DELETE, CREATE TABLE等の変更がイベントとして記録される
- レプリカのI/Oスレッドがソースサーバに接続
- レプリケーション用ユーザで認証を行う
- I/Oスレッドがバイナリログイベントを取得
- ソースサーバのBinlog Dump Threadから受信
- 取得したイベントをリレーログに書き込み
- レプリカサーバのローカルファイルに一時保存
- レプリカのSQLスレッドがリレーログのイベントを読み取り
- リレーログを順次処理
- SQLスレッドがイベントを実行してデータを反映
- ソースサーバと同じ変更をレプリカで再現
この仕組みにより、ソースサーバのデータ変更がレプリカサーバに伝播される。
デフォルトでは非同期レプリケーションであり、ソースサーバはレプリカの確認を待たずに処理を継続する。
レプリケーションスレッド
レプリケーションでは、以下のスレッドが動作する。
| スレッド名 | 説明 |
|---|---|
| Binlog Dump Thread | レプリカが接続すると起動される。 バイナリログの内容をレプリカに送信する。 複数のレプリカが接続している場合、各レプリカごとに1つのBinlog Dump Threadが動作する。 |
| スレッド名 | 説明 |
|---|---|
| I/O Thread | ソースサーバに接続してバイナリログイベントを受信する。 受信したイベントをリレーログに書き込む。 接続が切れた場合は自動的に再接続を試行する。 |
| SQL Thread | リレーログからイベントを読み取る。 イベントを実行してデータをレプリカに反映する。 単一スレッドまたはマルチスレッド (並列実行) で動作可能である。 |
マルチスレッドレプリカ
slave_parallel_workers (または replica_parallel_workers) パラメータを1以上に設定することにより、複数のワーカースレッドが並列でイベントを実行できる。
これにより、レプリケーション遅延の低減が期待できる。
[mysqld]
replica_parallel_workers = 4
replica_parallel_type = LOGICAL_CLOCK
スレッドの状態確認
SHOW REPLICA STATUS\G
-- 主要フィールド
-- Replica_IO_Running: Yes/No (I/Oスレッドの状態)
-- Replica_SQL_Running: Yes/No (SQLスレッドの状態)
レプリケーションの種類
MySQLでは、以下のレプリケーション方式が提供されている。
| 特性 | 説明 |
|---|---|
| デフォルトの方式 | 追加設定不要である。 |
| ソースサーバの動作 | ソースサーバはレプリカの確認を待たない。 コミット後すぐにクライアントに応答を返す。 |
| パフォーマンス | 最も高いパフォーマンスを実現する。 レプリカの遅延がソースに影響しない。 |
| データ転送保証 | レプリカへのデータ転送は保証されない。 ソースサーバ障害時にデータ損失の可能性がある。 |
| 特性 | 説明 |
|---|---|
| 有効化方法 | プラグインをインストールして有効化する。 rpl_semi_sync_source および rpl_semi_sync_replica を使用する。 |
| ソースサーバの動作 | ソースサーバは少なくとも1つのレプリカがリレーログに書き込むまで待機する。 コミット完了前にレプリカからの確認を待つ。 |
| データ損失対策 | データ損失のリスクを低減する。 レプリカへのデータ転送を保証する。 |
| フォールバック機能 | タイムアウト時は非同期にフォールバックする。 レプリカが応答しない場合でもサービス継続が可能である。 |
| 特性 | 説明 |
|---|---|
| レプリケーション方式 | 複数ノード間で合意ベースのレプリケーションを実現する。 Paxosベースの分散合意アルゴリズムを採用している。 |
| フェイルオーバーとマスター構成 | 自動フェイルオーバーとマルチマスター構成に対応する。 ノード障害時の自動復旧が可能である。 |
| 高可用性 | 高可用性を重視したレプリケーション方式である。 データの一貫性を保証する。 |
用語変更 (MySQL 8.0.26以降)
MySQL 8.0.26以降では、レプリケーション関連の用語が変更された。
MySQL 8.4では旧構文が完全削除されたため、新構文の使用が必須である。
| 旧用語 | 新用語 | 説明 |
|---|---|---|
| master | source | ソースサーバ |
| slave | replica | レプリカサーバ |
| CHANGE MASTER TO | CHANGE REPLICATION SOURCE TO | レプリケーション設定変更コマンド |
| SHOW SLAVE STATUS | SHOW REPLICA STATUS | レプリケーション状態確認コマンド |
| START SLAVE | START REPLICA | レプリケーション開始コマンド |
| STOP SLAVE | STOP REPLICA | レプリケーション停止コマンド |
| rpl_semi_sync_master | rpl_semi_sync_source | 半同期レプリケーションプラグイン名 |
バイナリログ
バイナリログは、MySQLのレプリケーションとポイントインタイムリカバリの中核となる機能である。
データベース変更を記述するイベントを格納し、レプリケーションやデータ復旧に使用される。
バイナリログの概要
バイナリログの基本的な特徴を以下に示す。
- データベース変更をイベントとして記録
- INSERT, UPDATE, DELETE, CREATE TABLE, ALTER TABLE等
- 2つの主要な役割を持つ
- レプリケーション (レプリカサーバへのデータ転送)
- ポイントインタイムリカバリ (任意の時点までのデータ復旧)
- MySQL 8.0ではデフォルトで有効
- 明示的な
--skip-log-binオプションで無効化可能
- 明示的な
- バイナリログファイルは連番で管理
- mysql-bin.000001, mysql-bin.000002 のように連番が付与される
- ログローテーションが発生する
max_binlog_sizeを超えた場合やFLUSH BINARY LOGS実行時
バイナリログの基本的な使用例を以下に示す。
-- バイナリログ一覧を表示
SHOW BINARY LOGS;
-- 現在使用中のバイナリログファイルを確認
SHOW MASTER STATUS;
-- バイナリログのイベントを表示
SHOW BINLOG EVENTS IN 'mysql-bin.000001';
-- ログローテーション実行
FLUSH BINARY LOGS;
バイナリログ形式
バイナリログには、3つの記録形式がある。
MySQL 8.0のデフォルトはROW形式である。
| 特性 | 説明 |
|---|---|
| ログ記録方式 | SQL文をそのまま記録する。実行されたSQL文が記録される。 |
| ログサイズ | ログサイズが小さい。SQL文1つで多数の行を変更してもログサイズは小さい。 |
| 非決定的関数での問題 | 非決定的関数で再現性に問題がある。NOW()、RAND()、UUID() 等は実行時刻により結果が変化する。 |
| レプリカでの結果 | レプリカで異なる結果が発生する可能性がある。データ不整合の原因となる。 |
| 特性 | 説明 |
|---|---|
| ログ記録方式 | 行変更を記録する。 変更された行のデータを記録する。 |
| MySQL 8.0での位置付け | MySQL 8.0のデフォルトである。 最も安全な形式である。 |
| 安全性 | 最も安全である。 非決定的関数でもデータ整合性を保証する。 |
| ログサイズ | ログサイズが大きい。 多数の行を変更した場合はログサイズが増大する。 |
| レプリカでの実行 | レプリカでの実行が高速である。 SQL文の再解析が不要である。 |
| 特性 | 説明 |
|---|---|
| デフォルト動作 | 通常はSTATEMENT形式である。 基本的にはSQL文を記録する。 |
| 自動切替機能 | 必要時にROW形式に自動切替する。 非決定的関数が使用された場合は自動的にROW形式に切り替える。 |
| バランス | ログサイズと安全性のバランスが取れている。 状況に応じて最適な形式を選択する。 |
- 形式の設定例
[mysqld] binlog_format = ROW
- 設定を動的に変更
SET GLOBAL binlog_format = 'ROW'; SET SESSION binlog_format = 'ROW';
MySQL 8.0.34以降の変更を以下に示す。
binlog_formatパラメータが非推奨化- 将来のバージョンで削除予定
- 将来はROW形式のみサポート予定
- STATEMENT形式とMIXED形式は廃止予定
バイナリログ関連パラメータ
バイナリログの動作を制御する主要パラメータを以下に示す。
| カテゴリ | パラメータ名 | 説明 |
|---|---|---|
| 基本パラメータ | log_bin | バイナリロギングの有効 / 無効を設定する。 MySQL 8.0デフォルト: ON 設定例: log_bin = mysql-bin |
| 基本パラメータ | server_id | 各サーバの一意識別子 範囲: 1〜4294967295 レプリケーション構成では必須である。 設定例: server_id = 1 |
| 基本パラメータ | binlog_format | ロギング形式 (ROW/STATEMENT/MIXED) を指定する。 MySQL 8.0デフォルト: ROW MySQL 8.0.34以降は非推奨である。 |
| ROW形式関連 | binlog_row_image | ROW形式での記録内容を指定する。 FULL (デフォルト): 全カラムを記録する。 MINIMAL: 変更されたカラムのみ記録する。 NOBLOB: BLOBカラムを除外する。 |
| ログ管理 | binlog_expire_logs_seconds | バイナリログ保持期間 (秒) を設定する。 デフォルト: 2592000 (30日)。 古いログは自動削除される。 |
| ログ管理 | max_binlog_size | バイナリログファイルの最大サイズを設定する。 デフォルト: 1GB。 この値を超えるとログローテーションが発生する。 |
| ログ管理 | binlog_cache_size | トランザクション用キャッシュサイズを設定する。 デフォルト: 32KB。 トランザクションが大きい場合は増やす。 |
| 安全性関連 | sync_binlog | ディスク同期ポリシーを設定する。 デフォルト: 1 (最も安全) 1: 各トランザクション後に同期する。 0: OSに任せる。(高速だが障害時にデータ損失) |
| 安全性関連 | binlog_encryption | バイナリログ暗号化の有効 / 無効を設定する。 MySQL 8.0.14以降で利用可能である。 デフォルト: OFF |
| セッション制御 | sql_log_bin | セッション単位でバイナリロギング制御を行う。 デフォルト: ON 設定例: SET sql_log_bin = 0; (一時的に無効化) |
設定ファイルの例を以下に示す。
[mysqld]
server_id = 1
log_bin = /var/lib/mysql/mysql-bin
binlog_format = ROW
binlog_row_image = FULL
max_binlog_size = 1G
binlog_expire_logs_seconds = 2592000
sync_binlog = 1
binlog_cache_size = 32K
バイナリログの管理
バイナリログの管理操作を以下に示す。
- バイナリログ一覧の確認
SHOW BINARY LOGS; -- 結果例: -- +------------------+-----------+ -- | Log_name | File_size | -- +------------------+-----------+ -- | mysql-bin.000001 | 1073741824| -- | mysql-bin.000002 | 177 | -- +------------------+-----------+
- 現在のバイナリログ位置の確認
SHOW MASTER STATUS; -- 結果例: -- +------------------+----------+--------------+------------------+ -- | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | -- +------------------+----------+--------------+------------------+ -- | mysql-bin.000002 | 177 | | | -- +------------------+----------+--------------+------------------+
- 古いバイナリログの削除
-- 指定日時より古いログを削除 PURGE BINARY LOGS BEFORE '2026-02-01 00:00:00'; -- 指定ファイルより古いログを削除 PURGE BINARY LOGS TO 'mysql-bin.000005'; -- 全バイナリログ削除 (ソースサーバのみ、レプリケーション中は危険) RESET MASTER;
- バイナリログの検査と再生
# バイナリログの内容を表示 mysqlbinlog /var/lib/mysql/mysql-bin.000001 # 特定時刻範囲のイベントを抽出 mysqlbinlog --start-datetime="2026-02-15 10:00:00" \ --stop-datetime="2026-02-15 11:00:00" \ mysql-bin.000001 # バイナリログを再生 (ポイントインタイムリカバリ) mysqlbinlog mysql-bin.000001 | mysql -u root -p # 特定位置範囲のイベントを再生 mysqlbinlog --start-position=154 --stop-position=1234 \ mysql-bin.000001 | mysql -u root -p
- バイナリログのローテーション
-- 手動でバイナリログをローテーション FLUSH BINARY LOGS; -- 自動ローテーション条件: -- 1. max_binlog_size を超えた場合 -- 2. サーバ再起動時 -- 3. FLUSH BINARY LOGS 実行時
詳細な設定方法は、MySQL - 設定ファイル を参照すること。
位置ベースレプリケーション
位置ベースレプリケーションは、バイナリログファイル名と位置 (position) を使用してレプリケーションを設定する従来の方式である。
シンプルな構成では有効だが、ログローテーションやフェイルオーバー時の管理が煩雑になる。
ソースサーバの設定
ソースサーバの設定手順 (my.cnfファイル) を以下に示す。
[mysqld]
server_id = 1
log_bin = mysql-bin
binlog_format = ROW
| パラメータ名 | 説明 |
|---|---|
| server_id | 各サーバの一意識別子 レプリケーション構成内で重複しない値を設定する。 |
| log_bin | バイナリログの有効化 ファイル名のプレフィックスを指定する。 |
| binlog_format | バイナリログ形式 ROW形式を推奨する。 |
- サーバ再起動
systemctl restart mysqld
- レプリケーション用ユーザの作成
- 認証方式の詳細は、MySQL - 認証プラグイン を参照すること。
CREATE USER 'repl_user'@'%' IDENTIFIED BY 'password'; GRANT REPLICATION SLAVE ON *.* TO 'repl_user'@'%'; FLUSH PRIVILEGES;
- バイナリログ位置の確認
SHOW MASTER STATUS; -- 結果例: -- +------------------+----------+--------------+------------------+ -- | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | -- +------------------+----------+--------------+------------------+ -- | mysql-bin.000001 | 154 | | | -- +------------------+----------+--------------+------------------+
この情報 (File, Position) をレプリカサーバの設定で使用する。
レプリカサーバの設定
レプリカサーバの設定手順 (my.cnfファイル) を以下に示す。
[mysqld]
server_id = 2
relay_log = mysql-relay-bin
read_only = 1
| パラメータ名 | 説明 |
|---|---|
| server_id | ソースサーバとは異なる一意識別子。例: 2, 3, 4 等 |
| relay_log | リレーログのファイル名プレフィックス。レプリカサーバで必須である。 |
| read_only | 読み取り専用モード。レプリカへの誤った書き込みを防止する。 |
- サーバ再起動
systemctl restart mysqld
- レプリケーション接続の設定 (MySQL 8.0.23以降の新構文)
CHANGE REPLICATION SOURCE TO SOURCE_HOST='source.example.com', SOURCE_PORT=3306, SOURCE_USER='repl_user', SOURCE_PASSWORD='password', SOURCE_LOG_FILE='mysql-bin.000001', SOURCE_LOG_POS=154;
| オプション名 | 説明 |
|---|---|
| SOURCE_HOST | ソースサーバのホスト名またはIPアドレス |
| SOURCE_PORT | ソースサーバのポート番号 (デフォルト: 3306) |
| SOURCE_USER | レプリケーション用ユーザ名 |
| SOURCE_PASSWORD | レプリケーション用パスワード |
| SOURCE_LOG_FILE | ソースサーバのバイナリログファイル名 |
| SOURCE_LOG_POS | ソースサーバのバイナリログ位置 |
旧構文を以下に示す。(MySQL 8.0.22以前、MySQL 8.4で削除)
CHANGE MASTER TO
MASTER_HOST='source.example.com',
MASTER_PORT=3306,
MASTER_USER='repl_user',
MASTER_PASSWORD='password',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=154;
MySQL 8.4では旧構文が完全削除されたため、新構文の使用が必須である。
レプリケーションの開始と停止
レプリケーションの基本操作を以下に示す。
- レプリケーション開始
START REPLICA; -- または I/O Thread のみ開始 START REPLICA IO_THREAD; -- または SQL Thread のみ開始 START REPLICA SQL_THREAD;
- レプリケーション状態確認
SHOW REPLICA STATUS\G -- 主要フィールド: -- Replica_IO_Running: Yes/No (I/Oスレッドの状態) -- Replica_SQL_Running: Yes/No (SQLスレッドの状態) -- Seconds_Behind_Source: レプリケーション遅延秒数 -- Last_Error: エラーメッセージ -- Source_Host: ソースサーバのホスト名 -- Source_Log_File: 現在読み取り中のバイナリログファイル -- Read_Source_Log_Pos: 読み取り位置 -- 正常に動作している場合 -- Replica_IO_Running: Yes -- Replica_SQL_Running: Yes -- Seconds_Behind_Source: 0
- レプリケーション停止
STOP REPLICA; -- または I/O Thread のみ停止 STOP REPLICA IO_THREAD; -- または SQL Thread のみ停止 STOP REPLICA SQL_THREAD;
- レプリケーション設定のリセット
-- レプリケーション設定を削除 RESET REPLICA; -- リレーログも削除 RESET REPLICA ALL;
旧構文を以下に示す。(MySQL 8.0.22以前、MySQL 8.4で削除)
START SLAVE;
SHOW SLAVE STATUS\G
STOP SLAVE;
RESET SLAVE;
位置ベースレプリケーションの制約
位置ベースレプリケーションには以下に示す制約がある。
- バイナリログファイル名と位置の管理が煩雑
- ログローテーションのたびに位置情報が変化
- フェイルオーバー時の設定変更が複雑
- 新しいソースサーバのバイナリログ位置を手動で特定する必要
- 旧バイナリログ削除後は復旧不可
- 必要なバイナリログが削除されるとレプリケーション再構築が必要
- マルチソース構成での管理が困難
- 複数のソースサーバの位置情報を個別管理
これらの問題を解決するため、現在はGTIDレプリケーションが推奨される。
GTIDレプリケーション
GTID (Global Transaction Identifier) レプリケーションは、グローバルトランザクション識別子を使用したレプリケーション方式である。
位置ベースレプリケーションの制約を解決し、フェイルオーバーやトポロジ変更が容易になる。
GTIDの概要
下表に、GTIDの基本的な特徴を示す。
| 特徴 | 説明 |
|---|---|
| 各トランザクションに一意な識別子を付与 | サーバUUIDとトランザクション番号の組み合わせで実現される。 形式は server_uuid:transaction_id である。 例: 3E11FA47-71CA-11E1-9E33-C80AA9429562:23 |
| バイナリログ位置管理が不要 | GTIDで自動的に同期ポイントを決定される。 |
| フェイルオーバーが容易 | レプリカが新しいソースに接続する際に自動的に適切な位置を特定される。 |
| レプリケーショントポロジの変更が簡単 | 複雑なレプリケーション構成でも管理が容易である。 |
GTIDの構造を以下に示す。
server_uuid: サーバの一意識別子 (自動生成) transaction_id: トランザクション番号 (1から始まる連番)
GTIDセットの例を以下に示す。
3E11FA47-71CA-11E1-9E33-C80AA9429562:1-5 3E11FA47-71CA-11E1-9E33-C80AA9429562:1-5:10-15 3E11FA47-71CA-11E1-9E33-C80AA9429562:1-5, AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEE:1-10
GTIDの有効化
GTIDを有効化する設定手順を以下に示す。
設定ファイル (my.cnfファイル) を編集する。
[mysqld]
server_id = 1
log_bin = mysql-bin
gtid_mode = ON
enforce_gtid_consistency = ON
| パラメータ名 | 説明 |
|---|---|
| gtid_mode | GTIDモードの有効化を制御する。 ON: GTID有効 OFF: GTID無効 |
| enforce_gtid_consistency | GTID一貫性の強制を制御する ON: GTIDで許可されない操作を禁止する。 OFF: 制約チェックなし |
MySQLサーバを再起動する。
systemctl restart mysqld
GTID状態を確認する。
SHOW VARIABLES LIKE 'gtid_mode';
SHOW VARIABLES LIKE 'enforce_gtid_consistency';
-- 実行済みGTIDセットの確認
SELECT @@GLOBAL.gtid_executed;
SELECT @@GLOBAL.gtid_purged;
GTIDベースのレプリケーション設定
GTIDレプリケーションの設定手順を以下に示す。
ソースサーバを設定する。(my.cnfファイル)
[mysqld]
server_id = 1
log_bin = mysql-bin
gtid_mode = ON
enforce_gtid_consistency = ON
binlog_format = ROW
レプリケーション用ユーザを作成する。
CREATE USER 'repl_user'@'%' IDENTIFIED BY 'password';
GRANT REPLICATION SLAVE ON *.* TO 'repl_user'@'%';
FLUSH PRIVILEGES;
レプリカサーバを設定する。(my.cnfファイル):
[mysqld]
server_id = 2
relay_log = mysql-relay-bin
gtid_mode = ON
enforce_gtid_consistency = ON
read_only = 1
レプリケーション接続を設定する。
CHANGE REPLICATION SOURCE TO
SOURCE_HOST='source.example.com',
SOURCE_PORT=3306,
SOURCE_USER='repl_user',
SOURCE_PASSWORD='password',
SOURCE_AUTO_POSITION=1;
| 項目 | 説明 |
|---|---|
| SOURCE_AUTO_POSITION=1 | GTIDベースの自動位置決定を有効化する。 SOURCE_LOG_FILE、SOURCE_LOG_POS の指定は不要である。 |
| レプリカの動作 | レプリカが自動的に最適な同期ポイントを決定される。 既に実行済みのGTIDをスキップして次のトランザクションから実行される。 |
レプリケーションを開始する。
START REPLICA;
-- 状態確認
SHOW REPLICA STATUS\G
-- 主要フィールド:
-- Auto_Position: 1 (GTIDモード有効)
-- Retrieved_Gtid_Set: 取得したGTIDセット
-- Executed_Gtid_Set: 実行済みGTIDセット
GTIDの制約と注意事項
GTIDレプリケーションには以下の制約がある。
| 制約事項 | 説明 |
|---|---|
| CREATE TABLE ... SELECT 禁止 (MySQL 8.0.21で緩和) | この構文は2つの操作 (CREATE と INSERT) を含むため制限されている。 回避策: CREATE TABLE と INSERT INTO ... SELECT を分離する。 |
| 一時テーブルの制限 | CREATE TEMPORARY TABLE はGTID内では制限されている。 |
| トランザクション内での非トランザクショナルテーブル操作の制限 | MyISAM等の非トランザクショナルテーブルの使用に制約がある。 |
enforce_gtid_consistency=ON で禁止される操作を以下に示す。
- 一般テーブル
-- CREATE TABLE ... SELECT (MySQL 8.0.20以前) CREATE TABLE new_table SELECT * FROM old_table; -- ERROR: Statement violates GTID consistency -- 回避策 CREATE TABLE new_table LIKE old_table; INSERT INTO new_table SELECT * FROM old_table;
- 一時テーブル
-- トランザクション外では使用可能 CREATE TEMPORARY TABLE temp_data (id INT); INSERT INTO temp_data VALUES (1); DROP TEMPORARY TABLE temp_data; -- トランザクション内では制限 START TRANSACTION; CREATE TEMPORARY TABLE temp_data (id INT); -- 制限される COMMIT;
オンラインでのGTID有効化
既存のレプリケーション構成でGTIDを段階的に有効化する手順を以下に示す。
以下の手順により、レプリケーションを停止せずにGTIDモードに移行できる。
- ステップ1 : GTID一貫性チェックを警告モードで有効化
- エラーログを監視して警告が出ないことを確認する。
SET GLOBAL ENFORCE_GTID_CONSISTENCY = WARN;
- ステップ2 : GTID一貫性を強制
SET GLOBAL ENFORCE_GTID_CONSISTENCY = ON;
- ステップ3 : GTIDモードをOFF_PERMISSIVEに変更
- この状態では、匿名トランザクション (GTID無し) と GTID付きトランザクションの両方を受け入れる。
SET GLOBAL GTID_MODE = OFF_PERMISSIVE;
- ステップ4 : GTIDモードをON_PERMISSIVEに変更
- この状態では、新規トランザクションはGTID付きで記録され、匿名トランザクションも処理可能。
SET GLOBAL GTID_MODE = ON_PERMISSIVE;
- ステップ5 : 全匿名トランザクションの完了を確認
SHOW STATUS LIKE 'ONGOING_ANONYMOUS_TRANSACTION_COUNT'; -- 結果が0になるまで待機
- ステップ6 : GTIDモードをONに変更
SET GLOBAL GTID_MODE = ON;
- ステップ7 : レプリカで SOURCE_AUTO_POSITION=1 に変更
STOP REPLICA; CHANGE REPLICATION SOURCE TO SOURCE_AUTO_POSITION=1; START REPLICA;
- ステップ8 : 設定ファイルに永続化 (my.cnfファイル)
[mysqld] gtid_mode = ON enforce_gtid_consistency = ON
半同期レプリケーション
半同期レプリケーションは、非同期レプリケーションとフルシンクロナスレプリケーションの中間に位置する方式である。
ソースサーバのデータ損失リスクを低減しつつ、パフォーマンスへの影響を最小限に抑える。
半同期レプリケーションの仕組み
半同期レプリケーションの動作を以下に示す。
| カテゴリ | 項目 | 説明 |
|---|---|---|
| 動作フロー | ソースサーバがトランザクションをコミット | バイナリログに書き込まれる。 |
| 少なくとも1つのレプリカがリレーログに書き込み完了 | レプリカからの確認 (ACK) を待つ。 | |
| レプリカからの確認を受信 | リレーログへの書き込み完了を通知される。 | |
| ソースサーバがクライアントにコミット完了を返す | クライアントに応答を返される。 | |
| 非同期レプリケーションとの違い | 非同期レプリケーション | ソースサーバはレプリカの確認を待たない。 レプリカへのデータ転送は保証されない。 |
| 半同期レプリケーション | ソースサーバは少なくとも1つのレプリカからの確認を待つ。 レプリカへのデータ転送を保証する。 | |
| 利点 | データ損失リスク低減 | ソースサーバ障害時のデータ損失リスクを低減する。 コミット済みトランザクションは少なくとも1つのレプリカに転送済みである。 |
| フェイルオーバー時のデータ一貫性向上 | レプリカが最新のデータを持つため、データ一貫性が向上される。 | |
| 欠点 | レイテンシ増加 | レプリカからの確認待ちによるレイテンシが増加する。 非同期レプリケーションより遅い。 |
| タイムアウト発生 | レプリカがダウンするとタイムアウトが発生する。 タイムアウト後は非同期にフォールバックされる。 |
プラグインのインストールと設定
半同期レプリケーションはプラグインとして提供される。
MySQL 8.0.26以降の新プラグイン名を使用する。
- ソースサーバでのプラグインインストール
INSTALL PLUGIN rpl_semi_sync_source SONAME 'semisync_source.so'; -- プラグイン確認 SHOW PLUGINS;
- レプリカサーバでのプラグインインストール
INSTALL PLUGIN rpl_semi_sync_replica SONAME 'semisync_replica.so'; -- プラグイン確認 SHOW PLUGINS;
- 旧プラグイン名 (MySQL 8.0.25以前、MySQL 8.4で削除)
-- ソース側 (旧) INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so'; -- レプリカ側 (旧) INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
- ソースサーバでの有効化
SET GLOBAL rpl_semi_sync_source_enabled = 1; -- 確認 SHOW VARIABLES LIKE 'rpl_semi_sync_source_enabled';
- レプリカサーバでの有効化
SET GLOBAL rpl_semi_sync_replica_enabled = 1; -- 確認 SHOW VARIABLES LIKE 'rpl_semi_sync_replica_enabled'; -- レプリケーションを再起動 (設定反映のため) STOP REPLICA IO_THREAD; START REPLICA IO_THREAD;
- 設定ファイルでの永続化 (my.cnfファイル)
- ソースサーバ
[mysqld] plugin_load_add = semisync_source.so rpl_semi_sync_source_enabled = 1 rpl_semi_sync_source_timeout = 10000
- レプリカサーバ
[mysqld] plugin_load_add = semisync_replica.so rpl_semi_sync_replica_enabled = 1
- ソースサーバ
rpl_semi_sync_source_wait_point
半同期レプリケーションには、2つの待機ポイント設定がある。
AFTER_SYNC (デフォルト、ロスレス半同期):
| カテゴリ | 説明 |
|---|---|
| トランザクション処理順序 | 1. バイナリログ書き込み |
| 2. ディスク同期 (sync_binlog=1の場合) | |
| 3. レプリカからの確認待ち | |
| 4. ストレージエンジンコミット | |
| 5. クライアントに応答 | |
| メリット | ソースサーバ障害時もコミット済みトランザクションはレプリカに送信済みである。 |
| データ損失が発生しない (ロスレス) | |
| デメリット | クライアントはコミット前にレプリカの確認を待つ。 |
| カテゴリ | 説明 |
|---|---|
| トランザクション処理順序 | 1. バイナリログ書き込み |
| 2. ストレージエンジンコミット | |
| 3. レプリカからの確認待ち | |
| 4. クライアントに応答 | |
| メリット | ストレージエンジンコミット後にレプリカ確認を行う。 |
| デメリット | ソースサーバ障害時にデータ喪失の可能性がある。 |
| コミット済みだがレプリカ未転送のトランザクションが存在しうる。 |
設定例を以下に示す。
SET GLOBAL rpl_semi_sync_source_wait_point = 'AFTER_SYNC';
-- または
SET GLOBAL rpl_semi_sync_source_wait_point = 'AFTER_COMMIT';
データ損失を防ぐため、AFTER_SYNC (デフォルト) の使用を推奨する。
タイムアウトと非同期へのフォールバック
半同期レプリケーションのタイムアウト動作を以下に示す。
| カテゴリ | パラメータ / 項目 | 説明 |
|---|---|---|
| タイムアウト設定 | rpl_semi_sync_source_timeout | レプリカからの確認待ち時間 (ミリ秒) を設定する。 デフォルト: 10000 (10秒) 設定例: SET GLOBAL rpl_semi_sync_source_timeout = 5000; |
| タイムアウト時の動作 | 指定時間内にレプリカから確認が得られない場合 | 自動的に非同期レプリケーションにフォールバックされる。 |
| レプリカが復旧した場合 | レプリカが復旧すると自動的に半同期に戻る。 サービスの継続性を保証される。 | |
| 確認必要なレプリカ数 | rpl_semi_sync_source_wait_for_replica_count | 確認を待つレプリカの最小数を設定する。 デフォルト: 1 設定例: SET GLOBAL rpl_semi_sync_source_wait_for_replica_count = 2; |
ステータスを確認する。
SHOW STATUS LIKE 'Rpl_semi_sync_source%';
-- 主要ステータス:
-- Rpl_semi_sync_source_status: ON/OFF (半同期状態)
-- Rpl_semi_sync_source_clients: 接続中の半同期レプリカ数
-- Rpl_semi_sync_source_yes_tx: 半同期で成功したトランザクション数
-- Rpl_semi_sync_source_no_tx: 非同期にフォールバックしたトランザクション数
-- Rpl_semi_sync_source_timeoutes: タイムアウト回数
レプリカ側のステータスを確認する。
SHOW STATUS LIKE 'Rpl_semi_sync_replica%';
-- 主要ステータス:
-- Rpl_semi_sync_replica_status: ON/OFF (半同期状態)
設定ファイルの例を以下に示す。(my.cnfファイル)
[mysqld]
plugin_load_add = semisync_source.so
rpl_semi_sync_source_enabled = 1
rpl_semi_sync_source_timeout = 10000
rpl_semi_sync_source_wait_point = AFTER_SYNC
rpl_semi_sync_source_wait_for_replica_count = 1
レプリケーションフィルタ
レプリケーションフィルタは、特定のデータベースやテーブルのみをレプリケーション対象とする機能である。
不要なデータのレプリケーションを防ぎ、ストレージとネットワーク帯域を節約できる。
データベースレベルのフィルタ
データベース単位でレプリケーション対象を制御する方法を以下に示す。
| パラメータ名 | 説明 |
|---|---|
| binlog_do_db | 指定したデータベースのみバイナリログに記録する。 設定例: binlog_do_db = db1 |
| binlog_ignore_db | 指定したデータベースをバイナリログに記録しない。 設定例: binlog_ignore_db = test |
| パラメータ名 | 説明 |
|---|---|
| replicate_do_db | 指定したデータベースのみレプリケーションする。 設定例: replicate_do_db = db1 |
| replicate_ignore_db | 指定したデータベースをレプリケーションしない。 設定例: replicate_ignore_db = test |
設定ファイルでの例を以下に示す。(my.cnfファイル)
[mysqld]
# ソース側
binlog_do_db = production_db
binlog_ignore_db = test_db
binlog_ignore_db = development_db
# レプリカ側
replicate_do_db = production_db
replicate_ignore_db = test_db
動的に設定を変更する方法を以下に示す。
CHANGE REPLICATION FILTER REPLICATE_DO_DB = (db1, db2);
CHANGE REPLICATION FILTER REPLICATE_IGNORE_DB = (test, temp);
現在のフィルタ設定を確認する。
SHOW REPLICA STATUS\G
-- フィルタ関連フィールド:
-- Replicate_Do_DB: レプリケーション対象データベース
-- Replicate_Ignore_DB: レプリケーション除外データベース
テーブルレベルのフィルタ
テーブル単位でレプリケーション対象を制御する方法を以下に示す。
| パラメータ名 | 説明 |
|---|---|
| replicate_do_table | 指定したテーブルのみレプリケーションする。 設定例: replicate_do_table = db1.table1 |
| replicate_ignore_table | 指定したテーブルをレプリケーションしない。 設定例: replicate_ignore_table = db1.temp_table |
| パラメータ名 | 説明 |
|---|---|
| replicate_wild_do_table | ワイルドカードパターンでレプリケーション対象を指定する。 設定例: replicate_wild_do_table = db1.log_% |
| replicate_wild_ignore_table | ワイルドカードパターンでレプリケーション除外を指定する。 設定例: replicate_wild_ignore_table = %.temp_% |
設定ファイルでの例を以下に示す。(my.cnfファイル)
[mysqld]
# 特定テーブルのみレプリケーション
replicate_do_table = db1.orders
replicate_do_table = db1.customers
# 特定テーブルを除外
replicate_ignore_table = db1.temp_data
# ワイルドカードパターン
replicate_wild_do_table = db1.log_%
replicate_wild_ignore_table = %.cache_%
動的に設定を変更する方法を以下に示す。
CHANGE REPLICATION FILTER REPLICATE_DO_TABLE = (db1.table1, db2.table2);
CHANGE REPLICATION FILTER REPLICATE_IGNORE_TABLE = (db1.temp_table);
CHANGE REPLICATION FILTER REPLICATE_WILD_DO_TABLE = ('db1.log_%');
CHANGE REPLICATION FILTER REPLICATE_WILD_IGNORE_TABLE = ('%.cache_%');
複数フィルタの組み合わせ方法を以下に示す。
CHANGE REPLICATION FILTER
REPLICATE_DO_DB = (db1),
REPLICATE_WILD_IGNORE_TABLE = ('db1.temp_%');
フィルタの注意事項
レプリケーションフィルタ使用時の注意点を以下に示す。
| binlog_format | 説明 |
|---|---|
| STATEMENT形式 | デフォルトデータベース (USE文で指定) を基準にフィルタされる。 クロスデータベース文で予期しない動作が発生する可能性がある。 |
| ROW形式 | 変更された行のデータベースを基準にフィルタされる。 より正確なフィルタリングが実現される。 |
クロスデータベース文の扱いを以下に示す。
USE db1;
UPDATE db2.table1 SET col1 = 1;
-- STATEMENT形式: db1がフィルタ対象かで判定
-- ROW形式: db2がフィルタ対象かで判定
※ROW形式での推奨事項
データ整合性のため、ROW形式でのレプリケーションフィルタ使用を推奨する。
GTIDとフィルタの組み合わせを以下に示す。
- GTIDモードでフィルタを使用する場合の制約
- マルチソース構成では各チャネルで同じフィルタ設定が必要となる。
- GTIDセットの不整合に注意する。
※外部キー制約の問題
- 親テーブルと子テーブルを異なるフィルタで扱うと整合性が破綻
- 外部キー制約を持つテーブルは同じフィルタ設定を推奨
-- 親テーブルと子テーブルは同じフィルタ設定
CHANGE REPLICATION FILTER
REPLICATE_DO_TABLE = (db1.parent, db1.child);
フィルタのクリア方法を以下に示す。
CHANGE REPLICATION FILTER REPLICATE_DO_DB = ();
CHANGE REPLICATION FILTER REPLICATE_IGNORE_DB = ();
CHANGE REPLICATION FILTER REPLICATE_DO_TABLE = ();
CHANGE REPLICATION FILTER REPLICATE_WILD_DO_TABLE = ();
マルチソースレプリケーション
マルチソースレプリケーションは、1つのレプリカサーバが複数のソースサーバから並行してレプリケーションを受ける機能である。
複数のソースサーバのデータを1つのレプリカサーバに集約する場合に有用である。
マルチソースレプリケーションの概要
マルチソースレプリケーションの特徴を以下に示す。
- 1つのレプリカが複数のソースから並行レプリケーション
- 各ソースサーバは独立したチャネルで接続
- 各ソースに独立したチャネル (FOR CHANNEL 'channel_name')
- チャネル名でソースサーバを識別
- 各チャネルは独自のI/O Thread、SQL Thread、リレーログを持つ
- 完全に独立したレプリケーション処理
- GTIDモードと位置ベースの両方で使用可能
- GTIDモードを推奨
使用例:
- 複数のソースサーバのデータを1つのレプリカに集約
- データウェアハウスやレポーティングサーバ
- 地理的に分散したソースサーバからのデータ収集
- 複数拠点のデータを中央で集約
- シャーディング構成での集約レプリカ
- 各シャードのデータを1つのレプリカに統合
設定方法
マルチソースレプリケーションの設定手順を以下に示す。
レプリカサーバを設定する。(my.cnfファイル)
[mysqld]
server_id = 100
relay_log = mysql-relay-bin
gtid_mode = ON
enforce_gtid_consistency = ON
master_info_repository = TABLE
relay_log_info_repository = TABLE
| パラメータ名 | 説明 |
|---|---|
| master_info_repository = TABLE | ソース情報をテーブルに保存する。マルチソース必須である。 |
| relay_log_info_repository = TABLE | リレーログ情報をテーブルに保存する。マルチソース必須である。 |
- チャネルごとのレプリケーション設定
-- ソース1への接続設定 CHANGE REPLICATION SOURCE TO SOURCE_HOST='source1.example.com', SOURCE_PORT=3306, SOURCE_USER='repl_user', SOURCE_PASSWORD='password', SOURCE_AUTO_POSITION=1 FOR CHANNEL 'source1'; -- ソース2への接続設定 CHANGE REPLICATION SOURCE TO SOURCE_HOST='source2.example.com', SOURCE_PORT=3306, SOURCE_USER='repl_user', SOURCE_PASSWORD='password', SOURCE_AUTO_POSITION=1 FOR CHANNEL 'source2'; -- ソース3への接続設定 CHANGE REPLICATION SOURCE TO SOURCE_HOST='source3.example.com', SOURCE_PORT=3306, SOURCE_USER='repl_user', SOURCE_PASSWORD='password', SOURCE_AUTO_POSITION=1 FOR CHANNEL 'source3';
- チャネル別のレプリケーション開始
-- 全チャネル開始 START REPLICA; -- 特定チャネルのみ開始 START REPLICA FOR CHANNEL 'source1'; START REPLICA FOR CHANNEL 'source2'; -- 特定チャネルのI/Oスレッドのみ開始 START REPLICA IO_THREAD FOR CHANNEL 'source1';
- チャネル別のレプリケーション停止
-- 全チャネル停止 STOP REPLICA; -- 特定チャネルのみ停止 STOP REPLICA FOR CHANNEL 'source1'; -- 特定チャネルのSQLスレッドのみ停止 STOP REPLICA SQL_THREAD FOR CHANNEL 'source2';
- チャネル別の状態確認
-- 全チャネルの状態確認 SHOW REPLICA STATUS\G -- 特定チャネルの状態確認 SHOW REPLICA STATUS FOR CHANNEL 'source1'\G
- チャネル別のフィルタ設定
-- source1チャネルはdb1のみレプリケーション CHANGE REPLICATION FILTER REPLICATE_DO_DB = (db1) FOR CHANNEL 'source1'; -- source2チャネルはdb2のみレプリケーション CHANGE REPLICATION FILTER REPLICATE_DO_DB = (db2) FOR CHANNEL 'source2';
- チャネルのリセット
-- 特定チャネルのレプリケーション設定を削除 RESET REPLICA FOR CHANNEL 'source1'; RESET REPLICA ALL FOR CHANNEL 'source1';
- Performance Schemaでのモニタリング
SELECT * FROM performance_schema.replication_connection_status; SELECT * FROM performance_schema.replication_applier_status_by_channel;
※注意
- 各ソースサーバの server_id は一意である必要がある。
- 同じserver_idは使用不可
- データベース名の衝突に注意する。
- 複数ソースで同じデータベース名を使用する場合はフィルタで制御する。
- GTIDモード使用時はGTIDセットの管理に注意する。
- 各ソースのGTIDセットが重複しないように設定する。
遅延レプリケーション
遅延レプリケーションは、レプリカサーバでの変更実行を意図的に遅延させる機能である。
誤操作からの回復や過去のデータ状態確認に使用される。
概要と使用場面
遅延レプリケーションの特徴を以下に示す。
- レプリカでの変更実行を指定時間だけ遅延
- SOURCE_DELAY (旧: MASTER_DELAY) オプションで設定
- ソースサーバからのバイナリログ取得は通常通り
- I/Oスレッドは遅延なし
- SQLスレッドの実行のみを遅延
- リレーログの実行を指定時間遅らせる
| 用途 | 説明 |
|---|---|
| 誤操作からの回復 | ソースサーバで誤ってDROPやDELETEを実行した場合、遅延レプリカから復旧することができる。 |
| テーブル削除やデータ削除の誤操作対策 | 遅延期間内であれば遅延レプリカから復旧可能である。 |
| 過去のデータ状態確認 | 特定時点のデータ状態を参照することができる。 |
| 遅延テスト | レプリケーション遅延が発生した場合の動作確認を行うことができる。 |
| ステップ | 説明 |
|---|---|
| ソースサーバで誤操作を実行 | 例: DROP TABLE orders; |
| 誤操作を検知 | 遅延レプリカにはまだ反映されていない。 |
| 遅延レプリカでレプリケーション停止 | 誤操作のイベントが実行される前に停止する。 |
| 遅延レプリカからデータを復旧 | mysqldump コマンド や バックアップツールでデータを取得する。
|
| ソースサーバにデータを復元 | 誤操作前の状態に戻す。 |
設定方法
遅延レプリケーションの設定手順を以下に示す。
- 遅延時間の設定
-- 1時間 (3600秒) 遅延 CHANGE REPLICATION SOURCE TO SOURCE_DELAY = 3600; -- 30分 (1800秒) 遅延 CHANGE REPLICATION SOURCE TO SOURCE_DELAY = 1800; -- 遅延なし (通常レプリケーション) CHANGE REPLICATION SOURCE TO SOURCE_DELAY = 0;
- 旧構文 (MySQL 8.0.22以前、MySQL 8.4で削除)
CHANGE MASTER TO MASTER_DELAY = 3600;
- マルチソースレプリケーションでのチャネル別設定
-- 特定チャネルのみ遅延 CHANGE REPLICATION SOURCE TO SOURCE_DELAY = 3600 FOR CHANNEL 'source1';
- 遅延状態の確認
SHOW REPLICA STATUS\G -- 遅延関連フィールド: -- SQL_Delay: 設定された遅延時間 (秒) -- SQL_Remaining_Delay: 残りの遅延時間 (秒) -- Seconds_Behind_Source: ソースからの実際の遅延秒数
# 出力例 SQL_Delay: 3600 SQL_Remaining_Delay: 2100 Seconds_Behind_Source: 3600
- Performance Schemaでの確認
SELECT * FROM performance_schema.replication_applier_configuration; -- DESIRED_DELAY: 設定された遅延時間 SELECT * FROM performance_schema.replication_applier_status; -- REMAINING_DELAY: 残りの遅延時間
- 誤操作からの回復例
-- ステップ1: ソースサーバで誤操作を検知 -- (例: 10:00にDROP TABLE ordersを実行) -- ステップ2: 遅延レプリカ (1時間遅延) でレプリケーション停止 -- (遅延レプリカは09:00のデータ状態) STOP REPLICA SQL_THREAD; -- ステップ3: 遅延レプリカからデータをバックアップ mysqldump -u root -p db1 orders > orders_backup.sql -- ステップ4: ソースサーバにデータを復元 mysql -u root -p db1 < orders_backup.sql -- ステップ5: 遅延レプリカのレプリケーション再開 START REPLICA SQL_THREAD;
推奨設定を以下に示す。
- 遅延時間は業務要件に応じて設定する。
- 誤操作の検知時間を考慮する。
- 例: 1時間~数時間
- 遅延レプリカは読み取り専用に設定する。
- read_only = 1
- 遅延レプリカは通常の読み取りクエリには使用しない。
- 理由 : 古いデータが返されるため。
レプリケーションの監視
レプリケーションの正常性を監視するための方法を以下に示す。
適切な監視により、レプリケーション遅延やエラーを早期に検出できる。
SHOW REPLICA STATUS
レプリケーション状態を確認する基本的なコマンドを以下に示す。
SHOW REPLICA STATUS\G
| フィールド名 | 説明 |
|---|---|
| Replica_IO_Running | I/Oスレッドの状態 Yes: 正常動作 No: 停止またはエラー Connecting: 接続試行中 |
| Replica_SQL_Running | SQLスレッドの状態 Yes: 正常動作 No: 停止またはエラー |
| Seconds_Behind_Source | ソースサーバからの遅延秒数 0または低い値: 正常 大きい値: 遅延発生 NULL: SQLスレッド停止またはリレーログ処理済み |
| フィールド名 | 説明 |
|---|---|
| Last_Error | 最後に発生したエラーメッセージ 空の場合は、エラー無しである。 |
| Last_IO_Error | I/Oスレッドの最後のエラー 接続エラーやネットワークエラーが表示される。 |
| Last_SQL_Error | SQLスレッドの最後のエラー SQL実行エラーやデータ不整合が表示される。 |
| Last_SQL_Errno | 最後のSQLエラーコード エラー番号例: 1062 - Duplicate entry |
| フィールド名 | 説明 |
|---|---|
| Retrieved_Gtid_Set | I/Oスレッドが取得したGTIDセット リレーログに書き込み済みのGTID |
| Executed_Gtid_Set | SQLスレッドが実行済みのGTIDセット レプリカで実行完了したGTID |
| Auto_Position | GTIDベースの自動位置決定が有効かどうか 1: GTID有効 0: 位置ベース |
| フィールド名 | 説明 |
|---|---|
| Source_Log_File | 現在読み取り中のバイナリログファイル |
| Read_Source_Log_Pos | バイナリログの読み取り位置 |
| Relay_Log_File | 現在処理中のリレーログファイル |
| Relay_Log_Pos | リレーログの読み取り位置 |
| Exec_Source_Log_Pos | ソースサーバのバイナリログで実行済みの位置 |
| フィールド名 | 説明 |
|---|---|
| Source_Host | ソースサーバのホスト名 |
| Source_Port | ソースサーバのポート番号 |
| Source_User | レプリケーション用ユーザ名 |
- 正常状態の例
Replica_IO_Running: Yes Replica_SQL_Running: Yes Seconds_Behind_Source: 0 Last_Error: (空) Retrieved_Gtid_Set: 3E11FA47-71CA-11E1-9E33-C80AA9429562:1-100 Executed_Gtid_Set: 3E11FA47-71CA-11E1-9E33-C80AA9429562:1-100
- エラー状態の例
Replica_IO_Running: No Replica_SQL_Running: Yes Last_IO_Error: error connecting to master 'repl_user@source.example.com:3306' - retry-time: 60 retries: 1
Performance Schema によるモニタリング
Performance Schemaを使用した詳細な監視方法を以下に示す。
- レプリケーション接続状態
SELECT * FROM performance_schema.replication_connection_status\G -- 主要カラム: -- CHANNEL_NAME: チャネル名 -- SOURCE_UUID: ソースサーバのUUID -- THREAD_ID: I/OスレッドのID -- SERVICE_STATE: ON/OFF/CONNECTING -- LAST_ERROR_NUMBER: エラー番号 -- LAST_ERROR_MESSAGE: エラーメッセージ
- レプリケーション適用状態
SELECT * FROM performance_schema.replication_applier_status\G -- 主要カラム: -- CHANNEL_NAME: チャネル名 -- SERVICE_STATE: ON/OFF -- REMAINING_DELAY: 遅延レプリケーションの残り時間
- ワーカースレッド別の状態
SELECT * FROM performance_schema.replication_applier_status_by_worker\G -- 主要カラム: -- WORKER_ID: ワーカースレッドID -- THREAD_ID: スレッドID -- SERVICE_STATE: ON/OFF/IDLE -- LAST_ERROR_NUMBER: エラー番号 -- LAST_ERROR_MESSAGE: エラーメッセージ -- LAST_APPLIED_TRANSACTION: 最後に適用したGTID
- レプリケーション設定情報
SELECT * FROM performance_schema.replication_connection_configuration\G -- 主要カラム: -- CHANNEL_NAME: チャネル名 -- HOST: ソースサーバホスト名 -- PORT: ソースサーバポート番号 -- USER: レプリケーションユーザ名 -- AUTO_POSITION: GTID自動位置決定
- レプリケーション遅延の監視クエリ
SELECT CHANNEL_NAME, LAST_QUEUED_TRANSACTION, LAST_APPLIED_TRANSACTION, APPLYING_TRANSACTION FROM performance_schema.replication_connection_status JOIN performance_schema.replication_applier_status_by_worker USING (CHANNEL_NAME);
レプリケーション遅延の検出と対処
レプリケーション遅延の検出方法と対処法を以下に示す。
- 遅延の検出方法
SHOW REPLICA STATUS\G -- Seconds_Behind_Source フィールドを確認 -- 0または小さい値: 正常 -- 大きい値: 遅延発生 -- NULL: SQLスレッド停止
※注意
- Seconds_Behind_SourceはSQLスレッドの遅延のみを示す。
- I/Oスレッドの遅延は反映されない。
- ネットワークが遅い場合は不正確
- I/Oスレッドが遅延していても検出されない。
- NULLの場合は、SQLスレッド停止 または リレーログ処理済み
- レプリケーション状態を確認する必要がある。
| 原因 | 説明 |
|---|---|
| ソースサーバの書き込みが多い | レプリカの処理能力を超えている。 |
| レプリカサーバのリソース不足 | CPU、メモリ、ディスクI/Oが不足している。 |
| ネットワーク帯域不足 | 大量のバイナリログ転送により帯域が不足している。 |
| 単一スレッドでの実行 | マルチスレッドレプリカで改善可能である。 |
| 大きなトランザクション | 長時間かかるトランザクションがボトルネックとなっている。 |
遅延の対処法を以下に示す。
- マルチスレッドレプリカの有効化
STOP REPLICA SQL_THREAD; SET GLOBAL replica_parallel_workers = 4; SET GLOBAL replica_parallel_type = LOGICAL_CLOCK; START REPLICA SQL_THREAD;
- レプリカサーバのリソース増強
- CPUコア数の増加する。
- マルチスレッドレプリカの効果向上
- メモリを増加する。
- バッファプールサイズの拡大
- ディスクI/O性能を向上させる。
- SSDの使用、RAID構成の最適化
- CPUコア数の増加する。
- バイナリログ形式の最適化
- これにより、バイナリログサイズが削減され、ネットワーク転送量が減少する。
SET GLOBAL binlog_row_image = MINIMAL;
- レプリケーションフィルタの使用
- 不要なデータベースやテーブルをレプリケーション対象から除外することにより、処理量を削減できる。
- 遅延監視スクリプトの例
#!/usr/bin/env sh DELAY=$(mysql -e "SHOW REPLICA STATUS\G" | grep Seconds_Behind_Source | awk '{print $2}') if [ "$DELAY" -gt 60 ]; then echo "WARNING: Replication delay is ${DELAY} seconds" # アラート送信 fi
トラブルシューティング
レプリケーション停止
レプリケーションが停止した場合の対処法を以下に示す。
エラーの確認
SHOW REPLICA STATUS\G
-- Last_Error フィールドを確認
-- Last_IO_Error: I/Oスレッドのエラー
-- Last_SQL_Error: SQLスレッドのエラー
-- Last_SQL_Errno: SQLエラー番号
対処法
Duplicate entry エラー (エラー番号: 1062) Last_SQL_Error: Error 'Duplicate entry '1' for key 'PRIMARY on query.
- 原因
- レプリカに既に存在するキーを挿入しようとしたため、データの不整合が発生
- 対処法 (GTIDモード)
-- 問題のあるGTIDをスキップ SET GTID_NEXT='3E11FA47-71CA-11E1-9E33-C80AA9429562:100'; BEGIN; COMMIT; SET GTID_NEXT='AUTOMATIC'; START REPLICA;
- 対処法 (位置ベース)
-- 1つのイベントをスキップ STOP REPLICA; SET GLOBAL sql_replica_skip_counter = 1; START REPLICA;
Table doesn't exist エラー (エラー番号: 1146) Last_SQL_Error: Error 'Table 'db1.orders' doesn't exist' on query.
- 原因
- レプリカにテーブルが存在しないため、データベース構造の不整合が発生
- 対処法
-- ソースサーバからテーブル定義をコピー mysqldump -u root -p --no-data db1 orders > orders_schema.sql -- レプリカサーバでテーブルを作成 mysql -u root -p db1 < orders_schema.sql -- レプリケーション再開 START REPLICA;
I/O Thread接続エラー Last_IO_Error: error connecting to master 'repl_user@source.example.com:3306'
- 原因
- ネットワーク接続の問題
- ファイアウォール、ルーティング
- レプリケーションユーザの認証失敗
- パスワード誤り、権限不足
- ソースサーバの停止
- メンテナンスや障害
- ネットワーク接続の問題
- 対処法
# ネットワーク接続確認 ping source.example.com telnet source.example.com 3306 # ソースサーバで接続確認 mysql -h source.example.com -u repl_user -p # レプリケーションユーザの権限確認 SHOW GRANTS FOR 'repl_user'@'%';
認証に関する詳細は、MySQL - 認証プラグインのページを参照すること。
データ不整合
ソースサーバとレプリカサーバのデータ不整合の検出と修復を以下に示す。
- 不整合の検出 (pt-table-checksum)
pt-table-checksum --host=source.example.com \ --user=checksum_user --password=password \ --databases=db1 # 結果例: # DIFFS: 不整合があるテーブル数 # ROWS: チェックした行数 # CHUNKS: チェックしたチャンク数
- 不整合の修復 (pt-table-sync)
pt-table-sync --execute \ --sync-to-master replica.example.com \ --databases=db1 \ --tables=orders # 注意: --executeオプションで実際に修復が実行される # 事前に --print または --dry-run で確認推奨
- 手動での不整合修復
-- レプリケーション停止 STOP REPLICA; -- ソースサーバからデータをダンプ mysqldump -u root -p --single-transaction db1 orders > orders.sql -- レプリカサーバでテーブルを再作成 mysql -u root -p db1 < orders.sql -- レプリケーション再開 START REPLICA;
不整合の予防を以下に示す。
- レプリカサーバを read_only=1 に設定する。
- 誤った書き込みを防止
- GTIDモードを使用する。
- データ整合性が向上
- ROW形式のバイナリログ
- 非決定的関数の影響を回避
- 半同期レプリケーション
- データ損失リスクを低減
接続エラー
レプリケーション接続エラーの診断と対処法を以下に示す。
- ネットワーク接続確認
# pingでホスト到達性確認 ping source.example.com # telnetでポート接続確認 telnet source.example.com 3306 # または nc (netcat) を使用 nc -zv source.example.com 3306 # MySQLクライアントで接続確認 mysql -h source.example.com -u repl_user -p
- レプリケーションユーザの認証確認
-- ソースサーバでユーザ確認 SELECT User, Host FROM mysql.user WHERE User = 'repl_user'; -- 権限確認 SHOW GRANTS FOR 'repl_user'@'%'; -- 必要な権限: REPLICATION SLAVE -- ユーザが存在しない場合は作成 CREATE USER 'repl_user'@'%' IDENTIFIED BY 'password'; GRANT REPLICATION SLAVE ON *.* TO 'repl_user'@'%'; FLUSH PRIVILEGES;
- ファイアウォール設定確認
# iptablesルール確認 iptables -L -n | grep 3306 # firewalldでポート開放 firewall-cmd --add-port=3306/tcp --permanent firewall-cmd --reload
- server_idの一意性確認
-- 各サーバでserver_idを確認 SHOW VARIABLES LIKE 'server_id'; -- 全てのサーバで異なる値である必要がある
- バイナリログの存在確認
-- ソースサーバでバイナリログ確認 SHOW BINARY LOGS; -- 現在のバイナリログ位置確認 SHOW MASTER STATUS;
- SSL/TLS接続の確認
- レプリケーション接続でSSL/TLSを使用している場合、証明書の有効性を確認する。
- 詳細は、MySQL - SSL TLS接続のページを参照すること。
- レプリケーション接続のリセット
-- 既存のレプリケーション設定を削除 STOP REPLICA; RESET REPLICA ALL; -- レプリケーション接続を再設定 CHANGE REPLICATION SOURCE TO SOURCE_HOST='source.example.com', SOURCE_PORT=3306, SOURCE_USER='repl_user', SOURCE_PASSWORD='password', SOURCE_AUTO_POSITION=1; START REPLICA;
バージョン別の変更点
MySQL 8.0の主要変更
下表に、MySQL 8.0での重要な変更点を示す。
| バージョン | 機能/変更 | 説明 |
|---|---|---|
| MySQL 8.0 | デフォルトでバイナリロギング有効 | log_binがデフォルトでON 明示的に無効化しない限りバイナリログが記録される。 設定例: --skip-log-bin で無効化
|
| MySQL 8.0.17 | GTIDモード - オンライン有効化 | オンラインでのGTID有効化がサポートされる。 段階的な移行が可能である。 |
| MySQL 8.0.21 | GTIDモード - CREATE TABLE制約緩和 | CREATE TABLE ... SELECT の制約緩和GTIDモードでも使用可能になる。 |
| MySQL 8.0.20 | バイナリログトランザクション圧縮 | binlog_transaction_compression パラメータでバイナリログの圧縮によりネットワーク転送量削減が実現される。 設定例: SET GLOBAL binlog_transaction_compression = ON; |
| MySQL 8.0.22 | レプリカの非同期接続フェイルオーバー | SOURCE_CONNECTION_AUTO_FAILOVER オプションでソースサーバ障害時に自動的に別のソースに接続される。グループレプリケーション構成で有用である。 |
| MySQL 8.0.23 | 新構文の導入 | <ccode>CHANGE REPLICATION SOURCE TO (CHANGE MASTER TOの新構文)START REPLICA / STOP REPLICA (START SLAVE / STOP SLAVEの新構文)SHOW REPLICA STATUS (SHOW SLAVE STATUSの新構文)
|
| MySQL 8.0.26 | 用語の変更 | master → source、slave → replica rpl_semi_sync_master → rpl_semi_sync_source rpl_semi_sync_slave → rpl_semi_sync_replica 全ての構文とパラメータで変更される。 |
| MySQL 8.0.34 | binlog_format非推奨化 | binlog_formatパラメータが非推奨になる。 将来のバージョンで削除予定である。 将来はROW形式のみサポート。 STATEMENT形式 と MIXED形式は廃止予定である。 |
MySQL 8.4の変更点
MySQL 8.4での破壊的変更を以下に示す。
| 旧構文 | 新構文 | 説明 |
|---|---|---|
| CHANGE MASTER TO | CHANGE REPLICATION SOURCE TO | CHANGE MASTER TO は削除済みである。CHANGE REPLICATION SOURCE TO を使用する。
|
| SHOW SLAVE STATUS | SHOW REPLICA STATUS | SHOW SLAVE STATUS は削除済みである。SHOW REPLICA STATUS を使用する。
|
| START SLAVE / STOP SLAVE | START REPLICA / STOP REPLICA | START SLAVE / STOP SLAVE は削除済みである。START REPLICA / STOP REPLICA を使用する。
|
| RESET SLAVE | RESET REPLICA | RESET SLAVE は削除済みである。RESET REPLICA を使用する。
|
| 旧プラグイン名 | 新プラグイン名 | 説明 |
|---|---|---|
| rpl_semi_sync_master | rpl_semi_sync_source | rpl_semi_sync_master は削除済みである。 rpl_semi_sync_source を使用する。 |
| rpl_semi_sync_slave | rpl_semi_sync_replica | rpl_semi_sync_slave は削除済みである。 rpl_semi_sync_replica を使用する。 |
| 旧パラメータ | 新パラメータ | 説明 |
|---|---|---|
| MASTER_HOST, MASTER_PORT, MASTER_USER 等 | SOURCE_HOST, SOURCE_PORT, SOURCE_USER | CHANGE MASTER TOのオプション名は削除済みである。SOURCE_HOST、SOURCE_PORT、SOURCE_USER を使用する。
|
| slave_parallel_workers | replica_parallel_workers | slave_parallel_workers は削除済みである。 replica_parallel_workers を使用する。 |
| slave_parallel_type | replica_parallel_type | slave_parallel_type は削除済みである。 replica_parallel_type を使用する。 |
※MySQL 8.4へのアップグレード時の注意
- アップグレード前に全ての旧構文を新構文に置き換える。
- スクリプトや設定ファイルの書き換え
- 半同期レプリケーションプラグインを新バージョンに変更
- rpl_semi_sync_source / rpl_semi_sync_replica
- 設定ファイル (my.cnfファイル) のパラメータ名を変更
- slave_ → replica_ に置換
互換性を確認する方法を以下に示す。
-- MySQL 8.0.26以降で新構文が使用可能か確認
SELECT VERSION();
-- 新構文が使用できることを確認してからアップグレード
参考リンク
- MySQL 8.4 Replication - MySQL公式ドキュメント
- MySQL GTID - MySQL公式ドキュメント
- MySQL Semi-Synchronous Replication - MySQL公式ドキュメント