主頁 > 資料庫 > MySQL鎖

MySQL鎖

2021-01-18 13:05:57 資料庫

文章目錄

  • 為什么需要鎖
  • 鎖的基本原理
  • 鎖的型別
    • 行級鎖
    • 表級鎖
    • 意向鎖
    • 自增鎖
  • 鎖的演算法
    • 記錄鎖
    • 間隙鎖
    • 臨鍵鎖
  • 鎖問題
    • 臟讀
    • 不可重復讀
    • 丟失更新

為什么需要鎖

鎖機制用于管理對共享資源的并發訪問,

鎖不僅是資料庫事務實作不同級別隔離性的手段,由其帶來的所沖突也是影響資料庫并發訪問性能的一個重要因素,

  • MyISAM是表級鎖,并發讀沒有問題,但并發插入性能較差,

  • Microsoft SQL Server資料庫,在2005版本之前都是頁鎖,相對MyISAM并發性能有所提升,但對于熱點資料頁的并發問題依然無能為力,

  • InnoDB存盤引擎鎖的實作與Oracle非常相似,提供一致性的非鎖定讀、行級鎖支持,

鎖的基本原理

當我們說的MySQL鎖住了這一行,其實并不會真正的鎖住對應記錄,而是鎖住相應的索引,具體的鎖哪些索引是根據查詢條件來決定的,

因為MySQL的表的資料,本身通過1個或多個B+樹索引來組織的,其中主鍵索引包含了完整的每一行的資料,非主鍵索引記錄的是到行記錄對應的主鍵索引的位置,所以,通過在索引記錄上進行加鎖操作,可以有效的讀取、插入、修改、洗掉進行沖突判斷,

如果這個表沒有索引,是不是就加不了鎖?這是不可能的,因為MySQL的每一個表至少有一個隱藏的聚簇索引,即主鍵索引,

鎖的型別

行級鎖

InnoDB存盤引擎實作了如下兩種標準的行級鎖:

  • 共享鎖(S Lock),允許事務讀一行的資料,

  • 排它鎖(X Lock),允許事務洗掉或更新一行的資料,

行鎖即只會鎖住一行,它的原理即是在對應的索引記錄上加鎖;

具有并發度高、鎖沖突的概率低的優勢,相對而言,由于粒度小,行鎖成本高;

舉例來說,當一行記錄加了排它行鎖的時候,其它事務是不能對這行記錄進行修改的,但其他的行則不受此鎖的影響,

但需要注意的是,在RR模型下進行更新一行記錄時,如查詢條件所在的列并無索引時,會退化成在主鍵索引對應的記錄上全部加鎖,即鎖表,

表級鎖

InnoDB同時支持表鎖,表鎖又分為表級讀鎖和表級寫鎖,具體語法是

LOCK TABLES XXX READ|WRITE

如表加了讀鎖時,這個表進入了只讀模式,其它會話不能對此表進行修改;

如表加了寫鎖,則此表進入獨占模式,其它表的讀和寫都會被阻塞,一般用于特殊的場景,如drop table或者truncate table的場景

表鎖實作原理,不是由InnoDB存盤引擎層管理的,而是由其上一層MySQL Server負責的,需要注意以下兩點:

(1)需要設定autocommit=0,innodb_table_lock=1(也是默認設定),InnoDB層才能知道MySQL加的表鎖

(2)在事務結束前,不要用UNLOCAK TABLES釋放表鎖,因為UNLOCK TABLES會隱含地提交事務;同時,COMMIT或ROLLBACK不能釋放由LOCAK TABLES加的表級鎖,必須用UNLOCK TABLES釋放表鎖,

意向鎖

InnoDB存盤引擎支持意向鎖的設計比較簡練,其意向鎖即為表級鎖,設計目的主要是為了在一個事務中揭示下一行將被請求的鎖型別,

其支持兩種意向鎖:

意向共享鎖(IS Lock),事務想要獲得一張表中某幾行的共享鎖,

意向排它鎖(IX Lock),事務想要獲得一張表中某幾行的排它鎖,

由于InnoDB存盤引擎支持的是行級別鎖,因此意向鎖不會阻塞除全表掃描以外的任何請求,

