mysql 查看锁_SQL-mysql锁等待与死锁
一 前言
本篇是MYSQL高級進階篇內容第二篇,學習本篇的基礎是知識追尋者之前發布過的文章,尤其是《MYSQL架構入門篇》重中之重;
《SQL-你真的了解什么SQL么?》
《SQL-小白最佳入門sql查詢一》
《SQL-小白最佳入門sql查詢二》
《SQL- 多年開發人員都不懂的插入與更新刪除操作注意點》
《SQL-SQL事物操作》
《SQL-Mysql數據類型》
《SQL-mysql視圖的前世今生》
《SQL-mysql儲存過程》
《SQL-mysql游標與觸發器》
《SQL-mysql用戶權限管理》
《SQL-mysql架構入門》
公眾號:知識追尋者
知識追尋者(Inheriting the spirit of open source, Spreading technology knowledge;)二 鎖等待
鎖等待的意思非常好理解,就是session (事物會話,開啟一個事物代表一個會話)A 對 某行數據獲取獨占鎖(在這邊一般就是寫鎖),然后session B 對相同的行進行獲取獨占鎖就發生了鎖等待;簡單理解就是 小孩子搶玩具,誰先搶到 誰 先玩,沒搶到的玩具的孩子只能 等待 搶到玩具孩子玩膩了再給你,瞬間淚奔有木有,就是這么殘酷,當然MYSQL 沒 這么殘忍 其 還是有一個保留參數 innodb_lock_wait_timeout 指定死鎖 的時間,如果超過 死鎖等待時間就是報異常;
知識追尋者 做個實驗:
session A 執行如下語句,開啟事物,更新索引為1 的語句;此時 session A 獲取了 id= 1 這條 語句的 寫鎖權限;
BEGIN; update `order` set `year`= '2022' where id = '1';session B 執行如下 語句 , 跟 上面的語句一樣 ,由于 id =1 這條數據的寫鎖已經被session A 獲取,故會發生鎖等待的情況;
BEGIN; update `order` set `year`= '2022' where id = '1';知識追尋者這邊默認等待了50秒 就報了如下異常
Lock wait timeout exceeded; try restarting transaction查看 默認鎖等待 語句
show VARIABLES like 'innodb_lock_wait_timeout'三 死鎖
3.1 死鎖的產生
死鎖 就是 兩個以上的會話 在 搶占 資源過程中 ,產生相互等待的情況;有點繞是不是,其實很簡單 死鎖是建立在 鎖等待的基礎上,session A 獲取 id = 1 的寫鎖 , session B 獲取 id =2 的寫鎖 ,此時由于索引不同,故不會長生鎖等待現象 ; 當 session A 嘗試 獲取 id =2 的 寫鎖時 ,由于 id = 2 寫鎖已經被 session B 獲取 ,故產生鎖等待;當 session B 嘗試 獲取 id = 1 的寫鎖時 ,由于id =1 寫鎖已經被 session A 獲取, 此時 產生鎖等待; 由于 session A 與 session B 同時 都在 鎖 等待狀態,產生了等待對方釋放鎖,故會產生死鎖;
知識追尋者做個試驗
session A 執行語句, 獲取 id =1 的 寫鎖權限;
BEGIN; update `order` set `year`= '2022' where id = '1';session B 執行語句, 獲取 id =2 的 寫鎖權限;
BEGIN; update `order` set `year`= '2022' where id = '2';session A 執行語句, 嘗試獲取 id =2 的 寫鎖權限,進入鎖等待狀態
update `order` set `year`= '2022' where id = '2';session B 執行語句, 嘗試獲取 id =1 的 寫鎖權限,進入鎖等待狀態
update `order` set `year`= '2022' where id = '1';當 B 進入 鎖等待后就直接報死鎖異常
Deadlock found when trying to get lock; try restarting transaction3.2 查看死鎖
可以使用 show engine innodb status 查看死鎖
...... *** (1) TRANSACTION: // 事物A TRANSACTION 253507, ACTIVE 474 sec starting index read mysql tables in use 1, locked 1 // 已經使用一個鎖 LOCK WAIT 3 lock struct(s), heap size 1136, 2 row lock(s), undo log entries 1 MySQL thread id 17001, OS thread handle 139824777217792, query id 2191731 ...... root updating update `order` set `year`= '2022' where id = '2'//執行得語句 *** (1) WAITING FOR THIS LOCK TO BE GRANTED: // 等待鎖釋放獲取鎖 RECORD LOCKS space id 65 page no 3 n bits 80 index PRIMARY of table `zszxz`.`order` trx id 253507 lock_mode X locks rec but not gap waiting ..... ? *** (2) TRANSACTION: // 事物 B TRANSACTION 253508, ACTIVE 425 sec starting index read mysql tables in use 1, locked 1 // 已經使用一個鎖 3 lock struct(s), heap size 1136, 2 row lock(s), undo log entries 1 MySQL thread id 17002, OS thread handle 139824778569472, query id 2191735 ...... root updating update `order` set `year`= '2022' where id = '1'//執行得語句 *** (2) HOLDS THE LOCK(S): //持有鎖 RECORD LOCKS space id 65 page no 3 n bits 80 index PRIMARY of table `zszxz`.`order` trx id 253508 lock_mode X locks rec but not gap ...... ? *** (2) WAITING FOR THIS LOCK TO BE GRANTED: // 等待鎖釋放獲取鎖 RECORD LOCKS space id 65 page no 3 n bits 80 index PRIMARY of table `zszxz`.`order` trx id 253508 lock_mode X locks rec but not gap waiting ...... ?不得不說下字母代表鎖得類型如下
- 共享鎖(S)
- 排他鎖(X)
- 意向共享(IS)
- 意向排他(IX)
- gap lock(GK), 間隙鎖,鎖定一個范圍,不包括當前記錄本身;
- RECORD LOCKS 代表記錄鎖;
可以看見上面得語句 (1) 代表 事物A ,MYSQL 線程id 17001 ; (2) 代表事物B, MYSQL 線程id 17002 ; 事物 A 與B 都在等待 對方釋放鎖 ,產生了死鎖;
Tip; 查看表鎖 : show status like 'table%';如何解決死鎖,知識追尋者這邊給個思路:
查找到死鎖線程,殺死MYSQL死鎖的線程(kill命令);
如果事物未提交,直接回滾事物;
3.3 如何避免死鎖
- 在死鎖容易產生得表使用表鎖不會產生死鎖;
- 避免交叉使用相同的鎖
總結
以上是生活随笔為你收集整理的mysql 查看锁_SQL-mysql锁等待与死锁的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: loadrunner11 linux服务
- 下一篇: 数据库技术基础:查询优化相关知识笔记