主頁 > 資料庫 > 鎖(理論篇)

鎖(理論篇)

2023-06-25 08:14:27 資料庫

MVCC機制遺留的問題

為什么在可重復讀級別下,幻讀沒有產生?
回想一下在事務隔離級別那篇文章中,可串行化是通過什么保證的?
對操作的每一行記錄加讀鎖、寫鎖和范圍鎖;任何其他事務都必須等待持有鎖的事務釋放鎖之后才能進行操作;
而可重復讀級別相比之下唯一少的就是范圍鎖,所以無論你是否了解過具體原因,都應該去猜測推理,大概率是加了范圍鎖,而在這里,他有一個特殊的名字,叫做間隙鎖,
雖然我很想直接上間隙鎖相關的內容,但是為了更加有體系化,最好還是完整梳理一下;
本篇文章最好是有一點基礎再看,因為本身就是自記錄,沒有打算寫一篇完整的教學博客,

讀鎖和寫鎖(共享鎖和排它鎖)

Shared Lock 共享鎖(S鎖),也叫讀鎖;不和讀鎖沖突,但和寫鎖沖突;
當事務A持有讀鎖的時候,事務B依然可以加讀鎖;但是除了事務A自己可以加寫鎖,其他事務都無法對這條記錄加寫鎖,
Exclusive Lock 排他鎖(X鎖),也叫寫鎖;和誰都沖突;
即當事務A持有記錄的寫鎖時,其他事務讀鎖和寫鎖都加不了

S X
S 兼容 沖突
X 沖突 沖突

行和列代表不同事務

表鎖

上鎖和解鎖

lock tables 表名 [as alisa] 鎖型別;
unlock tables ;

表鎖的命令就是上述兩行,且表鎖也分讀寫鎖,表級讀寫的兼容沖突和讀寫鎖一致,
通過lock tables 命令加鎖的session,在釋放鎖之前,能且只能執行lock tables 命令后面指定的表,命令型別和鎖型別保持一致;比如 lock tables A read,那么后面就只能讀A表,而不能執行讀B表,或者寫A表;如下面的例子一樣;另外如果使用了別名,那么需要確保查詢陳述句涉及的別名和lock table的別名完全一致;

lock tables simple read;
select * from simple;
select * from batch_insert;
//[HY000][1100] Table 'batch_insert' was not locked with LOCK TABLES
update simple set name=3 where id=2;
Table 'simple' was locked with a READ lock and can't be updated

Unlock tables 會顯式的釋放所有該session之前加的所有表;另一個作用是釋放FLUSH TABLES WITH READ LOCK命令所加的全域讀鎖;

Another use for UNLOCK TABLES is to release the global read lock acquired with the FLUSH TABLES WITH READ LOCK statement, which enables you to lock all tables in all databases. See Section 13.7.8.3, “FLUSH Statement”.

lock tables、start transcation命令可以隱式的釋放之前持有的鎖;
查看鎖情況
可通過下面的命令查看表是否上鎖,name_locked為0表示上鎖
show OPEN TABLES where In_use > 0;
image

WRITE locks normally have higher priority than READ locks to ensure that updates are processed as soon as possible. This means that if one session obtains a READ lock and then another session requests a WRITE lock, subsequent READ lock requests wait until the session that requested the WRITE lock has obtained the lock and released it.

對于讀-寫-讀的情況,由于鎖的優先級較高,如果申請寫的session遲遲獲取不到鎖,會阻塞后續其他session申請讀鎖;具體分析看Case1;

全域讀鎖

關于全域鎖,我一共只在兩篇檔案中看到過;一個是《Mysql45講》的06篇,一個mysql官方檔案的lock-table文章和FLUSH Statement文章,所以了解的并不全,加上此時的我還不太關心資料庫主從的問題,所以也沒有深入研究,
FLUSH TABLES WITH READ LOCK

Closes all open tables and locks all tables for all databases with a global read lock.

元資料鎖

