mysql的鎖機制詳解

来源:https://www.cnblogs.com/pluto-charon/archive/2019/11/15/11863768.html
-Advertisement-
Play Games

這段時間一直在學習mysql資料庫。項目組一直用的是oracle,所以對mysql的瞭解也不深。本文主要是對mysql鎖的總結。 Mysql的鎖主要分為3大類: 表級鎖:存儲引擎為Myisam。鎖住整個表,特點是開銷小,加鎖快,鎖定力度大,發生鎖衝突的概率最高,併發度最低。 頁級鎖:存儲引擎為BDB ...


這段時間一直在學習mysql資料庫。項目組一直用的是oracle,所以對mysql的瞭解也不深。本文主要是對mysql鎖的總結。

Mysql的鎖主要分為3大類:

   表級鎖:存儲引擎為Myisam。鎖住整個表,特點是開銷小,加鎖快,鎖定力度大,發生鎖衝突的概率最高,併發度最低。

   頁級鎖:存儲引擎為BDB。鎖住某一頁的數據(16kb左右),特點:開銷和枷鎖時間介於表級和行級之間;會出現死鎖,鎖定力度介於表鎖和行鎖之間,併發度一般。

   行級鎖:存儲引擎為innodb。鎖住某一行的數據,特點:鎖的實現更加複雜,開銷大,加鎖速度慢。

根據以上特點,僅從鎖的角度來說:表級鎖更適合於以查詢為主,只有少量按索引條件更新數據的應用,如Web應用;而行級鎖則更適合於有大量按索引條件併發更新少量不同數據,同時又有併發查詢的應用,如一些線上事務處理(OLTP)系統。

 

接下來進行行級鎖的詳解,行級鎖主要分為以下7類:共用/排他鎖、意向鎖、記錄鎖、間隙鎖、臨建鎖、插入意向鎖、自增鎖。

 

共用/排他鎖:

  共用鎖:又稱讀鎖,可以允許讀,但不能寫。共用鎖可以與共用鎖一起使用。語句:

select ... lock in share mode

 

   排他鎖:又稱寫鎖,不能允許讀,也不能允許寫,排他鎖不能與其他所一起使用。語句:

 

select ... for update

mysql中,updatedeleteinsertalter這些寫的操作預設都會加上排他鎖。Select預設不會加任何鎖類型。一旦寫數據的任務沒有完成,數據是不能被其他任務讀取的,這對併發操作有較大的影響。

 

意向鎖:innoDB為了支持多粒度的鎖,即允許行級鎖和表級鎖共存,而引入意向鎖。意向鎖是指未來的某個時刻,事務可能要加共用/排他鎖,先提前聲明一個意向。這樣如果有人嘗試對全表進行修改,就不需要判斷表中的數據是否被加鎖了,只需要通過等待意向互斥鎖被釋放就行了。

   意向共用鎖(IS):事務想要在獲得表中某些記錄的共用鎖,需要在表上先加意向共用鎖。

   意向互斥鎖(IX):事務想要在獲得表中某些記錄的互斥鎖,需要在表上先加意向互斥鎖。

意向鎖其實不會阻塞全表掃描之外的任何請求,它們的主要目的是為了表示是否有人請求鎖定表中的某一行數據。

 

  記錄鎖(RS):單個行記錄上的鎖。記錄鎖總是會鎖住索引記錄,如果innoDB存儲引擎表

在建立的時候沒有設置任何一個索引,那麼innoDB存儲引擎會使用隱式的主鍵來進行鎖定。

 

間隙鎖(GR):間隙鎖鎖住記錄中的間隔,即範圍查詢的記錄。

 Select * From user where id between 1 and 10 for update

   這個腳本會鎖住110 的數據,以防止其他事務修改該區間的記錄;

 

間隙鎖的主要目的,就是為了防止其他事務在間隔中插入數據,以導致“不可重覆讀”。如果把事務的隔離級別降級為讀提交(Read Committed, RC),間隙鎖則會自動失效

 

臨建鎖(next-key Locks):臨建鎖是記錄鎖和間隙鎖的組合,鎖的範圍既包含記錄又包含索引區間。預設情況下,innoDB使用臨建鎖來鎖定記錄。但當查詢的索引含有唯一屬性的時候,臨建鎖會進行優化,將其降級為記錄鎖,即僅鎖住索引本身,不是範圍。

臨鍵鎖的主要目的,也是為了避免幻讀(Phantom Read)。如果把事務的隔離級別降級為RC,臨鍵鎖則也會失效。

 

 插入意向鎖(insert intention locks):對已有數據行的修改和刪除,必須加互斥鎖,對於數據的插入,加插入意向鎖。是專門針對於insert操作的。

 

