日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 综合教程 >内容正文

综合教程

my40_MySQL锁概述之意向锁

發(fā)布時(shí)間:2023/12/13 综合教程 25 生活家
生活随笔 收集整理的這篇文章主要介紹了 my40_MySQL锁概述之意向锁 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

本文在鎖概述的基礎(chǔ)上,通常實(shí)驗(yàn)舉例,詳細(xì)地介紹了意向鎖的原理。

鎖范圍

全局鎖(global lock)
表鎖(table lock)
行鎖 (row lock)

ROW LOCK的粒度
LOCK_REC_NOG_GAP, record lock with out gap lock
LOCK_GAP, gap lock
LOCK_ORDINARY , next key lock = record lock + gap lock

鎖等待與死鎖
鎖等待 事務(wù)提交或等待超時(shí);死鎖,是一個(gè)死循環(huán)。死鎖中必有鎖等待。

表鎖
5.5以后在server層實(shí)現(xiàn)表鎖
innodb中有IS/IX表級(jí)鎖,以及自增鎖(auto-inc)

讀鎖
加讀鎖后,只能對(duì)表讀,不能對(duì)表寫(xiě);允許多個(gè)會(huì)話同時(shí)讀;其他會(huì)話可以加共享讀鎖
lock tabletable_name read

寫(xiě)鎖
lock table table_name write
持有鎖的會(huì)話可寫(xiě)可讀
其他會(huì)話訪問(wèn)表或請(qǐng)求加鎖都會(huì)被阻塞,直到鎖釋放

釋放鎖
unlock tables;
lock table 鎖不能相互嵌套,一個(gè)事務(wù)開(kāi)始就意味著另外一個(gè)事務(wù)結(jié)束
顯式開(kāi)啟一個(gè)事務(wù),因?yàn)槭聞?wù)中不能支持表鎖,所以事務(wù)開(kāi)始則表鎖斷開(kāi)
Kill或連接斷開(kāi)

innodb鎖
默認(rèn)為行鎖
在索引上加鎖來(lái)實(shí)現(xiàn)行鎖
如果沒(méi)有索引,那么升級(jí)為全表記錄鎖,最終效果等同于表鎖;但表鎖只需要在根節(jié)點(diǎn)上加鎖,而不是對(duì)所有記錄加鎖,所以代價(jià)要小一些

鎖類(lèi)型
共享鎖
排他鎖/獨(dú)占鎖
意向鎖,innodb特有,加在表級(jí)別上的鎖

共享鎖與獨(dú)占鎖均用于事務(wù)當(dāng)中,隨事務(wù)的結(jié)束而解除。

共享鎖(share lock)
又稱(chēng)讀鎖,讀取操作創(chuàng)建的鎖。
一旦上鎖,任何事務(wù)(包括當(dāng)前事務(wù))無(wú)法對(duì)其修改,其他事務(wù)可以并發(fā)讀取數(shù)據(jù),也可在對(duì)此數(shù)據(jù)再加共享鎖
語(yǔ)法:SELECT ... LOCK IN SHARE MODE;

排他鎖(exclusive lock)
又稱(chēng)寫(xiě)鎖,如果事務(wù)對(duì)數(shù)據(jù)A加上排他鎖后,則其他事務(wù)不可并發(fā)讀取數(shù)據(jù),也不能再對(duì)A加任何類(lèi)型的鎖。獲得排他鎖的事務(wù)既能讀數(shù)據(jù),又能修改數(shù)據(jù)。
語(yǔ)法:SELECT ... FOR UPDATE
這里的“其他事務(wù)不可并發(fā)讀取數(shù)據(jù)”,指的是不可以加共享鎖,即不可以以lock in share mode的方式讀取數(shù)據(jù),比如

會(huì)話一

mysql> select * from test for update;
+----+------+------+
| id | v1   | v2   |
+----+------+------+
|  1 |    1 |    0 |
|  2 |    3 |    1 |
|  3 |    4 |    2 |
|  5 |    5 |    3 |
|  7 |    7 |    4 |
| 10 |    9 |    5 |
+----+------+------+
6 rows in set (0.00 sec)

會(huì)話二:

mysql> select * from test lock in share mode;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

直接查詢(xún)完全可以

