Een van de grote problemen bij datacorruptie van applicaties of menselijke fouten is dat de beledigende schrijfactie naar de primaire onmiddellijk wordt gerepliceerd naar de secundaire.
Dit is een van de redenen waarom gebruikers profiteren van "slaveDelay" - een optie om een van uw secundaire knooppunten met een vaste vertraging uit te voeren (dat helpt u natuurlijk alleen als u de fout of bug ontdekt gedurende de periode die korter is dan de vertraging op die secundaire).
Als je zo'n instelling niet hebt, moet je vertrouwen op een back-up om de staat van de records die je moet herstellen naar hun pre-bug-status te herstellen.
Voer alle bewerkingen uit op een afzonderlijke stand-alone kopie van uw gegevens - pas nadat u heeft gecontroleerd of alles correct opnieuw is gemaakt, moet u de gecorrigeerde gegevens vervolgens naar uw productiesysteem verplaatsen.
Wat nodig is om dit te kunnen doen, is een recente kopie van de back-up (laten we zeggen dat de back-up X uur oud is) en de oplog op uw cluster moet meer dan X uur aan gegevens bevatten. Ik heb niet gespecificeerd van welk knooppunt de oplog is omdat (a) elk lid van de replicaset dezelfde inhoud heeft in de oplog en (b) het is het is mogelijk dat uw oplog-grootte verschilt op verschillende node-leden, in welk geval u de "grootste" wilt aanvinken.
Dus laten we zeggen dat je meest recente back-up 52 uur oud is, maar gelukkig heb je een oplog die 75 uur aan gegevens bevat (yay).
Je realiseerde je al dat al je nodes (primaire en secundaire) de "slechte" gegevens hebben, dus wat je zou doen is deze meest recente back-up terugzetten naar een nieuwe mongod. Dit is waar u deze records herstelt naar wat ze waren voor de gewraakte update - en dan kunt u ze gewoon verplaatsen naar de huidige primaire van waar ze worden gerepliceerd naar alle secundairen.
Maak tijdens het herstellen van je back-up een mongodump van je oplog-verzameling via deze opdracht:
mongodump -d local -c oplog.rs -o oplogD
Verplaats de oplog naar zijn eigen map en hernoem hem naar oplog.bson:
mkdir oplogR
mv oplogD/local/oplog.rs.bson oplogR/oplog.bson
Nu moet je de "aanstootgevende" bewerking vinden. Je kunt de oplog dumpen in een voor mensen leesbare vorm, met behulp van de bsondump
commando in het oplogR/oplog.bson-bestand (en gebruik dan grep of wat dan ook om de "slechte" update te vinden). Als alternatief kunt u een query uitvoeren op de originele oplog in de replicaset via use local
en db.oplog.rs.find()
commando's in de shell.
Je doel is om dit item te vinden en de ts
te noteren veld.
Het kan er zo uitzien:
"ts" : Timestamp( 1361497305, 2789 )
Merk op dat de mongorestore
commando heeft twee opties, één genaamd --oplogReplay
en de andere genaamd oplogLimit
. Je speelt deze oplog nu opnieuw af op de herstelde stand-alone server MAAR je stopt voor deze beledigende update-operatie.
De opdracht zou zijn (host en poort zijn waar uw zojuist herstelde back-up zich bevindt):
mongorestore -h host --port NNNN --oplogReplay --oplogLimit 1361497305:2789 oplogR
Dit herstelt elke bewerking van het oplog.bson-bestand in de oplogR-directory en stopt vlak voor het item met de ts-waarde Timestamp (1361497305, 2789).
Bedenk dat de reden dat u dit op een afzonderlijke instantie deed, is dat u kunt controleren of de herstel- en replay-gemaakte juiste gegevens zijn gemaakt - zodra u dit hebt geverifieerd, kunt u de herstelde records naar de juiste plaats in de echte primaire schrijven (en toestaan dat replicatie wordt verspreid de gecorrigeerde records naar de secundairen).