En av de stora problemen med datakorruption för program eller mänskliga fel är att den kränkande skrivningen till den primära omedelbart kommer att replikeras till den sekundära.
Detta är en av anledningarna till att användare drar nytta av "slaveDelay" - ett alternativ att köra en av dina sekundära noder med en fast tidsfördröjning (det hjälper dig naturligtvis bara om du upptäcker felet eller buggen under en tidsperiod som är kortare än fördröjningen på den sekundära).
Om du inte har en sådan inställning måste du förlita dig på en säkerhetskopia för att återskapa tillståndet för de poster som du behöver återställa till deras tillstånd före bugg.
Utför alla operationer på en separat fristående kopia av dina data - först efter att ha verifierat att allt återskapats korrekt bör du sedan flytta den korrigerade datan till ditt produktionssystem.
Det som krävs för att kunna göra detta är en ny kopia av säkerhetskopian (låt oss säga att säkerhetskopian är X timmar gammal) och oploggen på ditt kluster måste innehålla mer än X timmars data. Jag specificerade inte vilken nods oplog eftersom (a) varje medlem i replikuppsättningen har samma innehåll i oploggen och (b) den är möjligt att din oplogstorlek är olika på olika nodmedlemmar, i vilket fall du vill markera den "största".
Så låt oss säga att din senaste säkerhetskopia är 52 timmar gammal, men som tur är har du en oplogg som innehåller 75 timmars data (yay).
Du har redan insett att alla dina noder (primära och sekundära) har "dåliga" data, så vad du skulle göra är att återställa den här senaste säkerhetskopian till en ny mongod. Det är här du kommer att återställa dessa poster till vad de var precis före den kränkande uppdateringen - och sedan kan du bara flytta dem till den nuvarande primära varifrån de kommer att replikeras till alla sekundärer.
Medan du återställer din säkerhetskopia, skapa en mongodump av din oplogsamling med detta kommando:
mongodump -d local -c oplog.rs -o oplogD
Flytta oplogen till sin egen katalog och byt namn på den till oplog.bson:
mkdir oplogR
mv oplogD/local/oplog.rs.bson oplogR/oplog.bson
Nu måste du hitta den "kränkande" operationen. Du kan dumpa oploggen till läsbar form med hjälp av bsondump
kommandot i filen oplogR/oplog.bson (och använd sedan grep eller what-not för att hitta den "dåliga" uppdateringen). Alternativt kan du fråga mot den ursprungliga oploggen i replikuppsättningen via use local
och db.oplog.rs.find()
kommandon i skalet.
Ditt mål är att hitta denna post och notera dess ts
fältet.
Det kan se ut så här:
"ts" : Timestamp( 1361497305, 2789 )
Observera att mongorestore
kommandot har två alternativ, ett som heter --oplogReplay
och den andra kallas oplogLimit
. Du kommer nu att spela upp den här oploggen på den återställda fristående servern MEN du kommer att sluta före denna stötande uppdatering.
Kommandot skulle vara (värd och port är där din nyligen återställda säkerhetskopia är):
mongorestore -h host --port NNNN --oplogReplay --oplogLimit 1361497305:2789 oplogR
Detta kommer att återställa varje operation från filen oplog.bson i oplogR-katalogen och stannar precis före posten med ts-värdet Timestamp(1361497305, 2789).
Kom ihåg att anledningen till att du gjorde detta på en separat instans är att du kan verifiera återställningen och spela upp korrekta data - när du väl har verifierat det kan du skriva de återställda posterna till lämplig plats i den verkliga primära (och tillåta replikering att spridas de korrigerade posterna till sekundärerna).