3つのメンバー(プライマリ、セカンダリ、セカンダリ)のレプリカがあります。セカンダリにレプリカを1日戻した後、どのようにして見つけることができますか?同期済みかどうか?
私はテスト環境でそれを行いましたが、rs.status()
とdb.printReplicationInfo()
から有用なデータを見つけることができませんでした。
db.printReplicationInfo()
に「ログの長さの開始から終了」があります。しかし、デフォルトでは大きな時間であり、セカンダリがダウンすると大きくなります。
注:ユーザーフレンドリーな同等物については、 arcseldon によって提供される 答え を必ず確認してください。
rs.status()
の出力を使用できます。セカンダリが同期され、slaveDelay
オプションを使用して作成されていない場合、セカンダリのoptime
およびoptimeDate
は、プライマリと同等または近い(現在の操作がある場合)必要があります。その場合、stateStr
はSECONDARY
と等しくなければなりません。したがって、セカンダリが同期されている場合、次のような出力が表示されます(わかりやすくするために、1つのメンバーが出力から削除されています)。
{
"set" : "rs0",
"date" : ISODate("2013-11-08T14:58:49Z"),
"myState" : 1,
"members" : [
{
"_id" : 0,
"name" : "hostname:27001",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 155,
"optime" : Timestamp(1383915748, 1),
"optimeDate" : ISODate("2013-11-08T13:02:28Z"),
"self" : true
},
{
"_id" : 2,
"name" : "hostname:27003",
"health" : 0,
"state" : 8,
"stateStr" : "SECONDARY",
"uptime" : 0,
"optime" : Timestamp(1383915748, 1),
"optimeDate" : ISODate("2013-11-08T13:02:28Z"),
"lastHeartbeat" : ISODate("2013-11-08T14:58:48Z"),
"lastHeartbeatRecv" : ISODate("2013-11-08T14:58:42Z"),
"pingMs" : 0,
"syncingTo" : "hostname:27001"
}
],
"ok" : 1
}
セカンダリの1つが同期されていない場合、同じレプリカセットのrs.status()
の出力があります。最初に、hostname:27003
のoptime
およびoptimeDate
がprimaryと異なり、stateStrがRECOVERING
に設定され、適切なlastHeartbeatMessage
があることがわかります。
{
"set" : "rs0",
"date" : ISODate("2013-11-08T15:01:34Z"),
"myState" : 1,
"members" : [
{
"_id" : 0,
"name" : "hostname:27001",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 320,
"optime" : Timestamp(1383922858, 767),
"optimeDate" : ISODate("2013-11-08T15:00:58Z"),
"self" : true
},
{
"_id" : 2,
"name" : "hostname:27003",
"health" : 1,
"state" : 3,
"stateStr" : "RECOVERING",
"uptime" : 14,
"optime" : Timestamp(1383915748, 1),
"optimeDate" : ISODate("2013-11-08T13:02:28Z"),
"lastHeartbeat" : ISODate("2013-11-08T15:01:34Z"),
"lastHeartbeatRecv" : ISODate("2013-11-08T15:01:34Z"),
"pingMs" : 0,
"lastHeartbeatMessage" : "still syncing, not yet to minValid optime 527cfc90:19c4",
"syncingTo" : "hostname:27001"
}
],
"ok" : 1
}
セカンダリがslaveDelay
で作成されている場合、optime
とoptimeDate
は異なる場合がありますが、stateStr
とlastHeartbeatMessage
は、ラグがあるかどうかを示します。
2017年2月13日更新
rs.status()
は適切な情報を提供し、覚えやすいコマンドであるという受け入れられた答えに同意します。ただし、(個人的にMongo 3を使用)、 rs.printSlaveReplicationInfo()
の便利さと読みやすさも本当に好きです=。
次のような出力が得られます。
rs.printSlaveReplicationInfo()
source: node-2:27017
syncedTo: Mon Feb 13 2017 06:15:17 GMT-0500 (EST)
0 secs (0 hrs) behind the primary
source: node-3:27017
syncedTo: Mon Feb 13 2017 06:15:16 GMT-0500 (EST)
1 secs (0 hrs) behind the primary
ご覧のとおり、レプリカセット内のノード間の同期が正常かどうかを簡単に把握できます。
MongoDB Shell用の小さなスクリプトを書きました。 optimeとoptimeDateの差分が表示されます。レプリカセットメンバーを手動で比較する代わりに使用できます。
var isMaster = rs.isMaster();
var me = isMaster.me;
if(!isMaster.ismaster && isMaster.secondary)
{
var status = rs.status();
var master = isMaster.primary;
var masterOptime = 0;
var masterOptimeDate = 0;
var myOptime = 0;
var myOptimeDate = 0;
for(var i = 0 ; i < status.members.length ; i++)
{
var member = status.members[i];
if(member.name == me)
{
if(member.stateStr == "SECONDARY") {
myOptime = member.optime.getTime();
myOptimeDate = member.optimeDate.getTime();
}
else
{
print(me + ' is out of sync ' + member.stateStr);
break;
}
}
else if(member.name == master)
{
masterOptime = member.optime.getTime();
masterOptimeDate = member.optimeDate.getTime();
}
}
if(myOptime && myOptimeDate)
{
var optimeDiff = masterOptime - myOptime;
var optimeDateDiff = masterOptimeDate - myOptimeDate;
print('optime diff: ' + optimeDiff);
print('optimeDate diff: ' + optimeDateDiff);
}
}
else
{
print(me + ' is not secondary');
}