亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Mysql中的Innodb事務(wù)和鎖詳解

 更新時(shí)間:2023年09月11日 11:01:07   作者:feiyingHiei  
這篇文章主要介紹了Mysql中的Innodb事務(wù)和鎖詳解,InnoDB是MySQL的一種存儲(chǔ)引擎,它是一種可靠性和性能非常好的存儲(chǔ)引擎,它具有ACID事務(wù)支持,可以提供高并發(fā)性和數(shù)據(jù)完整性,需要的朋友可以參考下

Innodb事務(wù)和鎖

一. 事務(wù)隔離級(jí)別

  1. READ UNCOMMITED :讀未提交,事務(wù)之間可以看到彼此之間正在修改的內(nèi)容,會(huì)出現(xiàn)所謂的臟讀現(xiàn)象
  2. READ COMMITED : 讀已提交,只能讀取已經(jīng)提交的事務(wù)修改的數(shù)據(jù),不會(huì)出現(xiàn)臟讀的現(xiàn)象,但會(huì)出現(xiàn)不可重復(fù)讀和幻讀的情況
  3. REPEATABLE READ : 可重復(fù)度,在innodb中解決了不可重復(fù)讀和幻讀的問(wèn)題
  4. SERIALIZED : 串行化, 這個(gè)使用的比較少,隔離性最強(qiáng),性能也最差

二. 鎖類型

  • S LOCK : 共享鎖 : S鎖與S鎖相互兼容,與X鎖不兼容
  • X LOCK :排他鎖 :與其他所有鎖類型不兼容,簡(jiǎn)單的可以理解為讀寫(xiě)鎖即可
  • 意向鎖 (IS, IX) : 主要是用來(lái)表達(dá)加鎖的一種層次概念,比如希望在行級(jí)別加X(jué)鎖,那么就需要在表級(jí)和頁(yè)級(jí)別加上IX鎖,意向鎖整體上兼容性會(huì)比較好,如果當(dāng)前表中已經(jīng)有了多個(gè)行級(jí)鎖,如果希望嘗試加表鎖,如果沒(méi)有意向鎖的話,那么就需要取檢測(cè)當(dāng)前行鎖的加鎖情況,但是有了意向鎖,就可以快速判斷當(dāng)前嘗試加表鎖可能是需要等待的。

監(jiān)控方法

  • SHOW ENGINE INNODB STATUS 命令查看innodb引擎信息,其中包含當(dāng)前執(zhí)行事務(wù)的狀態(tài)和鎖的狀態(tài)
  • 通過(guò)information_schema提供的表來(lái)排查可能存在的問(wèn)題
    • a. information_schema.innodb_trx
    • b. information_schema.innodb_locks
    • c. innodb_lock_waits

三.鎖釋放的時(shí)機(jī)

lock通常在事務(wù)commit或是rollback之后才會(huì)釋放

四. 一致性非鎖定讀

這是非常常見(jiàn)的問(wèn)題,事務(wù)中會(huì)有大量的select操作,select操作通常情況下是不會(huì)對(duì)數(shù)據(jù)做加鎖操作的, 這樣保證了數(shù)據(jù)的并發(fā)性能,在不同的事務(wù)隔離級(jí)別下,非一致性鎖定讀的行為是不太一樣的

  • READ COMMITED : 讀取undo_log中該行最新的一條快照數(shù)據(jù)
  • READ REPETABLE : 讀取undo_log中,最近的早于當(dāng)前事務(wù)開(kāi)啟時(shí)間的快照數(shù)據(jù)

五. 加鎖算法