mysql> select * from test;
+----+------+------+
| id | v1   | v2   |
+----+------+------+
|  1 |    1 |    0 |
|  2 |    3 |    1 |
|  3 |    4 |    2 |
|  5 |    5 |    3 |
|  7 |    7 |    4 |
| 10 |    9 |    5 |
+----+------+------+
6 rows in set (0.00 sec)

這是因?yàn)橹苯硬樵?xún)走的是一致性快照讀,讀的是MVCC版本控制下的快照,不加鎖;換句話說(shuō),排他鎖排斥的“讀”,是指S鎖下的讀,或者說(shuō)是當(dāng)前讀

意向鎖
InnoDB的表級(jí)鎖,其設(shè)計(jì)目的主要是為了在一個(gè)事務(wù)中揭示下一步將要被請(qǐng)求的鎖的類(lèi)型。
InnoDB中的兩個(gè)表鎖:
意向共享鎖(IS):表示事務(wù)準(zhǔn)備給數(shù)據(jù)行加入共享鎖,也就是說(shuō)一個(gè)數(shù)據(jù)行加共享鎖前必須先取得該表的IS鎖
意向排他鎖(IX):類(lèi)似上面,表示事務(wù)準(zhǔn)備給數(shù)據(jù)行加入排他鎖,說(shuō)明事務(wù)在一個(gè)數(shù)據(jù)行加排他鎖前必須先取得該表的IX鎖。
意向鎖是InnoDB自動(dòng)加的,不需要用戶(hù)干預(yù)。

意向鎖是表級(jí)鎖
事務(wù)要獲取表A某些行的S鎖必須要獲取表A的IS鎖
事務(wù)要獲取表A某些行的X鎖必須要獲取表A的IX鎖

上表描述幾種鎖之間的的關(guān)系,其中AI是自增鎖,表主健自增用到。

會(huì)話一鎖定了全表

會(huì)話二,結(jié)果集為空時(shí)不加鎖

意向鎖的目的在于提高innodb性能,會(huì)話一鎖定的是全表,那么會(huì)話二一看全表已被鎖定,則不再去看每行是否鎖定
會(huì)話二先判斷表上有沒(méi)有表鎖,如果沒(méi)有表級(jí)鎖,則開(kāi)始判斷有沒(méi)有行級(jí)鎖

會(huì)話一:不鎖定全表的S鎖

會(huì)話二:立即執(zhí)行,不被鎖;v1上有索引

v1字段上有索引,v2字段上沒(méi)有索引;有索引時(shí),優(yōu)先按有索引的規(guī)則來(lái),當(dāng)字段上沒(méi)有索引時(shí),S鎖,X鎖走意向鎖的邏輯;
會(huì)話一

mysql> begin;select * from test where v1 >4 lock in share mode;
Query OK, 0 rows affected (0.00 sec)

+----+------+------+
| id | v1   | v2   |
+----+------+------+
|  5 |    5 |    3 |
|  7 |    7 |    4 |
| 10 |    9 |    5 |
+----+------+------+
3 rows in set (0.00 sec)

mysql> rollback;
Query OK, 0 rows affected (0.00 sec)

mysql> begin;select * from test where v2 >4 lock in share mode;
Query OK, 0 rows affected (0.00 sec)

+----+------+------+
| id | v1   | v2   |
+----+------+------+
| 10 |    9 |    5 |
+----+------+------+
1 row in set (0.00 sec)

會(huì)話二:

mysql> begin;select * from test where v1 < 2 for update;
Query OK, 0 rows affected (0.00 sec)

+----+------+------+
| id | v1   | v2   |
+----+------+------+
|  1 |    1 |    0 |
+----+------+------+
1 row in set (0.00 sec)

mysql> rollback;
Query OK, 0 rows affected (0.00 sec)

mysql> 
mysql> 
mysql> begin;select * from test where v2 < 2 for update;
Query OK, 0 rows affected (0.00 sec)

ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
mysql> 

如果不是S鎖,而是快照讀的話,不會(huì)走意向鎖的邏輯,因?yàn)榭煺兆x不加鎖(不管是RC還是RR隔離級(jí)別);

會(huì)話一

mysql> begin;select * from test where v2 >4;
Query OK, 0 rows affected (0.00 sec)

