亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

MySQL的在RC和RR模式下的鎖

發布時間:2020-07-16 03:48:29 來源:網絡 閱讀:717 作者:zjdevops 欄目:MySQL數據庫

InnoDB的鎖機制:

數據庫使用所是為了支持更好的并發,提供數據的完整性和一致性。InnoDB是一個支持鎖的存儲引擎,鎖的類型有:共享鎖S鎖(X意向共享鎖(IS意向排鎖(IX支持更好的并發,InnoDB提供了鎖定讀:不需要等待訪問行上的鎖釋放,讀取行的一個快照。該方法是通過InnoDB的一個特寫:MVCC實現的。

InnoDB的分類:

  • Record Lock:行鎖:單個行記錄上的行鎖

  • Gap Lock:間隙鎖,鎖定一個范圍,但不包括記錄本身

  • Next-Key Lock:Gap+Record Lock,鎖定一個范圍,并且鎖定記錄本身



  • 索引+RC/RR

對無索引的字段進行更新時RR級別通過鎖主鍵的方式,來鎖住所有記錄RC級別不會鎖所有記錄。

構建及初始化數據:

mysql?-uroot?-p
USE?test;
DROP?TABLE?IF?EXISTS?t_none;
CREATE?TABLE?`t_none`?(
??`id`?int(11)?NOT?NULL,
??`mem_id`?int(11)?DEFAULT?NULL,
??PRIMARY?KEY?(`id`)
)?ENGINE=InnoDB;
INSERT?INTO?t_none?VALUES(1,1),(3,3),(5,5),(9,9),(11,11);

REPEATABLE-READRR)默認級別

Session?A

Session?B

root@localhost[zjkj]:10:53:18>prompt A>>

PROMPT set to 'A>>'

A>>select @@session.tx_isolation;

root@localhost[(none)]:11:02:58>prompt B>>

PROMPT set to 'B>>'

B>>select @@session.tx_isolation;

A>>begin;

Query OK, 0 rows affected (0.00 sec)

B>>begin;

Query OK, 0 rows affected (0.00 sec)

A>>select * from t_none;

+----+--------+

| id | mem_id |

+----+--------+

| ?1 | ?????1 |

| ?3 | ?????3 |

| ?5 | ?????5 |

| ?9 | ?????9 |

| 11 | ????11 |

+----+--------+

5 rows in set (0.00 sec)

B>>select * from t_none;

+----+--------+

| id | mem_id |

+----+--------+

| ?1 | ?????1 |

| ?3 | ?????3 |

| ?5 | ?????5 |

| ?9 | ?????9 |

| 11 | ????11 |

+----+--------+

5 rows in set (0.00 sec)


A>>?select * from t_none where mem_id=3 for update;

+----+--------+

| id | mem_id |

+----+--------+

| ?3 | ?????3 |

+----+--------+

1 row in set (0.01 sec)



B>>insert into t_none values(2,2);

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

B>>delete from t_none where id=9;

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

show engin inondb status部分輸出:

------------

TRANSACTIONS

------------

Trx id counter 10661

Purge done for trx's n:o < 10659 undo n:o < 0 state: running but idle

History list length 351

Total number of lock structs in row lock hash table 2

LIST OF TRANSACTIONS FOR EACH SESSION:

---TRANSACTION 10588, not started

MySQL thread id 4, OS thread handle 0x7f6f5085c700, query id 339 localhost root init

show engine innodb status

---TRANSACTION 10660, ACTIVE 17 sec inserting

mysql tables in use 1, locked 1

LOCK WAIT 2 lock struct(s), heap size 376, 1 row lock(s)

MySQL thread id 11, OS thread handle 0x7f6f508de700, query id 338 localhost root update

insert into t_none values(2,2)

------- TRX HAS BEEN WAITING 17 SEC FOR THIS LOCK TO BE GRANTED:

RECORD LOCKS space id 68 page no 3 n bits 72 index `PRIMARY` of table `test`.`t_none` trx id 10660 lock_mode X locks gap?before rec insert intention waiting

結論:通過上面很容易的看到,沒有通過索引for?update時,當進行都會鎖住,MySQL內部會通過基于默認主鍵方式對所有記錄加X

下面RC級別的實驗


Read?Committed級別RC

Session?A

Session?B

A>>set @@session.tx_isolation="read-committed";

Query OK, 0 rows affected (0.00 sec)

B>>set @@session.tx_isolation="read-committed";

Query OK, 0 rows affected (0.00 sec)

A>>select @@session.tx_isolation;

+------------------------+

| @@session.tx_isolation |

+------------------------+

| READ-COMMITTED ????????|

+------------------------+

1 row in set (0.00 sec)

B>>select @@session.tx_isolation;

+------------------------+

| @@session.tx_isolation |

+------------------------+

| READ-COMMITTED ????????|

+------------------------+

1 row in set (0.01 sec)

A>>begin;

Query OK, 0 rows affected (0.00 sec)

B>>begin;

Query OK, 0 rows affected (0.00 sec)

A>>select * from t_none where mem_id=3 for update;

+----+--------+

| id | mem_id |

+----+--------+

| ?3 | ?????3 |

+----+--------+

1 row in set (0.01 sec)



B>>insert into t_none values(2,2);

Query OK, 1 row affected (0.01 sec)


B>>select * from t_none;

+----+--------+

| id | mem_id |

+----+--------+

| ?1 | ?????1 |

| ?2 | ?????2 |

| ?3 | ?????3 |

| ?5 | ?????5 |

| ?9 | ?????9 |

| 11 | ????11 |

+----+--------+

6 rows in set (0.00 sec

A>>rollback;

Query OK, 0 rows affected (0.00 sec)

B>>rollback;

Query OK, 0 rows affected (0.00 sec)

結論:在RC級別下,事務B是可以進行增刪改(除被鎖定的記錄本身

  • 非唯一索引+RR/RC

? 在RR級別下InnoDB對于非唯一索引會加Gap Lock(也即鎖定一個區間),而RC級別

構造初始化表數據

mysql?-uroot?-p
USE?test;
DROP?TABLE?IF?EXISTS?t_idx;
CREATE?TABLE?`t_idx`?(
??`id`?int(11)?NOT?NULL,
??`mem_id`?int(11)?DEFAULT?NULL,
??PRIMARY?KEY?(`id`),
???KEY?`idx_mem_id`?(`mem_id`)
)?ENGINE=InnoDB;
INSERT?INTO?t_idx?VALUES(1,1),(3,3),(5,5),(9,9),(11,11);


REPEATABLE-READ(RR)默認級別(RR模式)

Session?A

Session?B

root@localhost[(none)]:06:01:59>use test;

root@localhost[zjkj]:10:53:18>prompt A>>

PROMPT set to 'A>>'

root@localhost[(none)]:06:01:59>use test;

root@localhost[(none)]:11:02:58>prompt B>>

PROMPT set to 'B>>'

A>>select @@session.tx_isolation;

+------------------------+

| @@session.tx_isolation |

+------------------------+

| REPEATABLE-READ ???????|

+------------------------+

1 row in set (0.00 sec)

B>>select @@session.tx_isolation;

+------------------------+

| @@session.tx_isolation |

+------------------------+

| REPEATABLE-READ ???????|

+------------------------+

1 row in set (0.02 sec)

A>>begin;

Query OK, 0 rows affected (0.00 sec)

B>>begin;

Query OK, 0 rows affected (0.00 sec)

A>>select * from t_idx;

+----+--------+

| id | mem_id |

+----+--------+

| ?1 | ?????1 |

| ?3 | ?????3 |

| ?5 | ?????5 |

| ?9 | ?????9 |

| 11 | ????11 |

+----+--------+

5 rows in set (0.04 sec)

B>>select * from t_idx;

+----+--------+

| id | mem_id |

+----+--------+

| ?1 | ?????1 |

| ?3 | ?????3 |

| ?5 | ?????5 |

| ?9 | ?????9 |

| 11 | ????11 |

+----+--------+

5 rows in set (0.00 sec)

A>>select * from t_idx where mem_id=3 for update;

+----+--------+

| id | mem_id |

+----+--------+

| ?3 | ?????3 |

+----+--------+

1 row in set (0.05 sec)



B>>insert into t_idx values(2,2);

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

#問題?這里為什么會出現阻塞呢?

B>>insert into t_idx values(4,4);

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

#問題?這里為什么會出現阻塞呢?

B>>insert into t_idx values(3,3);

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

B>>insert into t_idx values(5,5);

ERROR 1062 (23000): Duplicate entry '5' for key 'PRIMARY'

B>>insert into t_idx values(1,1);

ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'

#######下面插入全部可以######

B>>insert into t_idx values(6,6);

Query OK, 1 row affected (0.00 sec)

B>>insert into t_idx values(7,7);

B>>insert into t_idx values(8,8);

Query OK, 1 row affected (0.01 sec)

B>>insert into t_idx values(12,12);

Query OK, 1 row affected (0.00 sec)


B>>select * from t_idx;

+----+--------+

| id | mem_id |

+----+--------+

| ?1 | ?????1 |

| ?3 | ?????3 |

| ?5 | ?????5 |

| ?6 | ?????6 |

| ?7 | ?????7 |

| ?8 | ?????8 |

| ?9 | ?????9 |

| 11 | ????11 |

| 12 | ????12 |

+----+--------+

9 rows in set (0.00 sec)

show engine?inondb status部分輸出:

------------

TRANSACTIONS

------------

Trx id counter 11044

Purge done for trx's n:o < 11041 undo n:o < 0 state: running but idle

History list length 372

Total number of lock structs in row lock hash table 5

LIST OF TRANSACTIONS FOR EACH SESSION:

---TRANSACTION 0, not started

MySQL thread id 3, OS thread handle 0x7fd0430df700, query id 47 localhost root init

show engine innodb status

---TRANSACTION 11039, ACTIVE 228 sec inserting

mysql tables in use 1, locked 1

LOCK WAIT 3 lock struct(s), heap size 1248, 3 row lock(s), undo log entries 4

MySQL thread id 1, OS thread handle 0x7fd064099700, query id 45 localhost root update

insert into t_idx values(4,4)

Trx read view will not see trx with id >= 11040, sees < 11038

------- TRX HAS BEEN WAITING 22 SEC FOR THIS LOCK TO BE GRANTED:

RECORD LOCKS space id 70 page no 4 n bits 80 index `idx_mem_id` of table `test`.`t_idx` trx id 11039 lock_mode X locks gap?before rec insert intention waitin

結論:通過上面可以看到,通過唯一索引字段進行更新時,進行增刪改時,有記錄會出現阻塞,為什么會出現阻塞呢?其實就是用MySQL間隙鎖。那MySQL這里為什么要用間隙鎖呢?目的主要是防止幻讀。?那為什么有的記錄可以插入有的不可以,因為InnoDB對于行的查詢時采用了Next-Key Lock的算法鎖定的是一個范圍(GAP如下:(∞,1],(1,3],(3,5],(5,9],(9,11],(11,?∞)。InnoDB對輔助索引下一個鍵值也要加上Gap Lock例如上面進行插入2、4135,就可以看出其實鎖住的區間是(1,5)
Read?Committed級別(RC)

Session?A

Session?B

A>>rollback;

Query OK, 0 rows affected (0.00 sec)

B>>rollback;

Query OK, 0 rows affected (0.00 sec)

A>>set @@session.tx_isolation="read-committed";

Query OK, 0 rows affected (0.00 sec)

B>>set @@session.tx_isolation="read-committed";

Query OK, 0 rows affected (0.00 sec)

A>>select @@session.tx_isolation;

+------------------------+

| @@session.tx_isolation |

+------------------------+

| READ-COMMITTED ????????|

+------------------------+

1 row in set (0.00 sec)

B>>select @@session.tx_isolation;

+------------------------+

| @@session.tx_isolation |

+------------------------+

| READ-COMMITTED ????????|

+------------------------+

1 row in set (0.01 sec)

A>>begin;

Query OK, 0 rows affected (0.00 sec)

B>>begin;

Query OK, 0 rows affected (0.00 sec)

A>>select * from t_idx where mem_id=3 for update;

+----+--------+

| id | mem_id |

+----+--------+

| ?1 | ?????3 |

| ?3 | ?????3 |

+----+--------+

2 rows in set (0.00 sec)



B>>insert into t_idx values(1,1);

ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'

B>>insert into t_idx values(2,2);

Query OK, 1 row affected (0.00 sec)

B>>insert into t_idx values(3,3);

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

B>>insert into t_idx values(4,4);

Query OK, 1 row affected (0.01 sec)

結論:在RC級別下,事務B是可以進行增刪改(除被鎖定的記錄本身),沒有出現間隙鎖的現象


  • 唯一索引+RR/RC

構造初始數據

mysql?-uroot?–p
use?test;
DROP?TABLE?IF?EXISTS?t_pk;
CREATE?TABLE?`t_pk`?(
??`id`?int(11)?NOT?NULL?AUTO_INCREMENT,
??`mem_id`?int(11)?NOT?NULL?,
??PRIMARY?KEY?(`id`),
??UNIQUE??`uq_mem_id`?(`mem_id`)
)?ENGINE=InnoDB;
INSERT?INTO?t_pk?VALUES(1,1),(3,3),(5,5),(9,9),(11,11);
REPEATABLE READRR級別

root@localhost[(none)]:10:04:34>use test;

root@localhost[test]:10:04:41>prompt A>>

PROMPT set to 'A>>'

root@localhost[(none)]:10:04:37>use test;

root@localhost[test]:10:04:52>prompt B>>

PROMPT set to 'B>>'

A>>select @@session.tx_isolation;

+------------------------+

| @@session.tx_isolation |

+------------------------+

| REPEATABLE-READ ???????|

+------------------------+

1 row in set (0.01 sec)

B>>select @@session.tx_isolation;

+------------------------+

| @@session.tx_isolation |

+------------------------+

| REPEATABLE-READ ???????|

+------------------------+

1 row in set (0.00 sec)

A>>begin;

Query OK, 0 rows affected (0.00 sec)

B>>begin;

Query OK, 0 rows affected (0.00 sec)

A>>select * from t_pk;

+----+--------+

| id | mem_id |

+----+--------+

| ?1 | ?????1 |

| ?3 | ?????3 |

| ?5 | ?????5 |

| ?9 | ?????9 |

| 11 | ????11 |

+----+--------+

5 rows in set (0.00 sec)

B>>select * from t_pk;

+----+--------+

| id | mem_id |

+----+--------+

| ?1 | ?????1 |

| ?3 | ?????3 |

| ?5 | ?????5 |

| ?9 | ?????9 |

| 11 | ????11 |

+----+--------+

5 rows in set (0.00 sec)

A>>select * from t_pk where mem_id=3 for update;

+----+--------+

| id | mem_id |

+----+--------+

| ?3 | ?????3 |

+----+--------+

1 row in set (0.00 sec)



B>>insert into t_pk values(2,2);

Query OK, 1 row affected (0.00 sec)

B>>insert into t_pk values(4,4);

Query OK, 1 row affected (0.00 sec)

B>>insert into t_pk values(3,3);

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

B>>insert into t_pk values(5,5);

ERROR 1062 (23000): Duplicate entry '5' for key 'PRIMARY'

B>>insert into t_pk values(7,7);

Query OK, 1 row affected (0.00 sec)

結論:從這里可以看到,對于基于唯一索引的更新,MySQL只是鎖定了記錄本身。

同理,我們可以推導出主鍵也是一樣的。實驗的話我就略了,其實就是上面的mem_id改成id即可

基于主鍵Record Lock還是RR級別

A>>rollback;

Query OK, 0 rows affected (0.00 sec)

B>>rollback;

Query OK, 0 rows affected (0.00 sec)

A>>begin;

Query OK, 0 rows affected (0.00 sec

B>>begin;

Query OK, 0 rows affected (0.00 sec)

A>>select * from t_pk where id=3 for update;

+----+--------+

| id | mem_id |

+----+--------+

| ?3 | ?????3 |

+----+--------+

1 row in set (0.00 sec)



B>>insert into t_pk values(2,2);

Query OK, 1 row affected (0.00 sec)

B>>insert into t_pk values(4,4);

Query OK, 1 row affected (0.00 sec)

結論:說明上面的推導正確。
Read-Committed級別RC

A>>rollback;

Query OK, 0 rows affected (0.00 sec)

B>>rollback;

Query OK, 0 rows affected (0.00 sec)

A>>set @@session.tx_isolation="read-committed";

Query OK, 0 rows affected (0.01 sec)

B>>set @@session.tx_isolation="read-committed";

Query OK, 0 rows affected (0.00 sec)

A>>select @@session.tx_isolation;

+------------------------+

| @@session.tx_isolation |

+------------------------+

| READ-COMMITTED ????????|

+------------------------+

1 row in set (0.00 sec)

B>>select @@session.tx_isolation;

+------------------------+

| @@session.tx_isolation |

+------------------------+

| READ-COMMITTED ????????|

+------------------------+

1 row in set (0.00 sec)

A>>begin;

Query OK, 0 rows affected (0.00 sec)

B>>begin;

Query OK, 0 rows affected (0.00 sec)

A>>select * from t_pk;

+----+--------+

| id | mem_id |

+----+--------+

| ?1 | ?????1 |

| ?3 | ?????3 |

| ?5 | ?????5 |

| ?9 | ?????9 |

| 11 | ????11 |

+----+--------+

5 rows in set (0.00 sec)

B>>select * from t_pk;

+----+--------+

| id | mem_id |

+----+--------+

| ?1 | ?????1 |

| ?3 | ?????3 |

| ?5 | ?????5 |

| ?9 | ?????9 |

| 11 | ????11 |

+----+--------+

5 rows in set (0.00 sec)

A>>select * from t_pk where mem_id=3 for update;

+----+--------+

| id | mem_id |

+----+--------+

| ?3 | ?????3 |

+----+--------+

1 row in set (0.00 sec)



B>>insert into t_pk values(2,2);

Query OK, 1 row affected (0.00 sec)

B>>insert into t_pk values(4,4),(6,6),(10,10);

Query OK, 3 rows affected (0.00 sec)

Records: 3 ?Duplicates: 0 ?Warnings: 0

結論:說明RC級別下,沒有間隙鎖存在。
  • 主鍵+RR/RC

這跟唯一索引+RR/RC一樣的,請參看上面的唯一索引+RR/RC。






向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

临清市| 常宁市| 绥阳县| 砀山县| 新邵县| 汝南县| 当涂县| 竹溪县| 福州市| 塔河县| 乌拉特前旗| 彰化县| 开远市| 平阳县| 鸡东县| 黎平县| 军事| 新兴县| 临泉县| 瓮安县| 宜兰市| 天等县| 民和| 图木舒克市| 石门县| 山阳县| 米泉市| 博野县| 陵川县| 长岭县| 云梦县| 广水市| 浙江省| 阜城县| 安岳县| 潼南县| 肥东县| 丹凤县| 郑州市| 翼城县| 郓城县|