上文描述了鎖的類型,即排它鎖,共享鎖,意向鎖之類,這里所說(shuō)的是加鎖的算法,即為innodb使用了什么樣的加鎖策略來(lái)處理實(shí)際場(chǎng)景中的并發(fā)問(wèn)題。

  • record lock : 行鎖,對(duì)單個(gè)行記錄進(jìn)行加鎖,行是innodb的最小數(shù)據(jù)管理單位,innodb中有專門(mén)的數(shù)據(jù)結(jié)構(gòu)來(lái)存儲(chǔ)和管理行記錄,我們所有的查詢的數(shù)據(jù)最終都會(huì)落到存儲(chǔ)引擎的行上
  • gap lock : 間隙鎖,即對(duì)間隙加鎖,間隙其實(shí)就這里只是針對(duì)間隙,不包括行(todo ,間隙的概念需要搞一下)
  • next-key lock : 對(duì)行和間隙和行都進(jìn)行加鎖

netx-key lock算法主要解決的問(wèn)題就是幻讀問(wèn)題,因此這個(gè)算法只在 RR事務(wù)隔離級(jí)別中會(huì)使用

疑問(wèn)? 不是MVCC可以在無(wú)鎖的情況下解決幻讀的問(wèn)題嗎,為什么還要上next-key lock這么重的算法呢?這里就要引出兩個(gè)概念了,一致性非鎖定讀(快照讀) 和一致性鎖定讀(當(dāng)前讀) 的概念了

一致性非鎖定讀 : 我們平時(shí)使用的select * from table 這種查詢語(yǔ)句,都是快照讀,在innodb RC和RR級(jí)別下都是通過(guò)MVCC機(jī)制來(lái)實(shí)現(xiàn)的,過(guò)程中是不加鎖的,讀取的數(shù)據(jù)未必是當(dāng)前行中的真實(shí)的數(shù)據(jù)。

一致性鎖定讀 : select * from table for update 或者select * from table in shared mode 在這種情況下RC基本是會(huì)對(duì)對(duì)應(yīng)的行加鎖,RR級(jí)別下就會(huì)使用next-key算法加鎖。

六、redo日志

redo日志是物理日志,記錄的頁(yè)的物理修改日志

七、undo日志

undo日志是邏輯日志,記錄的是操作的sql邏輯,通常我們?cè)谛薷臄?shù)據(jù)的時(shí)候,先對(duì)行加鎖,然后將該版本的數(shù)據(jù)拷貝到undo日志中,然后修改當(dāng)前行的操作事務(wù)id,修改該行事務(wù),然后把回滾指針指向und日志。

七、MVCC

多版本控制(MVCC)在許多關(guān)系型數(shù)據(jù)庫(kù)中都有實(shí)現(xiàn),innodb中主要是依賴undo日志來(lái)實(shí)現(xiàn),其中涉及到的一個(gè)比較重要的概念就是read veiw

  • low_limit_id :最大活躍事務(wù)id
  • up_limit_id : 最小活躍事務(wù)id
  • trx_ids : 活躍事務(wù)集合
  • 如果當(dāng)前trx_id > low_limit_id,那數(shù)據(jù)一定是不可見(jiàn)的,因?yàn)閿?shù)據(jù)是在當(dāng)前事務(wù)開(kāi)啟后才修改的
  • 如果當(dāng)前trx_id < up_limit_id,那么數(shù)據(jù)一定是可見(jiàn)的,因?yàn)槭聞?wù)在當(dāng)前事務(wù)開(kāi)啟前就已經(jīng)提交了
  • 如果trx_id 在這之間,那么如果trx_id在trx_ids中,說(shuō)明事務(wù)還沒(méi)有提交,那么數(shù)據(jù)就不可見(jiàn), 否則事務(wù)就是可見(jiàn)的。

無(wú)論是在什么事務(wù)隔離級(jí)別下,基于read view的快照讀機(jī)制都相同的,只是創(chuàng)建read view的機(jī)制不太一樣。

在RR基本下,read view在事務(wù)開(kāi)啟的時(shí)候就創(chuàng)建完成了,二在RC級(jí)別下,每次查詢都會(huì)重新創(chuàng)建read view。

