mysql鎖機(jī)制 mysql鎖的分類
夕逆IT
- 開發(fā)語(yǔ)言
- 2023-08-13
- 89

這篇文章給大家聊聊關(guān)于mysql鎖機(jī)制,以及mysql鎖的分類對(duì)應(yīng)的知識(shí)點(diǎn),希望對(duì)各位有所幫助,不要忘了收藏本站哦。關(guān)于MySQL中的表鎖和行鎖1.程序中非數(shù)據(jù)庫(kù)交互操...
這篇文章給大家聊聊關(guān)于mysql鎖機(jī)制,以及mysql鎖的分類對(duì)應(yīng)的知識(shí)點(diǎn),希望對(duì)各位有所幫助,不要忘了收藏本站哦。
關(guān)于MySQL中的表鎖和行鎖
1.程序中非數(shù)據(jù)庫(kù)交互操作導(dǎo)致事務(wù)掛起
將接口調(diào)用或者文件操作等這一類非數(shù)據(jù)庫(kù)交互操作嵌入在SQL事務(wù)代碼之中,那么整個(gè)事務(wù)很有可能因此掛起(接口不通等待超時(shí)或是上傳下載大附件)。
2.事務(wù)中包含性能較差的查詢SQL
事務(wù)中存在慢查詢,導(dǎo)致同一個(gè)事務(wù)中的其他DML無(wú)法及時(shí)釋放占用的行鎖,引起行鎖等待。
3.單個(gè)事務(wù)中包含大量SQL
通常是由于在事務(wù)代碼中加入for循環(huán)導(dǎo)致,雖然單個(gè)SQL運(yùn)行很快,但是SQL數(shù)量一大,事務(wù)就會(huì)很慢。
4.級(jí)聯(lián)更新SQL執(zhí)行時(shí)間較久
這類SQL容易讓人產(chǎn)生錯(cuò)覺(jué),例如:updateAset...where...in(selectB)這類級(jí)聯(lián)更新,不僅會(huì)占用A表上的行鎖,也會(huì)占用B表上的行鎖,當(dāng)SQL執(zhí)行較久時(shí),很容易引起B(yǎng)表上的行鎖等待。
5.磁盤問(wèn)題導(dǎo)致的事務(wù)掛起
極少出現(xiàn)的情形,比如存儲(chǔ)突然離線,SQL執(zhí)行會(huì)卡在內(nèi)核調(diào)用磁盤的步驟上,一直等待,事務(wù)無(wú)法提交。
綜上可以看出,如果事務(wù)長(zhǎng)時(shí)間未提交,且事務(wù)中包含了DML操作,那么就有可能產(chǎn)生行鎖等待,引起報(bào)錯(cuò)。
mysql串行化加的什么鎖
MySQL大致可歸納為以下3種鎖:
表級(jí)鎖:開銷小,加鎖快;不會(huì)出現(xiàn)死鎖;鎖定粒度大,發(fā)生鎖沖突的概率最高,并發(fā)度最低。
行級(jí)鎖:開銷大,加鎖慢;會(huì)出現(xiàn)死鎖;鎖定粒度最小,發(fā)生鎖沖突的概率最低,并發(fā)度也最高。
頁(yè)面鎖:開銷和加鎖時(shí)間界于表鎖和行鎖之間;會(huì)出現(xiàn)死鎖;鎖定粒度界于表鎖和行鎖之間,并發(fā)度一般
mysql查詢會(huì)導(dǎo)致鎖表嗎
mysql鎖表或鎖行的情況是:
當(dāng)主鍵或者唯一索引的效果時(shí),是鎖行。但是如果“重復(fù)率”高時(shí),Mysql不會(huì)把這個(gè)普通索引當(dāng)做索引,即會(huì)造成一個(gè)沒(méi)有索引的SQL,從而形成鎖表。
特別是在UPDATE、DELETE操作時(shí),MySQL不僅鎖定WHERE條件掃描過(guò)的所有索引記錄,而且會(huì)鎖定相鄰的鍵值,即所謂的next-keylocking。
怎么解決數(shù)據(jù)庫(kù)Mysql自增鎖問(wèn)題
在innodb里里面又一個(gè)參數(shù)叫innodb_autoinc_lock_mode,它的值分別為0,1,2.
下面來(lái)說(shuō)說(shuō)這三個(gè)值分別是什么意思。
0:傳統(tǒng)方式。串行自增的,并且是連續(xù)的。這樣需要獨(dú)占的串行鎖,語(yǔ)句完成才釋放鎖,所以性能最低。例如:1、2、3、4、5、6
1:連續(xù)方式。自增的,并且是連續(xù)的。當(dāng)語(yǔ)句申請(qǐng)到自增鎖就釋放自增鎖,自增鎖就可以給其它語(yǔ)句使用。性能會(huì)好很多。這個(gè)是系統(tǒng)默認(rèn)的。例如:1、2、3、4、5、6
2:交錯(cuò)方式。多語(yǔ)句插入數(shù)據(jù)時(shí),有可能自增的序列號(hào)和執(zhí)行先后順不一致,并且中間可能有斷裂。一次分配一批自增值,然后下個(gè)語(yǔ)句就再進(jìn)行分配一批自增值,阻塞很小,性能很高。例如:1、2、3、6、5
樓主說(shuō)的自增鎖的問(wèn)題應(yīng)該就是并發(fā)高的時(shí)候,語(yǔ)句執(zhí)行完畢才會(huì)釋放鎖,所以可能會(huì)遇到語(yǔ)句阻塞。如果您不需要連續(xù)的自增id的話,可以把innodb_autoinc_lock_mode=2,并且把innodb_autoextend_increment設(shè)置大一些,例如innodb_autoextend_increment=10,這樣可以緩解mysql自增鎖的問(wèn)題。
但是在statement-basedreplication下不一定是安全的,因?yàn)樗迦氲臄?shù)據(jù)不一定是連續(xù)的,可能會(huì)導(dǎo)致一些主從不一致的情況。
mysql數(shù)據(jù)庫(kù)怎么設(shè)置樂(lè)觀鎖
樂(lè)觀鎖與悲觀鎖不同的是,它是一種邏輯上的鎖,而不需要數(shù)據(jù)庫(kù)提供鎖機(jī)制來(lái)支持
當(dāng)數(shù)據(jù)很重要,回滾或重試一次需要很大的開銷時(shí),需要保證操作的ACID性質(zhì),此時(shí)應(yīng)該采用悲觀鎖
而當(dāng)數(shù)據(jù)對(duì)即時(shí)的一致性要求不高,重試一次不太影響整體性能時(shí),可以采用樂(lè)觀鎖來(lái)保證最終一致性,同時(shí)有利于提高并發(fā)性
通常,樂(lè)觀鎖采用版本號(hào)/時(shí)間戳的形式實(shí)現(xiàn):給數(shù)據(jù)額外增加一個(gè)版本號(hào)字段進(jìn)行控制;更新時(shí),若提交的數(shù)據(jù)所帶的版本號(hào)與當(dāng)前記錄的版本號(hào)一致,則允許變更執(zhí)行并更新版本號(hào);若不一致,則意味著產(chǎn)生沖突,根據(jù)業(yè)務(wù)需求直接丟棄并返回失敗,或者嘗試合并
在MySQL的實(shí)踐中,常見(jiàn)的一種使用樂(lè)觀鎖的方法,是在需要使用樂(lè)觀鎖的表中,新增一個(gè)version字段
例如:
createtableproduct_amount(
idintnotnullprimarykeyauto_increment,
product_namevarchar(64)notnull,
selling_amountintnotnull,
storing_amountintnotnull,
versionintnotnull
);
當(dāng)需要更新銷售中的商品數(shù)量(selling_amount)時(shí),使用如下的SQL語(yǔ)句:
updateproduct_amountsetselling_amount=#{selling_amount},version=#{new_version}whereid=#{id}andversion=#{old_version};
若該語(yǔ)句返回1,則表示更新成功;若返回0,則表示前后的version不一致,產(chǎn)生沖突,更新失敗
對(duì)于更新倉(cāng)庫(kù)中的商品數(shù)據(jù)(storing_amount)時(shí),也是同理
不過(guò),這樣為每行記錄都統(tǒng)一設(shè)置一個(gè)version字段的樂(lè)觀鎖方式,存在一個(gè)問(wèn)題:上例中,如果同時(shí)需要單獨(dú)對(duì)selling_amount及storing_amount進(jìn)行update(兩條SQL語(yǔ)句分別單獨(dú)執(zhí)行),那么后執(zhí)行的一條會(huì)因?yàn)橄葓?zhí)行的一條更新了version字段而失敗,而這種失敗顯然是沒(méi)有必要的,白白浪費(fèi)了開銷
一種比較好的方式是為每個(gè)需要樂(lè)觀鎖的字段單獨(dú)設(shè)置版本號(hào),例如對(duì)上例的改造:
createtableproduct_amount(
idintnotnullprimarykeyauto_increment,
product_namevarchar(64)notnull,
selling_amountintnotnull,
selling_versionintnotnull,
storing_amountintnotnull,
storing_versionintnotnull
);
selling_amount和storing_amount分別擁有自己的樂(lè)觀鎖版本號(hào)(selling_version和storing_version),更新時(shí)分別只關(guān)注自己的版本號(hào),這樣就不會(huì)因?yàn)榘姹咎?hào)被其它字段修改而失敗,提高了并發(fā)性
mysql插入鎖等待超時(shí)
等待加鎖線程完畢后再執(zhí)行。以MyISAM表的表級(jí)寫鎖為例,MySql5.0說(shuō)得很清楚的:當(dāng)一個(gè)線程獲得對(duì)一個(gè)表的寫鎖后,只有持有鎖的線程可以對(duì)表進(jìn)行更新操作。其他線程的讀、寫操作都會(huì)等待,直到鎖被釋放為止。
文章分享結(jié)束,mysql鎖機(jī)制和mysql鎖的分類的答案你都知道了嗎?歡迎再次光臨本站哦!
本文鏈接:http://xinin56.com/kaifa/2911.html