matsukaz's blog

Agile, node.js, ruby, AWS, cocos2d-xなどなどいろいろやってます

MongoDBでReplicaSetをaddShardする際の注意点

MongoDB 1.6.5で発生した問題です。それ以外のバージョンで発生するかは不明です。

公式サイトのAdding shardsにて、ReplicaSetをShardとして追加する場合は、replicaSetName/[:port][,serverhostname2[:port],...], というコマンドで少なくとも1つのサーバを指定するようにと説明されてます。

> db.runCommand( { addshard : "foo/<serverhostname>[:<port>]" } );

1つ指定すれば、あとで勝手に他のサーバも追加してくれる、という仕様みたい。実際、以前はそれでうまくいきました。

use config;
db.shards.find();
{ "_id" : "shard1", "host" : "shard1/xx.xx.xx.xx:27018,xx.xx.xx.xx:27018,xx.xx.xx.xx:27018" }

が、あるときから1つ指定しただけだと他のサーバが追加されないケースが。

use config;
db.shards.find();
{ "_id" : "shard1", "host" : "shard1/xx.xx.xx.xx:27018,xx.xx.xx.xx:27018,xx.xx.xx.xx:27018" }
{ "_id" : "shard2", "host" : "shard2/xx.xx.xx.xx:27018" }

普段の動作は問題ないですが、もしShard2の該当サーバが落ちると、ReplicaSetなのに他のサーバにつなぎにいってくれない状況になります。ReplicaSetをShardに登録する場合は、3つのサーバを指定する方が安全そう。

もし上記の問題が発生した場合は、全てのmongosを落とした後に、全てのmongocにログインしてそれぞれ以下のコマンドでconfig情報を更新、その後mongoc→mongosと再起動すれば復活出来ました。

use config
db.shards.update({_id:"shard2"},{host:"shard2/xx.xx.xx.xx::27018,xx.xx.xx.xx::27018,xx.xx.xx.xx::27018"});

ちなみに、サーバをカンマ区切りで複数指定する場合に、間に空白とか入れると正しく動作しないのでご注意を。若干ハマりました。