InnoDB存盤引擎中鎖的兼容性

ISIXSX
IS兼容兼容兼容不兼容
IX兼容兼容不兼容不兼容
S兼容兼容兼容不兼容
X不兼容不兼容不兼容不兼容

簡而言之,排它鎖不兼容任何鎖;意向排它鎖不兼容共享鎖;其他場景均可兼容,

自增鎖

自增長是資料庫一種常見屬性,也是很多DBA或開發人員首選的主鍵方式,

在InnoDB存盤引擎的記憶體結構中,對每個含有自增長值的表都有一個自增長計數器(auto-increment counter),

當對含有自增長的計數器的表進行插入操作時,這個計數器會被初始化,執行如下的陳述句來得到計數器的值,

SELECT MAX(auto_inc_col) FROM t FOR UPDATE;

這個實作方式稱作AUTO-INC Locking,這種鎖其實是采用一種特殊的表鎖機制,為了提高插入的性能,鎖不是在一個事務完成后才釋放,而是在完成對自增長值插入的SQL陳述句后立即釋放,

鎖的演算法

  • Record Lock:單個行記錄上的鎖,

  • Gap Lock:間隙鎖,鎖定一個范圍,但不包含記錄本身,

  • Next-Key Lock:Gap Lock + Record Lock,鎖定一個范圍,并且鎖定記錄本身,

記錄鎖

Record Lock總是會鎖住索引記錄,如果沒有設定索引,會使用隱式的主鍵來進行鎖定,

間隙鎖

間隙鎖(gap lock)是RR模式下,為了防止幻讀而設計出來的,它鎖住的是一個區間(開區間),當一個區間被加了間隙鎖時,是無法執行插入的,

它的實作原理是,在對應的索引記錄范圍進行加鎖,是一個左右均是開區間,

TABLE `test` (
  `id` bigint(20) unsigned NOT NULL COMMENT '主鍵',
  `key` bigint(20) DEFAULT NULL COMMENT 'k',
  PRIMARY KEY (`id`),
  KEY `k` (`k`)
) 

如果(2,2)和(6,6)之間被加了間隙鎖,則事物2和事物3的插入,將會被阻塞,而事物1和事物4,則不會被阻塞,

需要注意的是,間隙鎖本身之間是不會相互沖突的,它的唯一作用就是阻止在間隙內插入新的行,

臨鍵鎖

臨鍵鎖即next-key lock,是行鎖和它之前的間隙共同構成的鎖,即一個前開后閉的加鎖區間,

然而,當查詢的索引含有唯一屬性時,InnoDB存盤引擎會對Next-Key Lock進行優化,降級為Record Lock,即僅鎖住索引本身,而不是范圍,

需要注意的是,對于唯一鍵值的鎖定,Next-Key Lock降級為Record Lock僅存在于查詢所有的唯一索引列,若唯一索引由多個列組成,而查詢僅是查找多個唯一索引列中的其中一個,那么查詢其實是range型別,而不是point型別,依然會使用Next-Key Lock進行鎖定,

由于間隙鎖和臨鍵鎖的加鎖規則比較復雜,這里參考林曉斌的總結為2個原則,2個優化,1個bug:

  • 原則1:RR模式加鎖的基本單位是next-key lock,即前開后閉的區間

  • 原則2:查找程序中訪問到的物件才會加鎖

  • 優化1:唯一索引上的等值查詢,next-key lock會退化為行鎖

  • 優化2:索引上的等值查詢,向右遍歷的時候,最后一個值不滿足等值條件的時候會退化為間隙鎖,

  • 一個bug:唯一索引上的范圍查詢,會訪問到不滿足條件的第一個值為止,

這里舉例來說明

TABLE `test` (
  `id` int(11) unsigned NOT NULL COMMENT '主鍵',
  `c` int(11) DEFAULT NULL,
  `d` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `k` (`c`)
) 
insert into t values (0,0,0),(5,5,5), (10,10,10),(15,15,15), (20,20,20),(25,25,25)

例子一:唯一索引查詢間隙鎖,sql如下:

update t set d=d+1 where id=7;

根據加鎖規則1,加鎖范圍是(5,10]

