初學者從源碼理解MySQL死鎖問題
通過好多個深夜艱難的單步調試,終于找到了一個理想的斷點,可以看到大部分獲取鎖的過程
代碼在lock0lock.c的static enum db_err lock_rec_lock() 函數中,這個函數會顯示,獲取鎖的過程,以及獲取鎖成功與否。
場景1:通過主鍵進行刪除
表結構
CREATE TABLE `t1` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(10) NOT NULL DEFAULT '', PRIMARY KEY (`id`) ) ENGINE=InnoDB; delete from t1 where id = 10;

可以看到,對索引 PRIMARY 加鎖,mode = 1027,1027是什么意思呢?1027 = LOCK_REC_NOT_GAP + LOCK_X(非 gap 的記錄鎖且是 X 鎖)
過程如下

結論:根據主鍵 id 去刪除數據,且沒有其它索引的情況下,此 SQL 只需要在 id = 10 這條記錄上對主鍵索引加 X 鎖即可
場景2:通過唯一索引進行刪除
表結構做了微調,增加了 name 的唯一索引
構造數據 CREATE TABLE `t2` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(10) NOT NULL DEFAULT '', PRIMARY KEY (`id`), UNIQUE KEY `uk_name` (`name`) ) ; INSERT INTO `t2` (`id`, `name`) VALUES (1,'M'), (2,'Y'), (3,'S'), (4,'Q'), (5,'L'); 測試sql語句 delete from t2 where name = "Y"
來看實際源碼調試的結果
第一步:

第二步:

結論:這個過程是先對唯一鍵 uk_name 加 X 鎖,然后再對聚簇索引(主鍵索引)加 X 鎖
過程如下

場景3:通過普通索引進行刪除
構造數據 CREATE TABLE `t3` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(10) NOT NULL DEFAULT '', PRIMARY KEY (`id`), KEY `idx_name` (`name`) ); INSERT INTO `t3` (`id`, `name`) VALUES (1,'N'), (2,'G'), (3,'I'), (4,'N'), (5,'X'); 測試語句: delete from t3 where name = "N";
調試過程如圖:

結論:通過普通索引進行更新時,會對滿足條件的所有普通索引加 X 鎖,同時會對相關的主鍵索引加 X 鎖
過程如下

場景4:不走索引進行刪除
CREATE TABLE `t4` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(10) NOT NULL DEFAULT '', PRIMARY KEY (`id`) ) INSERT INTO `t4` (`id`, `name`) VALUES (1,'M'), (2,'Y'), (3,'S'), (4,'Q'), (5,'L'); delete from t4 where name = "S";


總共有 5 把 X 鎖,剩下的 3 把就不一一放上來了
結論:不走索引進行更新時,sql 會走聚簇索引(主鍵索引)對全表進行掃描,因此每條記錄,無論是否滿足條件,都會被加上X鎖。還沒完...
但是為了效率考量,MySQL做了優(yōu)化,對于不滿足條件的記錄,會在判斷后放鎖,最終持有的,是滿足條件的記錄上的鎖,但是不滿足條件的記錄上的加鎖/放鎖動作不會省略。
過程如下

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
實例驗證MySQL|update字段為相同的值是否會記錄binlog
這篇文章主要介紹了實例驗證MySQL|update字段為相同的值是否會記錄binlog,幫助大家更好的理解和學習MySQL數據庫,感興趣的朋友可以了解下2020-10-10
MySQL中實現多表查詢的操作方法(配sql+實操圖+案例鞏固 通俗易懂版)
本文主要講解了MySQL中的多表查詢,包括子查詢、笛卡爾積、自連接、多表查詢的實現方法以及多列子查詢等,通過實際例子和操作,幫助讀者理解如何合并多個表的數據,并進行復雜的查詢操作,感興趣的朋友一起看看吧2025-03-03
weblogic服務建立數據源連接測試更新mysql驅動包的問題及解決方法
WebLogic是用于開發(fā)、集成、部署和管理大型分布式Web應用、網絡應用和數據庫應用的Java應用服務器,這篇文章主要介紹了weblogic服務建立數據源連接測試更新mysql驅動包,需要的朋友可以參考下2022-01-01
mysql ONLY_FULL_GROUP_BY設置sql_mode無效排查問題(windows)
這篇文章主要介紹了mysql ONLY_FULL_GROUP_BY設置sql_mode無效排查問題(windows),具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-09-09

