<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
資料庫鎖設計的初衷是處理並行問題。作為多使用者共用 的資源,當出現並行存取的時候,資料庫需要合理地控制資源的存取規則。而鎖就是用來實 現這些存取規則的重要資料結構。
根據加鎖的範圍,MySQL 裡面的鎖大致可以分成全域性鎖
、表級鎖
和行鎖
三類
全域性鎖就是對整個資料庫範例加鎖。全域性鎖的典型使用場景是,做全庫邏輯備份,全庫邏輯備份有以下幾種方式:
Flush tables with read lock (FTWRL)
可以讓整個庫處於唯讀狀態的時候,使用這個命令,之後其他執行緒的資料更新語句(資料的增刪改)、資料定義語句(包括建表、修改表結構等)和更新類事務的提交語句講被阻塞。之所以備份需要加全域性鎖是為了保證資料的一致性,
使用此命令會先啟動一個事務拿到一致性檢視。由於 MVCC 的支援, 這個過程中其他執行緒可以進行正常操作,但是使用mysqldump –single-transaction
的前提是需要支援事務,如果存在MyISAM引擎的表,並不能保證一致性。
set global readonly=true
也可以保證全庫唯讀,主要有兩個原因:
在有些系統中,readonly 的值會被用來做其他邏輯,比如用來判斷一個庫是主庫還是備庫。因此,修改 global 變數的方式影響面更大。 在例外處理機制上有差異。如果執行 FTWRL 命令之後由於使用者端發生異常斷開, 那麼 MySQL 會自動釋放這個全域性鎖,整個庫回到可以正常更新的狀態。而將整個庫設定為 readonly 之後,如果使用者端發生異常,則資料庫就會一直保持 readonly 狀態,這樣會導致整個庫長時間處於不可寫狀態,風險較高。
多個未提交事務修改相繼對同一條記錄進行改動的時候,需要進行排隊,排隊過程其實就是通過為記錄加鎖實現的。當一個事務想修改記錄的時候,首先需要看下有沒有於記錄相關聯的鎖結構,如果沒有,那麼會在記憶體中生成與之對應的鎖結構
可能多個事務同時修改同一記錄,會產生多個鎖結構,其中只有一個事務可以獲取到鎖,其is_waiting為false,其他事務is_waiting為true,當獲取鎖的事務結束後,會喚醒其他等待的事務
mysql innodb 在repeatable隔離級別下很大程度下避免了幻讀(後續詳細說到)
Mysql InnoDB多版本並行控制MVCC 這篇部落格我們詳細說到了mvcc的實現的原理,簡單來說就是在事務執行時會生成read view,其包含四個部分
查詢語句只可以查詢生成read view 時刻可以看到的資料,及事務id小於min_trx_id中的資料,寫操作則針對最新的資料。非當前讀的普通語句在讀資料的時候,生成read view的時機不同,在可重複讀的時候只會在第一次讀取(如果使用start transaction with consistent snapshot
則是在事務啟動時)生成一個read view 後續不變,達到可重複讀的目的,對於讀已提交,則是每次讀取都會生成新的read view,從重新整理未提交事務集合,和min_trx_id,讀取到已經提交的資料。使用mvcc讓讀寫並不衝突,資料庫的並行能力更強。
比如在銀行存款業務中,我們需要先讀取賬戶餘額,然後加上新增存款,然後進行寫回操作,整個流程中,我們不希望存在另外一個ATM進行存取的操作,讀寫都需要排隊,這時候就得使用鎖。
上面我們說了,寫操作進行排隊可以解決髒寫,那麼髒讀,不可重複讀,幻讀是怎麼使用讀寫加鎖解決暱?
髒讀產生的原因是,當前事務讀取到了另外一個事務沒有提交的資料,那麼只需要另外一個事務對操作的記錄加鎖,當前事務無法獲取到鎖,自然就不會發生髒讀。
不可重複讀產生的原因是,當前事務先讀取了一條記錄,然後存在另外一個事務修改了此記錄的資料,那麼只要當前事務對記錄進行加鎖,自然後續的事務將無法修改,自然不會發生不可重複讀。
幻讀產生的原因是,當前事務根據條件查詢得到一批資料,然後後續事務新增了滿足這些條件的資料,導致再次查詢時發現多了一些資料,如同出現了幻覺。這裡加鎖則不是單對記錄加鎖,而是要鎖住一個範圍,讓其他事務無法插入資料,從而解決幻讀(後續會說到這種鎖)
很明顯讀寫都加鎖,並行能力不及mvcc
事務利用MVCC進行讀取操作稱為一致性讀(又稱一致性無鎖讀,快照讀)
,基本上所有的普通讀在可重複讀,讀提交隔離級別下,都是一致性讀。
共用鎖:簡稱S鎖,事務要讀取一條記錄的時候需要先獲取到記錄的共用鎖
獨佔鎖:簡稱x鎖,當事務需要改動記錄的時候,需要先獲取記錄的獨佔鎖
共用鎖和共用鎖相容,獨佔鎖和獨佔鎖,獨佔鎖和共用鎖互斥
select xxx lock in share mode
可以對讀取的記錄加S鎖
select xxx for update
可以對讀取的記錄加X鎖
delete
刪除記錄首先要在b+數中定位到這條記錄的位置,然後獲取x鎖,然後指向delete mark(標記記錄被刪除)
update
如果未修改鍵值,並且修改前後資料的儲存空間大小不變,那麼現在b+樹上定位記錄,然後加x鎖。反之需要在b+樹上定位資料,然後把記錄徹底刪除嗎,然後再插入一條新的記錄,對新增的這條資料加x鎖
insert
新插入記錄一般都是加隱式鎖(後面說)不需要在記憶體中生成對應的鎖結構。
innodb支援表級鎖,也支援行級鎖,表級鎖粒度相對更粗,佔用資源較少。使用表級鎖效果相當於為表中的所有記錄加鎖,所以效能比較差。
表級S鎖,X鎖
使用Lock Tables t Read
,innodb儲存引擎會對錶t加共用鎖
使用Lock tables t write
,innodb儲存引擎會對錶t加獨佔鎖
類似於Java中的讀寫鎖,共用鎖和共用鎖不互斥,獨佔鎖和獨佔鎖,獨佔鎖和共用鎖互斥。
innodb儲存引擎中,當對錶中某些記錄加S鎖之前,會在表上加上一個IS鎖,同樣加X鎖之前會加表級IX鎖,這裡的I表示意向鎖,SX表示共用還是互斥,表級意向鎖存在的目的是後續對錶加S鎖,X鎖的時候,可以快速判斷表中是否存在加鎖的記錄,避免遍歷每一個記錄檢視是否被加鎖。
mysql可以為某列執行Auto Increment自增,系統給自增列賦值的實現方式主要存在兩種
使用AUTO-INC鎖,執行插入語句的時候加一個表級AUTO-INC鎖,然後為每條待插入的記錄中的自增列,進行遞增賦值,單個插入語句執行結束後釋放AUTO-INC鎖
。這樣會導致其他事務的插入被阻塞。 採用輕量級AUTO-INC鎖,在為插入列賦值結束後,就釋放輕量級鎖,而不是插入語句執行完後才釋放 四.MDL
一般情況下 對某一個表執行增刪改查的時候,都不會加表鎖,但是執行一些DDL修改表結構,刪除表時,其他事務對這表的增刪改查發生阻塞。這是由MDL鎖實現的,MDL鎖也分為讀鎖和寫鎖,在進行crud操作的時候,會加MDL讀鎖,進行DDL的時候會加MDL寫鎖。
我們需要注意MDL讀鎖寫鎖是互斥的
如圖四個不同的session先後依次執行語句,其中A,B都是獲取MDL讀鎖,互不阻塞,隨即C獲取MDL寫鎖,這時候C會被阻塞,這一阻塞不打緊,還會阻塞後續獲取MDL讀鎖的事務,造成整個表不可用。這啟發了我們,在做DDL的時候要解決長事務,事務不提交,就會一直佔著MDL鎖。在 MySQL 的 information_schema 庫的innodb_trx 表中,可以查到當前執行中的事務。如果要做 DDL 變更的表剛好有長事務在執行,要考慮先暫停 DDL,或者 kill 掉這個長事務。
官方名稱Lock_REC_NOT_GAP
記錄鎖有S鎖和X鎖,S型記錄鎖之間可以共用,X型記錄鎖和S型記錄鎖,X型記錄鎖互斥
innodb的可重複讀級別,使用詞鎖解決幻讀問題,前面我們說過,其難點在於,加鎖的時候幻影記錄還未出現。官方使用Lock_GAP
實現如下操作
此處的gap鎖可以反之其他事務在number為8記錄前面的間隙插入新的記錄,在區間(3,8)內無法進行插入操作,當另外一個事務要插入number為4的記錄時,首先需要定位到該條記錄的下一條記錄,也就是number為8的記錄,此時number為8的記錄具備gap鎖,所以將阻塞插入操作,直到gap鎖被釋放,其他事務才能進行插入。gap鎖出現的目的,就是為了防止插入幻影記錄,如果對記錄上gap鎖,並不會限制其他事務對記錄加記錄鎖
。
innodb有兩個虛擬的記錄Infimum(虛擬最小),Supermun(虛擬最大)
當我們想在(xx,正無窮)範圍鎖住幻影記錄時就可以對Supermun加gap鎖。
Next-Key Lock = 記錄鎖 + gap鎖,既鎖住記錄,也鎖住記錄之前的間隙
插入意向鎖,表示事務想在某個間隙插入新的記錄,但是當前處於等待狀態。
比如事務A持有(4,8)範圍內的gap鎖,事務B和C,想插入(4,8)範圍內的記錄,就會在記憶體中生成事務B,C對應的插入意向鎖,當前事務A釋放gap鎖的時候,將喚醒事務B和C,事務B和C可以同時獲取插入意向鎖,然後進行插入。插入意向鎖並不會阻止對記錄繼續上鎖。
為事務生成記憶體中的鎖結構並不是一個0成本的事情,為了節省這個成本,提出隱式鎖
的概念。
當一個事務插入語一條記錄A,其他事務
select xxx Lock in share mode
讀取記錄A(獲取記錄A的S鎖),或者使用select xxx for update
(獲取記錄A的X鎖) 立即修改記錄A(獲取x鎖)
對於聚簇索引來說,有一個隱藏列trx_id
此列儲存著最後更改記錄的事務id,在當前事務A插入記錄後,便是儲存著當前事務A的id,其他事務B企圖獲取x鎖,s鎖的時候,就需要下先看一下,trx_id隱藏列對應的事務是否存活,如果不是那麼正常獲取,反之需要為當前事務A建立一個x鎖記憶體結構,並標記is_waiting為false,然後事務B將為自己建立一個鎖結構,is_waiting 為true然後事務B進入等待狀態
對於二級索引來說,其不具備隱藏列trx_id
但是在二級索引頁面的page header中的page_maxt_trx_id
屬性,記錄了改動頁面最大的事務id,如果其屬性值小於當前最小的活躍事務id,那麼說明對頁面的改動事務已經提交,否則需要定位到二級索引記錄,然後回表對聚簇索引進行上述聚簇索引的操作。
一個事務對新插入的記錄不需要顯示的加鎖,由於事務id的存在相當於加了一個隱式鎖,別的事務需要加S鎖或者X鎖的時候,先幫之前的事務生成鎖結構,然後為自己生成鎖結構,再進入阻塞狀態。隱式鎖起到了延遲加鎖的作用,也許別的事務不會獲取於隱式鎖衝突的鎖,這時候可以減少記憶體中生成鎖結構。
到此這篇關於一篇文章帶你瞭解清楚Mysql 鎖的文章就介紹到這了,更多相關Mysql 鎖詳解內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45