同時由于優化2,最終的加鎖范圍是(5,10).

例子二:非唯一索引等值鎖

select id from t where c=5 lock in share mode;

1)根據加鎖原則1,加鎖區間是(0,5],

2)但由于c是普通索引,需要繼續向右遍歷,直到查詢到c=10才會放棄

3)根據優化2,由于10不滿足等值判斷,因此會退化成間隙鎖(5,10)

4)根據原則2,只有訪問到的物件才會加鎖,這個查詢本身是有覆寫索引,并不需要訪問主鍵,因此id主鍵上并沒有鎖,因此不會阻塞如下sql

update t set d=d+1 where id=5

例子三:主鍵索引范圍鎖

考慮如下兩個SQL,語意上等同的,但是對加鎖的效果確是不一樣的,

select * from t where id=10 for update;
select * from t where id>=10 and id < 11 for update;

我們都知道第一條陳述句,會退化成id=10的行鎖,

第二條陳述句,其實是id=10和 10<id<11的兩個查找聯合加鎖結果,對于id=10,會加一個行鎖,對于10<id<11會加一個(10,15]的臨鍵鎖

鎖問題

臟讀

臟頁:在緩沖池中已經被修改的頁,但是還沒重繪到磁盤中,即資料庫實體記憶體中的頁和磁盤中的頁的資料是不一致的,當然在重繪到磁盤之前,日志都已經被寫入到了重做日志檔案中,

而所謂臟資料是指事務對緩沖池中行記錄的修改,并且還沒有被提交(commit),在一個事務中可以讀到另一個事務中未提交的資料(臟資料),顯然違反了資料庫的隔離性,

主從拷貝程序的slave節點,并且slave節點上的查詢不需要特別精確的回傳值的情況下,可以采用臟讀隔離級別,

臟讀本身違反了事務的隔離性,

不可重復讀

不可重復讀是指在一個事務內多次讀取到同一資料集合(范圍查詢),且兩次讀到的資料可能不一樣(其他事務對部分資料進行修改),這種情況稱為不可重復讀,

不可重復讀本身違反了事務的一致性,

丟失更新

丟失更新是另一個鎖導致的問題,簡單來說就是一個事務的更新操作會被另一個事務的更新操作所覆寫,從而導致資料的不一致,

事務T1將行記錄R更新為V1,但不提交,

事務T2將行記錄R更新為V2,但不提交,

事務T1提交,

事務T2提交,

此時事務T1的更新就被事務T2覆寫了,但事實上,在當前資料庫的任何隔離級別下,都不會導致資料庫理論意義上的丟失更新問題,

但可能存在邏輯上的丟失更新,將上述程序想象成,用戶查詢資料到界面,更新資料,但未提交至資料庫,

轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/250280.html

標籤:其他

上一篇:JDBC鏈接資料庫