Statements acquire metadata locks one by one, not simultaneously, and perform deadlock detection in the process.
DML statements normally acquire locks in the order in which tables are mentioned in the statement.
DDL statements, LOCK TABLES, and other similar statements try to reduce the number of possible deadlocks between concurrent DDL statements by acquiring locks on explicitly named tables in name order.

元資料鎖是一個個獲取的,DML和DDL通過不同的方式定義執行的順序;官網提供了一個rename table的順序例子,但那個例子挺迷的;
//可以通過這個表查看元資料鎖的情況
select * from performance_schema.metadata_locks;

To ensure transaction serializability, the server must not permit one session to perform a data definition language (DDL) statement on a table that is used in an uncompleted explicitly or implicitly started transaction in another session. The server achieves this by acquiring metadata locks on tables used within a transaction and deferring release of those locks until the transaction ends. A metadata lock on a table prevents changes to the table's structure. This locking approach has the implication that a table that is being used by a transaction within one session cannot be used in DDL statements by other sessions until the transaction ends.

如果一個session或者一個事務持有某個表的元資料鎖,那么另一個session或者事務就無法執行DDL操作;
https://dev.mysql.com/doc/refman/8.0/en/metadata-locking.html

讀寫阻塞問題

關于元資料鎖,在《Mysql45講》中有提到一個問題,后加的讀鎖會被前面的寫鎖所阻塞,很類似于表鎖最后提到的優先級問題,有沒有可能是一個原因呢?具體見case2

行鎖(Record Lock)

A record lock is a lock on an index record.

行鎖是在索引上的一個鎖,這句話非常重要!
這里的索引可以是聚簇索引也可以是二級索引,如果表中沒有索引或者查詢的條件沒有索引,又或者優化器認為索引沒有作用,這個時候就會退化為“表鎖”,但我總感覺像是鎖定了所有行,
另外,如果表中沒有定義聚簇索引,會自動生成一個隱藏的索引,

間隙鎖(Gap Lock)

A gap lock is a lock on a gap between index records, or a lock on the gap before the first or after the last index record.

單靠行鎖是無法解決幻讀的問題的,所以innodb引入了間隙鎖的概念,只在RR級別生效,間隙鎖是一個范圍鎖,比如所以索引1和索引3之間就存在(1,3)這樣一個間隙,當這個間隙被鎖定的時候,就無法插入值為2的記錄,
不同的事務對于同一個間隙加鎖是允許發生的,因為都是在保護這個間隙不被插入資料,

Gap locking is not needed for statements that lock rows using a unique index to search for a unique row.

當查詢條件是唯一索引,如果查詢的值存在且是唯一的一行記錄,那么是不需要加間隙鎖的;因為間隙鎖的出現就是為了防止幻讀,對于加了唯一索引的表,同樣的查詢條件永遠只能查出唯一的一條,既然已經保證了唯一,那么就沒有間隙鎖的必要了,
那如果查詢結果不存在?以及查詢條件是范圍查詢?又或者是普通索引甚至沒有索引呢?
關于這些情況的排列組合,見case3..

臨鍵鎖(next-key Lock)

A next-key lock is a combination of a record lock on the index record and a gap lock on the gap before the index record.

臨建鎖=行鎖+間隙鎖,是innodb RR級別默認加的鎖;由于鎖定的是當前索引記錄行和索引前的部分,所以一般總結為左開右閉;
假如存在索引10,11,13,20,那么就會存在以下幾個區間,最后一個范圍是mysql會假定一個非常大的supremum,但由于實際并不存在這個值,所以是左開右開,
(negative infinity, 10]
(10, 11]
(11, 13]
(13, 20]
(20, positive infinity)

意向鎖

表意向鎖

