MySQL 5.6 リファレンスマニュアル  /  ...  /  フェイルオーバー中にマスターを切り替える

17.3.6 フェイルオーバー中にマスターを切り替える

GTID ベースのレプリケーションを使用するときは (セクション17.1.3「グローバルトランザクション識別子を使用したレプリケーション」を参照してください)、障害時に MySQL Utilities で提供される mysqlfailover を使用してマスターとスレーブ間のフェイルオーバーを提供できます。詳細については、mysqlfailover — Automatic replication health monitoring and failoverを参照してください。そうでない場合は、マスターと 1 つ以上のスレーブをセットアップする必要があります。それから、起動しているかどうかを確認するためにマスターをモニターするアプリケーションまたはスクリプトを書いたり、障害時に別のマスターに変更するようにスレーブおよびアプリケーションに指示したりする必要があります。このセクションでは、この方法でフェイルオーバーをセットアップするときに遭遇するいくつかの問題について説明します。

CHANGE MASTER TO ステートメントを使用して、新しいマスターに切り替えるようにスレーブに指示できます。スレーブは、マスター上のデータベースがスレーブ上のものと互換性があるかどうかを確認しません。単に、新しいマスターのバイナリログ内の指定された座標からイベントを読み取って実行するだけです。フェイルオーバーの状況では、グループ内のすべてのサーバーが同じバイナリログファイルから同じイベントを実行するのが一般的であるため、イベントのソースを変更しても、変更を加えるときに注意することで、データベースの構造または完全性に影響を与えないはずです。

スレーブは、--log-bin オプション付き、--log-slave-updates なしで実行するべきです。この方法では、スレーブはスレーブ mysqld を再起動せずにマスターになる準備が整っています。図17.4「レプリケーションを使用する冗長性、初期構造」で示す構造を想定してください。

図 17.4 レプリケーションを使用する冗長性、初期構造

レプリケーションを使用する冗長性、初期構造

この図では、MySQL Master はマスターデータベースを保持し、MySQL Slave ホストはレプリケーションスレーブで、Web Client マシンはデータベース読み取りおよび書き込みを発行しています。読み取りだけを発行する (そして、一般的にスレーブに接続されている) Web クライアントは示されていません。障害時に新しいサーバーに切り替える必要がないためです。読み取り/書き込みスケールアウトレプリケーション構造の詳細例については、セクション17.3.3「スケールアウトのためにレプリケーションを使用する」を参照してください。

各 MySQL Slave (Slave 1Slave 2Slave 3) は、--log-bin 付き、--log-slave-updates なしで動作しているスレーブです。--log-slave-updates が指定されないかぎり、スレーブがマスターから受け取る更新のログはバイナリログに記録されないため、各スレーブ上のバイナリログは最初は空です。何らかの原因により MySQL Master が使用できなくなった場合、スレーブの 1 つを選んで新しいマスターにできます。たとえば、Slave 1 を選択した場合、すべての Web ClientsSlave 1 (そのバイナリログに更新を書き込む) にリダイレクトされるはずです。すると、Slave 2Slave 3Slave 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 SLAVERESET MASTER を発行してください。

ほかのスレーブ Slave 2Slave 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 2Slave 3START SLAVE を実行します。

新しいレプリケーションセットアップが実行されたあと、各 Web Client がそれぞれのステートメントを Slave 1 に送るように指示する必要があります。この時点から、Web Client から Slave 1 に送られるすべての更新ステートメントが Slave 1 のバイナリログに書き込まれます (Master の停止以降に Slave 1 に送られるすべての更新ステートメントが含まれます)。

結果のサーバー構造を図17.5「レプリケーションを使用する冗長性、マスター障害後」に示します。

図 17.5 レプリケーションを使用する冗長性、マスター障害後

レプリケーションを使用する冗長性、マスター障害後

Master がふたたび利用できる状態になったら、それを Slave 1 のスレーブにするべきです。これを実行するには、先ほど Slave 2Slave 3 で発行したものと同じ CHANGE MASTER TO ステートメントを Master で発行します。すると MasterSlave 1 のスレーブになり、オフラインであったときに受け取らなかった Web Client 書き込みを受け取ります。

Master をふたたびマスターにするには (たとえば、これがもっとも強力なマシンであるため)、Slave 1 が利用できない状態で Master が新しいマスターになるように先ほどの手順を使用します。この手順では、MasterSlave 1Slave 2、および Slave 3 を作成する前に、MasterRESET MASTER を実行するのを忘れないでください。これを実行しない場合は、スレーブが Web Client アプリケーションから、Master が利用できなくなった時点より前の古い書き込みを受け取る可能性があります。

