sql >> Databáze >  >> NoSQL >> MongoDB

Jak zabránit vrácení zpět v MongoDB

Replikace v MongoDB zahrnuje sady replik členů s architekturou primárního a sekundárního člena, ale někdy s členem, který nenese data, zvaným arbitr. Proces replikace spočívá v tom, že kdykoli jsou data zapsána do primárního uzlu, změny se zaznamenají do souboru oplog, ze kterého sekundární členové aplikují stejné změny. Operace čtení lze provádět z libovolného člena nesoucího data, čímž se vytváří scénář běžně známý jako vysoká dostupnost.

V některých případech se však sekundárním členům nemusí podařit dohnat primární uzel při provádění změn a v případě, že primární uzel selže dříve, než budou tyto změny aplikovány, jeden bude nucen znovu synchronizovat celý cluster aby mohly být ve stejném stavu dat.

Co je vrácení zpět?

Toto je funkce automatického převzetí služeb při selhání v MongoDB, kde primární uzel v sadě replik může selhat při provádění změn, které se bohužel nakonec neprojeví na sekundárních členech včas z oplogu, a proto je potřeba vrátit stavu primárního na jeden před provedením změn.

Vrácení změn je proto nutné pouze tehdy, když primární souhlasil se zápisem operací, které nebyly replikovány na sekundární členy, než primární z nějakého důvodu, jako je síťový oddíl, odejde. Pokud se operace zápisu podaří replikovat v jednom z členů, který je dostupný a přístupný většině sady replik, k vrácení nedojde.

Hlavním důvodem vrácení v MongoDB je zachování konzistence dat pro všechny členy, a proto, když se primární znovu připojí k sadě replik, pokud její změny nebyly aplikovány na sekundární členy, bude vrácena do stavu před poruchou.

Nicméně návraty by měly být v MongoDB vzácné nebo se jim spíše vyhnout, protože mohou vést ke ztrátě velkého množství dat a následně ovlivnit provoz aplikací připojených k databázi.

Proces vrácení zpět MongoDB

Uvažujme  tříčlennou sadu replik s A jako primárními členy, B a C jako sekundárními členy. Data naplníme do A a zároveň spustíme nějaké rozdělení sítě na B a C. V tomto testu použijeme MongoDB verze 4.2 a Atlas.

Nejprve získáme stav sady replik spuštěním příkazu rs.status() na mongo shell  

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

Při pohledu na atribut členů můžete vidět něco jako

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

}

],

To vám ukáže stav každého člena vaší sady replik. Nyní jsme otevřeli nový terminál pro uzel A a naplnili jej 20 000 záznamy:

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

Během rozdělování sítě bude A mimo provoz, čímž bude nedostupný pro B a C, a proto B bude v našem případě zvolen jako primární. Když se A znovu připojí, bude přidán jako sekundární a můžete to zkontrolovat pomocí příkazu rs.status(). Některé záznamy se však podařilo replikovat do člena B před rozdělením sítě, jak je vidět níže:(Pamatujte si, že v tomto případě je B nyní primární)

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

12480    

Číslo je počet dokumentů, které bylo možné replikovat do B, než A zmizelo.

Pokud zapíšeme nějaká data do B a umožníme A připojit se k síti, můžeme si všimnout některých změn v 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>

Pomocí nástroje oplogFetcher sekundární členové synchronizují položky oplog ze svého zdroje synchronizace. OplogFetcher spouští metodu hledání do zdrojového oplogu následovanou řadou sérií kurzorů getMores. Když se A znovu připojí jako sekundární, použije se stejný přístup a vrátí se dokument větší než časové razítko predikátu. Pokud se první dokument v B neshoduje s posledním záznamem oplogu A, A bude nucen vrátit zpět.

Obnovení dat o vrácení v MongoDB