下一篇:【R語言】必學包之lubridate包

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • GPU虛擬機創建時間深度優化

    **?桔妹導讀:**GPU虛擬機實體創建速度慢是公有云面臨的普遍問題,由于通常情況下創建虛擬機屬于低頻操作而未引起業界的重視,實際生產中還是存在對GPU實體創建時間有苛刻要求的業務場景。本文將介紹滴滴云在解決該問題時的思路、方法、并展示最終的優化成果。 從公有云服務商那里購買過虛擬主機的資深用戶,一 ......

    uj5u.com 2020-09-10 06:09:13 more
  • 可編程網卡芯片在滴滴云網路的應用實踐

    **?桔妹導讀:**隨著云規模不斷擴大以及業務層面對延遲、帶寬的要求越來越高,采用DPDK 加速網路報文處理的方式在橫向縱向擴展都出現了局限性。可編程芯片成為業界熱點。本文主要講述了可編程網卡芯片在滴滴云網路中的應用實踐,遇到的問題、帶來的收益以及開源社區貢獻。 #1. 資料中心面臨的問題 隨著滴滴 ......

    uj5u.com 2020-09-10 06:10:21 more
  • 滴滴資料通道服務演進之路

    **?桔妹導讀:**滴滴資料通道引擎承載著全公司的資料同步,為下游實時和離線場景提供了必不可少的源資料。隨著任務量的不斷增加,資料通道的整體架構也隨之發生改變。本文介紹了滴滴資料通道的發展歷程,遇到的問題以及今后的規劃。 #1. 背景 資料,對于任何一家互聯網公司來說都是非常重要的資產,公司的大資料 ......

    uj5u.com 2020-09-10 06:11:05 more
  • 滴滴AI Labs斬獲國際機器翻譯大賽中譯英方向世界第三

    **桔妹導讀:**深耕人工智能領域,致力于探索AI讓出行更美好的滴滴AI Labs再次斬獲國際大獎,這次獲獎的專案是什么呢?一起來看看詳細報道吧! 近日,由國際計算語言學協會ACL(The Association for Computational Linguistics)舉辦的世界最具影響力的機器 ......

    uj5u.com 2020-09-10 06:11:29 more
  • MPP (Massively Parallel Processing)大規模并行處理

    1、什么是mpp? MPP (Massively Parallel Processing),即大規模并行處理,在資料庫非共享集群中,每個節點都有獨立的磁盤存盤系統和記憶體系統,業務資料根據資料庫模型和應用特點劃分到各個節點上,每臺資料節點通過專用網路或者商業通用網路互相連接,彼此協同計算,作為整體提供 ......

    uj5u.com 2020-09-10 06:11:41 more
  • 滴滴資料倉庫指標體系建設實踐

    **桔妹導讀:**指標體系是什么?如何使用OSM模型和AARRR模型搭建指標體系?如何統一流程、規范化、工具化管理指標體系?本文會對建設的方法論結合滴滴資料指標體系建設實踐進行解答分析。 #1. 什么是指標體系 ##1.1 指標體系定義 指標體系是將零散單點的具有相互聯系的指標,系統化的組織起來,通 ......

    uj5u.com 2020-09-10 06:12:52 more
  • 單表千萬行資料庫 LIKE 搜索優化手記

    我們經常在資料庫中使用 LIKE 運算子來完成對資料的模糊搜索,LIKE 運算子用于在 WHERE 子句中搜索列中的指定模式。 如果需要查找客戶表中所有姓氏是“張”的資料,可以使用下面的 SQL 陳述句: SELECT * FROM Customer WHERE Name LIKE '張%' 如果需要 ......

    uj5u.com 2020-09-10 06:13:25 more
  • 滴滴Ceph分布式存盤系統優化之鎖優化

    **桔妹導讀:**Ceph是國際知名的開源分布式存盤系統,在工業界和學術界都有著重要的影響。Ceph的架構和演算法設計發表在國際系統領域頂級會議OSDI、SOSP、SC等上。Ceph社區得到Red Hat、SUSE、Intel等大公司的大力支持。Ceph是國際云計算領域應用最廣泛的開源分布式存盤系統, ......

    uj5u.com 2020-09-10 06:14:51 more
  • es~通過ElasticsearchTemplate進行聚合~嵌套聚合

    之前寫過《es~通過ElasticsearchTemplate進行聚合操作》的文章,這一次主要寫一個嵌套的聚合,例如先對sex集合,再對desc聚合,最后再對age求和,共三層嵌套。 Aggregations的部分特性類似于SQL語言中的group by,avg,sum等函式,Aggregation ......

    uj5u.com 2020-09-10 06:14:59 more
  • 爬蟲日志監控 -- Elastc Stack(ELK)部署

    傻瓜式部署,只需替換IP與用戶 導讀: 現ELK四大組件分別為:Elasticsearch(核心)、logstash(處理)、filebeat(采集)、kibana(可視化) 下載均在https://www.elastic.co/cn/downloads/下tar包,各組件版本最好一致,配合fdm會 ......

    uj5u.com 2020-09-10 06:15:05 more