スレーブ間の同期がないため (それらが同じマスターを共有していても)、一部のスレーブがほかのものよりかなり進んでしまう可能性があることを承知してください。これは場合によっては、前の例で説明した手順が期待どおりに機能しない可能性があることを意味します。ただし実際には、すべてのスレーブ上のリレーログは互いにかなり近いはずです。

アプリケーションがマスターの場所を常に知っているための 1 つの方法は、マスターの動的 DNS エントリを持つことです。bindnsupdate を使用することで DNS を動的に更新できます。


User Comments
  Posted by Zachary Buckholz on June 8, 2007
Another option instead of dynamic dns is to use a network VIP. Read-Only, Read-Write or Write-Only.

Each MySQL server master and slave(s) have two IPs. The first IP is the server's base IP. The second is a floating IP that can be changed at will.

If the master dies, just assign the IP from the master to one of the slaves.

If the master comes backup, it should check if the floating IP is in use before assigning it back to itself.
  Posted by Marian Marinov on December 3, 2009
You could consider Linux-HA for handling the migration of the Master. There are a lot of people using this software for doing just that.
  Posted by Gavin Towey on December 24, 2009
Zach:

If a master dies and you switch writes to go to one of the slave, you should *never* let the failed master start taking writes again. It would have missed all the updates that happened to the slave, and now you have two copies of the database that need to be merged -- that's a nightmare.

Promoting a slave to master isn't a process that can be reversed. When the failed master comes back up, it's no longer useful. It should be rebuilt as a new slave of the new master.
  Posted by Baron Schwartz on April 26, 2010
Dynamic DNS is not a good way to do anything. DNS is the source of many problems. Use virtual IP addresses and treat DNS as static.
  Posted by Rodolfo Campos on August 19, 2010
I'd many troubles configuring a M->S1->S2 configuration. Here's a cheat sheet that I've made (in spanish):

Replicación Maestro->Esclavo1->Esclavo2 en mySQL
http://camposer-techie.blogspot.com/2010/08/replicacion-maestro-esclavo1-esclavo2.html
  Posted by rajesh karka on February 10, 2011
Hi,

We are going to configure the same configuration in Linux cluster environment So Is there any specific configuration required?


  Posted by Richard Lynch on November 4, 2011
Add a log-bin with the same value to all master/slave[s] my.cnf in the mysqld section if you EVER think you might maybe need the slave to become a master. I think.

The Master Setup [1] has a sample entry. The Slave Setup [2] does not, though it discusses it in the last paragraph for "data backups and crash recovery on the slave, and also use the slave as part of a more complex replication topology (for example, where the slave acts as a master to other slaves)"

I believe the implications are:
Use log-bin on slave if you want backup/recovery
Don't use log-bin on slave if it will NEVER be a master
(Using log-bin adds disk write overhead)

I guess if your only goal is read-only slaves for blinding fast performance, not having log-bin on the slave will save some performance.

But then down the road, when you want to build a tier of
master->>distributed-slave-masters->>>>slaves
You need the log-bin anyway on that middle tier of "branches", so they can replicate to the leaves.

How much overhead does log-bin add, really?

Is it worth never being able to promote a slave to master for disaster recovery or for a complex three-tier topology of distributed "slave-master" in a middle tier? Seems to me that unless the log-bin disk write over head is quite significant, the flexibility of having a slave ready to take over as master is far more beneficial.

NOTE:
I am just puzzling this out for myself as I type this. I could be way off base.

If I am correct, suggested Doc Change:
# comment this out for maximum performance
# penalty: this slave cannot be made master later
log-bin=mysql-bin #MUST match Master log-bin setting

I think that suits the more common use cases, but clearly provides the pro/con for max performance users.
1: http://dev.mysql.com/doc/refman/5.0/en/replication-howto-masterbaseconfig.html

2: http://dev.mysql.com/doc/refman/5.5/en/replication-howto-slavebaseconfig.html#c12063

  Posted by Junho Whang on March 16, 2014
I believe description in this page only applies if all the slaves are at same point in recovery. If all the slaves are at different point in recovery when master fails, then the procedure described will not work. In this case, all the slaves should be running with log_slave_update enabled. So that the most advanced slave is chosen to be new master, the other slaves can be repointed to the new master with "change master" command, and the new master's log will have transactions which have not yet been applied to other slaves.
In this case, the new master should be reset with "reset slave all" not "reset master" since that will lose all the binary log information.
Sign Up Login You must be logged in to post a comment.