關於rr和間隔鎖的一些實驗
測試表如下:
mysql> show create table test\g
*************************** 1. row ***************************
table: test
create table: create table `test` (
`id` int(11) not null,
`c` int(11) default null,
`d` int(11) default null,
primary key (`id`),
key `idx` (`c`),
key `idx_d` (`d`)
) engine=innodb default charset=utf8
1 row in set (0.00 sec)
案例1:
session 1:
mysql> select * from test;
+-----+------+------+
| id | c | d |
+-----+------+------+
| 0 | 0 | 0 |
| 5 | 5 | 5 |
| 10 | 10 | 10 |
| 15 | 15 | 15 |
| 20 | 10 | 20 |
| 100 | 100 | 100 |
+-----+------+------+
6 rows in set (0.00 sec)
mysql>
mysql> begin;
query ok, 0 rows affected (0.00 sec)
mysql> update test set c=100 where c=10;
query ok, 2 rows affected (0.00 sec)
rows matched: 2 changed: 2 warnings: 0
mysql> select * from test;
+-----+------+------+
| id | c | d |
+-----+------+------+
| 0 | 0 | 0 |
| 5 | 5 | 5 |
| 10 | 100 | 10 |
| 15 | 15 | 15 |
| 20 | 100 | 20 |
| 100 | 100 | 100 |
+-----+------+------+
6 rows in set (0.00 sec)
session 2:
mysql> select * from test;
+-----+------+------+
| id | c | d |
+-----+------+------+
| 0 | 0 | 0 |
| 5 | 5 | 5 |
| 10 | 10 | 10 |
| 15 | 15 | 15 |
| 20 | 10 | 20 |
| 100 | 100 | 100 |
+-----+------+------+
6 rows in set (0.00 sec)
mysql>
mysql> begin;
query ok, 0 rows affected (0.00 sec)
mysql> update test set c=10 where id=0;
此時session2被堵塞的原因是,session1在c的索引上存在next-key鎖(5,10],(10,15),而session2要將c改為10,也就是要把id=0這一行的c=0改為c=10,索引c上的操作是將c=0,id=0這一行索引標記為刪除,然後插入c=10,id=0這一行索引,所以會被session1的next-key鎖堵塞。
順便分析一下,session1都拿了什麼鎖:
1.mdl讀鎖
2.索引c上的next-key鎖(5,10],(10,15)
3.主鍵索引上id=10和id=20的行鎖
案例2:表結構與上面一致
session1:
mysql> select * from test;
+-----+------+------+
| id | c | d |
+-----+------+------+
| 0 | 0 | 0 |
| 5 | 5 | 5 |
| 10 | 10 | 10 |
| 15 | 15 | 15 |
| 20 | 10 | 20 |
| 100 | 100 | 100 |
+-----+------+------+
6 rows in set (0.00 sec)
mysql> begin;
query ok, 0 rows affected (0.00 sec)
mysql> update test set d=100 where c=10;
query ok, 2 rows affected (0.00 sec)
rows matched: 2 changed: 2 warnings: 0
session2:
mysql> begin;
query ok, 0 rows affected (0.00 sec)
mysql> insert into test values(1000,1000,10);
query ok, 1 row affected (0.00 sec)
這裡插入d=10為什麼不被堵塞呢?session1在修改id=10這一行時,由於d列有索引,那不應該在索引d上的d=10附近維護乙個next-key鎖嗎?
嘗試分析一下,其實session1的執行流程是從索引c定位到所有c=10的主鍵id,然後回表讀取資料行,從中拿出d列,這裡根本不需要訪問索引d,所以索引d上是沒有鎖的
所以session1的拿鎖情況是:
1.mdl讀鎖
2.索引c上的next-key鎖
3.主鍵索引上行鎖
總結一下mysql上鎖的規則:
1.只對訪問到的索引上鎖,這個索引包括主鍵索引,二級索引;
2.如果查詢條件列沒有索引,則鎖全表
關於執行緒一些鎖的概念和擴充套件
一.擴充套件 臨界區 指的是乙個訪問共用資源 例如 共用裝置或是共用儲存器 的程式片段,而這些共用資源又無法同時被多個執行緒訪問的特性。當有執行緒進入臨界區段時,其他執行緒或是程序必須等待 例如 bounded waiting 等待法 有一些同步的機制必須在臨界區段的進入點與離開點實現,以確保這些共...
關於MySQL鎖的一些試驗
1 共享鎖,也叫讀鎖,當前事務可以進行讀寫操作,而其他事務只能進行讀操作,不能寫操作,禁止其他事務對同樣的資料集加排他鎖,但允許加共享鎖。如 select from user where email 5122809388 163.com lock in share mode 2 排他鎖,只允許當前事...
關於Oracle鎖的一些總結
煙一支一支地點 酒一杯一杯的幹 請你要體諒我 我酒量不好別給我挖坑 不時會遇到,不小心把錶鎖住的情況。再此,相對oracle鎖相關的知識做一些粗淺的總結。當不小心鎖表時 1 查詢session被鎖的sql,簡要查詢,得到sid select object name,machine,s.sid,s.s...