自增鎖(auto-inc locks):是一種特殊的表級別的鎖,專門針對事務插入auto-increment類型的列。最簡單的情況,如果一個事務正在往表中插入記錄,所有其他事務的插入必須等待,以便第一個事務插入的行,是連續的主鍵值。

 

---------------------------------------------------------分界線--------------------------------------------------------------

接下看講一下其他的鎖:

  死鎖:產生是因為線程鎖之間交替等待產生的。值兩個或兩個以上的事務在執行過程中,因爭奪資源而造成的一種相互等待的現象。

   Mysql處理死鎖的方法:根據數據寫的數據量的大小來回滾小事務。

 

   樂觀/悲觀鎖:

      樂觀鎖:樂觀的假定大概率不會發生併發更新衝突,訪問,處理數據的過程中不加鎖,只在更新數據時根據版本號或時間戳判斷是否有衝突,有則處理,無責提交事務。

如果系統併發量非常大,悲觀鎖會帶來非常大的性能問題,選擇使用樂觀鎖,現在大部分應用屬於樂觀鎖

     悲觀鎖:悲觀的假定大概率會發生併發更新衝突,訪問,處理數據前就加排他鎖,在整個數據處理過程中鎖定數據,事務提交或回滾後才釋放鎖。

     優點:

     悲觀併發控制實際上是“先取鎖再訪問”的保守策略,為數據處理的安全提供了保證。

     缺點:

    (a)在效率方面,處理加鎖的機制會讓資料庫產生額外的開銷,還有增加產生死鎖的機會;

    (b) 在只讀型事務處理中由於不會產生衝突,也沒必要使用鎖,這樣做只能增加系統負載;還有會降低了並行性,一個事務如果鎖定了某行數據,其他事務就必須等待該事務處理完才可以處理那行數

 

建議:

  1. 控制事務的大小(操作寫的數據量)
  2. 使用鎖的時候儘量要配合與攜帶索引的欄位使用,避免升級為表鎖
  3. 範圍查詢,儘量減少基於範圍查詢的事務的大小
  4. 如果業務必須要使用鎖,鎖的衝突特別高的話,改為表鎖
  5. 可以根據項目自身的情況調節事務的innodb_flush_log_at_trx_commit

 

感謝以下博主的文檔支持:

https://www.cnblogs.com/volcano-liu/p/9890832.html

https://blog.csdn.net/bruceleenumberone/article/details/81865045

https://blog.csdn.net/qq_32679835/article/details/93745182


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 環境:centos7 一、 ssh連接超時設置 (1)客戶端設置 連接工具:SecureCRT 1、SecureCRT客戶端->Options(選項)->Session Options(會話設置) 2、Terminal(終端)-> 設置每60秒發送NOOP命令到伺服器保持連接 (2)服務端配置 1. ...
  • 一 前置準備1.1 前置條件相應的充足資源的Linux伺服器;設置相應的主機名,參考命令: 1 hostnamectl set-hostname k8smaster Mac及UUID唯一;若未關閉防火牆則建議放通相應埠,如下:Master節點—— 規則方向埠範圍作用使用者TCPInbound64 ...
  • 在無模擬器情況下設置: 調試模擬,點擊view菜單下registers 軟體模擬時計算兩斷點CYCLECOUNTER(在CPU registers中)的差值,乘以指令周期(MCLK)便是執行時間 ...
  • ip配置: vim /etc/network/interfaces auto eth0 iface eth0 inet static >靜態 iface eth0 inet dhcp >動態 address 192.168.0.133 netmask 255.255.255.0 gateway 19 ...
  • 字元串的MD5值 下麵這個例子是字元串 hello 的MD5值 命令解析 echo 預設是帶換行符做結尾的 echo n 可以去掉換行符 md5sum 列印或檢查MD5(128位)校驗和 文件的MD5值 下麵這個例子是文件 a.txt 的MD5值 命令解析 md5sum 列印或檢查MD5(128位) ...
  • Linux關鍵的根文件介紹 /etc:配置文件 /home:用戶的家目錄。每一個用戶的家目錄通常預設為/home/用戶名 /root:管理員的家目錄 /lib:庫文件 靜態庫:.a 動態庫:.dll .so /lib/modules:內核模塊文件 /media:掛載點目錄(常應用於移動設備) /mn ...
  • 電腦操作系統鎖機制. 在多線程編程中,操作系統引入了鎖機制。通過鎖機制,能夠保證在多核多線程環境中,在某一個時間點上,只能有一個線程進入臨界區代碼,從而保證臨界區中操作數據的一致性。 所謂的鎖,可以理解為記憶體中的一個整型數,擁有兩種狀態:空閑狀態和上鎖狀態。加鎖時,判斷鎖是否空閑,如果空閑,修改為 ...
  • 監控SQLServer資料庫 SSMS執行相關SQL SQL模板命名規則 Zabbix客戶端導入模板 添加SQLServer監控圖形 SQLServer伺服器關聯模板 監控思科Cisco防火牆交換機 監控SQLServer資料庫 SSMS執行相關SQL SQL模板命名規則 Zabbix客戶端導入模板 ...
