こんにちは、かつコーチです。
「インデックス・パフォーマンス編」が完結し、今回からは「レプリケーション・バックアップ編」です。
1本目のテーマは、複数のMySQLサーバー間でデータを複製するレプリケーションの仕組みとメリットです。
上級者向けの内容として、レプリケーションを支える裏側の仕組みまで踏み込んで解説します。
レプリケーションとは
1台のMySQLで運用する限界
小規模なサービスでは1台のMySQLサーバーで十分ですが、サービスが成長すると次のような課題が出てきます。
- 読み取りクエリが増え、1台のCPU・I/Oでは捌ききれなくなる
- サーバーがダウンすると、サービス全体が停止してしまう
- バックアップ取得中にサーバーへの負荷が跳ね上がる
レプリケーションは、マスター(ソース)と呼ばれる元のサーバーのデータを、レプリカ(スレーブ)と呼ばれる別サーバーに複製し続けることで、これらの課題に対応する仕組みです。
レプリケーションで得られる主なメリット
- 読み取り負荷の分散:参照系クエリをレプリカに振り分け、マスターの負荷を下げる
- 可用性の向上:マスターに障害が起きた際、レプリカを昇格させて切り替えられる
- バックアップの分離:レプリカ側でバックアップを取得し、マスターへの負荷を避けられる
特に読み取りが多いサービスでは、アプリケーション側で書き込みはマスターへ、参照はレプリカへ振り分ける構成が定番です。
レプリケーションの仕組み
バイナリログを起点にした非同期の複製
MySQLレプリケーションの中核にあるのがバイナリログ(binlog)で、マスター上でのデータ変更(INSERT・UPDATE・DELETEなど)をすべて記録するログファイルです。
複製の流れは次のようになります。
- マスターがデータ変更をバイナリログに書き込む
- レプリカの
IOスレッドがマスターのバイナリログを読み取り、自身のリレーログに書き込む - レプリカの
SQLスレッドがリレーログの内容を再生し、レプリカのデータに反映する
-- マスター側:レプリケーション用ユーザーを作成
CREATE USER 'repl_user'@'%' IDENTIFIED WITH mysql_native_password BY 'strong_password';
GRANT REPLICATION SLAVE ON *.* TO 'repl_user'@'%';
-- マスターのバイナリログ状態を確認
SHOW MASTER STATUS;
-- レプリカ側:マスターへの接続情報を設定して開始する
CHANGE REPLICATION SOURCE TO
SOURCE_HOST = '192.168.1.10',
SOURCE_USER = 'repl_user',
SOURCE_PASSWORD = 'strong_password',
SOURCE_LOG_FILE = 'binlog.000123',
SOURCE_LOG_POS = 4;
START REPLICA;
-- レプリケーションの状態を確認
SHOW REPLICA STATUS\G
MySQL 8.0.23以降では、旧来のMASTER/SLAVEという用語がSOURCE/REPLICAに置き換わっており、CHANGE MASTER TOはCHANGE REPLICATION SOURCE TOに変更されています。
非同期・準同期・GTIDレプリケーション
レプリケーションには、マスターへの反映タイミングによって主に2種類の方式があります。
| 方式 | 特徴 |
|---|---|
| 非同期レプリケーション | マスターはレプリカへの反映を待たずコミットを返す。デフォルト方式で高速だが、障害時にレプリカへ未反映のデータが失われる可能性がある |
| 準同期レプリケーション | 最低1台のレプリカがログを受信するまでマスターがコミットを待つ。データ損失リスクを下げられるがレイテンシは増える |
また、バイナリログの位置(ファイル名+オフセット)ではなく、トランザクションごとに一意なIDで管理するGTID(Global Transaction Identifier)を使うと、フェイルオーバー時の再接続やポジション管理が簡単になります。
-- GTIDベースのレプリケーションで再接続する例
CHANGE REPLICATION SOURCE TO
SOURCE_HOST = '192.168.1.10',
SOURCE_USER = 'repl_user',
SOURCE_PASSWORD = 'strong_password',
SOURCE_AUTO_POSITION = 1;
SOURCE_AUTO_POSITION = 1を指定すると、GTIDをもとにMySQLが自動的に再開位置を判断してくれるため、旧来のSOURCE_LOG_FILE・SOURCE_LOG_POSを手動指定する必要がなくなります。
レプリケーション運用の注意点
レプリケーション遅延という現実
非同期レプリケーションでは、マスターへの書き込みからレプリカへの反映までにレプリケーション遅延(レプリカラグ)が発生します。
「注文直後にレプリカから注文情報を参照したら、まだ反映されておらず見つからなかった」という不整合は、レプリケーションを使う構成で典型的に起こる問題です。
-- レプリカの遅延秒数を確認する
SHOW REPLICA STATUS\G
-- Seconds_Behind_Source の値を確認する
書き込み直後に同じデータを参照する処理は、レプリカではなくマスターに向けるなど、アプリケーション側での考慮が必要になります。
私がレプリカラグに気づかず障害対応した話
以前、決済完了直後に注文詳細ページへリダイレクトする処理で、参照系クエリをすべてレプリカに向けていたところ、「決済したのに注文が見つからない」という問い合わせが散発的に発生したことがありました。
SHOW REPLICA STATUSのSeconds_Behind_Sourceを確認すると、ピーク時間帯に1〜2秒の遅延が発生しており、決済直後のリダイレクト先だけがその遅延の影響をもろに受けていました。
対応として、決済直後の注文詳細取得だけはマスターから読む処理に変更し、それ以外の一覧参照はレプリカのままにすることで、負荷分散のメリットを保ちながら不整合を解消しました。
「レプリケーションは常に一貫性のあるデータを返す」という思い込みが原因だった失敗で、非同期レプリケーションを使う以上、遅延は前提として設計すべきだと学んだ経験です。
まとめ
この記事のポイント
- レプリケーションはマスターのデータをレプリカへ複製する仕組みで、負荷分散・可用性向上・バックアップ分離に役立つ
- 複製はバイナリログを起点に、IOスレッドとSQLスレッドを介して非同期に行われる
- MySQL 8.0.23以降は
SOURCE/REPLICA用語に統一され、GTIDとSOURCE_AUTO_POSITIONで再接続が簡単になる - 非同期レプリケーションではレプリケーション遅延が発生し、書き込み直後の参照はマスターに向けるなどの設計配慮が必要
次に読むべき記事
次回は「mysqldumpでバックアップ・リストアする方法」です。
レプリケーションと並んで重要な、データ保護のもう1つの柱であるバックアップについて解説します。
タグ: MySQL, 上級者向け, レプリケーション