マスターと 1 つ以上のスレーブをセットアップする必要があります。それから、起動しているかどうかを確認するためにマスターをモニターするアプリケーションまたはスクリプトを書いたり、障害時に別のマスターに変更するようにスレーブおよびアプリケーションに指示したりする必要があります。このセクションでは、この方法でフェイルオーバーをセットアップするときに遭遇するいくつかの問題について説明します。
CHANGE MASTER TO
ステートメントを使用して、新しいマスターに切り替えるようにスレーブに指示できます。スレーブは、マスター上のデータベースがスレーブ上のものと互換性があるかどうかを確認しません。単に、新しいマスターのバイナリログ内の指定された座標からイベントを読み取って実行するだけです。フェイルオーバーの状況では、グループ内のすべてのサーバーが同じバイナリログファイルから同じイベントを実行するのが一般的であるため、イベントのソースを変更しても、変更を加えるときに注意することで、データベースの構造または完全性に影響を与えないはずです。
スレーブは、--log-bin
オプション付き、--log-slave-updates
なしで実行するべきです。この方法では、スレーブはスレーブ mysqld を再起動せずにマスターになる準備が整っています。図17.4「レプリケーションを使用する冗長性、初期構造」で示す構造を想定してください。
この図では、MySQL Master
はマスターデータベースを保持し、MySQL Slave
ホストはレプリケーションスレーブで、Web Client
マシンはデータベース読み取りおよび書き込みを発行しています。読み取りだけを発行する (そして、一般的にスレーブに接続されている) Web クライアントは示されていません。障害時に新しいサーバーに切り替える必要がないためです。読み取り/書き込みスケールアウトレプリケーション構造の詳細例については、セクション17.3.3「スケールアウトのためにレプリケーションを使用する」を参照してください。
各 MySQL Slave (Slave 1
、Slave 2
、Slave 3
) は、--log-bin
付き、--log-slave-updates
なしで動作しているスレーブです。--log-slave-updates
が指定されないかぎり、スレーブがマスターから受け取る更新のログはバイナリログに記録されないため、各スレーブ上のバイナリログは最初は空です。何らかの原因により MySQL Master
が使用できなくなった場合、スレーブの 1 つを選んで新しいマスターにできます。たとえば、Slave 1
を選択した場合、すべての Web Clients
を Slave 1
(そのバイナリログに更新を書き込む) にリダイレクトされるはずです。すると、Slave 2
と Slave 3
は Slave 1
から複製されるはずです。
--log-slave-updates
なしでスレーブを実行する理由は、スレーブの 1 つを新しいマスターにしたために、スレーブが更新を 2 回受け取らないようにすることです。Slave 1
は、その --log-slave-updates
が有効である場合は、Master
から受け取る更新を自身のバイナリログに書き込みます。これは、Slave 2
のマスターが Master
から Slave 1
に変更されると、Slave 1
がすでに Master
から受け取っていた更新を受け取る可能性があることを意味します。
すべてのスレーブがそれぞれのリレーログ内のステートメントを処理したことを確認してください。各スレーブで STOP SLAVE IO_THREAD
を発行して、Has read all relay log
を見るまで SHOW PROCESSLIST
の出力をチェックしてください。これがすべてのスレーブで true のときは、それらを新しいセットアップに再構成できます。昇格してマスターになるスレーブ Slave 1
では、STOP SLAVE
と RESET MASTER
を発行してください。
ほかのスレーブ Slave 2
と Slave 3
では、STOP SLAVE
および CHANGE MASTER TO MASTER_HOST='Slave1'
を使用します (ここで、'Slave1'
は Slave 1
の実際のホスト名を表します)。CHANGE MASTER TO
を使用するには、Slave 2
または Slave 3
から Slave 1
に接続する方法に関するすべての情報 (ユーザー
、パスワード
、ポート
) を追加してください。ここで CHANGE MASTER TO
ステートメントを発行するときは、Slave 1
バイナリログファイルの名前、または読み取るログ位置を指定する必要はありません (最初のバイナリログファイルおよび位置 4 がデフォルトです)。最後に、Slave 2
と Slave 3
で START SLAVE
を実行します。
新しいレプリケーションセットアップが実行されたあと、各 Web Client
がそれぞれのステートメントを Slave 1
に送るように指示する必要があります。この時点から、Web Client
から Slave 1
に送られるすべての更新ステートメントが Slave 1
のバイナリログに書き込まれます (Master
の停止以降に Slave 1
に送られるすべての更新ステートメントが含まれます)。
結果のサーバー構造を図17.5「レプリケーションを使用する冗長性、マスター障害後」に示します。
Master
がふたたび利用できる状態になったら、それを Slave 1
のスレーブにするべきです。これを実行するには、先ほど Slave 2
と Slave 3
で発行したものと同じ CHANGE MASTER TO
ステートメントを Master
で発行します。すると Master
が Slave 1
のスレーブになり、オフラインであったときに受け取らなかった Web Client
書き込みを受け取ります。
Master
をふたたびマスターにするには (たとえば、これがもっとも強力なマシンであるため)、Slave 1
が利用できない状態で Master
が新しいマスターになるように先ほどの手順を使用します。この手順では、Master
の Slave 1
、Slave 2
、および Slave 3
を作成する前に、Master
で RESET MASTER
を実行するのを忘れないでください。これを実行しない場合は、スレーブが Web Client
アプリケーションから、Master
が利用できなくなった時点より前の古い書き込みを受け取る可能性があります。
スレーブ間の同期がないため (それらが同じマスターを共有していても)、一部のスレーブがほかのものよりかなり進んでしまう可能性があることを承知してください。これは場合によっては、前の例で説明した手順が期待どおりに機能しない可能性があることを意味します。ただし実際には、すべてのスレーブ上のリレーログは互いにかなり近いはずです。
アプリケーションがマスターの場所を常に知っているための 1 つの方法は、マスターの動的 DNS エントリを持つことです。bind
で nsupdate
を使用することで DNS を動的に更新できます。