資料越來越和我們的生活離不開,資料在生命週期的各個階段有著不同的痛點和需求以及特殊場景。
curd是資料的四大基本需求:寫入,更新,讀取,刪除.
今天,來談一談死鎖問題
死鎖是高併發下mysql不可迴避的乙個問題。
這句話可以引申四個問題:
1.什麼是死鎖?
2.mysql什麼時候會檢測死鎖?
3.資料庫系統如何處理死鎖?
4.有哪些典型的高併發死鎖場景?
1.我們先來看看什麼是死鎖。
在《資料庫系統實現》第八章第二節這樣定義死鎖
併發執行的事務由於競爭資源而到達乙個存在死鎖的狀態:若干事務的每乙個事務都在等待被其他事務占用的資源,因而每個事務都不能取得進展。
這個描述貌似很拗口,我們舉兩個例子來形象化認識一下:
1.兩位木匠釘地板,一位只握一把斧頭,而另一位沒有榔頭,卻有釘子
2.堵車現象
看完死鎖的定義描述和形象化認識,那對於mysql,什麼時候會進行死鎖檢測?
2.mysql的死鎖檢測和回滾
這裡談論mysql的死鎖檢測,目前僅討論innodb的處理,暫不涉及myrocks的死鎖檢測處理。
當innodb事務嘗試獲取(請求)加乙個鎖,並且需要等待時,innodb會進行死鎖檢測.
正常的流程如下:
1.innodb的初始化乙個事務,當事務嘗試獲取(請求)加乙個鎖,並且需要等待時(wait_lock),innodb會開始進行死鎖檢測(deadlock_mark)
2.進入到lock_deadlock_check_and_resolve ,名字很明顯了,要檢測死鎖和解決死鎖
3.檢測死鎖過程中,也是有計數器來進行限制的
4.死鎖檢測的邏輯之一是等待圖的處理過程,如果通過鎖的資訊和事務等待鏈構造出乙個圖,如果圖**現迴路,就認為發生了死鎖。
5.死鎖的回滾,內部**的處理邏輯之一是比較undo的數量
3.資料庫系統如何處理死鎖
我們回頭繼續看《資料庫系統實現》裡面提到的死鎖處理
1.超時死鎖檢測:當存在死鎖時,想所有事務都能同時繼續執行通常是不可能的,因此,至少乙個事務必須中止並重新開始。超時是最直接的辦法,對超出活躍時間的事務進行限制和回滾
2.等待圖:等待圖的實現,是可以表明哪些事務在等待其他事務持有的鎖,可以在資料庫的死鎖檢測裡面加上這個機制來進行檢測是否有環的形成。
3.通過元素排序預防死鎖:這個想法很美好,但現實很殘酷,通常都是發現死鎖後才去想辦法解決死鎖的原因
4.通過時間戳檢測死鎖:對每個事務都分配乙個時間戳,根據時間戳來進行回滾策略。
這裡貼一下等待圖的示例
4.有哪些典型的高併發死鎖場景?
1.秒殺場景,每個秒殺都是針對同一行的活躍事務,源源不斷的事務發現自己加鎖的那一行已經被人鎖了,這時候innodb會進入乙個蛋疼的沒必要的死鎖檢測,後續給大家講講怎麼解決
2.使用二級索引去高併發更新二級索引記錄(很拗口吧?),mysql的索引計畫不是100%準確的,我手上有case在併發更新不同記錄的時候,因為索引計畫走錯了,導致某乙個事務用了二級索引讀記錄,另外乙個事務用主鍵來讀記錄,進而產生了死鎖,這個案例後續也會整理出來。
最後 mysql的原始碼如何進行死鎖檢測和處理?
這個問題是後續的關鍵,但沒整理完,先歇一歇...
mysql併發死鎖優化教程
1.使用一般使用innodb引擎進行事務回滾 2.如果需要修改表的結構,可以在 量少的情況下進行操作,因為dml 增刪改查 操作都會產生元資料鎖,會卡死。3.解決死鎖 在命令列輸入show engine innodb statusg 可以顯示最近死鎖的資訊,然後加以解決 其次可以設定鎖等待時間,這個...
MySQL 高併發優化
保證在實現功能的基礎上,儘量減少對資料庫的訪問次數 可以用快取儲存查詢結果,減少查詢次數 通過搜尋引數,儘量減少對錶的訪問行數,最小化結果集,從而減輕網路負擔 能夠分開的操作盡量分開處理,提高每次的響應速度 在資料視窗使用 sql 時,盡量把使用的索引放在選擇的首列 演算法的結構盡量簡單 在查詢時,...
mysql悲觀鎖,高併發
1.高併發的時候有2種處理 1 後端進行執行緒安全處理,synchrnoized,還有其他不同粒度的鎖 2 在資料庫設定鎖,當你讀的時候,不允許其他人修改。可以用mysql的悲觀鎖 2.悲觀鎖 select from 表名 for update for update很重要,就是如果你查詢這個事務沒有...