Die Replikation in MongoDB umfasst Replikatsätze von Mitgliedern mit einer Architektur aus primären und sekundären Mitgliedern, aber manchmal mit einem nicht datentragenden Mitglied, das als Arbiter bezeichnet wird. Der Replikationsprozess besteht darin, dass immer dann, wenn die Daten auf den primären Knoten geschrieben wurden, die Änderungen in einer Oplog-Datei aufgezeichnet werden, aus der die sekundären Mitglieder dieselben Änderungen anwenden. Lesevorgänge können von jedem datentragenden Mitglied aus durchgeführt werden, wodurch ein Szenario entsteht, das allgemein als Hochverfügbarkeit bekannt ist.
In einigen Fällen kann es jedoch vorkommen, dass die sekundären Mitglieder beim Vornehmen von Änderungen nicht mit dem primären Knoten Schritt halten, und falls der primäre Knoten ausfällt, bevor diese Änderungen angewendet wurden, wird man gezwungen, den gesamten Cluster neu zu synchronisieren damit sie im gleichen Datenzustand sein können.
Was ist ein Rollback?
Dies ist eine automatische Failover-Funktion in MongoDB, bei der der primäre Knoten in einem Replikatsatz fehlschlagen kann, während er Änderungen vornimmt, die leider nicht rechtzeitig vom Oplog auf die sekundären Mitglieder übertragen werden und daher rückgängig gemacht werden müssen Zustand des primären auf einen, bevor die Änderungen vorgenommen wurden.
Rollbacks sind daher nur dann erforderlich, wenn der primäre Server akzeptiert hat, die Operationen zu schreiben, die nicht auf die sekundären Mitglieder repliziert wurden, bevor der primäre aus irgendeinem Grund, wie z. B. einer Netzwerkpartitionierung, herunterfährt. Falls es den Schreibvorgängen gelingt, in einem der Mitglieder repliziert zu werden, das verfügbar und für einen Großteil des Replikatsatzes zugänglich ist, wird kein Rollback durchgeführt.
Der Hauptgrund für Rollbacks in MongoDB besteht darin, die Datenkonsistenz für alle Mitglieder aufrechtzuerhalten, und daher wird es zurückgesetzt, wenn das primäre dem Replikatsatz wieder beitritt, wenn seine Änderungen nicht auf die sekundären Mitglieder angewendet wurden auf den Zustand vor dem Ausfall.
Allerdings sollten Rollbacks in MongoDB selten oder eher vermieden werden, da sie zu vielen Datenverlusten führen und folglich den Betrieb von mit der Datenbank verbundenen Anwendungen beeinträchtigen können.
MongoDB-Rollback-Prozess
Betrachten wir einen Replikatsatz mit drei Mitgliedern mit A als primärem, B und C als sekundären Mitgliedern. Wir werden Daten in A füllen und gleichzeitig eine gewisse Netzwerkpartitionierung in B und C auslösen. Wir werden in diesem Test MongoDB Version 4.2 und Atlas verwenden.
Zunächst rufen wir den Status des Replikatsatzes ab, indem wir den Befehl rs.status() auf der Mongo-Shell
ausführenMongoDB Enterprise Cluster0-shard-0:PRIMARY> rs.status()
Wenn Sie sich das Mitgliederattribut ansehen, sehen Sie so etwas wie
"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" : ""
}
],
Dies zeigt Ihnen den Status jedes Mitglieds Ihres Replica-Sets. Jetzt haben wir ein neues Terminal für Knoten A geöffnet und es mit 20000 Datensätzen gefüllt:
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
Während der Netzwerkpartitionierung wird A heruntergefahren, wodurch es für B und C nicht verfügbar ist, und daher wird B in unserem Fall als primär gewählt. Wenn A wieder beitritt, wird es als sekundäre hinzugefügt und Sie können dies mit dem Befehl rs.status() überprüfen. Einige Datensätze konnten jedoch vor der Netzwerkpartitionierung wie unten gezeigt auf Mitglied B repliziert werden:(Denken Sie daran, dass B in diesem Fall jetzt der primäre ist)
MongoDB Enterprise Cluster0-shard-0:PRIMARY> db.mytest.find({}).count()
12480
Die Zahl ist die Anzahl der Dokumente, die auf B repliziert werden konnten, bevor A ausfiel.
Wenn wir einige Daten an B schreiben und A erlauben, dem Netzwerk beizutreten, dann können wir einige Änderungen an A bemerken
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>
Sekundäre Mitglieder verwenden einen oplogFetcher, um oplog-Einträge von ihrer syncSource zu synchronisieren. Der oplogFetcher löst eine Find-Methode für den Quell-Oplog aus, gefolgt von einer Reihe von getMores-Cursor-Serien. Wenn A als Sekundärteil wieder hinzukommt, wird derselbe Ansatz angewendet und ein Dokument zurückgegeben, das größer als der Prädikatzeitstempel ist. Wenn das erste Dokument in B nicht mit dem letzten Oplog-Eintrag von A übereinstimmt, wird A zu einem Rollback gezwungen.
Wiederherstellen von Rollback-Daten in MongoDB
Rollback ist keine schlechte Sache in MongDB, aber man sollte so viel wie möglich versuchen, um sicherzustellen, dass sie nicht zu oft vorkommen. Dies ist eine automatische Sicherheitsmaßnahme, um die Datenkonsistenz zwischen Mitgliedern eines Replikatsatzes sicherzustellen. Falls ein Rollback auftritt, sind hier einige Schritte, um die Situation zu beheben:
Rollback-Datenerfassung
Sie müssen Mitgliedsdaten bezüglich des Rollbacks sammeln. Dies geschieht, indem Sie sicherstellen, dass Rollback-Dateien erstellt werden (nur verfügbar mit MongoDB Version 4.0), indem Sie createRollbackDataFiles aktivieren. Standardmäßig ist diese Option auf „true“ gesetzt, daher werden immer Rollback-Dateien erstellt.
Die Rollback-Dateien liegen im Pfad
Laden der Daten der Rollback-Dateien in eine separate Datenbank oder einen separaten Server
Mongorestore ist ein wichtiger Aspekt von MongoDB, der die Wiederherstellung von Rollback-Datendateien unterstützen kann. Als erstes kopieren Sie Rollback-Dateien auf einen neuen Server und laden dann die Dateien mit mongorestore auf Ihren Server. Der Befehl mongorestore ist unten dargestellt.
mongorestore -u <> -p <> -h 127.0.0.1 -d <rollbackrestoretestdb> -c <rollbackrestoretestc> <path to the .bson file> --authenticationDatabase=<database of user>
Nicht benötigte Daten bereinigen und Daten sichten
Bei diesem Schritt muss man nach eigenem Ermessen zwischen den Daten wählen, die aus Rollback-Dateien aufbewahrt werden sollen, und den Daten, die verworfen werden sollen. Es ist ratsam, alle Daten der Rollback-Dateien zu importieren. Dieser Entscheidungspunkt macht diesen Schritt zum schwierigsten Schritt bei der Datenwiederherstellung.
Verwenden der primären als Cluster zum Importieren von Daten
Beginnen Sie den letzten Schritt, indem Sie bereinigte Daten mithilfe von mongorestore und mongodump herunterladen. Anschließend importieren Sie die Daten erneut in den ursprünglichen Produktionscluster.
MongoDB-Rollbacks verhindern
Um Rollbacks von Daten bei der Verwendung von MongoDB zu verhindern, kann man Folgendes tun.
Running All Voting Members 'MAJORITY'
Dies kann durch Verwendung von w:Majority Write Concern erfolgen, das die Möglichkeit hat, eine Bestätigungsanforderung anzufordern, die einen Schreibvorgang für bestimmte Tags von Mongod-Instanzen ermöglicht. Dies kann erreicht werden, indem die Option w gefolgt vom Tag
Benutzervorgänge
Die aktualisierte Version von MongoDB, d. h. Version 4.2, hat die Fähigkeit, alle laufenden Vorgänge im Falle eines Rollbacks herunterzufahren.
Indexaufbauten
Version 4.2 der MongoDB-Funktionskompatibilitätsversion (fcv) "4.2" kann auf alle laufenden Indizes warten, die erstellt und abgeschlossen werden, bevor ein Rollback erfolgt Ort. Version 4.0 wartet jedoch auf den fortlaufenden Fortschritt und erstellt einen Hintergrundindex, daher ist die Wahrscheinlichkeit eines Rollbacks hoch.
Größe und Einschränkungen
Version 4.0 von MongoDB hat keine aufgeführten Grenzwerte für bestimmte Daten, die zurückgesetzt werden können, wenn ein laufender Hintergrundindex erstellt wird.
Schlussfolgerung
MongoDB-Rollback ist ein häufiges Phänomen für diejenigen, die MongoDB verwenden, ohne zu wissen, wie man es verhindern kann. Rollbacks sind vermeidbar, wenn man einige sichere Praktiken und Möglichkeiten zur Vermeidung von Rollbacks in MongoDB genau befolgt und einhält. Insgesamt ist es immer ratsam, auf die neueste Version von MongoDB zu aktualisieren, um einige vermeidbare Schluckaufe zu vermeiden.