mongodb mysql 写_MongoDB与MySQL关于写确认的异同
云妹導(dǎo)讀:
所謂寫確認(rèn),是指用戶將數(shù)據(jù)寫入數(shù)據(jù)庫之后,數(shù)據(jù)庫告知用戶寫入成功的一個概念。根據(jù)數(shù)據(jù)庫的特點和配置,可以在不同的寫入程度上,返回給用戶,而這其中,就涉及到了不同的性能、數(shù)據(jù)安全等級以及數(shù)據(jù)一致性的內(nèi)容。
不同的寫入確認(rèn)級別或配置,是數(shù)據(jù)庫提供給用戶的一種自我控制的能力,用戶可以針對自身業(yè)務(wù)的特點、數(shù)據(jù)管理的需要、性能的考慮、數(shù)據(jù)一致性以及服務(wù)可用性各種因素進(jìn)行考慮,選擇適合的數(shù)據(jù)庫配置,來實現(xiàn)自身的需要。
首先介紹幾個重要的概念,這些概念也是數(shù)據(jù)庫中常識性的知識了,不過是在不同數(shù)據(jù)庫的不同表述。
這些概念主要涉及到寫確認(rèn)的兩個重要考量點,一個是本地數(shù)據(jù)庫寫操作的不丟失,一個是分布式環(huán)境下,數(shù)據(jù)冗余的一致性。
本地數(shù)據(jù)庫寫操作是指數(shù)據(jù)庫在處理用戶的寫操作后,能夠持續(xù)化,防止因為意外導(dǎo)致的數(shù)據(jù)丟失,這個主要涉及到日志,比如MySQL中的redo log和MongoDB中的journal日志。
數(shù)據(jù)冗余的一致性是指多副本的環(huán)境下,比如主從或復(fù)制集架構(gòu)下,數(shù)據(jù)寫入主節(jié)點后,如何實現(xiàn)從節(jié)點與主節(jié)點的數(shù)據(jù)一致,而主從之間是以另外一個日志實現(xiàn)數(shù)據(jù)同步的,比如MySQL的binlog和MongoDB中的oplog日志。
另外防止主節(jié)點崩潰,數(shù)據(jù)未能同步到從節(jié)點,導(dǎo)致從節(jié)點成為新的主節(jié)點后,未同步數(shù)據(jù)丟失,也是寫確認(rèn)中重要的內(nèi)容,即不但同步數(shù)據(jù),而且要讓數(shù)據(jù)安全快速的同步。
redo/journal
MySQL的redo log和MongoDB的journal日志都是數(shù)據(jù)庫存儲引擎層面的WAL(Write-Ahead Logging)預(yù)寫式日志,記錄的是數(shù)據(jù)的物理修改,是提高數(shù)據(jù)系統(tǒng)持久性的一種技術(shù)。
redo log
redo log是MySQL的默認(rèn)存儲引擎innodb事務(wù)日志中的核心日志文件之一,俗稱重做日志,主要用作前滾的數(shù)據(jù)恢復(fù)。
當(dāng)我們想要修改MySQL數(shù)據(jù)庫中某一行數(shù)據(jù)的時候,innodb是把數(shù)據(jù)從磁盤讀取到內(nèi)存的緩沖池上進(jìn)行修改。這個時候數(shù)據(jù)在內(nèi)存中被修改,與磁盤中相比就存在了差異,我們稱這種有差異的數(shù)據(jù)為臟頁。innodb對臟頁的處理不是每次生成臟頁就將臟頁刷新回磁盤,這樣會產(chǎn)生海量的io操作,嚴(yán)重影響innodb的處理性能,因此并不是每次有了臟頁都立刻刷新到磁盤中。既然臟頁與磁盤中的數(shù)據(jù)存在差異,那么如果在這期間數(shù)據(jù)庫出現(xiàn)故障就會造成數(shù)據(jù)的丟失。
而redo log就是為了解決這個問題。由于redo log的存在,可以延遲刷新臟頁到磁盤的時間,保障了數(shù)據(jù)庫性能的情況下提高了數(shù)據(jù)的安全。雖然增加了redo log刷新的開銷,但是由于redo log采用的順序io,比數(shù)據(jù)頁的隨機(jī)io要快很多,這額外的開銷可接受。
即,數(shù)據(jù)庫先將數(shù)據(jù)頁的物理修改情況寫到刷盤較快的redo log文件中,防止數(shù)據(jù)丟失。一旦發(fā)生故障,數(shù)據(jù)庫重啟恢復(fù)的時候,可以先從redo log把未刷新到磁盤的已經(jīng)提交的物理數(shù)據(jù)頁恢復(fù)回來。
journal
journal是MongoDB存儲引擎層面的概念,MongoDB主要支持的mmapv1、wiredtiger、mongorocks等存儲引擎,都?持配置journal。MongoDB可以基于journal來恢復(fù)因為崩潰未及時寫到磁盤的信息。
MongoDB 所有的數(shù)據(jù)寫?、讀取最終都是調(diào)存儲引擎層的接?來存儲、讀取數(shù)據(jù),journal 是存儲引擎存儲數(shù)據(jù)時的一種輔助機(jī)制。
在MongoDB的4.0版本以前,用戶可以設(shè)置是否開啟journal日志;從4.0版本開始,副本集成員必須開啟journal功能。
以wiredtiger為例,如果不配置journal,寫入wiredtiger的數(shù)據(jù),并不會立即持久化存儲;而是每分鐘會做一次全量的checkpoint( storage.syncPeriodSecs配置項,默認(rèn)為1分鐘),將所有的數(shù)據(jù)持久化。如果中間出現(xiàn)宕機(jī),那么數(shù)據(jù)只能恢復(fù)到最近的一次checkpoint,這樣最多可能丟掉1分鐘的數(shù)據(jù)。
所以建議「一定要開啟journal」,開啟journal后,每次寫入會記錄一條操作日志(通過journal可以重新構(gòu)造出寫入的數(shù)據(jù))。這樣即使出現(xiàn)宕機(jī),啟動時 Wiredtiger 會先將數(shù)據(jù)恢復(fù)到最近的一次checkpoint的點,然后重放后續(xù)的 journal操作日志來恢復(fù)數(shù)據(jù)。
binlog/oplog
MySQL的binlog和MongoDB的oplog都是數(shù)據(jù)庫層面的寫操作對應(yīng)的邏輯日志,主要用于實現(xiàn)數(shù)據(jù)在主備之間的同步復(fù)制以及增量備份和恢復(fù)。
binlog
binlog是MySQL數(shù)據(jù)庫層面的一種二進(jìn)制日志,不管底層使用的什么存儲引擎,對數(shù)據(jù)庫的修改都會產(chǎn)生這種日志。binlog記錄操作的方法是邏輯性語句,可以通過設(shè)置log-bin=mysql-bin來啟動該功能。
binlog中記錄了有關(guān)寫操作的執(zhí)行時間、操作類型、以及操作的具體內(nèi)容,比如SQL語句(statement)或每行實際數(shù)據(jù)的變更(row)。
上圖是MySQL主從之間是如何實現(xiàn)數(shù)據(jù)復(fù)制的,其中的三個重要過程是:
主庫(Master)把數(shù)據(jù)庫更改記錄到binlog(圖中的Binary Log)中;
備庫(Slave)將主庫上的binlog復(fù)制到自己的中繼日志(Relay log)中;
備庫讀取中繼日志中的事件,將其重放(Replay)到備庫數(shù)據(jù)之上。
這樣源源不斷的復(fù)制,實現(xiàn)了數(shù)據(jù)在數(shù)據(jù)庫節(jié)點之間的一致。
oplog
oplog是MongoDB數(shù)據(jù)庫層面的概念,在復(fù)制集架構(gòu)下,主備節(jié)點之間通過oplog來實現(xiàn)節(jié)點間的數(shù)據(jù)同步。Primary中所有的寫入操作都會記錄到MongoDB Oplog中,然后從庫會來主庫一直拉取Oplog并應(yīng)用到自己的數(shù)據(jù)庫中。這里的Oplog是MongoDB local數(shù)據(jù)庫的一個集合,它是Capped collection,通俗意思就是它是固定大小,循環(huán)使用的。
oplog 在 MongoDB 里是一個普通的 capped collection,對于存儲引擎來說,oplog只是一部分普通的數(shù)據(jù)而已。
只有按復(fù)制集架構(gòu)啟動的節(jié)點會自動在local庫中創(chuàng)建oplog.rs的集合。
oplog中記錄了有關(guān)寫操作的操作時間、操作類型、以及操作的具體內(nèi)容,幾乎保留的每行實際數(shù)據(jù)的變更(在4.0及以后版本中,一個事務(wù)中涉及的多個文檔,會寫在一條oplog中)。
上圖是MongoDB主備之間如何實現(xiàn)數(shù)據(jù)復(fù)制的,其中的四個重要過程是:
主庫(Primary)把數(shù)據(jù)庫更改記錄到oplog(圖中的Capped Oplog集合)中;
備庫(Secondary)把主庫上的oplog拉取到自己的回放隊列中(Queue)中;
備庫讀取隊列中的oplog,批量回放(applyOps)到備庫數(shù)據(jù)中;
再將隊列中的Oplog寫入到備庫中的oplog.rs集合中。
這樣源源不斷的復(fù)制,實現(xiàn)了數(shù)據(jù)在數(shù)據(jù)庫節(jié)點之間的一致。
另外MongoDB支持鏈?zhǔn)綇?fù)制,即oplog不一定從Primary中獲取,還可以從其他Secondary獲取。上圖是MongoDB主備之間如何實現(xiàn)數(shù)據(jù)復(fù)制的,其中的四個重要過程是:
主庫(Primary)把數(shù)據(jù)庫更改記錄到oplog(圖中的Capped Oplog集合)中;
備庫(Secondary)把主庫上的oplog拉取到自己的回放隊列中(Queue)中;
備庫讀取隊列中的oplog,批量回放(applyOps)到備庫數(shù)據(jù)中;
再將隊列中的Oplog寫入到備庫中的oplog.rs集合中。
這樣源源不斷的復(fù)制,實現(xiàn)了數(shù)據(jù)在數(shù)據(jù)庫節(jié)點之間的一致。
另外MongoDB支持鏈?zhǔn)綇?fù)制,即oplog不一定從Primary中獲取,還可以從其他Secondary獲取。
redo與binlog
redo log是在innodb存儲引擎層產(chǎn)生,而binlog是MySQL數(shù)據(jù)庫的上層產(chǎn)生的,并且binlog不僅僅針對innodb存儲引擎,MySQL數(shù)據(jù)庫中的任何存儲引擎對于數(shù)據(jù)庫的更改都會產(chǎn)生binlog。
兩種日志記錄的內(nèi)容形式不同。MySQL的binlog是邏輯日志,其記錄是對應(yīng)的SQL語句或行的修改內(nèi)容。而innodb存儲引擎層面的redo log是物理日志。
兩種日志與記錄寫入磁盤的時間點不同,binlog只在事務(wù)提交完成后進(jìn)行一次寫入。而innodb存儲引擎的redo log在事務(wù)進(jìn)行中不斷地被寫入,并日志不是隨事務(wù)提交的順序進(jìn)行寫入的。
binlog僅在事務(wù)提交時記錄,并且對于每一個事務(wù),僅在事務(wù)提交時記錄,并且對于每一個事務(wù),僅包含對應(yīng)事務(wù)的一個日志。而對于innodb存儲引擎的redo log,由于其記錄是物理操作日志,因此每個事務(wù)對應(yīng)多個日志條目,并且事務(wù)的redo log寫入是并發(fā)的,并非在事務(wù)提交時寫入,其在文件中記錄的順序并非是事務(wù)開始的順序。
binlog不是循環(huán)使用,在寫滿或者重啟之后,會生成新的binlog文件,redo log是循環(huán)使用。
binlog可以作為恢復(fù)數(shù)據(jù)使用,主從復(fù)制搭建,redo log作為異常宕機(jī)或者介質(zhì)故障后的數(shù)據(jù)恢復(fù)使用。
journal與oplog
journal日志是在wiretiger、mmapV1等存儲引擎層產(chǎn)生,而oplog是MongoDB數(shù)據(jù)庫的主從復(fù)制層面的概念,oplog也與存儲引擎無關(guān);
兩種日志記錄的內(nèi)容形式不同。MongoDB的oplog是邏輯日志,其記錄的是對應(yīng)的寫操作的內(nèi)容。而journal存儲的物理修改;
兩種日志與記錄寫入磁盤的時間點不同。
MongoDB 復(fù)制集里寫入一個文檔時,需要修改如下數(shù)據(jù)
將文檔數(shù)據(jù)寫入對應(yīng)的集合
更新集合的所有索引信息
寫入一條oplog用于同步 最終存儲引擎會將所有修改操作應(yīng)用,并將上述3個操作寫?到一條 journal 操作日志里。
journal不是循環(huán)使用,在寫滿或者重啟之后,會生成新的journal文件,oplog是循環(huán)使用;
oplog可以作為恢復(fù)數(shù)據(jù)使用,復(fù)制集架構(gòu),journal作為一場宕機(jī)或者介質(zhì)故障后的數(shù)據(jù)恢復(fù)使用。
寫確認(rèn)
寫確認(rèn)這個概念其實是來自于MongoDB中的write concern,描述的是MongoDB對一個寫操作的確認(rèn)(acknowledge)等級。而MySQL中對應(yīng)的這個概念,可以理解為,用戶在提交(commit)寫操作的時候,需要經(jīng)過哪些操作之后就會告知用戶提交成功。
MongoDB
在MongoDB中,數(shù)據(jù)庫支持基于write concern功能使用戶配置靈活的寫入策略,則不同的策略對應(yīng)不同的數(shù)據(jù)寫入程度即返回給用戶寫入成功,用戶可以繼續(xù)操作下一個寫請求。
write concern
write concern支持3個配置項:
{ w: , j: , wtimeout: }
其中:
w,該參數(shù)要求寫操作已經(jīng)寫入到個節(jié)點才向用戶確認(rèn);
{w: 0} 對客戶端的寫入不需要發(fā)送任何確認(rèn),適用于性能要求高,但不關(guān)注正確性的場景;
{w: 1} 默認(rèn)的writeConcern,數(shù)據(jù)寫入到Primary就向客戶端發(fā)送確認(rèn);
{w: "majority"} 數(shù)據(jù)寫入到副本集大多數(shù)成員后向客戶端發(fā)送確認(rèn),適用于對數(shù)據(jù)安全性要求比較高的場景,該選項會降低寫入性能;
j,該參數(shù)表示是否寫操作要進(jìn)行journal持久化之后才向用戶確認(rèn);
{j: true} 要求primary寫操作進(jìn)行了journal持久化之后才向用戶確認(rèn);
{j: false} 要求寫操作已經(jīng)在journal緩存中即可向用戶確認(rèn);journal后續(xù)會將持久化到磁盤,默認(rèn)是100ms;
wtimeout,該參數(shù)表示寫入超時時間,w大于1時有效;當(dāng)w大于1時,寫操作需要成功寫入若干個節(jié)點才算成功,如果寫入過程中節(jié)點有故障,導(dǎo)致寫操作遲遲不能滿足w要求,也就一直不能向用戶返回確認(rèn)結(jié)果,為了防止這種情況,用戶可以設(shè)置wtimeout來指定超時時間,寫入過程持續(xù)超過該時間仍未結(jié)束,則認(rèn)為寫入失敗。
副本集下的寫確認(rèn)
下面以一個副本集架構(gòu)來描述,一個寫操作的流程,來認(rèn)識MongoDB下的寫確認(rèn)。
上面這個寫操作,{w:2},需要至少兩個節(jié)點寫成功才可以返回給用戶寫成功;而每個節(jié)點的寫入成功可以基于參數(shù){j}來判斷,如果{j:true},則每個節(jié)點寫入操作的journal都刷盤才可以;如果{j:false},則寫入操作的journal在緩存中即可以返回成功;
另外,MongoDB的Primary如何知道Secondary是否已經(jīng)同步成功呢,是基于如下流程:
Client向Primary發(fā)起請求,指定writeConcern為{w: "majority"},Primary收到請求,本地寫入并記錄寫請求到oplog,然后等待大多數(shù)節(jié)點都同步了這條/批oplog(Secondary應(yīng)用完oplog會向主報告最新進(jìn)度);
Secondary拉取到Primary上新寫入的oplog,本地重放并記錄oplog。為了讓Secondary能在第一時間內(nèi)拉取到主上的oplog,find命令支持一個awaitData的選項,當(dāng)find沒有任何符合條件的文檔時,并不立即返回,而是等待最多maxTimeMS(默認(rèn)為2s)時間看是否有新的符合條件的數(shù)據(jù),如果有就返回;所以當(dāng)新寫入oplog時,備立馬能獲取到新的oplog;
Secondary上有單獨的線程,當(dāng)oplog的最新時間戳發(fā)生更新時,就會向Primary發(fā)送replSetUpdatePosition命令更新自己的oplog時間戳;
當(dāng)Primary發(fā)現(xiàn)有足夠多的節(jié)點oplog時間戳已經(jīng)滿足條件了,向客戶端發(fā)送確認(rèn),這樣,Primary即可知道數(shù)據(jù)已經(jīng)同步到了。
MySQL
MySQL數(shù)據(jù)庫在所謂寫確認(rèn)或?qū)懗晒Ψ矫婵梢酝ㄟ^執(zhí)行事務(wù)的commit提交來體現(xiàn),提交成功則為寫成功。因此我主要從事務(wù)在執(zhí)行事務(wù)以及commit事務(wù)的過程中,涉及的redo log、binlog以及兩種日志的刷盤和主從復(fù)制的流程來分析MySQL的寫成功相關(guān)的設(shè)置和問題。
MySQL復(fù)制架構(gòu)
目前MySQL較為流量的版本包括5.5、5.6、5.7、8.0,而8.0版本中使用的Group Replication來實現(xiàn)多節(jié)點的數(shù)據(jù)一致性,這種組復(fù)制依靠分布式一致性協(xié)議(Paxos協(xié)議的變體),實現(xiàn)了分布式下數(shù)據(jù)的最終一致性。
MySQL中有幾種常見復(fù)制機(jī)制:
同步復(fù)制。當(dāng)主庫提交事務(wù)之后,所有的從庫節(jié)點必須收到、Replay并且提交這些事務(wù),然后主庫線程才能繼續(xù)做后續(xù)操作。但缺點是,主庫完成一個事務(wù)的時間會被拉長,性能降低。
異步復(fù)制。主庫將事務(wù) Binlog 事件寫入到 Binlog文件中,此時主庫只會通知一下 Dump 線程發(fā)送這些新的Binlog,然后主庫就會繼續(xù)處理提交操作,而此時不會保證這些 Binlog 傳到任何一個從庫節(jié)點上。
半同步復(fù)制。是介于全同步復(fù)制與全異步復(fù)制之間的一種,主庫只需要等待至少一個從庫節(jié)點收到并且 Flush Binlog 到 Relay Log 文件即可,主庫不需要等待所有從庫給主庫反饋。同時,這里只是一個收到的反饋,而不是已經(jīng)完全完成并且提交的反饋,如此,節(jié)省了很多時間。
組復(fù)制。由若干個節(jié)點共同組成一個復(fù)制組,一個事務(wù)的提交,必須經(jīng)過組內(nèi)大多數(shù)節(jié)點(N / 2 + 1)決議并通過,才能得以提交。比如由3個節(jié)點組成一個復(fù)制組,Consensus層為一致性協(xié)議層,在事務(wù)提交過程中,發(fā)生組間通訊,由2個節(jié)點決議(certify)通過這個事務(wù),事務(wù)才能夠最終得以提交并響應(yīng)。
除了組復(fù)制,半同步復(fù)制技術(shù)是性能和安全相對更好的設(shè)計,尤其在5.7版本中,優(yōu)化了之前版本的半同步復(fù)制相關(guān)的邏輯,因此我們主要以5.7版本來介紹。
MySQL5.6/5.5半同步復(fù)制的原理:提交事務(wù)的線程會被鎖定,直到至少一個Slave收到這個事務(wù),由于事務(wù)在被提交到存儲引擎之后才被發(fā)送到Slave上,所以事務(wù)的丟失數(shù)量可以下降到最多每線程一個。因為事務(wù)是在被提交之后才發(fā)送給Slave的,當(dāng)Slave沒有接收成功,并且Master掛了,會導(dǎo)致主從不一致:主有數(shù)據(jù),從沒有數(shù)據(jù)。這個被稱為AFTER_COMMIT。
MySQL5.7在Master事務(wù)提交的時間方面做了改進(jìn),事務(wù)是在提交之前發(fā)送給Slave(AFTER_SYNC),當(dāng)Slave沒有接收成功,并且Master宕機(jī)了,不會導(dǎo)致主從不一致,因為此時主還沒有提交,所以主從都沒有數(shù)據(jù)。
不過假如Slave接收成功,并且Master中的binlog未來得及刷盤并且在存儲引擎提交之前宕機(jī)了,那么很明顯這個事務(wù)是不成功的,但由于對應(yīng)的Binlog已經(jīng)做了Sync操作,從庫已經(jīng)收到了這些Binlog,并且執(zhí)行成功,相當(dāng)于在從庫上多了數(shù)據(jù),也算是有問題的,但多了數(shù)據(jù),問題一般不算嚴(yán)重。此時可能就需要8.0版本中的組復(fù)制了。
MySQL寫確認(rèn)行為
我們以MySQL的5.7版本的半同步復(fù)制的主從架構(gòu)的為例子,來介紹MySQL各個參數(shù)對寫確認(rèn)即commit的不同影響。
上圖中,能夠體現(xiàn)半同步復(fù)制(AFTER SYNC)的過程為:
第6步,寫binlog;(sync_binlog參數(shù)在此起作用)
第7步,同步binlog到備庫的Relay log;(sync_relay_log參數(shù)在此起作用)
第8步,返回給主庫ack;
第9步和第10步,提交事務(wù),將redo log中該事務(wù)標(biāo)記為已提交;(innodb_flush_log_at_trx_commit參數(shù)在此起作用)
第11步,返回給用戶寫成功;
上圖中,能體現(xiàn)redo log和binlog順序一致性的過程為:
第4步,將redo log置為prepare并刷盤;
第6步,寫入binlog;(sync_binlog參數(shù)在此起作用)
第9步和第10步,提交事務(wù),并將redo log置為提交狀態(tài);
下面將把上面介紹的與刷盤有關(guān)的配置項引入這整個過程,來看寫操作不同的行為和風(fēng)險。
注意:以上是在開始內(nèi)部兩階段提交的流程,即innodb_support_xa=true,這個時候可以通過判斷binlog來恢復(fù)會提交的事務(wù),因此innodb_flush_log_at_trx_commit看起來可有可無;如果未開啟內(nèi)部事務(wù)的兩階段提交,則更會復(fù)雜,只有innodb_flush_log_at_trx_commit = 1 且 sync_binlog = 1 且 sync_relay_log = 1的情況下,可以保證已提交事務(wù)的安全,其他情況都有可能導(dǎo)致數(shù)據(jù)丟失或者主從數(shù)據(jù)不一致的風(fēng)險。
但是在innodb_flush_log_at_trx_commit = 1 且 sync_binlog = 1 且 sync_relay_log = 1 的情況下,MySQL的性能相對最低。可以在提高性能的情況下,比如 innodb_flush_log_at_trx_commit = 2 且 sync_binlog = N (N為500 或1000),由于這種情況,redo log和binlog都在系統(tǒng)緩存中,可以使用帶蓄電池后備電源的緩存cache,防止系統(tǒng)斷電異常。
此外,rpl_semi_sync_master_wait_for_slave_count參數(shù)是控制同步到多少個節(jié)點的,類似MongoDB中write concern中的 w 參數(shù),如果這個參數(shù)設(shè)置為0(其實不能,最低1),則變?yōu)榱思兇獾漠惒綇?fù)制;如果這個參數(shù)設(shè)置為最大(所有從節(jié)點個數(shù)),則變?yōu)榱思兇獾耐綇?fù)制,因此這個地方也可以根據(jù)需要來進(jìn)行調(diào)整,來提交數(shù)據(jù)的安全。
同時,有可能影響同步模式的還包括rpl_semi_sync_master_wait_no_slave參數(shù)、影響復(fù)制等待超時的參數(shù)rpl_semi_sync_master_timeout等。當(dāng)rpl_semi_sync_master_wait_no_slave為OFF時,只要master發(fā)現(xiàn)Rpl_semi_sync_master_clients小于rpl_semi_sync_master_wait_for_slave_count,則master立即轉(zhuǎn)為異步模式;如果為ON時,如果在事務(wù)提交階段(master等待ACK)超時rpl_semi_sync_master_timeout,master會轉(zhuǎn)為異步模式。
對比
配置比較
其他
雖然MongoDB和MySQL在很多方面可以有類似或相似的設(shè)置,但是還是存在一些區(qū)別,比如:
MongoDB的journal中包含了oplog的信息;而binlog和redo log是兩個相對獨立的內(nèi)容;
MySQL幾乎所有的寫操作都是基于事務(wù)來提交的;而MongoDB在4.0開始支持多文檔的事務(wù),單文檔的事務(wù)基于內(nèi)部事務(wù)邏輯實現(xiàn),未直接提供給用戶;
MySQL的寫確認(rèn)是已commit提交成功為標(biāo)志,MongoDB的普通寫操作是返回寫入成功為標(biāo)志;事務(wù)寫操作也是已commit為標(biāo)志;
總結(jié)
本文章所介紹的寫確認(rèn)的概念,涉及到了MongoDB與MySQL的日志文件(redo log/journal)、同步用日志(binlog/oplog)、刷盤機(jī)制和時機(jī)、主從同步架構(gòu)等多個流程和模塊,目的就是實現(xiàn)寫操作的原子性、持久性、分布式環(huán)境下的數(shù)據(jù)一致性等,對數(shù)據(jù)的性能和安全都有影響,需要根據(jù)數(shù)據(jù)、業(yè)務(wù)、壓力、安全等客觀因素去調(diào)整。
由于涉及的內(nèi)容非常多,未對所有的情況進(jìn)行測試驗證,可能有疏漏或錯誤,希望大家不吝賜教。也希望本篇內(nèi)容對于對MySQL和MongoDB都有興趣的同學(xué)可以作為一個總結(jié)和參考。
參考資料
以上,Enjoy~
點擊【閱讀】,可了解更多數(shù)據(jù)庫相關(guān)詳請
超強(qiáng)干貨來襲 云風(fēng)專訪:近40年碼齡,通宵達(dá)旦的技術(shù)人生總結(jié)
以上是生活随笔為你收集整理的mongodb mysql 写_MongoDB与MySQL关于写确认的异同的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql select 使用_mysq
- 下一篇: mariab修改mysql端口_修改my