はい、承知いたしました。MySQLレプリケーションの超基本から活用例までを網羅した、約5000語の詳細な記事を作成します。
MySQLレプリケーションの超基本!概要から活用例まで徹底解説
はじめに:なぜデータベースにレプリケーションが必要なのか?
現代のウェブサービスやエンタープライズシステムにおいて、データベースは心臓部とも言える重要なコンポーネントです。データベースが停止したり、性能が低下したりすると、サービス全体に甚大な影響が出ます。そのため、データベースには高い可用性、信頼性、そしてパフォーマンスが求められます。
しかし、どんなシステムにも物理的な限界や障害のリスクは存在します。サーバーの故障、ネットワークの問題、あるいは予期せぬ高負荷などが原因で、データベースが利用できなくなる可能性はゼロではありません。また、サービス規模の拡大に伴い、単一のデータベースサーバーでは処理しきれないほどのアクセスが発生することもあります。
ここで登場するのが「レプリケーション」という技術です。レプリケーションは、あるデータベースサーバー(マスター)のデータを別のデータベースサーバー(スレーブ)にリアルタイムに近い形で複製する仕組みです。これにより、以下のような様々なメリットが得られます。
- 高可用性 (High Availability – HA): マスターサーバーが障害で停止しても、スレーブサーバーを新しいマスターとして昇格させることで、サービスの停止時間を最小限に抑えることができます。
- 負荷分散 (Load Balancing): 特に読み込み(SELECTクエリ)の負荷が高いシステムでは、マスターへの書き込み(INSERT, UPDATE, DELETEクエリ)はそのままにしつつ、読み込みクエリを複数のスレーブサーバーに分散させることで、マスターの負荷を軽減し、全体のスループットを向上させることができます。
- バックアップとリカバリ: スレーブサーバーからデータベースのバックアップを取得することで、マスターサーバーの運用に影響を与えることなく安全にバックアップが可能です。また、ポイントインタイムリカバリ(特定の時点への復旧)を行う際にも、レプリケーションの情報が役立ちます。
- レポーティング/分析: マスターの運用系システムとは別に、スレーブを分析用・レポーティング用のデータベースとして利用することで、分析クエリによるマスターへの負荷を防ぎます。
- システムメンテナンス/バージョンアップ: マスターサーバーのメンテナンスやバージョンアップを行う際、一時的にスレーブサーバーに処理を切り替えることで、ダウンタイムを最小限に抑えることができます。
- 地理的な分散: 遠隔地にスレーブサーバーを設置することで、災害対策(Disaster Recovery – DR)として機能させることができます。
このように、レプリケーションは現代のデータベース運用において不可欠な技術と言えるでしょう。この記事では、MySQLのレプリケーションに焦点を当て、「超基本」と銘打つ通り、その仕組みの概要から始まり、具体的な設定方法、監視、そして様々な活用例までを徹底的に解説していきます。
対象読者は、MySQLの基本的な操作は理解しているが、レプリケーションについてはこれから学びたい、あるいは基本的な仕組みを再確認したいと考えている方々です。約5000語というボリュームで、レプリケーションに関する疑問を解消し、実際に設定・運用できるようになることを目指します。
MySQLレプリケーションの概要:マスターとスレーブの関係
MySQLレプリケーションは、基本的に「マスター(Master)」と「スレーブ(Slave)」という2つの役割を持つサーバーで構成されます。
- マスター: データの書き込み(INSERT, UPDATE, DELETE)が発生するサーバーです。ユーザーからの変更要求はまずマスターに送られ、ここでデータが変更されます。マスターは、自身で行われたすべてのデータの変更履歴を「バイナリログ(Binary Log)」と呼ばれる特別なファイルに記録します。
- スレーブ: マスターのバイナリログを読み取り、マスターで行われたデータの変更を自身のデータベースに反映(適用)するサーバーです。これにより、スレーブのデータはマスターのデータとほぼ同じ状態に保たれます。スレーブは通常、読み込み(SELECT)クエリの処理に利用されます。
レプリケーションは、このマスターが生成するバイナリログをスレーブが取得し、順番に適用していくことによって実現されます。この仕組みは、MySQLのバージョンや設定によっていくつかのバリエーションがありますが、最も基本的で広く使われているのは「非同期レプリケーション(Asynchronous Replication)」です。
非同期レプリケーションでは、マスターはデータ変更を自身のバイナリログに書き込んだ時点でトランザクションをコミットし、クライアントに応答を返します。その後、スレーブがそのバイナリログを非同期に取得し、適用します。この方式の利点は、マスターがスレーブの応答を待たないため、マスターの書き込み性能への影響が少ないことです。一方、デメリットとしては、マスターでコミットされても、それがスレーブにまだ適用されていない時間差(レプリケーション遅延、Replication Lag)が存在する可能性があることです。この時間差がある間にマスターに障害が発生した場合、スレーブにはマスターの最新データの一部が反映されていない可能性があります。
後のセクションで詳しく解説しますが、この非同期レプリケーションの欠点を補うために、準同期レプリケーションなどの方式も存在します。しかし、「超基本」として理解すべきは、マスターが変更を記録し、スレーブがそれを取り込んで適用するという、バイナリログを介した非同期のデータ同期の仕組みです。
レプリケーションがどのように機能するか:バイナリログとスレッドの役割
MySQLレプリケーションの中核となるのは、マスターの「バイナリログ」と、スレーブ側の2つのスレッド(I/OスレッドとSQLスレッド)です。
1. マスター側の処理
マスターサーバーでは、データ変更を伴うSQL文(INSERT, UPDATE, DELETE, DDLなど)が実行されると、その変更内容が「バイナリログ(Binary Log)」に記録されます。
- バイナリログ (Binlog): マスターで行われたデータ変更のイベントが記録されるファイルです。単なるSQL文の羅列ではなく、データの変更内容やイベントの発生時刻、トランザクションのコミット情報などがバイナリ形式で記録されます。バイナリログはレプリケーションだけでなく、ポイントインタイムリカバリにも利用されます。
- Binlogフォーマット: バイナリログにはいくつかのフォーマットがあります。
- STATEMENT: 実行されたSQL文そのものを記録します。シンプルですが、
NOW()
やUUID()
のような関数を使ったSQLや、LIMIT
句を使ったUPDATE
/DELETE
など、実行環境によって結果が変わる可能性のあるSQLは、スレーブで同じ結果にならない「非決定性」の問題を起こす可能性があります。 - ROW: SQL文ではなく、データの変更前後の行イメージ(値そのもの)を記録します。非決定性の問題を完全に回避でき、安全性が高いですが、ログのサイズが大きくなる傾向があります。
- MIXED: 基本的にはSTATEMENTフォーマットを使用しますが、非決定性の問題が発生しうるSQLの場合に自動的にROWフォーマットに切り替わります。安全性とログサイズを両立する目的で使用されます。特別な理由がなければ、通常はMIXEDまたはROWフォーマットが推奨されます。
- STATEMENT: 実行されたSQL文そのものを記録します。シンプルですが、
- Binlogファイル: バイナリログは通常、
mysql-bin.000001
,mysql-bin.000002
のように連番のファイルで管理されます。ファイルサイズが上限に達したり、MySQLサーバーが再起動したりすると、新しいファイルが作成されます。 - Binlogインデックスファイル: どのバイナリログファイルが存在するかを記録したファイル (
mysql-bin.index
) も生成されます。
- Binlogフォーマット: バイナリログにはいくつかのフォーマットがあります。
マスターサーバーには、スレーブからの接続要求を受け付け、バイナリログの内容を送信するための「Binlogダンプスレッド (Binlog Dump Thread)」が起動します。スレーブがマスターに接続し、レプリケーションを開始すると、このスレッドがそのスレーブのために生成され、要求された位置からバイナリログイベントを読み出してスレーブに送信します。
2. スレーブ側の処理
スレーブサーバーは、マスターから送られてきたバイナリログのイベントを受け取り、自身のデータベースに適用します。これには主に2つのスレッドが関与します。
- I/Oスレッド (I/O Thread): マスターのBinlogダンプスレッドに接続し、マスターのバイナリログイベントを要求して受信します。受信したイベントは、スレーブサーバー上の「リレーログ(Relay Log)」と呼ばれるファイルに順番に書き込まれます。I/Oスレッドの役割は、ひたすらマスターからイベントを取得してリレーログに書き込むことです。
- リレーログ (Relay Log): スレーブのI/Oスレッドがマスターから受け取ったバイナリログイベントを一時的に保存しておくファイルです。マスターのバイナリログとほぼ同じ内容ですが、ファイル名は通常
hostname-relay-bin.000001
のようになります。リレーログもインデックスファイル (hostname-relay-bin.index
) を持ちます。 - SQLスレッド (SQL Thread): リレーログを読み込み、そこに記録されているイベントを順番にスレーブ自身のデータベースに適用します。例えば、リレーログに
INSERT INTO table (col) VALUES (10)
というイベントが記録されていれば、SQLスレッドはスレーブのデータベースに対してそのINSERT
文を実行します(ROWフォーマットの場合は行の変更を適用します)。SQLスレッドがリレーログの最後までイベントを適用すると、次の新しいイベントがI/Oスレッドによってリレーログに書き込まれるのを待ちます。
レプリケーションのフローまとめ
- クライアントがマスターにデータ変更クエリ(例:
INSERT ...
)を送信します。 - マスターはクエリを実行し、トランザクションをコミットします。
- コミットされた変更内容はマスターのバイナリログに書き込まれます。
- スレーブのI/OスレッドがマスターのBinlogダンプスレッドに接続し、新しいバイナリログイベントを要求します。
- マスターのBinlogダンプスレッドは、要求された位置からバイナリログイベントをスレーブのI/Oスレッドに送信します。
- スレーブのI/Oスレッドは受信したイベントを自身の リレーログ に書き込みます。
- スレーブのSQLスレッドはリレーログからイベントを読み込み、自身のデータベースに対してその変更を適用します。
この一連の流れが、マスターとスレーブの間で継続的に繰り返されることで、データの同期が維持されます。非同期レプリケーションの場合、マスターがバイナリログに書き込んだ時点と、スレーブのSQLスレッドがそのイベントを適用完了した時点の間には時間差があります。この時間差がレプリケーション遅延となり得ます。
レプリケーションの種類:非同期、準同期、そして同期
レプリケーションの基本的な仕組みはバイナリログの受け渡しですが、マスターがトランザクションをコミットするタイミングと、スレーブがその変更を受け取った、あるいは適用したタイミングとの同期のレベルによって、いくつかの種類があります。
1. 非同期レプリケーション (Asynchronous Replication)
これは最も基本的なレプリケーション方式で、前述の仕組みそのままです。
- 仕組み: マスターはトランザクションが完了し、バイナリログに書き込まれた時点でクライアントに応答を返します。スレーブがバイナリログイベントを取得し、リレーログに書き込み、適用するのはマスターとは完全に非同期に行われます。
- メリット: マスターがスレーブの応答を待たないため、書き込み処理のパフォーマンスが最も優れています。マスター側のオーバーヘッドが最小限です。
- デメリット: レプリケーション遅延が発生する可能性があります。マスターに障害が発生した場合、スレーブにはまだ送信されていない、あるいは受信・適用されていない最新のデータ変更があるかもしれません。この場合、フェイルオーバー時に一部のデータが失われる(ロストアップデートが発生する)リスクがあります。
2. 準同期レプリケーション (Semisynchronous Replication)
非同期レプリケーションのデータ損失リスクを軽減するために考案された方式です。
- 仕組み: マスターはトランザクションをコミットした後、そのトランザクションに対応するバイナリログイベントが少なくとも1台のスレーブによって受信され、リレーログに書き込まれた(レプリケーション確認応答を受け取った)ことを確認してから、クライアントに応答を返します。これにより、マスターでコミットされたデータは、少なくとも1台のスレーブには到達していることが保証されます。スレーブでの適用は非同期のままです。
- メリット: マスター障害時のデータ損失リスクを低減できます。マスターでコミットされたデータが完全に失われる可能性は非同期よりも大幅に低くなります(ただし、スレーブが受け取っただけで適用していない可能性はあります)。
- デメリット: マスターの書き込み処理がスレーブからの確認応答を待つ分、非同期レプリケーションに比べて若干遅くなります。すべてのアクティブなスレーブが一時的に利用できなくなった場合、マスターの書き込み処理がブロックされる可能性があります(タイムアウト設定が可能)。
準同期レプリケーションは、MySQL 5.5以降でプラグインとして提供されており、設定によって有効化できます。マスター側でrpl_semi_sync_master_enabled=ON
、スレーブ側でrpl_semi_sync_slave_enabled=ON
を有効にし、マスター側で待機するスレーブの数をrpl_semi_sync_master_wait_for_slave_count
で指定します(通常は1)。また、待機する最大時間をrpl_semi_sync_master_timeout
で設定します。タイムアウトした場合は自動的に非同期レプリケーションに切り替わります。
3. 同期レプリケーション (Synchronous Replication)
厳密な意味での同期レプリケーションは、トランザクションがすべてのスレーブに適用完了したことをマスターが確認してからクライアントに応答を返す方式です。これは一般的なMySQLのレプリケーション機能では実現できません。
- MySQL Group Replication: MySQL 5.7以降で提供される「MySQL Group Replication」は、分散システムとPaxos合意アルゴリズムを利用して、複数ノード間での厳密な同期(実際に書き込みが行われたことを確認)を実現する技術です。これは従来のマスター/スレーブ型レプリケーションとは異なり、複数ノードがプライマリ(書き込み可能)となりうるマルチプライマリモードや、1ノードのみがプライマリとなるシングルプライマリモードで運用可能です。高い可用性とデータの整合性を提供しますが、設定や運用はより複雑になります。これはレプリケーションの「超基本」からは少し外れるため、ここでは簡単な紹介に留めます。
「超基本」としては、まず非同期レプリケーションの仕組みをしっかりと理解することが重要です。多くのシステムでは、準同期レプリケーションによってデータ損失リスクをある程度低減しつつ、非同期の性能メリットを享受する構成が採用されています。
基本的なレプリケーション構成例
MySQLレプリケーションは、様々な構成で利用できます。ここでは代表的な基本的な構成をいくつか紹介します。
1. マスター1台、スレーブ1台 (Master-Slave)
最もシンプルで基本的な構成です。
- 構成: マスターサーバー1台とスレーブサーバー1台。
- 用途: 主に高可用性(マスター障害時のフェイルオーバー)や、スレーブでのバックアップ取得などに利用されます。読み込み負荷分散も可能ですが、スレーブが1台なので分散効果は限定的です。
- メリット: 設定が比較的容易です。
- デメリット: スレーブが1台なので、読み込み負荷分散や冗長性の面で限界があります。スレーブ障害時はレプリケーションが一時的に停止します。
2. マスター1台、スレーブ複数台 (Master-Many Slaves)
読み込み負荷分散や冗長性を高めるためによく利用される構成です。
- 構成: マスターサーバー1台と、複数のスレーブサーバー。
- 用途: 大量の読み込みクエリが発生するシステムで、読み込み負荷を複数のスレーブに分散させるために使用されます。また、複数のスレーブがあることで、1台のスレーブが障害を起こしても他のスレーブがレプリケーションを継続できるため、冗長性が向上します。特定の用途(バックアップ、分析など)専用のスレーブを用意することも可能です。
- メリット: 読み込みスケーラビリティが高いです。スレーブの冗長性が向上します。
- デメリット: マスターのバイナリログを複数のスレーブに送信する必要があるため、マスターのネットワーク帯域を消費します。スレーブが増えるほど管理の手間が増えます。
3. マスター・マスター構成 (Master-Master, Active/Passive)
通常は片方のマスターのみをアクティブとして書き込みを受け付け、もう片方はパッシブとしてレプリケーションを待機する構成です。
- 構成: 2台のサーバーがお互いにマスターとスレーブの関係になります。サーバーAはサーバーBのスレーブであり、同時にサーバーBはサーバーAのスレーブとなります。ただし、通常は片方のサーバーのみに書き込みを行います(アクティブ/パッシブ構成)。両方に同時に書き込みを行う(アクティブ/アクティブ)と、データ競合(コンフリクト)が発生してデータの整合性が保てなくなるリスクが非常に高いため、特別な設計やミドルウェアがない限り推奨されません。
- 用途: 高可用性を実現する一般的な方法の一つです。アクティブなマスターに障害が発生した場合、パッシブ側のサーバーを新しいマスターとして迅速に昇格させることができます。フェイルバック(元の構成に戻すこと)も比較的容易です。
- メリット: 高可用性の実現に適しています。計画メンテナンス時の切り替えも比較的容易です。
- デメリット: 設定はマスター/スレーブ構成より少し複雑になります。意図せず両方のマスターに書き込みが発生しないよう、アプリケーション側や運用ルールで制御する必要があります。アクティブ/アクティブ構成はコンフリクト管理が非常に難しいです。
これらの基本的な構成を理解することが、実際のシステムにレプリケーションを導入する際の出発点となります。システムの要件(可用性レベル、読み込み負荷、予算など)に応じて最適な構成を選択します。
レプリケーションの超基本的な設定方法
ここでは、最も基本的な「マスター1台、スレーブ1台」の非同期レプリケーション構成を例に、最低限必要な設定手順を解説します。
前提:
- マスターサーバーとスレーブサーバーの2台のMySQLサーバーが起動していること。
- 両サーバー間でネットワーク疎通があり、MySQLのデフォルトポート(3306)で接続できること。
- 設定ファイルを編集するための適切な権限があること。
設定の大まかな流れ:
- マスター側でレプリケーションに必要な設定を行う。
- マスター側でレプリケーション用のユーザーを作成する。
- マスターの現在の状態(バイナリログファイル名と位置)を確認する。
- スレーブ側でレプリケーションに必要な設定を行う。
- スレーブ側でマスターへの接続情報を設定し、レプリケーションを開始する。
- スレーブのレプリケーション状態を確認する。
1. マスター側の設定
マスターとなるサーバーのMySQL設定ファイル(通常 /etc/my.cnf
または /etc/mysql/mysql.conf.d/mysqld.cnf
など)を編集します。
“`ini
[mysqld]
サーバーを一意に識別するID。各サーバーで異なるIDを設定する必要があります。
server_id = 1
バイナリログを有効にする設定。ファイル名のプレフィックスを指定します。
log_bin = mysql-bin
バイナリログのフォーマットを指定します。ROWまたはMIXEDを推奨。
binlog_format = ROW
または
binlog_format = MIXED
(オプション) バイナリログを自動削除する日数。ディスク容量に応じて設定。
expire_logs_days = 7
(オプション) レプリケーション対象から除外するデータベースやテーブル。
binlog_ignore_db = mysql
binlog_do_db = mydb
“`
設定変更後、MySQLサーバーを再起動します。
bash
sudo systemctl restart mysql # または mysqld
再起動後、MySQLにログインし、バイナリログが有効になっているか確認します。
“`sql
mysql> SHOW VARIABLES LIKE ‘log_bin’;
+—————+——-+
| Variable_name | Value |
+—————+——-+
| log_bin | ON |
+—————+——-+
mysql> SHOW VARIABLES LIKE ‘server_id’;
+—————+——-+
| Variable_name | Value |
+—————+——-+
| server_id | 1 |
+—————+——-+
mysql> SHOW VARIABLES LIKE ‘binlog_format’;
+—————+——-+
| Variable_name | Value |
+—————+——-+
| binlog_format | MIXED |
+—————+——-+
“`
2. マスター側でレプリケーションユーザーを作成する
スレーブがマスターに接続し、バイナリログを取得するための専用ユーザーを作成します。このユーザーにはREPLICATION SLAVE
権限が必要です。特定のIPアドレスまたはホストからのみ接続できるように制限することが推奨されます。
sql
mysql> CREATE USER 'repl_user'@'スレーブのIPアドレスまたはホスト名' IDENTIFIED BY 'パスワード';
mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl_user'@'スレーブのIPアドレスまたはホスト名';
mysql> FLUSH PRIVILEGES;
例: スレーブのIPアドレスが192.168.1.10の場合
sql
mysql> CREATE USER 'repl_user'@'192.168.1.10' IDENTIFIED BY 'my_secure_password';
mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl_user'@'192.168.1.10';
mysql> FLUSH PRIVILEGES;
3. マスターの現在の状態を確認する
スレーブがレプリケーションを開始する基準となる、マスターの現在のバイナリログファイル名と位置(ポジション)を確認します。これは、スレーブがどこからバイナリログの読み込みを開始すればよいかを指定するために必要です。
注意: この時点でのマスターのデータ状態をスレーブにコピーしておく必要があります。この時点以降にマスターで行われた変更をスレーブが受け取るためです。データコピーの方法としては、mysqldump
やmysqlpump
、あるいは物理バックアップツール(Percona XtraBackupなど)が使われます。mysqldump
でバックアップを取得する際は、必ず--master-data=2
オプションを付けて実行し、バックアップ中にマスターに変更がないようにロックをかける(あるいはリードロックをかけてからダンプを開始する)必要があります。
mysqldump
を使う場合の例(ロックをかけて、バックアップ中に変更が発生しないようにする):
“`bash
マスターサーバー上で実行
mysqldump -u root -p –all-databases –single-transaction –master-data=2 > full_backup.sql
“`
このコマンドを実行すると、バックアップファイル (full_backup.sql
) の中に以下のようなコメント行が含まれます。
sql
-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=12345;
この MASTER_LOG_FILE
と MASTER_LOG_POS
の値が、スレーブがレプリケーションを開始すべき位置です。--master-data=2
オプションは、バックアップ取得中に発生した変更に関するバイナリログ情報をコメントとしてバックアップファイルに含めます。--single-transaction
はInnoDBテーブルに対してトランザクション分離レベルを利用して一貫性のあるバックアップを取得しますが、DDL等には効果がないため、より厳密な場合はFLUSH TABLES WITH READ LOCK;
を実行してロックし、SHOW MASTER STATUS;
でログ位置を確認後、バックアップを取得し、UNLOCK TABLES;
を実行するという手順が推奨されます。
SHOW MASTER STATUS;
コマンドで確認する場合:
“`sql
mysql> FLUSH TABLES WITH READ LOCK;
mysql> SHOW MASTER STATUS;
+——————+———-+————–+——————+——————-+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+——————+———-+————–+——————+——————-+
| mysql-bin.000001 | 12345 | | | |
+——————+———-+————–+——————+——————-+
1 row in set (0.00 sec)
File: mysql-bin.000001, Position: 12345 がレプリケーション開始点です。
バックアップを取得…
mysqldump -u root -p –all-databases > full_backup.sql
mysql> UNLOCK TABLES;
“`
この File
と Position
の値をメモしておきます。
4. スレーブ側の設定
スレーブとなるサーバーのMySQL設定ファイル (my.cnf
など) を編集します。
“`ini
[mysqld]
サーバーを一意に識別するID。マスターとは異なるIDを設定します。
server_id = 2
リレーログを有効にする設定。ファイル名のプレフィックスを指定します。
relay_log = mysql-relay-bin # 最近のバージョンでは指定不要なことが多いですが、明示的に指定することも可能
(オプション) レプリケーション遅延を監視するための設定 (MySQL 5.6+)
slave_parallel_workers = N # 並列レプリケーションを有効にする場合 (後述)
(オプション) マスターとのSSL接続を有効にする場合
master_ssl = 1
“`
設定変更後、MySQLサーバーを再起動します。
bash
sudo systemctl restart mysql # または mysqld
スレーブにマスターから取得したバックアップファイル (full_backup.sql
) をインポートします。
“`bash
スレーブサーバー上で実行
mysql -u root -p < full_backup.sql
“`
5. スレーブ側でマスターへの接続情報を設定し、レプリケーションを開始する
スレーブにMySQLクライアントでログインし、CHANGE MASTER TO
コマンドを使用してマスターへの接続情報と、レプリケーション開始位置を設定します。
“`sql
mysql> CHANGE MASTER TO
-> MASTER_HOST=’マスターのIPアドレスまたはホスト名’,
-> MASTER_USER=’repl_user’,
-> MASTER_PASSWORD=’my_secure_password’,
-> MASTER_LOG_FILE=’mysql-bin.000001′, — SHOW MASTER STATUS で確認した File 名
-> MASTER_LOG_POS=12345; — SHOW MASTER STATUS で確認した Position 値
mysql> START SLAVE;
“`
ここで設定する MASTER_LOG_FILE
と MASTER_LOG_POS
は、前述の「マスターの現在の状態を確認する」手順で取得した値です。mysqldump --master-data=2
で取得したバックアップファイルから値をコピーしても構いません。
6. スレーブのレプリケーション状態を確認する
スレーブサーバーでMySQLクライアントにログインし、SHOW SLAVE STATUS
コマンドを実行してレプリケーションが正常に開始されているか確認します。
sql
mysql> SHOW SLAVE STATUS\G
出力される結果の中から、特に以下の項目を確認します。
Slave_IO_State
: スレーブI/Oスレッドの状態。Waiting for master to send event
またはWaiting for master_heartbeat event
などであれば正常にマスターからのイベント待機中です。Slave_IO_Running
: I/Oスレッドが実行中か。Yes
である必要があります。Slave_SQL_Running
: SQLスレッドが実行中か。Yes
である必要があります。Last_IO_Error
: I/Oスレッドで最後に発生したエラー。エラーがない場合は空欄です。Last_SQL_Error
: SQLスレッドで最後に発生したエラー。エラーがない場合は空欄です。Seconds_Behind_Master
: スレーブがマスターから遅延している秒数。0
に近いほどリアルタイムに同期できています。一時的に大きな値になることはありますが、時間が経てば減少していくのが正常です。長時間大きな値のままだったり増加し続けたりする場合は、レプリケーション遅延が発生しています。
Slave_IO_Running
と Slave_SQL_Running
が両方 Yes
であり、Last_IO_Error
と Last_SQL_Error
が空欄であれば、基本的なレプリケーションは正常に稼働しています。Seconds_Behind_Master
の値を確認し、遅延が発生していないか(あるいは許容範囲内か)を監視します。
これで、最も基本的なMySQLレプリケーションの設定は完了です。この設定は非同期レプリケーションとなります。準同期レプリケーションやGTIDを使ったレプリケーションは、これよりもう少し設定項目が増えますが、基本的な流れは同じです。
レプリケーションの監視とトラブルシューティング
レプリケーションは一度設定すれば終わりではなく、継続的な監視が必要です。特にスレーブの遅延やエラーは、サービスの可用性やデータの整合性に直結するため、迅速な検知と対応が求められます。
SHOW SLAVE STATUS\G
の重要項目と監視
前述の SHOW SLAVE STATUS\G
コマンドは、レプリケーションの状態を確認するための最も重要なコマンドです。以下の項目を定期的に確認・監視することが推奨されます。
Slave_IO_Running
/Slave_SQL_Running
: これらがNo
になっている場合、レプリケーションが停止しています。Last_IO_Error
またはLast_SQL_Error
を確認し、停止原因を特定する必要があります。Last_IO_Error
/Last_SQL_Error
: エラーメッセージが表示されている場合、何らかの問題が発生しています。I/Oエラーはマスターへの接続問題やバイナリログ取得の問題、SQLエラーはスレーブでのSQL適用時の問題(例: マスターで削除された行をスレーブで再度削除しようとした、マスターで作成されたキーがスレーブで既に存在したなど)が多いです。エラーメッセージを元に原因を特定し、対処します。Seconds_Behind_Master
: スレーブがマスターから遅延している秒数を示します。この値が大きい場合、スレーブの処理能力がマスターの書き込み速度に追いついていないことを意味します。継続的に監視し、閾値を超えたらアラートを出すように設定することが非常に重要です。Master_Log_File
,Read_Master_Log_Pos
: スレーブのI/Oスレッドがマスターから取得済みの最新のバイナリログファイルと位置です。Relay_Log_File
,Relay_Log_Pos
: スレーブのSQLスレッドがリレーログから読み込み中のリレーログファイルと位置です。Relay_Master_Log_File
,Exec_Master_Log_Pos
: スレーブのSQLスレッドが現在適用中のイベントが、マスターのどのバイナリログファイル・位置に対応するかを示します。Read_Master_Log_Pos
とExec_Master_Log_Pos
が近い値であれば、スレーブは取得したイベントをほぼリアルタイムに適用できていることになります。
スレーブ遅延 (Replication Lag) の原因と対策
Seconds_Behind_Master
の値が大きい(遅延している)場合、様々な原因が考えられます。
-
原因:
- スレーブの処理能力不足: スレーブのIOPS、CPU、メモリなどがマスターの書き込み負荷に比べて低い。特に書き込みが大量に発生する場合や、大きなトランザクションがある場合にSQLスレッドの適用が追いつかなくなることがあります。
- ネットワーク遅延: マスターとスレーブ間のネットワーク帯域が狭い、あるいは遅延が大きい。
- マスターの巨大なトランザクション: マスターで非常に時間がかかる大きなトランザクションが実行されると、バイナリログの生成が滞る、またはスレーブでの適用に時間がかかる。
- スレーブでの重いクエリ実行: スレーブを読み込み用に使っている場合、実行中の重いSELECTクエリがSQLスレッドの処理をブロックすることがあります(ストレージエンジンのロックなど)。
- スレーブのディスクI/O競合: スレーブでのデータ適用処理と、読み込みクエリ、バックアップ取得などが同時に行われることによるディスクI/Oの競合。
- 単一スレッドの問題: デフォルトではSQLスレッドは単一スレッドでリレーログを順番に適用します。マスターで並列に書き込みが行われていても、スレーブでの適用は直列になるため、負荷が高いと追いつかなくなります。
-
対策:
- スレーブのスペック向上: CPU、メモリ、特にストレージ(SSDへの変更など)をマスターと同等以上に強化します。
- MySQLのパラメータ調整: スレーブ側でキャッシュ(
innodb_buffer_pool_size
など)を適切に設定し、ディスクI/Oを減らします。 - 並列レプリケーションの利用: MySQL 5.6以降で利用可能な「並列レプリケーション(Multi-Threaded Slave – MTS)」を有効にします。これにより、複数のSQLスレッドがリレーログを並列に適用できるようになり、遅延を大幅に改善できる可能性があります。設定は
slave_parallel_workers = N
(N
はスレッド数) です。GTIDを使用している場合、異なるトランザクションをより効率的に並列処理できます。 - ネットワーク環境の改善: マスターとスレーブ間のネットワーク帯域を広げたり、遅延を減らしたりします。
- スレーブの負荷軽減: スレーブでの重い読み込みクエリを見直したり、バックアップ時間を調整したりします。
- 巨大なトランザクションの分割: 可能な限り、マスターでの巨大なトランザクションを避け、小さく分割します。
- Binlogフォーマットの検討: STATEMENTフォーマットはスレーブでのSQL解析・実行に時間がかかる場合があります。ROWまたはMIXEDフォーマットの方が一般的にスレーブでの適用は高速です。
レプリケーションエラーの対処法
Last_SQL_Error
などにエラーが表示され、Slave_SQL_Running
がNo
になっている場合、SQLスレッドが停止しています。エラーメッセージをよく読み、原因を特定する必要があります。
-
よくあるエラー例:
Error 'Duplicate entry ... for key ...'
(ER_DUP_ENTRY): マスターでINSERTされたデータが、スレーブでは既に存在していた場合に発生します。Error 'Unknown database/table ...'
(ER_BAD_DB_ERROR / ER_NO_SUCH_TABLE): マスターで操作対象のデータベースやテーブルが、スレーブに存在しない場合に発生します。Error 'Data too long for column ...'
(ER_TOO_LONG_STRING): マスターとスレーブでテーブル定義が異なり、マスターで許可されるサイズがスレーブで超過した場合に発生します。Error 'Cannot delete or update a parent row: a foreign key constraint fails ...'
(ER_ROW_IS_REFERENCED): マスターとスレーブで外部キー制約の定義が異なっていたり、スレーブのデータが不整合を起こしている場合に発生します。
-
対処法:
- エラー原因の特定: エラーメッセージと、エラーが発生したマスターのバイナリログファイル・位置 (
Relay_Master_Log_File
,Exec_Master_Log_Pos
) を確認します。 - スキップまたは修正: 原因に応じて、エラーイベントをスキップしてレプリケーションを再開するか、スレーブのデータやスキーマを修正します。
- スキップ:
SET GLOBAL sql_slave_skip_counter = 1;
を実行後、START SLAVE;
で1つだけエラーイベントをスキップしてレプリケーションを再開できます。ただし、これはあくまで一時的な対処であり、データの不整合を引き起こす可能性があります。安易なスキップは避けるべきです。原因を理解し、影響を評価した上で行います。 - データ/スキーマ修正: エラーの原因がデータ不整合やスキーマ不一致であれば、手動でスレーブのデータやスキーマを修正し、
START SLAVE;
でレプリケーションを再開します。例えば、Duplicate entryであればスレーブ側の該当レコードを削除するなど。
- スキップ:
- レプリケーションの再構築: エラーが頻発したり、データの不整合が深刻な場合は、スレーブを停止し、マスターから再度フルバックアップを取得してスレーブにリストアし、レプリケーションをゼロから再設定するのが最も安全な方法です。
- エラー原因の特定: エラーメッセージと、エラーが発生したマスターのバイナリログファイル・位置 (
ツールによる監視
手動で SHOW SLAVE STATUS
を実行するだけでなく、監視ツールを利用してレプリケーションの状態を自動的に監視し、閾値ベースのアラートを設定することが現実的な運用では不可欠です。
- Percona Toolkit:
pt-heartbeat
はマスターとスレーブ間のレプリケーション遅延をより正確に測定するためのツールです。pt-slave-find
はレプリケーション構造を調べたり、pt-slave-lag-graph
は遅延をグラフ化したりするのに役立ちます。 - Nagios, Zabbix, Prometheus+Grafana: 標準的な監視ツールで
SHOW SLAVE STATUS
の結果を取得し、Slave_IO_Running
,Slave_SQL_Running
,Seconds_Behind_Master
などの項目を監視・グラフ化・アラート設定できます。 - MySQL Enterprise Monitor: Oracleが提供する商用監視ツールで、MySQLレプリケーションに特化した監視機能を提供します。
- Monyog: レプリケーションを含むMySQLサーバーの監視に特化した商用GUIツールです。
これらのツールを活用することで、レプリケーションの異常を早期に検知し、サービスの安定稼働を維持できます。
レプリケーションの多様な活用例
レプリケーションは単にマスターのバックアップとしてだけでなく、システムの様々な課題を解決するために多目的に活用できます。
1. バックアップとリカバリ
- 活用法: スレーブサーバーから定期的にバックアップを取得します。マスターサーバーの稼働に影響を与えることなくバックアップが可能になります。スレーブでのバックアップは、マスターのデータ変更のタイミングを気にせずに行えるため、マスターに負荷をかけずに済むという大きなメリットがあります。
- ポイントインタイムリカバリ: バイナリログと、特定の時点までのデータを適用済みのスレーブ(またはフルバックアップ)を組み合わせることで、誤操作などによって失われたデータを特定の時点まで復旧させることが可能です。マスターのバイナリログは、フルバックアップ取得時点以降の変更をすべて記録しているため、バックアップリストア後に必要なバイナリログを適用することで、特定の時点のデータを再現できます。
2. 読み込み負荷分散 (Read Scaling)
- 活用法: ユーザーからの読み込みクエリ(SELECT文)を、マスターではなく1台以上のスレーブサーバーに振り分けます。アプリケーション側で書き込みと読み込みのコネクション先を分けたり、HAProxyやMaxScaleのようなプロキシサーバーを利用して自動的に読み込みクエリをスレーブにルーティングしたりします。
- 効果: マスターは書き込み処理に専念できるため、書き込み性能が向上します。また、読み込み負荷は複数のスレーブに分散されるため、全体の読み込みスループットが大幅に向上し、ユーザーへの応答速度も改善されます。これは、読み込みクエリが書き込みクエリよりも圧倒的に多い、一般的なWebサービスやSNSなどで非常に有効な手段です。
3. 高可用性 (High Availability – HA)
- 活用法: マスターサーバーに障害が発生し、利用できなくなった場合、スレーブサーバーを新しいマスターとして昇格させ、サービスを継続します。マスター・スレーブ構成やマスター・マスター(Active/Passive)構成がこれに利用されます。
- フェイルオーバー手順: マスター障害発生を検知 -> スレーブを停止し、最新のリレーログを全て適用(非同期の場合データ損失リスクあり)-> スレーブを新しいマスターとして設定変更 -> アプリケーションやプロキシの接続先を新しいマスター(旧スレーブ)に切り替える。この手順を自動化するために、MHA (Master High Availability Manager and Failover Manager) や Orchestrator のようなHAツールが利用されることが多いです。これらのツールは、マスター障害検知、最適なスレーブの選定、スレーブの昇格、他のスレーブの新しいマスターへの接続先変更などを自動で行ってくれます。
4. バージョンアップやメンテナンス時の利用
- 活用法: マスターサーバーのMySQLバージョンアップやOSのパッチ適用など、ダウンタイムを伴う可能性のあるメンテナンスを行う際に利用します。
- 手順:
- 新しいバージョンのMySQLをインストールしたサーバーを用意し、既存マスターのスレーブとしてレプリケーション設定します。
- レプリケーション遅延が解消され、新しいサーバーが最新の状態になったら、サービスの書き込みを一時的に停止します(あるいはプロキシでマスターへの書き込みをブロックします)。
- 新しいサーバー(旧スレーブ)を新しいマスターとして昇格させます。
- アプリケーションやプロキシの接続先を新しいマスターに切り替えます。
- サービスの書き込みを再開します。
- 古いマスターサーバーのメンテナンスを行います。
- メンテナンスが完了した古いマスターを、新しいマスターのスレーブとして接続し、レプリケーションを再開します(フェイルバック準備)。
この方法により、マスターの切り替え時のみ短いダウンタイムが発生するだけで、サービス全体としては長時間の停止を避けることができます。
5. データ移行
- 活用法: オンプレミスからクラウドへ、あるいは古いサーバーから新しいサーバーへデータベースを移行する際にレプリケーションを利用できます。
- 手順:
- 移行先サーバーにMySQLをセットアップし、移行元サーバーのスレーブとしてレプリケーション設定します。
- レプリケーション遅延が解消され、移行先サーバーが最新の状態になったら、サービスの書き込みを一時的に停止します。
- 移行元と移行先のデータが完全に一致していることを確認します。
- アプリケーションやプロキシの接続先を移行先サーバーに切り替えます。
- サービスの書き込みを再開します。
サービスの停止時間を最小限に抑えたデータ移行が可能になります。
6. 分析/レポーティング専用データベース
- 活用法: 日々の運用で発生するトランザクションを処理するマスターとは別に、スレーブを設置し、そこに分析チームやマーケティングチームなどが利用する集計クエリや複雑なJOINを含むクエリを実行させます。
- 効果: 時間のかかる分析クエリがマスターの性能に影響を与えることを防ぎ、運用系システムの安定性を維持できます。スレーブは読み込み専用であるため、分析担当者は比較的自由にクエリを実行できます。
これらの活用例は、レプリケーションがいかに多目的に利用できる技術であるかを示しています。システムの要件に応じて、これらの活用例を単独で、あるいは組み合わせて利用することで、データベースの能力を最大限に引き出すことができます。
発展的なレプリケーション技術(簡単に触れる)
「超基本」からは少し離れますが、現代のMySQLレプリケーションにおいて重要になってきている技術に少し触れておきます。
GTID (Global Transaction Identifier)
GTIDは、MySQL 5.6以降で導入されたレプリケーションを容易にするための機能です。各トランザクションに対してグローバルに一意な識別子を付与します。
- 利点:
- レプリケーションの開始位置指定が不要になる(ファイル名とポジションではなく、GTIDを指定)。
- スレーブがどのトランザクションまで適用済みかをGTIDで管理するため、マスターの切り替え(フェイルオーバー)やスレーブの交換・追加が非常に容易になる。新しいスレーブはマスターのGTIDセットから自分が持っていないトランザクションを取得するだけで同期できる。
- レプリケーション構成の変更が容易になる。
- 仕組み:
gtid_mode=ON
を設定することで有効になります。各サーバーは自身の実行したトランザクションのGTIDセット(Executed_Gtid_Set
)を持ち、スレーブはマスターのExecuted_Gtid_Set
を取得し、自身のExecuted_Gtid_Set
に含まれないトランザクションをマスターから要求・適用します。 - 注意: GTIDを有効化するには、既存のサーバー環境によっては注意が必要です。GTIDを使用しないサーバーとの間でレプリケーションを混在させる場合は、一時的に特別な設定が必要になります。新規にレプリケーションを構築する場合は、最初からGTIDを有効化することが強く推奨されます。
マルチソースレプリケーション (Multi-Source Replication)
MySQL 5.7以降で利用可能な機能です。1台のスレーブサーバーが、複数のマスターサーバーから同時にレプリケーションを行うことができます。
- 活用例: 複数のShardingされたデータベースのデータを1台のサーバーに集約して分析するなど。
- 仕組み: スレーブ側で複数の
CHANGE MASTER TO
文を実行し、それぞれ異なるマスターIDとリレーログファイル名を指定することで実現します。
Group Replication
前述の同期レプリケーションに関連する技術で、複数ノード間での高可用性と一貫性を目的としたものです。Paxosベースの合意アルゴリズムを使用して、グループ内のすべてのノードでトランザクションが安全にコミットされたことを保証します。Active/PassiveやActive/Active構成を構築できますが、運用には特有の知識が必要です。
これらの発展的な技術は、より高度な要件を持つシステムにおいて有効ですが、まずは基本的な非同期レプリケーションとGTIDを理解することが第一歩となります。
レプリケーションのメリット・デメリットまとめ
最後に、これまでに解説した内容を踏まえ、MySQLレプリケーションのメリットとデメリットをまとめます。
メリット
- 可用性の向上: マスター障害時にもサービス停止時間を最小限に抑えることが可能です。
- 負荷分散: 読み込みクエリをスレーブにオフロードすることで、マスターの負荷を軽減し、全体の処理能力を向上させます。
- バックアップ/リカバリの容易化: マスターに負荷をかけずにバックアップを取得でき、ポイントインタイムリカバリにも利用可能です。
- メンテナンスの容易化: 計画的なバージョンアップやメンテナンス時のダウンタイムを短縮できます。
- データ活用の促進: 分析やレポーティング用のデータベースを分離できます。
- データ移行の効率化: サービス停止時間を短縮してデータ移行が可能です。
デメリット
- レプリケーション遅延: 特に非同期レプリケーションでは、マスターの更新がスレーブに反映されるまでに時間差が生じます。遅延が大きいと、フェイルオーバー時のデータ損失リスクが増加したり、読み込みスレーブで古いデータを参照してしまう問題が発生します。
- 設定と運用の複雑さ: サーバーの追加や削除、エラー発生時の対処など、単一サーバー運用に比べて設定や運用管理の手間が増えます。
- リソース消費: レプリケーションのために複数のサーバーが必要となり、それに応じたハードウェアリソース、ネットワーク帯域、電力、運用コストが発生します。
- データ不整合のリスク: エラー時のスキップや、STATEMENTフォーマット使用時の非決定性などにより、マスターとスレーブ間でデータに不整合が生じる可能性があります。特にマスター・マスター(Active/Active)構成でのコンフリクト管理は非常に困難です。
- 書き込みスケーラビリティの限界: 基本的なマスター・スレーブ構成では、書き込み処理はマスター1台に集中するため、書き込み性能のスケーリングには限界があります(書き込みを分散するにはShardingなどの別の技術が必要です)。
これらのメリットとデメリットを理解した上で、システムの要件に合わせてレプリケーションを適切に設計・導入・運用することが重要です。デメリットを最小限に抑えるためには、準同期レプリケーションやGTIDの利用、並列レプリケーションの活用、そして継続的な監視と定期的な健全性チェックが不可欠です。
まとめ:レプリケーションはデータベース運用の要
この記事では、MySQLレプリケーションの「超基本」として、その概要、仕組み(バイナリログとスレッド)、種類(非同期、準同期)、基本的な構成、そして最低限必要な設定方法を解説しました。さらに、運用における監視とトラブルシューティングのポイント、そしてレプリケーションの多様な活用例についても紹介しました。
レプリケーションは、単にデータベースを複製するだけの機能ではありません。それは、システムの高可用性を実現し、パフォーマンスを向上させ、データの信頼性を高め、そして運用の柔軟性を向上させるための、現代のデータベース運用において必要不可欠な技術です。
確かに、設定や運用には多少の複雑さが伴いますが、そのメリットは計り知れません。特にインターネットに公開されるようなサービスや、基幹システムにおいては、単一障害点となるデータベースを冗長化することがサービスの安定稼働の鍵となります。
まずは基本的なマスター・スレーブ構成で非同期レプリケーションを試してみることから始めましょう。そして、システムの成長や要件の変化に合わせて、準同期レプリケーションへの切り替え、GTIDの導入、並列レプリケーションの有効化、読み込みスレーブの追加、そして最終的にはGroup Replicationのようなより高度なソリューションへとステップアップしていくことが考えられます。
この記事が、あなたがMySQLレプリケーションを理解し、自信を持って導入・運用するための一助となれば幸いです。レプリケーションをマスターし、より堅牢でスケーラブルなデータベースシステムを構築してください。