一周排行
    -Advertisement-
    Play Games
  • 概述:在C#中,++i和i++都是自增運算符,其中++i先增加值再返回,而i++先返回值再增加。應用場景根據需求選擇,首碼適合先增後用,尾碼適合先用後增。詳細示例提供清晰的代碼演示這兩者的操作時機和實際應用。 在C#中,++i 和 i++ 都是自增運算符,但它們在操作上有細微的差異,主要體現在操作的 ...
  • 上次發佈了:Taurus.MVC 性能壓力測試(ap 壓測 和 linux 下wrk 壓測):.NET Core 版本,今天計劃準備壓測一下 .NET 版本,來測試並記錄一下 Taurus.MVC 框架在 .NET 版本的性能,以便後續持續優化改進。 為了方便對比,本文章的電腦環境和測試思路,儘量和... ...
  • .NET WebAPI作為一種構建RESTful服務的強大工具,為開發者提供了便捷的方式來定義、處理HTTP請求並返迴響應。在設計API介面時,正確地接收和解析客戶端發送的數據至關重要。.NET WebAPI提供了一系列特性,如[FromRoute]、[FromQuery]和[FromBody],用 ...
  • 原因:我之所以想做這個項目,是因為在之前查找關於C#/WPF相關資料時,我發現講解圖像濾鏡的資源非常稀缺。此外,我註意到許多現有的開源庫主要基於CPU進行圖像渲染。這種方式在處理大量圖像時,會導致CPU的渲染負擔過重。因此,我將在下文中介紹如何通過GPU渲染來有效實現圖像的各種濾鏡效果。 生成的效果 ...
  • 引言 上一章我們介紹了在xUnit單元測試中用xUnit.DependencyInject來使用依賴註入,上一章我們的Sample.Repository倉儲層有一個批量註入的介面沒有做單元測試,今天用這個示例來演示一下如何用Bogus創建模擬數據 ,和 EFCore 的種子數據生成 Bogus 的優 ...
  • 一、前言 在自己的項目中,涉及到實時心率曲線的繪製,項目上的曲線繪製,一般很難找到能直接用的第三方庫,而且有些還是定製化的功能,所以還是自己繪製比較方便。很多人一聽到自己畫就害怕,感覺很難,今天就分享一個完整的實時心率數據繪製心率曲線圖的例子;之前的博客也分享給DrawingVisual繪製曲線的方 ...
  • 如果你在自定義的 Main 方法中直接使用 App 類並啟動應用程式,但發現 App.xaml 中定義的資源沒有被正確載入,那麼問題可能在於如何正確配置 App.xaml 與你的 App 類的交互。 確保 App.xaml 文件中的 x:Class 屬性正確指向你的 App 類。這樣,當你創建 Ap ...
  • 一:背景 1. 講故事 上個月有個朋友在微信上找到我,說他們的軟體在客戶那邊隔幾天就要崩潰一次,一直都沒有找到原因,讓我幫忙看下怎麼回事,確實工控類的軟體環境複雜難搞,朋友手上有一個崩潰的dump,剛好丟給我來分析一下。 二:WinDbg分析 1. 程式為什麼會崩潰 windbg 有一個厲害之處在於 ...
  • 前言 .NET生態中有許多依賴註入容器。在大多數情況下,微軟提供的內置容器在易用性和性能方面都非常優秀。外加ASP.NET Core預設使用內置容器,使用很方便。 但是筆者在使用中一直有一個頭疼的問題:服務工廠無法提供請求的服務類型相關的信息。這在一般情況下並沒有影響,但是內置容器支持註冊開放泛型服 ...
  • 一、前言 在項目開發過程中,DataGrid是經常使用到的一個數據展示控制項,而通常表格的最後一列是作為操作列存在,比如會有編輯、刪除等功能按鈕。但WPF的原始DataGrid中,預設只支持固定左側列,這跟大家習慣性操作列放最後不符,今天就來介紹一種簡單的方式實現固定右側列。(這裡的實現方式參考的大佬 ...