最新发布
  • day02-2-商鋪查詢快取

    功能02-商鋪查詢快取 3.商鋪詳情快取查詢 3.1什么是快取? 快取就是資料交換的緩沖區(稱作Cache),是存盤資料的臨時地方,一般讀寫性能較高。 快取的作用: 降低后端負載 提高讀寫效率,降低回應時間 快取的成本: 資料一致性成本 代碼維護成本 運維成本 3.2需求說明 如下,當我們點擊商店詳 ......

    uj5u.com 2023-04-20 08:33:24 more
  • MySQL中binlog備份腳本分享

    關于MySQL的二進制日志(binlog),我們都知道二進制日志(binlog)非常重要,尤其當你需要point to point災難恢復的時侯,所以我們要對其進行備份。關于二進制日志(binlog)的備份,可以基于flush logs方式先切換binlog,然后拷貝&壓縮到到遠程服務器或本地服務器 ......

    uj5u.com 2023-04-20 08:28:06 more
  • day02-短信登錄

    功能實作02 2.功能01-短信登錄 2.1基于Session實作登錄 2.1.1思路分析 2.1.2代碼實作 2.1.2.1發送短信驗證碼 發送短信驗證碼: 發送驗證碼的介面為:http://127.0.0.1:8080/api/user/code?phone=xxxxx<手機號> 請求方式:PO ......

    uj5u.com 2023-04-20 08:27:27 more
  • 快取與資料庫雙寫一致性幾種策略分析

    本文將對幾種快取與資料庫保證資料一致性的使用方式進行分析。為保證高并發性能,以下分析場景不考慮執行的原子性及加鎖等強一致性要求的場景,僅追求最終一致性。 ......

    uj5u.com 2023-04-20 08:26:48 more
  • sql陳述句優化

    問題查找及措施 問題查找 需要找到具體的代碼,對其進行一對一優化,而非一直把關注點放在服務器和sql平臺 降低簡化每個事務中處理的問題,盡量不要讓一個事務拖太長的時間 例如檔案上傳時,應將檔案上傳這一步放在事務外面 微軟建議 4.啟動sql定時執行計劃 怎么啟動sqlserver代理服務-百度經驗 ......

    uj5u.com 2023-04-20 08:26:35 more
  • 云時代,MySQL到ClickHouse資料同步產品對比推薦

    ClickHouse 在執行分析查詢時的速度優勢很好的彌補了MySQL的不足,但是對于很多開發者和DBA來說,如何將MySQL穩定、高效、簡單的同步到 ClickHouse 卻很困難。本文對比了 NineData、MaterializeMySQL(ClickHouse自帶)、Bifrost 三款產品... ......

    uj5u.com 2023-04-20 08:26:29 more
  • sql陳述句優化

    問題查找及措施 問題查找 需要找到具體的代碼,對其進行一對一優化,而非一直把關注點放在服務器和sql平臺 降低簡化每個事務中處理的問題,盡量不要讓一個事務拖太長的時間 例如檔案上傳時,應將檔案上傳這一步放在事務外面 微軟建議 4.啟動sql定時執行計劃 怎么啟動sqlserver代理服務-百度經驗 ......

    uj5u.com 2023-04-20 08:25:13 more
  • Redis 報”OutOfDirectMemoryError“(堆外記憶體溢位)

    Redis 報錯“OutOfDirectMemoryError(堆外記憶體溢位) ”問題如下: 一、報錯資訊: 使用 Redis 的業務介面 ,產生 OutOfDirectMemoryError(堆外記憶體溢位),如圖: 格式化后的報錯資訊: { "timestamp": "2023-04-17 22: ......

    uj5u.com 2023-04-20 08:24:54 more
  • day02-2-商鋪查詢快取

    功能02-商鋪查詢快取 3.商鋪詳情快取查詢 3.1什么是快取? 快取就是資料交換的緩沖區(稱作Cache),是存盤資料的臨時地方,一般讀寫性能較高。 快取的作用: 降低后端負載 提高讀寫效率,降低回應時間 快取的成本: 資料一致性成本 代碼維護成本 運維成本 3.2需求說明 如下,當我們點擊商店詳 ......

    uj5u.com 2023-04-20 08:24:03 more
  • day02-短信登錄

    功能實作02 2.功能01-短信登錄 2.1基于Session實作登錄 2.1.1思路分析 2.1.2代碼實作 2.1.2.1發送短信驗證碼 發送短信驗證碼: 發送驗證碼的介面為:http://127.0.0.1:8080/api/user/code?phone=xxxxx<手機號> 請求方式:PO ......

    uj5u.com 2023-04-20 08:23:11 more