MongoDB
 sql >> Base de données >  >> NoSQL >> MongoDB

Modifier et rejouer l'oplog MongoDB

L'un des gros problèmes de corruption de données d'application ou d'erreur humaine est que l'écriture incriminée sur le primaire sera immédiatement répliquée sur le secondaire.

C'est l'une des raisons pour lesquelles les utilisateurs profitent de "slaveDelay" - une option pour exécuter l'un de vos nœuds secondaires avec un délai fixe (bien sûr, cela ne vous aide que si vous découvrez l'erreur ou le bogue pendant la période de temps qui est plus courte que le délai sur ce secondaire).

Si vous ne disposez pas d'une telle configuration, vous devez vous fier à une sauvegarde pour recréer l'état des enregistrements dont vous avez besoin pour restaurer leur état d'avant le bogue.

Effectuez toutes les opérations sur une copie autonome distincte de vos données - ce n'est qu'après avoir vérifié que tout a été correctement recréé que vous devez ensuite déplacer les données corrigées dans votre système de production.

Ce qui est requis pour pouvoir faire cela est une copie récente de la sauvegarde (disons que la sauvegarde a X heures) et l'oplog sur votre cluster doit contenir plus de X heures de données. Je n'ai pas précisé l'oplog de quel nœud car (a) chaque membre du jeu de réplicas a le même contenu dans l'oplog et (b) il est possible que la taille de votre oplog soit différente sur différents membres de nœud, auquel cas vous souhaitez vérifier le "plus grand".

Supposons donc que votre sauvegarde la plus récente date de 52 heures, mais heureusement, vous disposez d'un oplog qui contient 75 heures de données (yay).

Vous avez déjà réalisé que tous vos nœuds (primaires et secondaires) ont les "mauvaises" données, donc ce que vous feriez est de restaurer cette sauvegarde la plus récente dans un nouveau mongod. C'est ici que vous restaurerez ces enregistrements à ce qu'ils étaient juste avant la mise à jour incriminée - et vous pourrez ensuite simplement les déplacer dans le primaire actuel d'où ils seront répliqués sur tous les secondaires.

Lors de la restauration de votre sauvegarde, créez un mongodump de votre collection oplog via cette commande :

mongodump -d local -c oplog.rs -o oplogD

Déplacez l'oplog dans son propre répertoire en le renommant oplog.bson :

mkdir oplogR
mv oplogD/local/oplog.rs.bson oplogR/oplog.bson

Vous devez maintenant trouver l'opération "incriminée". Vous pouvez vider l'oplog sous une forme lisible par l'homme, en utilisant le bsondump commande sur le fichier oplogR/oplog.bson (puis utilisez grep ou autre pour trouver la "mauvaise" mise à jour). Vous pouvez également interroger l'oplog d'origine dans le jeu de réplicas via use local et db.oplog.rs.find() commandes dans le shell.

Votre objectif est de trouver cette entrée et de noter ses ts champ.

Cela pourrait ressembler à ceci :

"ts" : Timestamp( 1361497305, 2789 )

Notez que le mongorestore La commande a deux options, l'une appelée --oplogReplay et l'autre appelé oplogLimit . Vous allez maintenant rejouer cet oplog sur le serveur autonome restauré MAIS vous vous arrêterez avant cette opération de mise à jour incriminée.

La commande serait (l'hôte et le port sont l'endroit où se trouve votre sauvegarde nouvellement restaurée) :

mongorestore -h host --port NNNN --oplogReplay --oplogLimit 1361497305:2789 oplogR

Cela restaurera chaque opération à partir du fichier oplog.bson dans le répertoire oplogR en s'arrêtant juste avant l'entrée avec la valeur ts Timestamp(1361497305, 2789).

Rappelez-vous que la raison pour laquelle vous faisiez cela sur une instance distincte est que vous pouvez vérifier la restauration et rejouer les données correctes créées - une fois que vous l'avez vérifié, vous pouvez écrire les enregistrements restaurés à l'endroit approprié dans le vrai primaire (et permettre la propagation de la réplication les fiches corrigées aux secondaires).