Rollback není v MongDB špatná věc, ale člověk by se měl snažit co nejvíce, aby se ujistil, že k nim nedochází příliš často. Jde o bezpečnostní automatické opatření zajišťující konzistenci dat mezi členy sady replik. V případě, že dojde k vrácení zpět, zde je několik kroků k vyřešení situace:

Rollback Data Collection

Potřebujete shromáždit data členů týkající se vrácení zpět. Toho dosáhnete vytvořením souborů vrácení zpět (k dispozici pouze s MongoDB verze 4.0) povolením createRollbackDataFiles. Ve výchozím nastavení je tato možnost nastavena na hodnotu true, takže soubory vrácení budou vždy vytvořeny.

Soubory vrácení zpět jsou umístěny v cestě /rollback/. a obsahují data, která lze převést z formátu BSON pomocí nástroje bsondump do formátu, který je čitelný člověkem.

Načtení dat zpětných souborů do samostatné databáze nebo serveru

Mongorestore je důležitým aspektem MongoDB, který může pomoci při obnově datových souborů pro vrácení zpět. První věcí je zkopírovat soubory vrácení zpět na nový server a poté pomocí mongorestore načíst soubory na váš server. Příkaz mongorestore je zobrazen níže.

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

Čištění nepotřebných dat a prosévání dat

Tento krok vyžaduje, abyste si zvolili podle vlastního uvážení mezi daty, která mají být uchována ze souborů pro vrácení zpět, a daty, která mají být vyhozena. Je vhodné naimportovat všechna data z rollback souborů, toto rozhodnutí činí tento krok nejobtížnějším krokem při obnově dat.

Použití primárního jako clusteru k importu dat 

Začněte poslední krok stažením vyčištěných dat pomocí mongorestore a mongodump a poté znovu importujte  data do původního produkčního clusteru.

Prevence vrácení MongoDB

Aby se při používání MongoDB zabránilo vrácení dat zpět, můžete provést následující.

Spuštění všech hlasujících členů „MAJORITY“

To lze provést pomocí w:většinový zápisový podnik, který má možnost požádat o potvrzení, které umožní operaci zápisu do daných konkrétních značek instancí Mongod. Toho lze dosáhnout použitím volby w následované tagem . Aby se zabránilo rollbacku, všichni hlasující členové v MongoDB budou mít povolený žurnál a budou používat w:většinový zápis, tím je zajištěno, že většina bude schopna zapisovat a nastavovat replikované uzly, než dojde k vrácení. Také zajišťuje, že klient obdrží potvrzení po rozšíření operace zápisu na sadu replik.

Uživatelské operace  

Aktualizovaná verze MongoDB, tedy verze 4.2, má schopnost vypnout všechny probíhající operace v případě vrácení zpět.

Sestavení indexu 

Verze 4.2 verze MongoDB pro kompatibilitu funkcí (fcv) "4.2" je schopna čekat na všechny probíhající indexy, které se sestavují a dokončují, než dojde k vrácení zpět místo. Verze 4.0 však čeká na pokračující vývoj a vytváří index na pozadí, takže možnost vrácení je vysoká.

Velikost a omezení

Verze 4.0 MongoDB nemá žádné uvedené limity daných dat, které lze vrátit zpět, když probíhá sestavení indexu na pozadí.

Závěr 

Vrácení MongoDB je běžný jev pro ty, kteří používají MongoDB, aniž by věděli, jak tomu zabránit. Vrácení změn lze předejít, pokud se důsledně řídíte a dodržujete některé z bezpečných postupů a způsobů, jak se v MongoDB vyhnout rollbackům. Celkově vzato je vždy vhodné upgradovat na nejnovější verzi MongoDB, abyste se vyhnuli některým škytavkám, kterým lze předejít.


  1. Do jaké úrovně blokuje MongoDB zápisy? (nebo:co to znamená na připojení

  2. Mongodb, sharding a služby pro více oken

  3. Začínáme s CouchDB

  4. Jak nasadit databáze s otevřeným zdrojovým kódem