MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

So verhindern Sie Rollbacks in MongoDB

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ühren
MongoDB 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 /rollback/. und enthalten Daten, die mit dem Tool bsondump aus dem BSON-Format konvertiert werden können in ein für Menschen lesbares Format.

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 verwendet wird. Um ein Rollback zu verhindern, wird für alle stimmberechtigten Mitglieder in MongoDB das Journal aktiviert und die Verwendung von w:Majority Write Concern gewährleistet, dass die Mehrheit in der Lage ist, Replikatknoten zu schreiben und festzulegen, bevor ein Rollback stattfindet. Es stellt auch sicher, dass der Client eine Bestätigung erhält, nachdem der Schreibvorgang auf dem Replikatsatz weitergegeben wurde.

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.