1.什么是MVCC?有什么作用腔剂?
多版本并發(fā)控制媒区,在理解MVCC前,先了解一下鎖的概念掸犬,當(dāng)有兩個或多個用戶讀寫數(shù)據(jù)庫時袜漩,為了保證數(shù)據(jù)的一致性,要給數(shù)據(jù)庫上鎖湾碎,鎖分兩種宙攻,讀鎖和寫鎖。
讀鎖也叫共享鎖介褥,當(dāng)一個用戶在讀數(shù)據(jù)時座掘,給數(shù)據(jù)加上讀鎖,此時其它用戶還可以共享讀這部分?jǐn)?shù)據(jù)柔滔,但是不能更新數(shù)據(jù)溢陪,必須要等到前一用戶讀鎖釋放,然后給數(shù)據(jù)加上寫鎖廊遍,才能更新數(shù)據(jù)嬉愧。
寫鎖也叫排它鎖,顧名思義喉前,數(shù)據(jù)加上寫鎖以后没酣,其它用戶不能讀也不能寫。
加鎖保證了數(shù)據(jù)的一致性卵迂,但是數(shù)據(jù)在同一時間只能串行訪問裕便,特別是寫鎖時,為了讓更多用戶或連接同時訪問數(shù)據(jù)见咒,鎖的粒度細(xì)分可以增加并發(fā)偿衰,鎖的粒度分為表鎖,行鎖改览。比如一個用戶在更新A表下翎,另一個可以訪問B表,相互不受影響宝当,這是表鎖视事,還有行鎖,一個用戶在更新A表的a行庆揩,另一個用戶可以訪問A表的b行俐东,也互不影響跌穗。所以粒度越細(xì),并發(fā)越高虏辫,但是開銷也越大蚌吸。
理解了鎖和鎖的粒度以后,再來看MVCC砌庄,為了更進(jìn)一步提高并發(fā)羹唠,特別是一些讀多寫少的應(yīng)用系統(tǒng),MVCC對數(shù)據(jù)行提供多個版本的數(shù)據(jù)快照功能鹤耍,使同一數(shù)據(jù)讀寫操作可以并發(fā)進(jìn)行肉迫。但也會引出不可重復(fù)讀,幻讀問題稿黄。
Innodb中的MVCC實(shí)現(xiàn)的方法是給每行數(shù)據(jù)添加兩個隱式字段喊衫,創(chuàng)建時間和刪除時間,這里的時間不是真的時間杆怕,應(yīng)稱為系統(tǒng)版本號族购,系統(tǒng)每開始一個事務(wù),系統(tǒng)版本號遞增陵珍,新開始的事務(wù)將系統(tǒng)版本號作為事務(wù)的版本號寝杖,當(dāng)一個用戶在讀某行數(shù)據(jù)時,只會讀到創(chuàng)建時間小于等于自己版本號(假定版本號為1)互纯,刪除時間大于自己的版本號或者為空的數(shù)據(jù)瑟幕,另一事務(wù)(版本號為2)此時對數(shù)據(jù)a進(jìn)行更新操作,會先將自己的版本號2寫入a的刪除時間字段留潦,然后新增一條更新過的數(shù)據(jù)c只盹,將版本號2寫入c的創(chuàng)建時間字段,如果事務(wù)2要刪除某行b兔院,只需將自己的版本號2寫入數(shù)據(jù)b的刪除時間字段內(nèi)殖卑。此時前一個事務(wù)1還是可以讀到數(shù)據(jù)a和c,因?yàn)閍坊萝,c數(shù)據(jù)的刪除時間大于事務(wù)1的版本號孵稽。卻讀不到數(shù)據(jù)b,因?yàn)閿?shù)據(jù)b創(chuàng)建時間大于事務(wù)1十偶。當(dāng)然這只是簡化的理解菩鲜,實(shí)際運(yùn)行要復(fù)雜得多。
所以MVCC的作用主要為了保證數(shù)據(jù)的一致性同時惦积,提供高并發(fā)能力接校。下面的隔離級別會詳細(xì)描述。
2.ACID中的I是怎么實(shí)現(xiàn)的荣刑?
ACID是支持事務(wù)數(shù)據(jù)庫的必備特性馅笙,分別是原子性,一致性厉亏,隔離性董习,持久性。
其中隔離性是指一個事務(wù)開始后但還未提交爱只,其它事務(wù)是看不到這個事務(wù)更新的結(jié)果的皿淋。
隔離性有四個級別,分別是read uncommitted未提交讀,read committed提交讀恬试,repeatable read可重復(fù)讀窝趣,serializable可串行化。
其中read uncommitted 級別训柴,舉例如事務(wù)1按執(zhí)行順序?qū)σ僮鞯臄?shù)據(jù)a加鎖哑舒,操作數(shù)據(jù)a,釋放a鎖 ... 獲得數(shù)據(jù)b鎖幻馁,操作數(shù)據(jù)b,釋放b鎖洗鸵。在未提交前,事務(wù)2可以讀到已經(jīng)更新過的數(shù)據(jù)仗嗦,如果此時事務(wù)1執(zhí)行回滾膘滨,那么事務(wù)2讀到的數(shù)據(jù)就是臟數(shù)據(jù),也叫臟讀稀拐。
為了解決臟讀火邓,引入第二個隔離級別read committed ,當(dāng)事務(wù)1要操作一組數(shù)據(jù)時德撬,會先獲得數(shù)據(jù)的讀鎖或?qū)戞i铲咨,但是用完以后不會馬上釋放,而是等到事務(wù)提交或回滾時一起釋放砰逻。這種辦法就叫2PL(兩階段鎖協(xié)議)鸣驱,這樣就解決了臟讀,如果事務(wù)2想要讀事務(wù)1已經(jīng)更新但未提交的數(shù)據(jù)蝠咆,需獲得數(shù)據(jù)的讀鎖踊东,而事務(wù)1在未提交前是不會釋放寫鎖的,所以事務(wù)2只能等待事務(wù)1釋放鎖刚操。雖然解決了臟讀闸翅,但是會引起新的問題死鎖,當(dāng)兩個事務(wù)都在等待對方已經(jīng)持有的鎖時菊霜,就會發(fā)生死鎖坚冀,所以必須設(shè)計(jì)檢測死鎖機(jī)制。
另外還有一個問題叫不可重復(fù)讀鉴逞,有的應(yīng)用系統(tǒng)希望事務(wù)內(nèi)讀取的數(shù)據(jù)始終一致记某,即事務(wù)1開始后查詢了一組數(shù)據(jù)a司训,同時事務(wù)2更新了數(shù)據(jù)據(jù)a并提交了,此時事務(wù)1再次查詢數(shù)據(jù)a液南,發(fā)現(xiàn)跟第一次查詢時不一致了壳猜。如果單單使用2pl協(xié)議是不會產(chǎn)生不可重復(fù)讀問題的,為什么滑凉?因?yàn)槭聞?wù)1開始查詢數(shù)據(jù)a時统扳,事務(wù)2不可能獲得數(shù)據(jù)a的寫鎖來更新數(shù)據(jù)〕╂ⅲ可是為什么還是會有這個問題咒钟,這是因?yàn)槭褂脙呻A段鎖協(xié)議后,數(shù)據(jù)的吞吐量降低了若未,相當(dāng)于串行化了事務(wù)朱嘴。所以mysql引入MVCC來提高性能,并發(fā)讀寫時陨瘩,相互不阻塞腕够,而利用精巧的版本控制功能解決臟讀,不可重讀問題舌劳。但是寫寫仍然要使用鎖機(jī)制帚湘。
第三個級別是repeatable read可重復(fù)讀 ,如上所述利用MVCC可以解決不可重讀的問題甚淡。但還是有一個幻讀問題大诸,即事務(wù)1開始后讀取數(shù)據(jù)集a是n條,此時事務(wù)2在表中新增一條記錄并提交贯卦,事務(wù)1再次讀取數(shù)據(jù)集a是n+1條资柔。稱為幻讀。mysql用next-key lock來解決撵割,簡單理解即事務(wù)1在第一次讀(當(dāng)前讀)數(shù)據(jù)時贿堰,給符合條件的數(shù)據(jù)行及涉及到的范圍加鎖(record lock+Gap lock),這樣其它事務(wù)就不能新增數(shù)據(jù)了啡彬。從而解決幻讀問題羹与。
至于第四個級別serializable,強(qiáng)制將所有事務(wù)串行化庶灿,大大降低并發(fā)纵搁。
本節(jié)參考http://hedengcheng.com/?p=771
本節(jié)參考https://www.zhihu.com/question/30272728/answer/132403859
3.2PC在數(shù)據(jù)庫中是怎么來實(shí)現(xiàn)的?
兩階段提交協(xié)議(Two-phase Commit往踢,2PC)經(jīng)常被用來實(shí)現(xiàn)分布式事務(wù)腾誉。在分布式事務(wù)數(shù)據(jù)庫中,每個節(jié)點(diǎn)(參與者)并不知道其它節(jié)點(diǎn)事務(wù)的執(zhí)行情況,這里需要一個總協(xié)調(diào)角色參與統(tǒng)一管理利职。
第一階段:協(xié)調(diào)者詢問參與者能否可以提交事務(wù)趣效。如果參與者事務(wù)操作執(zhí)行成功則回復(fù)yes,反之no
第二階段:參與者全部回復(fù)yes,協(xié)調(diào)者發(fā)出提交事務(wù)命令,參與者提交后回復(fù)完成給協(xié)調(diào)者猪贪。如果有一個參與者回復(fù)no英支,那么協(xié)調(diào)者發(fā)出中止命令,所有參與者回滾事務(wù)哮伟,回滾完成回復(fù)完成給協(xié)調(diào)者。
2PC協(xié)議因?yàn)榫W(wǎng)絡(luò)延遲妄帘,協(xié)調(diào)者宕機(jī)等原因存在單點(diǎn)故障楞黄,網(wǎng)絡(luò)阻塞的問題。
4.簡單講講CAP/base/paxos算法抡驼。
CAP理論認(rèn)為Consistency (數(shù)據(jù)一致性)鬼廓,Availability (可用性,正常響應(yīng))致盟,Partition Tolerance (分區(qū)容錯性碎税,節(jié)點(diǎn)宕機(jī)或網(wǎng)絡(luò)故障仍保證一致性和可用性)這三種特性不能同時滿足,只能滿足其二馏锡。
簡單的理解CAP理論雷蹂,假如有兩臺服務(wù)器A和B,運(yùn)行著相同的數(shù)據(jù)庫DB0,在正常的情況下杯道,用戶更新了A上的DB0匪煌,變成DB1,A與B通信進(jìn)行同步党巾,這時另一用戶訪問B上的DB萎庭,查看到的也是最新的DB1,這樣保證了一致證齿拂,和可用性驳规,但是當(dāng)A與B之間的通信斷開時,用戶更新了A上到DB2署海,B上還是DB1吗购,這時另一用戶再訪問B時,要么犧牲一致性叹侄,返回DB1給用戶巩搏,要么讓用戶等待通信恢復(fù),也是就犧牲可用性趾代。
那么通信在斷開形成網(wǎng)絡(luò)孤島時贯底,如何在可用性與一致性做出平衡呢,ACID理論要求保持強(qiáng)一致性,寧愿暫停服務(wù);BASE則想保持高可用禽捆,容許數(shù)據(jù)暫時不一致笙什。這是兩種不同的設(shè)計(jì)理念。
BASE的意思是指:
基本可用(Basically Available)允許部份功能不可用胚想,核心功能可用就行琐凭。
軟狀態(tài)( Soft State) 允許系統(tǒng)存在一種中間狀態(tài),
最終一致性( Eventual Consistency)數(shù)據(jù)可以因網(wǎng)絡(luò)延遲或宕機(jī)有不一致的情況浊服,但是經(jīng)過一段時間最終可以達(dá)到一致统屈。
paxos
Paxos是一種能夠基于多節(jié)點(diǎn)在不可靠的網(wǎng)絡(luò)條件下卻能可靠地實(shí)現(xiàn)共識的一致性的算法。
簡單描述如下牙躺,pasos系統(tǒng)內(nèi)有二種角色愁憔,一叫決策者,一叫提議者孽拷。
系統(tǒng)達(dá)成一項(xiàng)一致決定的過程分兩個階段:
首先是預(yù)決策階段吨掌,此時任意提議者都可以向決策者發(fā)送包含編號的預(yù)提議申請,決策者根據(jù)提議者編號的新舊程度進(jìn)行回復(fù)脓恕,如果提議者發(fā)送的編號是最新的膜宋,回復(fù)yes,并將編號存儲起來炼幔,如果提議者的編號小于決策者存儲的編號秋茫,那么回復(fù)no和存儲的編號。
第二階段是決策階段乃秀,提議者A收到了大多數(shù)決策者回復(fù)的ok学辱,于是正式向決策者發(fā)送提議信息a以及A的編號,決策者收到后环形,有兩種情況:
1策泣、如果在回復(fù)提議者A的ok信息之后一直到A再次發(fā)送正式提議信息a之間,都沒有再收到其它大于提議者A編號的預(yù)提議信息抬吟。也就是說存儲的編號仍然是提議者A申請的編號萨咕,那么決策者確定信息a為正式信息。將A的編號和提議信息都存起來火本∥6樱回復(fù)提議者A正式?jīng)Q定信息。提議者A統(tǒng)計(jì)回復(fù)的信息钙畔,如果占決策者的多數(shù)茫陆,則決議成功,向其它學(xué)習(xí)者廣播擎析。如果之后有其它提議者發(fā)送預(yù)提議申請簿盅,已經(jīng)決定了的決策者會拒絕并回復(fù)提議內(nèi)容a。
2、如果在回復(fù)提議者A的ok信息之后一直到A再次發(fā)送正式提議信息a之間桨醋,有其它提議者如B也發(fā)送了預(yù)提議申請信息棚瘟,并且編號比A大,一部分決策者將B的編號存起來喜最,并回復(fù)B準(zhǔn)備好了OK信息偎蘸。決策者是喜新厭舊的。所以這一部分決策者再次收到A的信息后瞬内,拒絕了A并回復(fù)了B的編號迷雪。A統(tǒng)計(jì)了一下決策者已經(jīng)決策成功的總數(shù)量沒有超過半數(shù),很不甘心虫蝶,于是將自己的編號在B的基礎(chǔ)上加1后振乏,再次向其它決策者發(fā)送預(yù)提議申請,回到第一階段秉扑。
經(jīng)過了這兩個階段后,每個提議者都可能獲得了一些決策者的支持调限,每個提議者會根據(jù)回復(fù)的提議信息進(jìn)行統(tǒng)計(jì)舟陆,將自己的提議改成支持最多的提議,直到形成半數(shù)以上決策者都同意了某個提議耻矮。決策結(jié)束秦躯。