Replicatie in MongoDB omvat replicasets door leden met een architectuur van primaire en secundaire leden, maar soms met een niet-gegevensdragend lid dat een arbiter wordt genoemd. Het replicatieproces houdt in dat, telkens wanneer de gegevens naar het primaire knooppunt zijn geschreven, de wijzigingen worden vastgelegd in een oplogbestand van waaruit de secundaire leden dezelfde wijzigingen toepassen. Leesbewerkingen kunnen worden uitgevoerd vanaf elk lid dat gegevens draagt, waardoor een scenario ontstaat dat algemeen bekend staat als Hoge Beschikbaarheid.
In sommige gevallen slagen de secundaire leden er echter niet in om de primaire in te halen bij het aanbrengen van wijzigingen en in het geval dat het primaire knooppunt faalt voordat deze wijzigingen zijn toegepast, wordt men gedwongen het hele cluster opnieuw te synchroniseren zodat ze dezelfde gegevensstatus kunnen hebben.
Wat is een terugdraaiing?
Dit is een automatische failover-functie in MongoDB waarbij het primaire knooppunt in een replicaset kan mislukken terwijl wijzigingen worden aangebracht die helaas niet op tijd worden weergegeven aan de secundaire leden van de oplog, dus moet de staat van de primaire naar een voordat de wijzigingen werden aangebracht.
Terugdraaien zijn daarom alleen nodig wanneer de primaire heeft geaccepteerd om de bewerkingen te schrijven die niet zijn gerepliceerd naar de secundaire leden voordat de primaire aftreedt vanwege een of andere reden, zoals een netwerkpartitie. Als de schrijfbewerkingen erin slagen te worden gerepliceerd in een van de leden die beschikbaar en toegankelijk is voor een meerderheid van de replicaset, zal er geen rollback plaatsvinden.
De belangrijkste reden achter rollbacks in MongoDB is om de gegevensconsistentie voor alle leden te behouden en daarom, wanneer de primaire opnieuw lid wordt van de replicaset en de wijzigingen niet zijn toegepast op de secundaire leden, wordt deze teruggedraaid naar de staat voor de storing.
Rolbacks zouden echter zeldzaam moeten zijn of liever vermeden worden in MongoDB, omdat ze kunnen leiden tot veel gegevensverlies en bijgevolg de werking van verbonden applicaties met de database beïnvloeden.
MongoDB-terugdraaiproces
Laten we een replicaset met drie leden overwegen met A als de primaire, B en C als de secundaire leden. We vullen gegevens in naar A en activeren tegelijkertijd netwerkpartitionering naar B en C. We zullen MongoDB versie 4.2 en Atlas in deze test gebruiken.
Eerst krijgen we de status van de replicaset door de opdracht rs.status() uit te voeren op de mongo-shell
MongoDB Enterprise Cluster0-shard-0:PRIMARY> rs.status()
Als je naar het ledenkenmerk kijkt, zie je zoiets als
"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" : ""
}
],
Hiermee ziet u de status van elk lid van uw replicaset. Nu hebben we een nieuwe terminal geopend voor knooppunt A en deze gevuld met 20000 records:
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
Tijdens de netwerkpartitionering zal A niet beschikbaar zijn voor B en C en daarom wordt B in ons geval als de primaire gekozen. Wanneer A weer deelneemt, wordt het toegevoegd als secundair en u kunt dat controleren met de opdracht rs.status(). Sommige records slaagden er echter in om naar lid B te worden gerepliceerd vóór de netwerkpartitionering, zoals hieronder te zien is:(Onthoud dat in dit geval B nu de primaire is)
MongoDB Enterprise Cluster0-shard-0:PRIMARY> db.mytest.find({}).count()
12480
Het aantal is het aantal documenten dat kon worden gerepliceerd naar B voordat A werd uitgeschakeld.
Als we wat gegevens naar B schrijven en A toestaan om zich bij het netwerk aan te sluiten, kunnen we enkele veranderingen in A opmerken
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>
Met behulp van een oplogFetcher synchroniseren secundaire leden oplog-items van hun syncSource. De oplogFetcher activeert een zoekmethode naar de bron-oplog, gevolgd door een reeks getMores-cursorreeksen. Wanneer A opnieuw deelneemt als secundair, wordt dezelfde benadering toegepast en wordt een document geretourneerd dat groter is dan het predikaattijdstempel. Als het eerste document in B niet overeenkomt met de laatste invoer van A's oplog, wordt A gedwongen terug te draaien.
Rolback-gegevens herstellen in MongoDB
Terugdraaien is geen slechte zaak in MongDB, maar je moet zoveel mogelijk proberen om ervoor te zorgen dat ze niet vaak voorkomen. Het is een automatische veiligheidsmaatregel om de gegevensconsistentie tussen leden van een replicaset te waarborgen. Als er een terugdraaiing plaatsvindt, volgen hier enkele stappen om de situatie aan te pakken:
Gegevensverzameling terugdraaien
U moet ledengegevens verzamelen met betrekking tot de rollback. Dit wordt gedaan door ervoor te zorgen dat rollback-bestanden worden gemaakt (alleen beschikbaar met MongoDB versie 4.0) door de createRollbackDataFiles in te schakelen. Standaard is deze optie ingesteld op true, vandaar dat er altijd terugdraaibestanden worden gemaakt.
De rollback-bestanden worden in het pad
De gegevens van de terugdraaibestanden in een afzonderlijke database of server laden
Mongorestore is een essentieel aspect van MongoDB dat kan helpen bij het herstellen van terugdraaigegevensbestanden. Het eerste is om rollback-bestanden naar een nieuwe server te kopiëren en vervolgens mongorestore te gebruiken om de bestanden op uw server te laden. Het mongorestore-commando wordt hieronder weergegeven.
mongorestore -u <> -p <> -h 127.0.0.1 -d <rollbackrestoretestdb> -c <rollbackrestoretestc> <path to the .bson file> --authenticationDatabase=<database of user>
Gegevens opschonen die niet nodig zijn en gegevens doorzoeken
Voor deze stap moet men discretie gebruiken om te kiezen tussen de gegevens die moeten worden bewaard uit terugdraaibestanden en de gegevens die moeten worden weggegooid. Het is raadzaam om alle gegevens van de terugdraaibestanden te importeren, dit beslissingspunt maakt deze stap de moeilijkste stap in gegevensherstel.
De primair gebruiken als cluster om gegevens te importeren
Begin de laatste stap door opgeschoonde gegevens te downloaden met behulp van mongorestore en mongodump, gevolgd door het opnieuw importeren van de gegevens in het oorspronkelijke productiecluster.
MongoDB-terugdraaiingen voorkomen
Om te voorkomen dat gegevens worden teruggedraaid wanneer u MongoDB gebruikt, kunt u het volgende doen.
Alle stemmende leden leiden 'MAJORITY'
Dit kan worden gedaan door gebruik te maken van w:meerderheidsschrijfzorg die de mogelijkheid heeft om optieverzoekbevestiging te vragen die schrijfbewerking naar bepaalde tags van Mongod-instanties mogelijk maakt. Dit kan worden bereikt door de optie w te gebruiken gevolgd door de tag
Gebruikersbewerkingen
Bijgewerkte versie van MongoDB, dat wil zeggen versie 4.2, heeft de mogelijkheid om alle bewerkingen die worden uitgevoerd af te sluiten in het geval van een terugdraaiing.
Index-builds
Versie 4.2 van MongoDB-functiecompatibiliteitsversie (fcv) "4.2" kan wachten op alle lopende indices die worden gebouwd en voltooid voordat een rollback plaatsvindt plaats. Versie 4.0 wacht echter op de voortdurende voortgang en bouwt een achtergrondindex op, dus de kans op een terugdraaiing is groot.
Grootte en beperkingen
Versie 4.0 van MongoDB heeft geen vermelde limieten voor bepaalde gegevens die kunnen worden teruggedraaid wanneer de lopende achtergrondindex wordt opgebouwd.
Conclusie
Het terugdraaien van MongoDB is een veelvoorkomend fenomeen voor degenen die MongoDB gebruiken zonder te weten hoe dit te voorkomen. Rollbacks zijn te voorkomen als men enkele veilige praktijken en manieren om rollbacks in MongoDB te vermijden scherp volgt en naleeft. Al met al is het altijd raadzaam om te upgraden naar de nieuwste versie van MongoDB om een aantal vermijdbare problemen te voorkomen.