這段時(shí)間一直在學(xué)習(xí)mysql數(shù)據(jù)庫(kù)。項(xiàng)目組一直用的是oracle,所以對(duì)mysql的了解也不深。本文主要是對(duì)mysql鎖的總結(jié)。 Mysql的鎖主要分為3大類: 表級(jí)鎖:存儲(chǔ)引擎為Myisam。鎖住整個(gè)表,特點(diǎn)是開(kāi)銷小,加鎖快,鎖定力度大,發(fā)生鎖沖突的概率最高,并發(fā)度最低。 頁(yè)級(jí)鎖:存儲(chǔ)引擎為BDB。鎖住某一頁(yè)的數(shù)據(jù)(16kb左右),特點(diǎn):開(kāi)銷和枷鎖時(shí)間介于表級(jí)和行級(jí)之間;會(huì)出現(xiàn)死鎖,鎖定力度介于表鎖和行鎖之間,并發(fā)度一般。 行級(jí)鎖:存儲(chǔ)引擎為innodb。鎖住某一行的數(shù)據(jù),特點(diǎn):鎖的實(shí)現(xiàn)更加復(fù)雜,開(kāi)銷大,加鎖速度慢。 根據(jù)以上特點(diǎn),僅從鎖的角度來(lái)說(shuō):表級(jí)鎖更適合于以查詢?yōu)橹?,只有少量按索引條件更新數(shù)據(jù)的應(yīng)用,如Web應(yīng)用;而行級(jí)鎖則更適合于有大量按索引條件并發(fā)更新少量不同數(shù)據(jù),同時(shí)又有并發(fā)查詢的應(yīng)用,如一些在線事務(wù)處理(OLTP)系統(tǒng)。 接下來(lái)進(jìn)行行級(jí)鎖的詳解,行級(jí)鎖主要分為以下7類:共享/排他鎖、意向鎖、記錄鎖、間隙鎖、臨建鎖、插入意向鎖、自增鎖。 共享/排他鎖: 共享鎖:又稱讀鎖,可以允許讀,但不能寫。共享鎖可以與共享鎖一起使用。語(yǔ)句: select ... lock in share mode 排他鎖:又稱寫鎖,不能允許讀,也不能允許寫,排他鎖不能與其他所一起使用。語(yǔ)句: select ... for update 在mysql中,update,delete,insert,alter這些寫的操作默認(rèn)都會(huì)加上排他鎖。Select默認(rèn)不會(huì)加任何鎖類型。一旦寫數(shù)據(jù)的任務(wù)沒(méi)有完成,數(shù)據(jù)是不能被其他任務(wù)讀取的,這對(duì)并發(fā)操作有較大的影響。 意向鎖:innoDB為了支持多粒度的鎖,即允許行級(jí)鎖和表級(jí)鎖共存,而引入意向鎖。意向鎖是指未來(lái)的某個(gè)時(shí)刻,事務(wù)可能要加共享/排他鎖,先提前聲明一個(gè)意向。這樣如果有人嘗試對(duì)全表進(jìn)行修改,就不需要判斷表中的數(shù)據(jù)是否被加鎖了,只需要通過(guò)等待意向互斥鎖被釋放就行了。 意向共享鎖(IS):事務(wù)想要在獲得表中某些記錄的共享鎖,需要在表上先加意向共享鎖。 意向互斥鎖(IX):事務(wù)想要在獲得表中某些記錄的互斥鎖,需要在表上先加意向互斥鎖。 意向鎖其實(shí)不會(huì)阻塞全表掃描之外的任何請(qǐng)求,它們的主要目的是為了表示是否有人請(qǐng)求鎖定表中的某一行數(shù)據(jù)。 記錄鎖(RS):?jiǎn)蝹€(gè)行記錄上的鎖。記錄鎖總是會(huì)鎖住索引記錄,如果innoDB存儲(chǔ)引擎表 在建立的時(shí)候沒(méi)有設(shè)置任何一個(gè)索引,那么innoDB存儲(chǔ)引擎會(huì)使用隱式的主鍵來(lái)進(jìn)行鎖定。 間隙鎖(GR):間隙鎖鎖住記錄中的間隔,即范圍查詢的記錄。 Select * From user where id between 1 and 10 for update 這個(gè)腳本會(huì)鎖住1到10 的數(shù)據(jù),以防止其他事務(wù)修改該區(qū)間的記錄; 間隙鎖的主要目的,就是為了防止其他事務(wù)在間隔中插入數(shù)據(jù),以導(dǎo)致“不可重復(fù)讀”。如果把事務(wù)的隔離級(jí)別降級(jí)為讀提交(Read Committed, RC),間隙鎖則會(huì)自動(dòng)失效 臨建鎖(next-key Locks):臨建鎖是記錄鎖和間隙鎖的組合,鎖的范圍既包含記錄又包含索引區(qū)間。默認(rèn)情況下,innoDB使用臨建鎖來(lái)鎖定記錄。但當(dāng)查詢的索引含有唯一屬性的時(shí)候,臨建鎖會(huì)進(jìn)行優(yōu)化,將其降級(jí)為記錄鎖,即僅鎖住索引本身,不是范圍。 臨鍵鎖的主要目的,也是為了避免幻讀(Phantom Read)。如果把事務(wù)的隔離級(jí)別降級(jí)為RC,臨鍵鎖則也會(huì)失效。 插入意向鎖(insert intention locks):對(duì)已有數(shù)據(jù)行的修改和刪除,必須加互斥鎖,對(duì)于數(shù)據(jù)的插入,加插入意向鎖。是專門針對(duì)于insert操作的。 自增鎖(auto-inc locks):是一種特殊的表級(jí)別的鎖,專門針對(duì)事務(wù)插入auto-increment類型的列。最簡(jiǎn)單的情況,如果一個(gè)事務(wù)正在往表中插入記錄,所有其他事務(wù)的插入必須等待,以便第一個(gè)事務(wù)插入的行,是連續(xù)的主鍵值。 ---------------------------------------------------------分界線-------------------------------------------------------------- 接下看講一下其他的鎖: 死鎖:產(chǎn)生是因?yàn)榫€程鎖之間交替等待產(chǎn)生的。值兩個(gè)或兩個(gè)以上的事務(wù)在執(zhí)行過(guò)程中,因爭(zhēng)奪資源而造成的一種相互等待的現(xiàn)象。 Mysql處理死鎖的方法:根據(jù)數(shù)據(jù)寫的數(shù)據(jù)量的大小來(lái)回滾小事務(wù)。 樂(lè)觀/悲觀鎖: 樂(lè)觀鎖:樂(lè)觀的假定大概率不會(huì)發(fā)生并發(fā)更新沖突,訪問(wèn),處理數(shù)據(jù)的過(guò)程中不加鎖,只在更新數(shù)據(jù)時(shí)根據(jù)版本號(hào)或時(shí)間戳判斷是否有沖突,有則處理,無(wú)責(zé)提交事務(wù)。 如果系統(tǒng)并發(fā)量非常大,悲觀鎖會(huì)帶來(lái)非常大的性能問(wèn)題,選擇使用樂(lè)觀鎖,現(xiàn)在大部分應(yīng)用屬于樂(lè)觀鎖 悲觀鎖:悲觀的假定大概率會(huì)發(fā)生并發(fā)更新沖突,訪問(wèn),處理數(shù)據(jù)前就加排他鎖,在整個(gè)數(shù)據(jù)處理過(guò)程中鎖定數(shù)據(jù),事務(wù)提交或回滾后才釋放鎖。 優(yōu)點(diǎn): 悲觀并發(fā)控制實(shí)際上是“先取鎖再訪問(wèn)”的保守策略,為數(shù)據(jù)處理的安全提供了保證。 缺點(diǎn): (a)在效率方面,處理加鎖的機(jī)制會(huì)讓數(shù)據(jù)庫(kù)產(chǎn)生額外的開(kāi)銷,還有增加產(chǎn)生死鎖的機(jī)會(huì); (b) 在只讀型事務(wù)處理中由于不會(huì)產(chǎn)生沖突,也沒(méi)必要使用鎖,這樣做只能增加系統(tǒng)負(fù)載;還有會(huì)降低了并行性,一個(gè)事務(wù)如果鎖定了某行數(shù)據(jù),其他事務(wù)就必須等待該事務(wù)處理完才可以處理那行數(shù) 建議:
|
|