Replikering i MongoDB involverar replikuppsättningar av medlemmar med en arkitektur av primära och sekundära medlemmar men ibland med en icke-databärande medlem som kallas en arbiter. Replikeringsprocessen är att, närhelst data har skrivits till den primära noden, registreras ändringarna i en oplog-fil från vilken de sekundära medlemmarna tillämpar samma ändringar. Läsoperationer kan göras från vilken databärande medlem som helst, vilket skapar ett scenario som vanligtvis kallas High Availability.
Men i vissa fall kan de sekundära medlemmarna misslyckas med att hinna med de primära när de gör ändringar och om den primära noden misslyckas innan dessa ändringar har tillämpats, kommer man att tvingas synkronisera om hela klustret så att de kan vara i samma datatillstånd.
Vad är en återställning?
Detta är en automatisk failover-funktion i MongoDB där den primära noden i en replikuppsättning kan misslyckas medan ändringar görs som tyvärr inte återspeglas till de sekundära medlemmarna i tid från oploggen och därför måste återställa tillstånd för primär till ett innan ändringarna gjordes.
Återkallningar är därför endast nödvändiga när den primära har accepterat att skriva de operationer som inte har replikerats till de sekundära medlemmarna innan de primära stegen ned på grund av någon anledning som nätverkspartition. Om skrivoperationerna lyckas replikeras i en av medlemmarna som är tillgänglig och tillgänglig för en majoritet av replikuppsättningen, kommer en återställning inte att ske.
Den huvudsakliga orsaken bakom återställningar i MongoDB är att hålla datakonsistensen för alla medlemmar och därför kommer den att återställas när den primära återansluter till replikuppsättningen, om dess ändringar inte har tillämpats på de sekundära medlemmarna. till staten innan misslyckandet.
Återställning bör dock vara sällsynt eller snarare undvikas i MongoDB eftersom de kan resultera i mycket dataförlust och följaktligen påverka driften av anslutna applikationer till databasen.
MongoDB återställningsprocess
Låt oss betrakta en replikuppsättning med tre medlemmar med A som primära, B och C som sekundära medlemmar. Vi kommer att fylla på data till A och samtidigt utlösa viss nätverkspartitionering till B och C. Vi kommer att använda MongoDB version 4.2 och Atlas i detta test.
Först får vi statusen för replikuppsättningen genom att köra kommandot rs.status() på mongoskalet
MongoDB Enterprise Cluster0-shard-0:PRIMARY> rs.status()
Om du tittar på medlemsattributet kan du se något liknande
"members" : [
{
"_id" : 0,
"name" : "cluster0-shard-00-00-sc27x.mongodb.net:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 1891079,
"optime" : {
"ts" : Timestamp(1594826711, 1),
"t" : NumberLong(27)
},
"optimeDurable" : {
"ts" : Timestamp(1594826711, 1),
"t" : NumberLong(27)
},
"optimeDate" : ISODate("2020-07-15T15:25:11Z"),
"optimeDurableDate" : ISODate("2020-07-15T15:25:11Z"),
"lastHeartbeat" : ISODate("2020-07-15T15:25:19.509Z"),
"lastHeartbeatRecv" : ISODate("2020-07-15T15:25:18.532Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncingTo" : "cluster0-shard-00-02-sc27x.mongodb.net:27017",
"syncSourceHost" : "cluster0-shard-00-02-sc27x.mongodb.net:27017",
"syncSourceId" : 2,
"infoMessage" : "",
"configVersion" : 4
},
{
"_id" : 1,
"name" : "cluster0-shard-00-01-sc27x.mongodb.net:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 1891055,
"optime" : {
"ts" : Timestamp(1594826711, 1),
"t" : NumberLong(27)
},
"optimeDurable" : {
"ts" : Timestamp(1594826711, 1),
"t" : NumberLong(27)
},
"optimeDate" : ISODate("2020-07-15T15:25:11Z"),
"optimeDurableDate" : ISODate("2020-07-15T15:25:11Z"),
"lastHeartbeat" : ISODate("2020-07-15T15:25:17.914Z"),
"lastHeartbeatRecv" : ISODate("2020-07-15T15:25:19.403Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncingTo" : "cluster0-shard-00-02-sc27x.mongodb.net:27017",
"syncSourceHost" : "cluster0-shard-00-02-sc27x.mongodb.net:27017",
"syncSourceId" : 2,
"infoMessage" : "",
"configVersion" : 4
},
{
"_id" : 2,
"name" : "cluster0-shard-00-02-sc27x.mongodb.net:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 1891089,
"optime" : {
"ts" : Timestamp(1594826711, 1),
"t" : NumberLong(27)
},
"optimeDate" : ISODate("2020-07-15T15:25:11Z"),
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "",
"electionTime" : Timestamp(1592935644, 1),
"electionDate" : ISODate("2020-06-23T18:07:24Z"),
"configVersion" : 4,
"self" : true,
"lastHeartbeatMessage" : ""
}
],
Detta kommer att visa dig statusen för varje medlem i din replikuppsättning. Nu öppnade vi en ny terminal för nod A och fyllde den med 20 000 poster:
MongoDB Enterprise Cluster0-shard-0:PRIMARY> for (var y = 20000; y >= 0; y--) {
db.mytest.insert( { record : y } )
}
WriteResult({ "nInserted" : 1 })
MongoDB Enterprise Cluster0-shard-0:PRIMARY> db.mytest 2020-07-15T21:28:40.436+2128 I NETWORK [thread1] trying reconnect to 127.0.0.1:3001 (127.0.0.1) failed
2020-07-15T21:28:41.436+2128 I
NETWORK [thread1] reconnect 127.0.0.1:3001 (127.0.0.1) ok
MongoDB Enterprise Cluster0-shard-0:SECONDARY> rs.slaveOk()
MongoDB Enterprise Cluster0-shard-0:SECONDARY> db.mytest.count()
20000
Under nätverkspartitioneringen kommer A att vara nere vilket gör den otillgänglig för B och C och därför väljs B som primär i vårt fall. När A går med igen kommer den att läggas till som sekundär och du kan kontrollera det med kommandot rs.status(). Vissa poster lyckades dock replikeras till medlem B innan nätverkspartitioneringen som visas nedan:(Kom ihåg att i det här fallet är B den primära nu)
MongoDB Enterprise Cluster0-shard-0:PRIMARY> db.mytest.find({}).count()
12480
Numret är antalet dokument som kunde replikeras till B innan A gick ner.
Om vi skriver en del data till B och tillåter A att gå med i nätverket kan vi märka några ändringar i A
connecting to: 127.0.0.1:3001/admin
MongoDB Enterprise Cluster0-shard-0:ROLLBACK>
MongoDB Enterprise Cluster0-shard-0:RECOVERING>
MongoDB Enterprise Cluster0-shard-0:SECONDARY>
MongoDB Enterprise Cluster0-shard-0:SECONDARY>
MongoDB Enterprise Cluster0-shard-0:PRIMARY>
Använda en oplogFetcher sekundära medlemmar synkronisera oplog-poster från deras syncSource. oplogFetcher utlöser en sökmetod till källoploggen följt av en serie getMores-markörserier. När A återförenas som sekundär tillämpas samma tillvägagångssätt och ett dokument som är större än predikatets tidsstämpel returneras. Om det första dokumentet i B inte stämmer överens med A:s senaste post i oplog, kommer A att tvingas till en återställning.
Återställa återställningsdata i MongoDB
Återställning är inte en dålig sak i MongDB men man bör försöka så mycket som möjligt för att säkerställa att de inte händer ganska ofta. Det är en automatisk säkerhetsåtgärd för att säkerställa datakonsistens mellan medlemmarna i en replikuppsättning. Om återställning inträffar, här är några steg för att lösa situationen:
Insamling av återställande data
Du måste samla in medlemsdata angående återställningen. Detta görs genom att se till att återställningsfiler skapas (endast tillgängligt med MongoDB version 4.0) genom att aktivera createRollbackDataFiles. Som standard är det här alternativet satt till sant, varför återställningsfiler alltid skapas.
Återställningsfilerna placeras i sökvägen
Läsa data för återställningsfiler i en separat databas eller server
Mongorestore är en viktig aspekt av MongoDB som kan hjälpa till att möjliggöra återställning av återställningsdatafiler. Det första är att kopiera återställningsfiler till en ny server och sedan använda mongorestore och ladda filerna till din server. Mongorestore-kommandot visas nedan.
mongorestore -u <> -p <> -h 127.0.0.1 -d <rollbackrestoretestdb> -c <rollbackrestoretestc> <path to the .bson file> --authenticationDatabase=<database of user>
Rengöra data som inte behövs och sålla igenom data
Detta steg kräver att man använder diskretion för att välja mellan data som ska sparas från återställningsfiler och data som ska slängas. Det är tillrådligt att importera all återställningsfildata, denna beslutspunkt gör detta steg till det svåraste steget i dataåterställning.
Använda det primära som ett kluster för att importera data
Börja det sista steget genom att ladda ner rensad data genom att använda mongorestore och mongodump, följ detta genom att återimportera data till det ursprungliga produktionsklustret.
Förhindra MongoDB-återställningar
För att förhindra att data återställs när du använder MongoDB kan man göra följande.
Köra alla röstande medlemmar 'MAJORITY'
Detta kan göras genom att använda w:majoritetsskrivbekymmer som har makten att välja bekräftelse på begäran som kommer att möjliggöra skrivoperation till givna specifika taggar av Mongod-instanser. Detta kan uppnås genom att använda w-alternativet följt av
Användaråtgärder
Uppdaterad version av MongoDB , det vill säga version 4.2 har förmågan att stänga av all pågående operation i fall av en återställning.
Indexbyggen
Version 4.2 av MongoDB funktionskompatibilitetsversion (fcv) "4.2" kan vänta på alla pågående index som håller på att byggas och avslutas innan en återställning tar plats. Däremot väntar version 4.0 på det fortsatta pågående och bygger bakgrundsindex, så möjligheten för en återställning är stor.
Storlek och begränsningar
Version 4.0 av MongoDB har inga listade gränser för given data som kan rullas tillbaka när pågående bakgrundsindex byggs upp.
Slutsats
MongoDB rollback är ett vanligt fenomen för de som använder MongoDB utan att veta hur man kan förhindra det. Återställningar kan förhindras om man noggrant följer och följer några av säkra metoder och sätt att undvika återkallningar i MongoDB. Sammantaget är det alltid tillrådligt att uppgradera till den senaste versionen av MongoDB för att undvika vissa förebyggbara hicka.