web-dev-qa-db-fra.com

Comment vérifier que le secondaire est synchronisé maintenant ou non

il y a la réplique à trois membres (primaire, secondaire, secondaire). Supposons que l'un des secondaires s'arrête pendant une journée, après avoir renvoyé le secondaire à la réplique, comment puis-je trouver, est-il encore synchronisé ou non?

Je l'ai fait dans un environnement de test, mais je n'ai pas pu trouver de données utiles à partir de rs.status() et db.printReplicationInfo().

il y a "longueur du journal du début à la fin" dans db.printReplicationInfo(). mais c'est grand temps par défaut et augmente lorsque le secondaire est en panne.

26
irmorteza

Remarque : Assurez-vous de vérifier la réponse fournie par arcseldon pour un équivalent convivial.

Vous pouvez utiliser la sortie de rs.status(). Si le secondaire est synchronisé et n'a pas été créé avec l'option slaveDelay, alors optime et optimeDate du secondaire doivent être égaux ou proches (s'il y a des opérations en cours) de ceux du primaire. Dans ce cas, stateStr doit être égal à SECONDARY. Donc, si le secondaire est synchronisé, vous devriez voir une sortie similaire à celle-ci (un membre a été supprimé de la sortie pour plus de clarté):

 {
    "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
}

Vous avez ici la sortie de rs.status() pour le même jeu de réplicas si l'un des secondaires n'est pas synchronisé. Tout d'abord, vous verrez que optime et optimeDate pour hostname:27003 Diffère de primaire, stateStr est défini sur RECOVERING et il y a 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
}

Si secondaire a été créé avec slaveDelay alors optime et optimeDate peut être différent mais stateStr et lastHeartbeatMessage indiquera s'il y a un décalage .

30
zero323

Mise à jour du 13 février 2017

Acceptez la réponse acceptée selon laquelle rs.status() offre des informations adéquates et est une commande facile à retenir. Cependant, (personnellement en utilisant Mongo 3 maintenant), j'aime aussi beaucoup la commodité et la lisibilité de rs.printSlaveReplicationInfo() =.

Il donne une sortie quelque chose comme:

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

Comme vous pouvez le voir, il est facile de déterminer si la synchronisation entre les nœuds du jeu de réplicas est saine ou non.

22
arcseldon

J'ai écrit un petit script pour mongoDB Shell. Il montre une différence entre optime et optimeDate. Vous pouvez l'utiliser au lieu de comparer manuellement les membres du jeu de réplicas.

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');
}
1
Andrey Hohutkin