+----+------+------+
| id | v1   | v2   |
+----+------+------+
| 10 |    9 |    5 |
+----+------+------+
1 row in set (0.00 sec)

會(huì)話二:立即執(zhí)行,沒(méi)有鎖等待

mysql> begin;select * from test where v2 < 2 for update;
Query OK, 0 rows affected (0.00 sec)

+----+------+------+
| id | v1   | v2   |
+----+------+------+
|  1 |    1 |    0 |
|  2 |    3 |    1 |
+----+------+------+
2 rows in set (0.00 sec)

對(duì)于無(wú)索引的情況,更新任何一條記錄,都會(huì)對(duì)該表加鎖,這時(shí)意向鎖將非常有用;但這個(gè)場(chǎng)景有個(gè)例外-->“半一致性讀”

半一致性讀的條件:
5.7及以下版本時(shí),需要innodb_locks_unsafe_for_binlog 開(kāi)啟或事務(wù)隔離級(jí)別為RC,語(yǔ)言類(lèi)型為update
8.0版本,語(yǔ)言類(lèi)型為update,事務(wù)隔離級(jí)別為RC;innodb_locks_unsafe_for_binlog 參數(shù)被廢棄。

8.0中半一致性讀測(cè)試
mysql> set global transaction isolation level read committed;
Query OK, 0 rows affected (0.00 sec)

會(huì)話一

mysql> begin;select * from test where v2 >4 for update;
Query OK, 0 rows affected (0.00 sec)

+----+------+------+
| id | v1   | v2   |
+----+------+------+
| 10 |    9 |    5 |
+----+------+------+
1 row in set (8.77 sec)

會(huì)話二:顯式開(kāi)始一個(gè)事務(wù)被阻塞,直接使用update語(yǔ)句不被阻塞;注意v2字段上無(wú)索引

mysql> begin;select * from test where v2 < 2 for update;
Query OK, 0 rows affected (0.00 sec)

^C^C -- query aborted
ERROR 1317 (70100): Query execution was interrupted

mysql> select * from test;
+----+------+------+
| id | v1   | v2   |
+----+------+------+
|  1 |    1 |    0 |
|  2 |    3 |    1 |
|  3 |    4 |    2 |
|  5 |    5 |    3 |
|  7 |    7 |    4 |
| 10 |    9 |    5 |
+----+------+------+
6 rows in set (0.00 sec)

mysql> update test set v2 = 1 where v2 < 2;
Query OK, 1 row affected (0.00 sec)
Rows matched: 2  Changed: 1  Warnings: 0

mysql> exit

8.0的RR隔離級(jí)別
mysql> set global transaction isolation level repeatable read;
Query OK, 0 rows affected (0.00 sec)
會(huì)話一:X鎖測(cè)試

mysql> begin;select * from test where v2 >4 for update;
Query OK, 0 rows affected (0.00 sec)

+----+------+------+
| id | v1   | v2   |
+----+------+------+
| 10 |    9 |    5 |
+----+------+------+
1 row in set (0.00 sec)

會(huì)話二:

mysql>  update test set v2 = 1 where v2 < 2;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

8.0中半一致讀的條件:RC及以下隔離級(jí)別,update語(yǔ)句

對(duì)于RR隔離級(jí)別,無(wú)索引的情況下,S鎖,X鎖,走意向鎖的邏輯

會(huì)話一:S鎖測(cè)試

mysql> begin;select * from test where v2 >4 lock in share mode;
Query OK, 0 rows affected (0.00 sec)

+----+------+------+
| id | v1   | v2   |
+----+------+------+
| 10 |    9 |    5 |
+----+------+------+
1 row in set (0.00 sec)

會(huì)話二:

mysql>  update test set v2 = 1 where v2 < 2;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

所以意向鎖的關(guān)鍵在于是否是S鎖與X鎖;如果是RC隔離級(jí)別,需要注意一下“半一致性讀”
S鎖會(huì)先有全表上加IS,X鎖會(huì)先在全表上加IX;IS與IX互斥,IX與IX及IS互斥;

對(duì)于經(jīng)常使用的RR隔離級(jí)別,對(duì)于無(wú)索引字段,意向鎖減少了后來(lái)鎖判斷行記錄上是否有鎖的時(shí)間

總結(jié)

以上是生活随笔為你收集整理的my40_MySQL锁概述之意向锁的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。