如果一個(gè)當(dāng)前事務(wù)為事務(wù)A, 另外一個(gè)事務(wù)是事務(wù)B, 如果事務(wù)A開(kāi)啟的時(shí)候,事務(wù)B已經(jīng)提交了,那么無(wú)論在RR級(jí)別或是RC級(jí)別下,B提交的數(shù)據(jù)對(duì)于事務(wù)A都是可見(jiàn)的; 如果B事務(wù)在A事務(wù)開(kāi)啟之前就已經(jīng)開(kāi)啟了,但是A啟動(dòng)的時(shí)候B事務(wù)還沒(méi)有提交,那么先讓無(wú)論RR級(jí)別還是RC級(jí)別,數(shù)據(jù)在快照讀模式下也都是不可見(jiàn)的;如果B事務(wù)在A開(kāi)啟之前就開(kāi)啟,但是在A事務(wù)提交前B事務(wù)就提交了,此時(shí)對(duì)于RR級(jí)別而言,B的trx_id在trx_ids之中(trx_ids是在開(kāi)啟事務(wù)的時(shí)候就已經(jīng)初始化了),那么RR級(jí)別下數(shù)據(jù)是可見(jiàn)的,但對(duì)于RC而言,重新生成的read view了,顯然數(shù)據(jù)就是可見(jiàn)的。

通過(guò)上述的分析,通過(guò)mvcc可以在RR級(jí)別下快照讀是完全解決了重復(fù)讀和幻讀的問(wèn)題,RC級(jí)別還是會(huì)有不可重復(fù)讀和幻讀的問(wèn)題,但是需要注意的是,MVCC只工作在快照讀(一致性非鎖定讀)條件下,對(duì)于當(dāng)前讀的問(wèn)題是無(wú)法走到MVCC的,所以一定要注意,MVCC只解決了快照讀的幻讀和不可重復(fù)讀問(wèn)題。

這里需要補(bǔ)充一個(gè)case來(lái)理解一下快照讀與當(dāng)前讀的巨大區(qū)別

CREATE TABLE `user_info` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(10) NOT NULL DEFAULT '',
  `age` int(10) unsigned NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`)
)
事務(wù)隔離級(jí)別為RR

初始化數(shù)據(jù)

insert into user_info ('name', 'age') values ('jack', 1);

T1時(shí)刻A開(kāi)啟事務(wù),然后啟用快照讀

select * from user_info where id = 1;

查詢到的結(jié)果是

+----+------+-----+
| id | name | age |
+----+------+-----+
|  1 | tom  |   0 |
+----+------+-----+

T2時(shí)刻我們開(kāi)啟事務(wù)B, 并且執(zhí)行

update user_info set age =1 where id = 1;

此時(shí)事務(wù)A中執(zhí)行當(dāng)前讀

select * from user_info where id = 1 for update;

事務(wù)A將會(huì)被阻塞 此時(shí)提交事務(wù)B,事務(wù)A中顯示的查詢結(jié)果為

+----+------+-----+
| id | name | age |
+----+------+-----+
|  1 | tom  |   1 |
+----+------+-----+

然后我們?cè)俅螆?zhí)行一次快照讀

select * from user_info where id = 1;

獲得的結(jié)果為

+----+------+-----+
| id | name | age |
+----+------+-----+
|  1 | tom  |   0 |
+----+------+-----+

通過(guò)上述的例子,可以看到,快照讀和當(dāng)前讀有著非常大的區(qū)別,在同一個(gè)事務(wù)當(dāng)中,快照讀和當(dāng)前讀返回的結(jié)果有可能是不一樣的。

我們看到,mvcc保證了快照讀每次讀取的數(shù)據(jù)是一致,next-key算法保證了當(dāng)前讀是一致。

到此這篇關(guān)于Mysql中的Innodb事務(wù)和鎖詳解的文章就介紹到這了,更多相關(guān)Innodb事務(wù)和鎖內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論