innodb支持多粒度鎖,即允許行鎖和表鎖同時存在,并且在加鎖的時候需要進行沖突檢測;
比如事務A已經持有了a表的一條記錄索引的行鎖,這個時候B事務想要給a表加表鎖,就需要一行行查看是否存在行鎖;為了優化這種情況,innodb引入了意向鎖的概念,
表意向鎖是個表級鎖,分為讀意向鎖(IS)和寫意向鎖(IX),它們添加的時機是在對行索引添加S鎖和X鎖之前;即如果想要對某一行加鎖,就必須先取得這個表的意向鎖,這樣當另一個事務需要判斷時,就不需要一行行進行檢查,只需要查看這個表是否具有意向鎖即可,
意向鎖的作用主要是用來阻塞表鎖的,所以其互相之間是不存在互斥的,只和表鎖存在沖突,即讀寫沖突,具體就像是下面表格這樣;
暫時無法在飛書檔案外展示此內容

插入意向鎖

An insert intention lock is a type of gap lock set by INSERT operations prior to row insertion. This lock signals the intent to insert in such a way that multiple transactions inserting into the same index gap need not wait for each other if they are not inserting at the same position within the gap. Suppose that there are index records with values of 4 and 7. Separate transactions that attempt to insert values of 5 and 6, respectively, each lock the gap between 4 and 7 with insert intention locks prior to obtaining the exclusive lock on the inserted row, but do not block each other because the rows are nonconflicting.

插入意向鎖是間隙鎖型別的一種意向鎖,鎖的是間隙;是在進行插入之前必須申請獲得的鎖,所以和間隙鎖是沖突的;換句話說,如果你想插入一條陳述句,那么這個陳述句對應的間隙必須不存在鎖,這樣你才能加上插入意向鎖,進而插入資料;
而且,插入意向鎖只要插入的不是同一行,那么就可以同時插入;

自增鎖(AUTO-INC Locks)

An AUTO-INC lock is a special table-level lock taken by transactions inserting into tables with AUTO_INCREMENT columns.

如官方檔案所說,自增鎖其實是只針對于自增的欄位,算是一個表級鎖,一般對我們來說就是自增主鍵;當有多個事務同時想要插入,由于自增的值必須保持連續,所以多個事務的插入必須串行;

參考檔案:

https://dev.mysql.com/doc/refman/8.0/en/innodb-locking.html#innodb-shared-exclusive-locks
https://dev.mysql.com/doc/refman/8.0/en/lock-tables.html
06 | 全域鎖和表鎖 :給表加個欄位怎么有這么多阻礙?-極客時間
mysql MDL讀寫鎖阻塞,以及online ddl造成的“插隊”現象_花落的速度的博客-CSDN博客
MYSQL查看表是否被鎖、以及解鎖_mysql查看鎖表_清石小猿的博客-CSDN博客

本文來自博客園,作者:起司啊,轉載請注明原文鏈接:https://www.cnblogs.com/qisi/p/innodb_lock.html

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

標籤:其他

上一篇:memcached使用中踩的一些坑

下一篇:返回列表

