sql >> Database teknologi >  >> NoSQL >> MongoDB

Sådan forhindrer du tilbagerulninger i MongoDB

Replikering i MongoDB involverer replikasæt af medlemmer med en arkitektur af primære og sekundære medlemmer, men til tider med et ikke-databærende medlem kaldet en arbiter. Replikeringsprocessen er, at når dataene er blevet skrevet til den primære node, registreres ændringerne på en oplog-fil, hvorfra de sekundære medlemmer anvender de samme ændringer. Læseoperationer kan udføres fra et hvilket som helst databærende medlem, hvilket skaber et scenario, almindeligvis kendt som High Availability.

I nogle tilfælde kan de sekundære medlemmer dog ikke indhente det primære ved at lave ændringer, og hvis den primære node fejler, før disse ændringer er blevet anvendt, vil man være tvunget til at synkronisere hele klyngen igen så de kan være i samme datatilstand.

Hvad er en tilbagerulning?

Dette er en automatisk failover-funktion i MongoDB, hvor den primære node i et replikasæt kan svigte, mens der foretages ændringer, som desværre ender med ikke at blive afspejlet til de sekundære medlemmer i tide fra oploggen, og derfor er det nødvendigt at vende tilbage tilstand af den primære til en, før ændringerne blev foretaget.

Rollbacks er derfor kun nødvendige, når den primære har accepteret at skrive de operationer, som ikke er blevet replikeret til de sekundære medlemmer før de primære trin ned på grund af en eller anden grund, såsom netværkspartition. Hvis i tilfælde af, at skriveoperationerne formår at blive replikeret i et af medlemmerne, som er tilgængeligt og tilgængeligt for et flertal af replikasættet, vil en tilbagerulning ikke ske.

Hovedårsagen bag tilbagerulninger i MongoDB er at holde datakonsistens for alle medlemmer, og derfor, når den primære genindtræder i replikasættet, hvis dens ændringer ikke er blevet anvendt på de sekundære medlemmer, vil den blive ført tilbage til staten før fiaskoen.

Tilbageføringer bør dog være sjældne eller snarere undgås i MongoDB, da de kan resultere i meget datatab og som følge heraf påvirke driften af ​​tilsluttede applikationer til databasen.

MongoDB tilbagerulningsproces

Lad os overveje et replikasæt med tre medlemmer med A som det primære, B og C som de sekundære medlemmer. Vi vil udfylde data til A og samtidig udløse en vis netværkspartitionering til B og C. Vi vil bruge MongoDB version 4.2 og Atlas i denne test.

Først får vi status for replikasættet ved at køre kommandoen rs.status() på mongo-skallen  

MongoDB Enterprise Cluster0-shard-0:PRIMARY> rs.status()

Når du ser på medlemsattributten, kan du se noget lignende

"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" : ""

}

],

Dette vil vise dig status for hvert medlem af dit replikasæt. Nu åbnede vi en ny terminal for node A og udfyldte den med 20000 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 netværksopdelingen vil A være nede, hvilket gør den utilgængelig for B og C og dermed B valgt som den primære i vores tilfælde. Når A slutter sig til igen, vil den blive tilføjet som den sekundære, og du kan kontrollere det ved at bruge kommandoen rs.status(). Det lykkedes dog nogle poster at blive replikeret til medlem B før netværksopdelingen som vist nedenfor:(Husk i dette tilfælde er B den primære nu)

MongoDB Enterprise Cluster0-shard-0:PRIMARY> db.mytest.find({}).count()

12480    

Antallet er antallet af dokumenter, der var i stand til at blive replikeret til B, før A gik ned.

Hvis vi skriver nogle data til B og tillader A at tilslutte sig netværket, så kan vi bemærke nogle ændringer til 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>

Ved brug af en oplogFetcher synkroniserer sekundære medlemmer oplog-poster fra deres syncSource. oplogFetcher udløser en find-metode til kildeoploggen efterfulgt af en række getMores-markørserier. Når A genføjes som den sekundære, anvendes den samme tilgang, og et dokument, der er større end prædikattidsstemplet, returneres. Hvis det første dokument i B ikke matcher A's sidste oplog-indgang, vil A blive tvunget til en rollback.

Gendannelse af tilbagerulningsdata i MongoDB

