DBサーバが止まるとサービス全体が止まる。アプリサーバは冗長化できても、DBがシングルポイントになっているケースは多い。
MySQLレプリケーションはDBの可用性を高めるための基本技術で、AWSのRDS Multi-AZやAurora Read Replicaもこの仕組みの上に成り立っている。
レプリケーションの仕組み
MySQLのレプリケーションはバイナリログを使った非同期コピーだ。
マスタ スレーブ
┌──────────────┐ ┌──────────────┐
│ 書き込み処理 │ │ 読み取り処理 │
│ │ │ │
│ バイナリログ │──────────→ │ リレーログ │
│ (binlog) │ I/Oスレッド │ (relaylog) │
└──────────────┘ │ │
│ SQLスレッド │
│ (再生) │
└──────────────┘
- マスタでデータ変更が発生するとバイナリログに記録される
- スレーブのI/Oスレッドがバイナリログを受け取りリレーログに書き込む
- スレーブのSQLスレッドがリレーログを再生してデータを更新する
非同期のため、スレーブはマスタより少し遅れる(レプリケーション遅延)。
シングルマスタ・マルチスレーブ構成
標準的な構成は1台のマスタと複数のスレーブだ。
[アプリサーバ]
/ \
書き込み 読み取り
↓ ↓
[マスタDB] ──→ [スレーブDB × N]
マスタ: 書き込み専用(INSERT・UPDATE・DELETE) スレーブ: 読み取り専用(SELECT)。複数台で読み取り負荷を分散する。
設定の基本(MySQL 8.0)
-- マスタ側の設定(my.cnf)
[mysqld]
server-id = 1
log-bin = mysql-bin
binlog-format = ROW # 推奨: ROW形式(行ベースのレプリケーション)
-- レプリケーション用ユーザを作成
CREATE USER 'repl'@'%' IDENTIFIED WITH mysql_native_password BY 'password';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
-- スレーブ側の設定(my.cnf)
[mysqld]
server-id = 2
relay-log = relay-bin
read-only = 1 # スレーブへの誤った書き込みを防ぐ
-- レプリケーション開始(MySQL 8.0+)
CHANGE REPLICATION SOURCE TO
SOURCE_HOST='master-host',
SOURCE_USER='repl',
SOURCE_PASSWORD='password',
SOURCE_AUTO_POSITION=1; # GTIDを使った自動ポジション管理
START REPLICA;
-- レプリケーション状態確認
SHOW REPLICA STATUS\G
-- Replica_IO_Running: Yes ← I/Oスレッドが動いているか
-- Replica_SQL_Running: Yes ← SQLスレッドが動いているか
-- Seconds_Behind_Source: 0 ← 遅延秒数(0が理想)
レプリケーション遅延への対策
非同期レプリケーションの弱点は遅延だ。書き込み直後にスレーブから読み取ると古いデータが返ることがある。
// アプリ側での対処パターン
// パターン1: 書き込み後の読み取りはマスタから
async function updateAndRead(userId: number, data: UpdateInput) {
await masterDb.update(userId, data);
// スレーブから読まずにマスタから読む
return masterDb.findOne(userId);
}
// パターン2: セッションに「最近書き込んだ」フラグを立てる
// 書き込み後N秒間はマスタ参照にする
半同期レプリケーション(MySQL 5.5+): 少なくとも1台のスレーブがバイナリログを受け取るまでコミットを待つ。データ損失を防ぐが書き込みのレイテンシが上がる。
フェイルオーバー設計
マスタが故障したとき、スレーブをマスタに昇格させる手順だ。
# 1. 故障したマスタへの接続を切断
# 2. スレーブの遅延を確認(全スレーブが追いついているか)
SHOW REPLICA STATUS\G -- Seconds_Behind_Source が 0 になるまで待つ
# 3. スレーブをマスタに昇格
STOP REPLICA;
RESET REPLICA ALL;
# 4. アプリの接続先を新マスタに切り替え
# VIP(仮想IP)を使っていれば切り替えを透過的にできる
手動フェイルオーバーは時間がかかるため、MySQL RouterやMHA for MySQLなどの自動フェイルオーバーツールを使うのが実務では一般的だ。
AWSでのマネージド対応
オンプレでMySQLレプリケーションを手動で管理する代わりに、AWSのマネージドサービスを使うことで運用コストを大幅に削減できる。
RDS Multi-AZ
プライマリ(書き込み・読み取り)
↕ 同期レプリケーション
スタンバイ(フェイルオーバー用)
- 同期レプリケーション: データ損失ゼロ
- 自動フェイルオーバー: 障害検知から60〜120秒でエンドポイントが切り替わる
- スタンバイは通常は読み取りに使えない(フェイルオーバー専用)
Aurora Read Replica
Auroraクラスター(共有ストレージ)
├── Writer(書き込み専用エンドポイント)
├── Reader 1(読み取り)
└── Reader 2(読み取り)
- 共有ストレージ: レプリカラグがほぼゼロ(ストレージレイヤーで同期)
- 最大15台のRead Replicaを追加可能
- フェイルオーバー時間: 約30秒(RDS Multi-AZより高速)
- 読み取り用エンドポイントで複数リーダーへ自動分散
比較
| 構成 | 遅延 | フェイルオーバー | 読み取り分散 | コスト |
|---|---|---|---|---|
| MySQL レプリケーション(手動) | 非同期 | 手動 | ◎ | 安い(要運用コスト) |
| RDS Multi-AZ | 同期 | 自動(〜120秒) | ❌ | 中 |
| Aurora + Read Replica | ほぼゼロ | 自動(〜30秒) | ◎ | 高い |
まとめ
MySQLレプリケーションの設計原則:
- マスタ1台・スレーブN台が基本構成
- 読み取り専用クエリはスレーブへ分散する
- 書き込み後即時読み取りはマスタから(レプリケーション遅延対策)
- フェイルオーバー手順を事前に決めておく
- AWSならRDS Multi-AZかAurora + Read Replicaで運用負荷を下げる
レプリケーションの設計思想はサーバ/インフラを支える技術の2章で詳しく解説されている。