聊一聊 MySQL 資料庫中的那些鎖

2022-07-03 12:30:13 字數 1714 閱讀 8027

在軟體開發中,程式在高併發的情況下,為了保證一致性或者說安全性,我們通常都會通過加鎖的方式來解決,在 mysql 資料庫中同樣有這樣的問題,一方面為了最大程度的利用資料庫的併發訪問,另一方面又需要保證每個使用者能以一致的方式讀取和修改資料,就引入了鎖機制。

全域性鎖是粒度最大的鎖,基本上也使用不上,就像我們家的大門一樣,控制這整個資料庫例項。全域性鎖就是對整個資料庫例項加鎖,讓整個資料庫處於唯讀狀態。

mysql 提供了乙個加全域性讀鎖的方法,命令是flush tables with read lock (ftwrl),加鎖之後整個資料庫例項處於唯讀狀態,有關資料操作的命令都會被掛起阻塞,例如資料更新語句、資料定義語句、更新類事務語句等等。

所以全域性鎖一般只用於全庫備份的時候,一般只用在不支援一致性讀的儲存引擎做全庫備份時,比如 myisam 這種不支援一致性讀的儲存引擎做全庫備份時需要使用全域性鎖,像 innodb 引擎做全庫備份時不需要使用全域性鎖。

表級鎖是 mysql 最基本的鎖策略,並且是開銷最小的策略,它鎖住的不是整個資料庫例項,而是一張表。

表級鎖跟全域性鎖一樣,mysql 資料庫提供了加鎖的命令:lock tables … read/write。例如 lock tables t1 read, t2 write; 命令,則其他執行緒寫 t1、讀寫 t2 的語句都會被阻塞。同時,執行緒 a 在執行 unlock tables 之前,也只能執行讀 t1、讀寫 t2 的操作。連寫 t1 都不允許,自然也不能訪問其他表。

我們可以使用 unlock tables 主動釋放鎖,如果沒有使用的話,在客戶端斷開的時候自動釋放

表級鎖存在乙個問題,如果乙個查詢正在遍歷乙個表中的資料,而執行期間另乙個執行緒對這個表結構做變更,刪了一列,那麼查詢執行緒拿到的結果跟表結構對不上,肯定是不行的。

為了解決這個問題,mysql 5.5版本之後引入了元資料鎖(meta data lock,mdl),mdl 是資料庫自動加鎖,當對乙個表做增刪改查操作的時候,加 mdl 讀鎖;當要對錶做結構變更操作的時候,加 mdl 寫鎖

mdl 鎖有以下兩個特點:

行級鎖顧名思義就是針對資料庫表中的行記錄加鎖,行級鎖可以最大程度的支援併發處理,但是同時也帶來了最大的鎖開銷。

行級鎖比較容易理解,比如事務 a 更新了一行,而這時候事務 b 也要更新同一行,則必須等事務 a 的操作完成後才能進行更新。

行級鎖是由儲存引擎各自實現的,也並不是所有的儲存引擎都支援行級鎖,比如 myisam 引擎就不支援行級鎖,這意味著 myisam 儲存引擎要控制併發只能使用表級鎖。

innodb 引擎實現了行級鎖,innodb 儲存引擎中實現了兩種標準的行級鎖:

共享鎖是相容鎖,就是當乙個事務已經獲得了行 r 的共享鎖,其他事務可以立即獲得行 r 的共享鎖,因為讀並未改變行 r 的資料。

排他鎖是非相容鎖,如果有事務想獲取行 r 的排他鎖,若行 r 上有共享鎖或者排它鎖,則它必須等其他事務釋放行 r 的鎖。

在 innodb 儲存引擎中,預設情況下使用的是一致性的非鎖定行讀,也就是通過行多版本控制器來讀取行資料,我們可以顯示的為行加上共享鎖和排它鎖,語句如下:

以上就是 mysql 資料庫中有關鎖的分享,希望這篇文章對您的學習或者工作有所幫助,如果您覺得文章有用,還請幫忙****,謝謝。

聊一聊Python中,if與elif的那些事兒

作為新手,還真是時常會忘記適用 elif 這個好用的判斷方法。或者乾脆不知道什麼時候適用 elif。只用 if 進行判斷和 if 與 elif 一起搭配判斷,有什麼區別?elif的適用情況有哪些?話不多說來看例子 在學習群裡看到有個丟擲這樣一段 先來猜猜最終會列印什麼?x 10 y 1 if x 2...

聊一聊系列 聊一聊移動web解析度的那些事兒

不同於pc時代,移動web的樣式更加多樣,也由於手機解析度的碎片化,移動web的相容問題日益突出,下面,我就和各位讀者一起聊聊移動web所面臨的手機解析度問題。在pc時代,我們書寫css的時候,理所應當的認為,我們所書寫的1px,在螢幕上就是1px的寬度。但是到了移動端,事情就不是這樣了,我們所書寫...

隨筆 聊一聊伺服器的那些事兒

今天和乙個搞前端的同學聊天,他認為的伺服器貌似和我們開發的時候的伺服器不一樣,正好藉著這個機會聊聊什麼是伺服器 大家眼中的伺服器是什麼樣子的。也就是大家心目中最常見的機房的形象,專門的環境和人員對大型伺服器進行管理。而在運維的同學眼中可能是這樣的 特點 企業購買或者租用伺服器,需要配備專門的運維人員...