Tilbageføring er ikke en dårlig ting i MongDB, men man bør prøve så meget som muligt for at sikre, at de ikke sker ret ofte. Det er en automatisk sikkerhedsforanstaltning til at sikre datakonsistens mellem medlemmer af et replikasæt. Hvis tilbagerulning sker, er her nogle trin til at løse situationen:

Rullback Data Collection

Du skal indsamle medlemsdata vedrørende rollback. Dette gøres ved at sikre, at rollback-filer oprettes (kun tilgængelig med MongoDB version 4.0) ved at aktivere createRollbackDataFiles. Som standard er denne indstilling sat til sand, så der vil altid blive oprettet rollback-filer.

Rulningsfilerne placeres i stien /rollback/. og de indeholder data, som kan konverteres fra BSON-formatet ved hjælp af bsondump-værktøjet til et format, der kan læses af mennesker.

Indlæsning af tilbagerulningsfilers data i en separat database eller server

Mongorestore er et vigtigt aspekt af MongoDB, der kan hjælpe med at aktivere gendannelse af tilbagerulningsdatafiler. Den første ting er at kopiere rollback-filer til en ny server og derefter indlæse filerne på din server ved hjælp af mongorestore. Mongorestore-kommandoen er vist nedenfor.

mongorestore -u <> -p <> -h 127.0.0.1 -d <rollbackrestoretestdb> -c <rollbackrestoretestc> <path to the .bson file> --authenticationDatabase=<database of user>

Rengøring af data, der ikke er nødvendige, og gennemsivning af data

Dette trin kræver, at man bruger skøn til at vælge mellem de data, der skal opbevares fra rollback-filer, og de data, der skal smides væk. Det er tilrådeligt at importere alle rollback-filernes data, dette beslutningspunkt gør dette trin til det sværeste trin i datagendannelse.

Brug af det primære som en klynge til at importere data 

Start det sidste trin ved at downloade rensede data ved at bruge mongorestore og mongodump, følg dette ved at genimportere dataene til den originale produktionsklynge.

Forebyggelse af MongoDB-tilbageføringer

For at forhindre tilbagerulning af data, når du bruger MongoDB, kan man gøre følgende.

Køre alle stemmeberettigede medlemmer 'MAJORITY'

Dette kan gøres ved at bruge w:majoritetsskrivebekymring, som har magten til at vælge en anmodningsbekræftelse, der vil muliggøre skriveoperation til givne specifikke tags af Mongod-forekomster. Dette kan opnås ved at bruge w-indstillingen efterfulgt af tag. For at forhindre tilbagerulning vil alle stemmeberettigede medlemmer i MongoDB have journal aktiveret og brug af w:majoritetsskrivebekymring, dette sikrer, at flertallet er i stand til at skrive og indstille replika-noder, før en tilbagerulning sker. Det sikrer også, at klienten modtager en bekræftelse efter udbredelse af skriveoperation på replikasæt.

Brugerhandlinger  

Opdateret version af MongoDB, dvs. version 4.2, har mulighed for at lukke ned for alle igangværende operationer i tilfælde af en tilbagerulning.

Indeksbuilds 

Version 4.2 af MongoDB funktionskompatibilitetsversion (fcv) "4.2" er i stand til at vente på alle de igangværende indekser, der er ved at blive bygget og afsluttet, før en tilbagerulning tager placere. Version 4.0 venter dog på den fortsatte igangværende og opbygger baggrundsindeks, så muligheden for en tilbagerulning er høj.

Størrelse og begrænsninger

Version 4.0 af MongoDB har ingen listede grænser for givne data, der kan rulles tilbage, når igangværende baggrundsindeks opbygges.

Konklusion 

MongoDB rollback er et almindeligt fænomen for dem, der bruger MongoDB uden at vide, hvordan man forhindrer det. Tilbageføringer kan forhindres, hvis man nøje følger og overholder nogle af sikre praksisser og måder at undgå tilbagerulninger i MongoDB. I det hele taget er det altid tilrådeligt at opgradere til den nyeste version af MongoDB for at undgå nogle hikke, der kan forhindres.


  1. importerer JSON til mongoDB ved hjælp af pymongo

  2. sorter efter strenglængde i Mongodb/pymongo

  3. Opdater flere dokumenter efter id-sæt. Mongoose

  4. Samme opgave udført flere gange