レプリケーションを構成した場合、レプリケーションは常にオンラインにしておくための冗長化技術なのでサーバーすべてをシャットダウンすることはそうそうありません。ただ、サーバーをすべて停止してそこから開始する場合もあるだろうと思って手順を調べてみました。

検証環境

  • MongoDB 2.6.4
  • Windows Server 2012R2

検証環境では1つのWindowsサーバー上に3つのMongoDBインスタンスを起動して構成したレプリケーション環境で実行しています。

また、最初に参考にしたURLを掲載しておきます。

- replSetFreeze コマンドと (rs.freeze())
http://docs.mongodb.org/manual/reference/command/replSetFreeze/
- rs.stepDown()
http://docs.mongodb.org/manual/reference/command/replSetStepDown/#dbcmd.replSetStepDown
- [mongodb-user] Shutdown, startup order for replica set?
http://grokbase.com/t/gg/mongodb-user/11b46wv0j2/shutdown-startup-order-for-replica-set

今回使用する方法では replSetFreeze (もしくは rs.freeze()) コマンドで レプリカセットをフリーズし、フェールオーバーが発生しないようにします。そのあとに、 rs.stepDown()コマンドで プライマリレプリカセットを セカンダリにステップダウンしたあと、各サーバーを停止します。停止するまでにプライマリの選択(election)が始まらないように replSetFreeze には十分大きな値を設定する必要があります。

それでは手順を簡単に記載していきます。

本記事では 3台構成(プライマリ、セカンダリ、アービター)でレプリケーションが構成されていることとします。また、接続に使用しているインスタンスの情報は環境に合わせて適宜読み替えてください。

1. レプリケーションのすべてのサーバーを停止

1.1.セカンダリ(Secondary), アービター (arbiter) に接続して replSetFreeze コマンドを実行

クライアントシェルから セカンダリ―に接続して、次のようなコマンドで プライマリの選択を一定期間(秒)行わないようにします。

.\mongo.exe localhost:40001
>use admin
use admin
>db.runCommand({replSetFreeze:360})
{ "ok" : 1 }

同じように アービターのMongoDBインスタンスに接続して、 replSetFreeze コマンドを実行します。今回は rs.freeze() コマンドを使用しています。

.\mongo.exe localhost:40002
>rs.freeze(360)
{ "ok" : 1 }

1.2. プライマリレプリカセットをセカンダリにステップダウンする

シェルプログラムを起動して、PRIMARYレプリカセットにインスタンスに接続します。下例のように rs.stepDown() コマンドを実行します。

.\mongo.exe localhost:40000
rs.stepDown(60)

別のオプションとして 下例のように replSetStepDown コマンドを実行する方法もあります。

use admin
db.runCommand({replSetStepDown:60})

いずれの方法を行うにせよ、 60 秒 をタイムアウト時間に指定して PRIMARYのレプリカセットを SECONDARY にステップダウンします。replSetFreeze を実行したのでフェールオーバーは発生しません。

今の状態で すべてのインスタンスが SECONDARY もしくは ARBITER になっています。rs.status()やdb.isMaster() を使用してみてください。

1.3.サーバーを停止

後は各サーバーに接続して シャットダウンします。下例が一例です。

>use admin
>db.shutdownServer()

2. レプリケーションの起動

すべてのサーバーを停止した状態でレプリケーションを開始します。PRIMARYに昇格しないように設定した後にPRIMARY用のインスタンスを起動していきます。

ARBITER を起動して 次のコマンドを実行します。

rs.freeze(360)

SECONDARY とするインスタンスも起動して同じように rs.freeze() コマンドを実行します。

rs.freeze(360)

これで指定した秒数間 セカンダリレプリカセットがプライマリに選出されなくなります。

あとは PRIMARY 用のインスタンスを起動します。セカンダリにするつもりだったインスタンスがPRIMARYになっていた場合は rs.stepDown() でSECONDARYに戻すことができます。