標籤雲
其他(161552) Python(38244) JavaScript(25513) Java(18251) C(15238) 區塊鏈(8272) C#(7972) AI(7469) 爪哇(7425) MySQL(7266) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5875) 数组(5741) R(5409) Linux(5347) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4606) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2437) ASP.NET(2404) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) .NET技术(1984) HtmlCss(1971) 功能(1967) Web開發(1951) C++(1942) python-3.x(1918) 弹簧靴(1913) xml(1889) PostgreSQL(1881) .NETCore(1863) 谷歌表格(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
最新发布
  • 鎖(理論篇)

    # MVCC機制遺留的問題 **為什么在可重復讀級別下,幻讀沒有產生?** 回想一下在事務隔離級別那篇文章中,可串行化是通過什么保證的? 對操作的每一行記錄加讀鎖、寫鎖和范圍鎖;任何其他事務都必須等待持有鎖的事務釋放鎖之后才能進行操作; 而可重復讀級別相比之下唯一少的就是范圍鎖,所以無論你是否了解過 ......

    uj5u.com 2023-06-25 08:14:27 more
  • memcached使用中踩的一些坑

    ## 背景 線上啟用memcached(以下簡稱mc)作為熱點快取組件已經多年,其穩定性和性能都經歷住了考驗,這里記錄一下踩過的幾個坑。 ## 大key存盤 某年某月某日,觀察mysql的讀庫CPU占比有些例外偏高,去check慢查詢log,發現部分應有快取的慢sql居然存在幾秒執行一次情況,不符合 ......

    uj5u.com 2023-06-25 08:13:41 more
  • 鎖(理論篇)

    # MVCC機制遺留的問題 **為什么在可重復讀級別下,幻讀沒有產生?** 回想一下在事務隔離級別那篇文章中,可串行化是通過什么保證的? 對操作的每一行記錄加讀鎖、寫鎖和范圍鎖;任何其他事務都必須等待持有鎖的事務釋放鎖之后才能進行操作; 而可重復讀級別相比之下唯一少的就是范圍鎖,所以無論你是否了解過 ......

    uj5u.com 2023-06-25 08:13:27 more
  • 分庫分表 21 招

    (一)好好的系統,為什么要分庫分表? 咱們先介紹下在分庫分表架構實施程序中,會接觸到的一些通用概念,了解這些概念能夠幫助理解市面上其他的分庫分表工具,盡管它們的實作方法可能存在差異,但整體思路基本一致。因此,在開始實際操作之前,我們有必要先掌握這些通用概念,以便更好地理解和應用分庫分表技術。 我們結 ......

    uj5u.com 2023-06-24 08:25:17 more
  • Elasticsearch核心應用場景-日志優化實踐

    1. 背景 日志領域是Elasticsearch(ES)最重要也是規模最大的應用場景之一。這得益于 ES 有高性能倒排索引、靈活的 schema、易用的分布式架構,支持高吞吐寫入、高性能查詢,同時有強大的資料治理生態、端到端的完整解決方案。但原生 ES 在高吞吐寫入、低成本存盤、高性能查詢等方面還有 ......

    uj5u.com 2023-06-24 08:13:06 more
  • 分庫分表 21 招

    (一)好好的系統,為什么要分庫分表? 咱們先介紹下在分庫分表架構實施程序中,會接觸到的一些通用概念,了解這些概念能夠幫助理解市面上其他的分庫分表工具,盡管它們的實作方法可能存在差異,但整體思路基本一致。因此,在開始實際操作之前,我們有必要先掌握這些通用概念,以便更好地理解和應用分庫分表技術。 我們結 ......

    uj5u.com 2023-06-24 08:12:12 more
  • Elasticsearch核心應用場景-日志優化實踐

    1. 背景 日志領域是Elasticsearch(ES)最重要也是規模最大的應用場景之一。這得益于 ES 有高性能倒排索引、靈活的 schema、易用的分布式架構,支持高吞吐寫入、高性能查詢,同時有強大的資料治理生態、端到端的完整解決方案。但原生 ES 在高吞吐寫入、低成本存盤、高性能查詢等方面還有 ......

    uj5u.com 2023-06-24 08:05:19 more
  • 2-Redis概述

    ?![image](https://img2023.cnblogs.com/blog/2942345/202306/2942345-20230622081504394-95093556.png)? ? # 1. 應用場景 ? ## 1.1 配合關系型資料庫做高速快取 ? - 高頻次,熱門訪問的資料, ......

    uj5u.com 2023-06-22 08:37:52 more
  • 2-Redis概述

    ?![image](https://img2023.cnblogs.com/blog/2942345/202306/2942345-20230622081504394-95093556.png)? ? # 1. 應用場景 ? ## 1.1 配合關系型資料庫做高速快取 ? - 高頻次,熱門訪問的資料, ......

    uj5u.com 2023-06-22 08:31:44 more
  • MySQL 8的MGR集群中設定autocommit=0引起ERROR 1064 (42000)錯誤

    在一套MySQL MGR集群測驗環境中,同事測驗時,在my.cnf引數檔案中修改了autocommit引數(修改為autocommit=0),結果上周五,由于系統管理員要升級RHEL 8.8的系統補丁,所以將這這三臺MySQL的資料庫服務關閉了,升級完RHEL 8.8的系統補丁后,啟動MySQL的集 ......

    uj5u.com 2023-06-22 08:10:21 more