MongoDB, proprio come qualsiasi altro database, potrebbe non riuscire durante l'esecuzione di un'operazione di scrittura. In tal caso è necessaria una strategia che conservi l'operazione da qualche parte in modo che il database possa riprendere quando viene ripristinato in funzione.
In MongoDB utilizziamo il journaling per cui c'è una registrazione in anticipo sui file journal su disco per mantenere i dati disponibili in caso di errore. Il motore di archiviazione WiredTiger può utilizzare i checkpoint per fornire una visualizzazione coerente dei dati su disco e consentire a MongoDB di eseguire il ripristino dall'ultimo checkpoint, ma solo se non si è chiuso in modo imprevisto. In caso contrario, per le informazioni che si sono verificate durante l'ultimo checkpoint, è necessario che sia stato abilitato il journaling per recuperare tali dati.
La procedura per il processo di ripristino è questa:il database cercherà nei file di dati per trovare l'identificatore dell'ultimo checkpoint, utilizzare questo identificatore per cercare nei file journal il record che lo corrisponde e quindi applica le operazioni nei file journal dall'ultimo checkpoint.
Come funziona il journaling nel motore di archiviazione WiredTiger
Per ogni client che avvia un'operazione di scrittura, WiredTiger crea un record di giornale composto da operazioni di scrittura interne che sono state attivate dalla scrittura iniziale. Si consideri un documento in una raccolta che deve essere aggiornato e prevediamo che anche il suo indice venga modificato. WiredTiger creerà un unico record di giornale che incorporerà l'operazione di aggiornamento e le corrispondenti modifiche all'indice.
Questo record verrà archiviato in un buffer in memoria la cui capacità massima è 128kB. Il motore di archiviazione sincronizza quindi i record del journal memorizzati nel buffer su disco quando viene soddisfatta una delle seguenti condizioni:
- Un'operazione di scrittura include/implica un problema di scrittura di j:true.
- WiredTiger crea un nuovo file journal che si trova dopo ogni 100 MB di dati.
- Dopo ogni 100 millisecondi a seconda di storage.journal.commitIntervalMs.
- In caso di membri del set di repliche:
- Istanza di operazioni in attesa di voci dell'oplog, ad esempio operazioni di lettura eseguite nell'ambito di sessioni causalmente coerenti e query di scansione in avanti rispetto all'oplog.
- Dopo ogni applicazione batch delle voci oplog nel caso dei membri secondari.
In caso di arresto forzato di mongod, se erano in corso operazioni di scrittura, gli aggiornamenti possono andare persi anche se i record del journal rimangono nei buffer di WiredTiger.
Compressione dati diario
L'impostazione predefinita in MongoDB indica a WiredTiger di utilizzare una compressione rapida per i dati del journal. Questo può essere modificato a seconda dell'algoritmo di compressione desiderato utilizzando l'impostazione storage.wiredTiger.engineConfig.journalCompressor. Questi record di registro vengono compressi solo se la loro dimensione è maggiore di 128 byte, che è la dimensione minima del record di registro di WiredTiger.
Limitare la dimensione di un file journal
La dimensione massima di un file journal è 100 MB e quindi se il file supera questo limite, ne verrà creato uno nuovo.
Dopo che il file journal è stato utilizzato in recovery o meglio ci sono file più vecchi di quello che può essere usato per recuperare dall'ultimo checkpoint, WiredTiger li rimuove automaticamente.
Pre-assegnazione
I file journal possono essere preallocati con il motore di archiviazione WiredTiger se il processo mongod determina che è più efficiente preallocare file journal piuttosto che crearne di nuovi.
Come funziona il journaling nel motore di archiviazione in memoria
Il motore di archiviazione in memoria è stato dichiarato come parte della disponibilità generale (GA) a partire da MongoDB Enterprise versione 3.2.6. Con questo motore di archiviazione, i dati vengono mantenuti in memoria, quindi nessuna tecnica di journaling separata. Se sono presenti operazioni di scrittura con un problema di scrittura (j:true), verranno immediatamente riconosciute.
Per un set di repliche con un membro votante che utilizza il motore di archiviazione in memoria, è necessario impostare writeConcernMajorityJournalDefault su false. In caso contrario, se è impostato su true, il set di repliche registrerà un avviso di avvio.
Quando questa opzione è impostata su false, il database non attende la scrittura di w:"maggioranza" per essere scritta sul diario su disco prima di confermare le scritture. Lo svantaggio di questo approccio è che con la maggior parte delle operazioni di scrittura è possibile eseguire il rollback in caso di perdita temporanea (come riavvio o arresto anomalo) della maggior parte dei nodi in un determinato set di repliche.
Se si utilizza il motore di archiviazione MMapv1, la pre-allocazione del journal può essere disabilitata utilizzando l'opzione --nopreallocation all'avvio di mongod.
Con il motore di archiviazione WiredTiger, da MongoDB versione 4.0 in poi, non è possibile specificare l'opzione --nojournal o anche storage.journal.enabled:false per i membri del set di repliche che utilizzano il motore di archiviazione WiredTiger.
Gestione del journal
Disabilitazione del journal
Il journal può essere disabilitato solo per le distribuzioni standalone e non è consigliato per i sistemi di produzione. Per MongoDB dalla versione 4.0 in poi, non è possibile specificare né l'opzione --nojournal né storage.journal.enabled:false quando sono coinvolti membri del set di repliche che utilizzano il motore di archiviazione WiredTiger.
Per disabilitare il journaling, avvia mongod con l'opzione della riga di comando --nojournal.
Monitoraggio dello stato del diario
Per ottenere le statistiche sul journal utilizzare il comando db.serverStatus() che restituisce wiredTiger.log.
Ricevi conferma di impegno
Usiamo l'opzione write concern con j per ottenere il riconoscimento del commit. {j:vero}. In questo caso è necessario abilitare il journaling, altrimenti l'istanza mongod potrebbe produrre un errore.
Se il journaling è abilitato, w:"maggioranza" potrebbe implicare j:true.
Per un set di repliche, quando j:true, l'impostazione richiede solo la scrittura primaria nel journal, indipendentemente dal problema di scrittura w:
Tuttavia, anche se j:true è configurato per un set di repliche, potrebbero verificarsi rollback a causa del failover primario del set di repliche.
Recupero dati arresto imprevisto
Tutti i file journal nella directory journal vengono riprodotti ogni volta che MongoDB si riavvia da un arresto anomalo prima che il server venga rilevato. Poiché questa operazione verrà registrata nell'output del log, non sarà necessario eseguire --repair.
Cambiare il WiredTiger Journal Compressor
Il compressore scattante è l'algoritmo di compressione predefinito per il journal. Tuttavia, è possibile modificarlo a seconda della configurazione dell'istanza mongod.
Per un'istanza mongod standalone:
- Imposta storage.wiredTiger.engineConfig.journalCompressor su un nuovo valore per aggiornarlo. Il modo più appropriato per farlo è tramite il file di configurazione, ma se si utilizzano le opzioni della riga di comando, è necessario aggiornare l'opzione della riga di comando --wiredTigerJournalCompressor durante il riavvio.
- Chiudi l'istanza mongod connettendoti a una shell mongo dell'istanza ed emette il comando:db.shutdownServer() o db.getSiblingDB('admin ).shutdownServer()
- Riavvia l'istanza mongod:
- Se si utilizza il file di configurazione, utilizzare:mongod -f
- Se utilizzi le opzioni della riga di comando, aggiorna wiredTigerJournalCompressor:
Mongod --wiredTigerJournalCompressor <differentCompressor|none>
- Se si utilizza il file di configurazione, utilizzare:mongod -f
Per un membro del set di repliche:
- Chiudi l'istanza mongod:db.shutdownServer() o db.getSiblingDB('admin).shutdownServer()
- Apportare le seguenti modifiche al file di configurazione:
- Imposta storage.journal.enabled su false.
- Commenta le impostazioni di replica
- Imposta il parametro disableLogicalSessionCacheRefresh su true.
i.e
storage:
journal:
enabled: false
#replication:
# replSetName: replA
setParameter:
disableLogicalSessionCacheRefresh: true
-
Riavvia l'istanza mongod:
-
Se si utilizza il file di configurazione, utilizzare:mongod -f
-
Se si utilizzano le opzioni della riga di comando:includi l'opzione --nojournal, rimuovi qualsiasi opzione della riga di comando di replica cioè --replSet e imposta il parametro disableLogicalSessionCacheRefresh su true
mongod --nojournal --setParameter disableLogicalSessionCacheRefresh=true
-
-
Chiudi l'istanza mongod:
db.shutdownServer() or db.getSiblingDB(‘admin).shutdownServer()
-
Aggiorna il file di configurazione per preparare il riavvio del membro della serie di repliche con il nuovo compressore journal:rimuovere lo storage. journal.enabled, decommentare le impostazioni di replica per la distribuzione, rimuovere l'opzione disableLogicalSessionCacheRefresh e infine rimuovere storage.wiredTiger.engineConfig.journalCompressor.
storage:
wiredTiger:
engineConfig:
journalCompressor: <newValue>
replication:
replSetName: replA
-
Riavvia l'istanza mongod come membro del set di repliche
- Se si utilizza il file di configurazione, utilizzare:mongod -f
- Se si utilizzano le opzioni della riga di comando:rimuovere le opzioni --nojournal e --wiredTigerJournalCompressor. Includere le opzioni della riga di comando di replica e rimuovere il parametro disableLogicalSessionCacheRefresh.
mongod --wiredTigerJournalCompressor <differentCompressor|none> --replSet ...
Conclusione
Affinché MongoDB garantisca la durabilità dell'operazione di scrittura, viene utilizzato il journaling in cui i dati vengono scritti su disco in anticipo registrazione. Per quanto il motore di archiviazione WiredTiger (che è il più preferito) possa recuperare i dati attraverso gli ultimi checkpoint, se MongoDB si chiude in modo imprevisto e il journaling non è abilitato, il recupero di tali dati diventa impossibile. In caso contrario, se il journaling è abilitato, MongoDB può riapplicare le operazioni di scrittura al riavvio e mantenere uno stato coerente.