關於RR和間隔鎖的一些實驗

2021-10-05 02:25:22 字數 3404 閱讀 6991

關於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...