2017-01-31 6 views
0

La plupart des directives recommandent d'utiliser mongodump/mongorestore, mais pour les grandes bases de données de produits les temps d'arrêt peuvent être très longsComment migrer d'MMAPv1 à WiredTiger avec un minimum de temps sans mongodump/mongorestore

+0

Est-ce une question? – Oisin

+0

Veuillez utiliser le format Q & A de Stack Overflow: Séparez la question et la réponse (éditez votre question, supprimez la réponse, puis ajoutez-la comme réponse - vous pouvez ajouter la réponse à votre propre question.) – Steeve

+0

Merci. Je l'ai corrigé –

Répondre

0

Vous pouvez utiliser la réplication et un serveur supplémentaire pour ce ou le même serveur si la charge le permet.

  1. Vous devez 3 en cours d'exécution par exemple MongoDB:

    • Votre serveur que vous souhaitez mettre à jour (rappeler que le soutien de WiredTiger depuis 3.0).
    • Deuxième instance de MongoDB pouvant être exécutée sur un serveur supplémentaire. La base de données sera temporairement copiée par la réplication.
    • Et la troisième instance de MongoDB est arbitre, qui ne stocke pas de données et participe uniquement à l'élection du serveur principal. L'arbitre peut être exécuté sur le serveur supplémentaire sur un port distinct.
  2. De toute façon, vous devez sauvegarder votre base de données. Vous pouvez exécuter "mongodump" sans paramètres et le répertoire "./dump" sera créé avec le vidage de la base de données. Vous pouvez utiliser le paramètre "--gzip" pour compresser la taille du résultat.

    mongodump --gzip 
    

    Juste au cas où, la commande pour restaurer:

    mongorestore --gzip 
    

    Il doit être exécuté dans le même répertoire où le paramètre « ./dump » dir et « --gzip » devrait être ajouté si utilisé dans "mongodump".

  3. Commencer la configuration à partir du serveur supplémentaire. Mon système cible est Linux RedHat sans Internet, donc je télécharge et installe MongoDB via RPM manuellement. Ajouter la section à /etc/mongod.conf:

    replication: 
        oplogSizeMB: 10240 
        replSetName: REPLICA 
    

    Vérifiez que la section nette ressembler à ceci pour permettre l'accès d'autres serveurs:

    net: 
        bindIp: 0.0.0.0 
        port: 27017 
    

    et exécuter:

    service mongod start 
    
  4. Exécutez la troisième instance MongoDB - arbitre. Il peut fonctionner sur le serveur supplémentaire sur un port différent. Créez un répertoire temporaire pour la base de données d'arbitre:

    mkdir /tmp/mongo 
    chmod 777 -R /tmp/mongo 
    

    et exécutez:

    mongod --dbpath /tmp/mongo --port 27001 --replSet REPLICA \ 
        --fork --logpath /tmp/mongo/db1.log 
    
  5. configurer maintenant le serveur principal. Editez/etc/mongod. conf

    replication: 
        oplogSizeMB: 10240 
        replSetName: REPLICA 
    

    et redémarrez MongoDB sur le serveur principal:

    service mongod restart 
    
  6. Il est important! Après le redémarrage du serveur principal, les opérations de lecture peuvent être indisponibles. Je recevais l'erreur suivante:

    { "ok" : 0, "errmsg" : "node is recovering", "code" : 13436 } 
    

    Alors aussi rapidement que possible, vous devez vous connecter à MongoDB sur le serveur principal via la console « mongo » et exécutez la commande suivante pour configurer la réplication:

    rs.initiate(
    { 
        _id: "REPLICA", 
        members: [ 
        { _id: 0, host : "<IP address of main server>:27017", 
           priority: 1.0 }, 
        { _id: 1, host : "<IP address of additional server>:27017", 
           priority: 0.5 }, 
        { _id: 2, host : "<IP address of additional server(the arbiter)>:27001", 
           arbiterOnly : true, priority: 0.5 } 
        ] 
    } 
    ) 
    

    Après cette opération, toutes les actions avec MongoDB seront disponibles et la synchronisation des données commencera.

    Je ne recommande pas d'utiliser rs.initiate() sur le serveur principal sans paramètres comme dans la plupart des tutoriels, parce que le nom du serveur principal sera configuré par défaut comme nom DNS du /etc/nom d'hôte. Ce n'est pas très pratique pour moi car j'utilise des adresses IP pour les communications dans mes projets.

    Pour vérifier la progression de la synchronisation, vous pouvez appeler à partir de la console « mongo »:

    rs.status() 
    

    exemple de résultats:

    { 
        "set" : "REPLICA", 
        "date" : ISODate("2017-01-19T14:30:34.292Z"), 
        "myState" : 1, 
        "term" : NumberLong(1), 
        "heartbeatIntervalMillis" : NumberLong(2000), 
        "members" : [ 
         { 
          "_id" : 0, 
          "name" : "<IP address of main server>:27017", 
          "health" : 1.0, 
          "state" : 1, 
          "stateStr" : "PRIMARY", 
          "uptime" : 165, 
          "optime" : { 
           "ts" : Timestamp(6377323060650835, 3), 
           "t" : NumberLong(1) 
          }, 
          "optimeDate" : ISODate("2017-01-19T14:30:33.000Z"), 
          "infoMessage" : "could not find member to sync from", 
          "electionTime" : Timestamp(6377322974751490, 1), 
          "electionDate" : ISODate("2017-01-19T14:30:13.000Z"), 
          "configVersion" : 1, 
          "self" : true 
         }, 
         { 
          "_id" : 1, 
          "name" : "<IP address of additional server>:27017", 
          "health" : 1.0, 
          "state" : 5, 
          "stateStr" : "STARTUP2", 
          "uptime" : 30, 
          "optime" : { 
           "ts" : Timestamp(0, 0), 
           "t" : NumberLong(-1) 
          }, 
          "optimeDate" : ISODate("1970-01-01T00:00:00.000Z"), 
          "lastHeartbeat" : ISODate("2017-01-19T14:30:33.892Z"), 
          "lastHeartbeatRecv" : ISODate("2017-01-19T14:30:34.168Z"), 
          "pingMs" : NumberLong(3), 
          "syncingTo" : "<IP address of main server>:27017", 
          "configVersion" : 1 
         }, 
         { 
          "_id" : 2, 
          "name" : "<IP address of additional server (the arbiter)>:27001", 
          "health" : 1.0, 
          "state" : 7, 
          "stateStr" : "ARBITER", 
          "uptime" : 30, 
          "lastHeartbeat" : ISODate("2017-01-19T14:30:33.841Z"), 
          "lastHeartbeatRecv" : ISODate("2017-01-19T14:30:30.158Z"), 
          "pingMs" : NumberLong(0), 
          "configVersion" : 1 
         } 
        ], 
        "ok" : 1.0 
    } 
    

    Après « stateStr » du serveur supplémentaire sera remplacé de "STARTUP2" à "SECONDAIRE", nos serveurs sont synchronisé.

  7. Pendant que nous attendons la fin de la synchronisation, il est nécessaire de modifier un peu les applications client pour qu'elles puissent fonctionner avec tous les serveurs de la réplique.

    • Si vous utilisez le ConnectionString, vous devez le remplacer par quelque chose comme:

      mongodb://<IP address of main server>:27017,<IP address of additional server>:27017,<IP address of additional server (the arbiter)>:27001/?replicaSet=REPLICA 
      
    • Si vous utilisez C de l'héritage mongo-cxx-pilote, comme je suis, vous devez utiliser mongo :: DBClientReplicaSet à la place mongo :: DBClientConnection et liste les trois serveurs dans les paramètres de connexion, y compris l'arbitre.

    • Il y a une troisième option - vous pouvez simplement changer IP du serveur MongoDB dans les clients après la mise PRIMAIRE-SECONDAIRE, mais ce n'est pas très juste.

  8. Une fois la synchronisation est terminée et un statut de serveur supplémentaire est établi comme SECONDAIRE, nous devons changer la PRIMAIRE et SECONDAIRE en exécutant la commande dans la console « mongo » sur la serveur principal. Ceci est important car la commande ne fonctionnera pas sur le serveur supplémentaire.

    cfg = rs.conf() 
    cfg.members[0].priority = 0.5 
    cfg.members[1].priority = 1 
    cfg.members[2].priority = 0.5 
    rs.reconfig(cfg) 
    

    Ensuite, vérifier l'état du serveur en exécutant:

    rs.status() 
    
  9. Arrêtez le MongoDB sur le serveur principal

    service mongod stop 
    

    et supprimer simplement le contenu d'un répertoire avec base de données. C'est sûr, parce que nous avons une copie de travail sur le serveur supplémentaire, et au début nous avons fait une sauvegarde. Faites attention. MongoDB ne crée pas de répertoire de base de données lui-même. Si vous avez supprimé, vous devez non seulement pour restaurer

    mkdir /var/lib/mongo 
    

    et propriétaire configuration:

    chown -R mongod:mongod /var/lib/mongo 
    
  10. Vérifiez moteur de stockage wiredTiger est configuré en /etc/mongod.conf. De 3.2, il est utilisé par défaut:

    storage: 
        ... 
        engine: wiredTiger 
        ... 
    

    et exécuter MongoDB:

    service mongod start 
    

    Le serveur principal obtenir la configuration du serveur secondaire automatiquement et les données seront synchronisées sur le stockage WiredTiger. Une fois la synchronisation terminée, réactivez le serveur PRIMARY. Cette opération doit être effectuée sur un serveur supplémentaire car il s'agit du PRIMARY maintenant.

    cfg = rs.conf() 
    cfg.members[0].priority = 1 
    cfg.members[1].priority = 0.5 
    cfg.members[2].priority = 0.5 
    rs.reconfig(cfg) 
    
  11. Retour l'ancienne version des clients de base de données ou modifier ConnectionString retour.

  12. Maintenant, désactivez la réplication si nécessaire. Retirer 2 serveurs de réplication du serveur principal:

    rs.remove("<IP address of additional server>:27017") 
    rs.remove("<IP address of additional server (the arbiter)>:27001") 
    

    Enlever tous section « réplication » de /etc/mongod.conf et redémarrez MongoDB:

    service mongod restart 
    

    Après ces nous obtenons l'avertissement lorsqu'il est connecté via le « mongo » console:

    2017-01-19T12:26:51.948+0300 I STORAGE [initandlisten] ** WARNING: mongod started without --replSet yet 1 documents are present in local.system.replset 
    2017-01-19T12:26:51.948+0300 I STORAGE [initandlisten] **   Restart with --replSet unless you are doing maintenance and no other clients are connected. 
    2017-01-19T12:26:51.948+0300 I STORAGE [initandlisten] **   The TTL collection monitor will not start because of this. 
    

    Pour se débarrasser de celui-ci, vous devez supprimer la base de données « local ". Il n'y a qu'une seule collection « startup_log » dans cette base de données dans l'état par défaut, donc vous pouvez le faire sans crainte via « mongo » console

    use local 
    db.dropDatabase() 
    

    et redémarrez MongoDB:

    service mongod restart 
    

    Si vous allez supprimer la base de données "local" avant la section "réplication" de /etc/mongod.conf, c'est im médiatement restauré. Donc, je ne pouvais pas faire un seul redémarrage MongoDB.

  13. Sur le serveur supplémentaire effectuer la même action:

    • supprimer « réplication « section de /etc/mongod.conf
    • restart MongoDB
    • laisser tomber le « locale "Base de données
    • nouveau redémarrer
  14. L'arbitre juste arrêter et supprimer:

    pkill -f /tmp/mongo 
    rm -r /tmp/mongo