最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Mysql技術(shù)內(nèi)幕之InnoDB鎖的深入講解

 更新時間:2020年12月23日 09:26:58   作者:晴轉(zhuǎn)陣雨  
這篇文章主要給大家介紹了關(guān)于Mysql技術(shù)內(nèi)幕之InnoDB鎖的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

前言

自7月份換工作以來,期間一直在學(xué)習(xí)MySQL的相關(guān)知識,聽了一些視頻課,但是一直好奇那些講師的知識是從哪里學(xué)習(xí)的。于是想著從書籍中找答案。畢竟一直

看視頻也不是辦法,不能形成自己的知識。于是想著看書汲取知識,看了幾本MySQL的相關(guān)書籍,包括《深入淺出Mysql》《高性能Mysql》《Mysql技術(shù)內(nèi)幕》,發(fā)現(xiàn)那些講

師講的內(nèi)容確實都在書上有出現(xiàn)過,于是確信看書才是正確的汲取知識方式。本片主要記錄了Mysql的鎖機(jī)制的學(xué)習(xí)。

1.什么是鎖

鎖是計算機(jī)協(xié)調(diào)多個進(jìn)程或線程并發(fā)訪問某一資源的機(jī)制。在數(shù)據(jù)庫中,除傳統(tǒng)的計算資源(如CPU、RAM、I/O等)的爭用以外,數(shù)據(jù)也是一種供許多用戶共享的資源。

如何保證數(shù)據(jù)并發(fā)訪問的一致性、有效性是所有數(shù)據(jù)庫必須解決的一個問題,鎖沖突也是影響數(shù)據(jù)庫并發(fā)訪問性能的一個重要因素。

相對其他數(shù)據(jù)庫而言,MySQL 的鎖機(jī)制比較簡單,其最顯著的特點是不同的存儲引擎支持不同的鎖機(jī)制。比如,MyISAM和MEMORY存儲引擎采用的是表級鎖(table-level

locking);BDB存儲引擎采用的是頁面鎖(page-levellocking),但也支持表級鎖;InnoDB存儲引擎既支持行級鎖(row-levellocking),也支持表級鎖,但默認(rèn)情況下是采用行級鎖。

MySQL這3種鎖的特性可大致歸納如下。

  • 表級鎖:開銷小,加鎖快;不會出現(xiàn)死鎖;鎖定粒度大,發(fā)生鎖沖突的概率最高,并發(fā)度最低。
  • 行級鎖:開銷大,加鎖慢;會出現(xiàn)死鎖;鎖定粒度最小,發(fā)生鎖沖突的概率最低,并發(fā)度也最高。
  • 頁面鎖:開銷和加鎖時間界于表鎖和行鎖之間;會出現(xiàn)死鎖;鎖定粒度界于表鎖和行鎖之間,并發(fā)度一般。

3種鎖的使用角度:

  • 表級鎖更適合于以查詢?yōu)橹?,只有少量按索引條件更新數(shù)據(jù)的應(yīng)用,如Web應(yīng)用;
  • 行級鎖則更適合于有大量按索引條件并發(fā)更新少量不同數(shù)據(jù),同時又有并發(fā)查詢的應(yīng)用,如一些在線事務(wù)處理(OLTP)系統(tǒng)。
  • BDB的頁面鎖已經(jīng)被InnoDB取代,不做討論。

2.InnoDB存儲引擎中的鎖

2.1鎖的類型

InnoDB存儲引擎實現(xiàn)了如下兩種標(biāo)準(zhǔn)的行級鎖:

  • 共享鎖(S Lock),允許事務(wù)讀一行數(shù)據(jù)。
  • 排他鎖(X Lock),允許事務(wù)刪除或更新一行數(shù)據(jù)。

如果一個事務(wù)T1已經(jīng)獲得了行r的共享鎖,那么另外的事務(wù)T2可以立即獲得行r的共享鎖,因為讀取沒有改變行r的數(shù)據(jù),稱這種情況

為鎖兼容(Lock Compatible)。但若有其他的事務(wù)T3想獲得行r的排他鎖,則其必須等待事務(wù)T1、T2釋放行r的共享鎖——這種情況稱為鎖不兼容。

  X S
X 不兼容 不兼容
S 不兼容 兼容

此外,InnoDB存儲引擎支持多粒度鎖定,這種鎖定允許事務(wù)在行級上鎖和表鎖上的鎖同時存在。為了支持在不同粒度上進(jìn)行加鎖操作,InnoDB存

儲引擎支持一種額外的鎖方式,稱之為意向鎖。意向鎖是將鎖定的對象分為多個層次,意向鎖意味著事務(wù)希望在更細(xì)粒度上進(jìn)行加鎖。 ​ InnoDB存

儲引擎支持意向鎖設(shè)計比較簡練,其意向鎖即為表級別的鎖。設(shè)計目的主要是為了在一個事務(wù)中揭示下一行將被請求的鎖類型。其支持兩種意向鎖:

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

2.2 一致性非鎖定讀

一致性的非鎖定讀(consistant nonlocking read)是指InnoDB存儲引擎通過多版本控制(multi versioning)的方法來讀取當(dāng)前執(zhí)行時間數(shù)據(jù)庫中行的

數(shù)據(jù)。如果讀取的行正在執(zhí)行Delete或Update操作,這時讀取操作不會因此去等待行上鎖的釋放。相反地,InnoDB存儲引擎會去讀取行的一個快照

版本。如下如所示。

上圖直觀地展現(xiàn)了InnoDB存儲引擎一致性的非鎖定讀。之所以稱為非鎖定讀,因為不需要等待訪問的行上X鎖的釋放??煺諗?shù)據(jù)是指該行的之前版本

的數(shù)據(jù),該實現(xiàn)是通過undo段來完成。而undo用來在事務(wù)中回滾數(shù)據(jù),因此快照數(shù)據(jù)本身是沒有額外的開銷。此外,讀取快照數(shù)據(jù)是不需要上鎖的,

因為沒有事務(wù)需要對歷史的數(shù)據(jù)進(jìn)行修改操作。

通過上圖可以知道,快照數(shù)據(jù)其實就是當(dāng)前行數(shù)據(jù)之前的歷史版本,每行記錄可能有多個版本,一般稱這種技術(shù)為行多版本技術(shù)。由此帶來的并發(fā)控制,

稱之為多版本并發(fā)控制(Multi Version Concurrency Control, MVCC)。

在事務(wù)隔離級別READ COMMITTED和REPEATABLE READ下,InnoDB存儲引擎使用非鎖定的一致性讀。然而,對于快照數(shù)據(jù)的定義卻不相同。在READ

COMMITTED事務(wù)隔離級別下,對于快照數(shù)據(jù),非一致性讀總是讀取被鎖定行的最新一份快照數(shù)據(jù)。而在REPEATABLE READ事務(wù)隔離級別下,對于快照

數(shù)據(jù),非一致性讀總是讀取事務(wù)開始時的行數(shù)據(jù)版本。如下表所示示例:

時間 會話A 會話B
1 begin  
2 select * from t_user where id = 1;  
3   begin
4   update t_user set id = 10 where id = 1;
5 select * from t_user where id = 1;  
6   commit;
7 select * from t_user where id = 1;  
8 commit;  

假設(shè)原本id = 1的記錄是存在的,大家可以按上表時間順序執(zhí)行對應(yīng)的會話,比較及驗證2者的不同。

2.3 一致性鎖定讀

在默認(rèn)配置下,在事務(wù)的隔離級別為REPEATABLE READ模式下,InnoDB存儲引擎的select操作使用一致性非鎖定讀。但是在某些情況下,用戶需要顯示地

對數(shù)據(jù)庫讀取操作進(jìn)行加鎖以保證數(shù)據(jù)邏輯的一致性。而這要求數(shù)據(jù)庫支持加鎖語句,即使時對于select的只讀操作。InnoDB存儲引擎對于select語句支持兩

種一致性的鎖定讀(locking read)操作:

  • select ··· for update
  • select ··· lock in share mode

select ··· for update對讀取的行記錄加一個X鎖,其他事務(wù)不能對已鎖定的行加上任何鎖。select ··· lock in share mode對讀取的行記錄加一個S鎖,其他事務(wù)可

以向被鎖定的行加S鎖,但是如果加X鎖,則會被阻塞。

對于一致性非鎖定讀,即使讀取的行已被執(zhí)行了select ··· for update,也是可以進(jìn)行讀取的。此外,select ··· for update或者select ··· lock in share mode必須在

一個事務(wù)中,當(dāng)事務(wù)提交了,鎖也就釋放了。因此在使用上述兩種select鎖定語句時,務(wù)必加上begin,start transaction或者set autocommit=0。

3 鎖的算法

3.1行鎖的3中算法

InnoDB存儲引擎有3種行鎖的算法,其分別是:

  • Record Lock:單個行記錄上的鎖
  • Gap Lock:間隙鎖,鎖定一個范圍,但不包含記錄本身
  • Next-Key Lock:Gap Lock + Record Lock,鎖定一個范圍,并且鎖定記錄本身

  Record Lock總是會去鎖住主鍵索引記錄,如果InnoDB存儲引擎表在建立的時候沒有設(shè)置任何一個主鍵或唯一非空索引,那么這時InnoDB存儲引擎會使用隱式的

主鍵來進(jìn)行鎖定。

Next-Key Lock是結(jié)合了Gap Lock+Record Lock的一種鎖定算法,在Next-Key Lock算法下,InnoDB對于行的查詢都是采用這種鎖定算法。假如一個索引有10,11

,13和20這4個值,那么該索引可能被Next-Key Locking的區(qū)間為:

(-無窮,10] ,(10,11], (11,13], (13,20], (20,+無窮)

  采用Next-Key Lock的鎖定技術(shù)稱為Next-Key Locking。其設(shè)計的目的是為了解決幻讀問題。而利用這種鎖定技術(shù),鎖定的不是單個值,而是一個范圍。 ​ 然而,

當(dāng)查詢的索引含有唯一屬性時,InnoDB存儲引擎會對Next-Key Lock進(jìn)行優(yōu)化將其降級為Record Lock,即僅鎖住索引本身,而不是范圍。下面演示一個例子。

mysql> create table t (a int primary key);
Query OK, 0 rows affected (0.01 sec)
​
mysql> insert into t select 1;
Query OK, 1 row affected (0.00 sec)
Records: 1 Duplicates: 0 Warnings: 0
​
mysql> insert into t select 2;
Query OK, 1 row affected (0.00 sec)
Records: 1 Duplicates: 0 Warnings: 0
​
mysql> insert into t select 5;
Query OK, 1 row affected (0.01 sec)
Records: 1 Duplicates: 0 Warnings: 0

接著按下表時間順序執(zhí)行操作。

時間 會話A 會話B
begin;  
select * from t where a = 5 for update;  
  begin;
  insert into t select 4;
  commit; #成功,不需要等待
commit;  

表t共有1,2,5三個值。在上面的例子中,在會話A中首先對a=5進(jìn)行X鎖定。而由于a是主鍵且唯一,因此鎖定的僅是5這個值,而不是(2,5)這個范圍,這樣在會話

B中插入值4而不會阻塞,可以立即插入并返回。即鎖定由Next-Key Lock算法降級為了Record Lock,從而提高應(yīng)用的并發(fā)性。

如上,Next-Key Lock降級為Record Lock僅在查詢的列是唯一索引的情況下。若是輔助索引,則情況會完全不同。同樣,首先創(chuàng)建測試表z進(jìn)行測試:

mysql> create table z (a int ,b int ,primary key(a), key(b));
mysql> insert into z select 1,1;
mysql> insert into z select 3,1;
mysql> insert into z select 5,3;
mysql> insert into z select 7,6;
mysql> insert into z select 10,8;

表z的列b是輔助索引,若在會話A中執(zhí)行下面的SQL語句:

mysql> select * from z where b = 3 for update;

很明顯,這時SQL語句通過索引列b進(jìn)行查詢,因此其使用傳統(tǒng)的Next-Key Locking技術(shù)加鎖,并且由于有兩個索引,其需要分別進(jìn)行鎖定。對于聚集索引,其僅對列

a等于5的索引加上Record Lock。而對于輔助索引,其加上的是Next-Key Lock,鎖定的范圍是(1,3),特別需要注意的是,InnoDB存儲引擎還會對輔助索引下一個

鍵值加上gap lock,即還有一個輔助索引范圍為(3,6)的鎖。因此,若在新會話B中運行下面的SQL語句,都會被阻塞:

mysql> select * from z where a = 5 lock in share mode;
mysql> insert into z select 4,2;
mysql> insert into z select 6,5;

第一個SQL語句不能執(zhí)行,因為在會話A中執(zhí)行的SQL語句已經(jīng)對聚集索引中列a=5的值加上X鎖,因此執(zhí)行會被阻塞。第二個SQL語句,主鍵插入4,沒有問題,但是插入

的輔助索引值2在鎖定的范圍(1,3)中,因此執(zhí)行同樣會被阻塞。第三個SQL語句,插入的主鍵6沒有被鎖定,5也不在范圍(1,3)之間。但插入的值5在另一個鎖定的

范圍(3,6)中,故同樣需要等待。而下面的SQL語句,不會被阻塞,可以立即執(zhí)行:

mysql> insert into z select 8,6;
mysql> insert into z select 2,0;
mysql> insert into z select 6,7;

從上面的例子可以看到,Gap Lock的作用是為了阻止多個事務(wù)將記錄插入到同一個范圍內(nèi),而這會導(dǎo)致幻讀問題的產(chǎn)生。假如在上面的例子中,會話A中用戶已經(jīng)鎖定了

b=3的記錄。若此時沒有Gap Lock鎖定(3,6),那么用戶可以插入索引b列為3的記錄,這會導(dǎo)致會話A中的用戶再次執(zhí)行同樣查詢時會返回不同的記錄,即幻讀。

這里主要探究的是InnoDB存儲引擎鎖表的機(jī)制,至少自己明白了Mysql的行鎖機(jī)制,不知道讀者是否有疑問,歡迎留言。下次會記錄關(guān)于Mysql事務(wù)特性及其內(nèi)部的實現(xiàn)機(jī)制,

包括mysql的內(nèi)部架構(gòu),InnoDB buffer Pool,redo log, undo log等具體的詳解,目前只是對知識過了一遍,但還未總結(jié)。

總結(jié)

到此這篇關(guān)于Mysql技術(shù)內(nèi)幕之InnoDB鎖的文章就介紹到這了,更多相關(guān)Mysql InnoDB鎖內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 深度解析MySQL 5.7之中文全文檢索

    深度解析MySQL 5.7之中文全文檢索

    InnoDB默認(rèn)的全文索引parser非常合適于Latin,因為Latin是通過空格來分詞的。但對于像中文,日文和韓文來說,沒有這樣的分隔符。一個詞可以由多個字來組成,所以我們需要用不同的方式來處理。在MySQL 5.7.6中我們能使用一個新的全文索引插件來處理它們:n-gram parser。
    2016-12-12
  • MySQL MaxCompute與AnalyticDB實現(xiàn)數(shù)據(jù)處理與轉(zhuǎn)換過程詳解

    MySQL MaxCompute與AnalyticDB實現(xiàn)數(shù)據(jù)處理與轉(zhuǎn)換過程詳解

    AnalyticDB MySQL(簡稱ads)與 MaxCompute(簡稱odps)進(jìn)行數(shù)據(jù)轉(zhuǎn)換時,個別語法有差別,記錄下來,方便備查,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧
    2022-12-12
  • MySQL多表查詢的案例詳解

    MySQL多表查詢的案例詳解

    這篇文章主要介紹了MySQL多表查詢的案例說明,包括多表查詢的分類及umion的使用,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-03-03
  • 帶你5分鐘讀懂MySQL字符集設(shè)置

    帶你5分鐘讀懂MySQL字符集設(shè)置

    本文詳細(xì)介紹了mysql字符集、字符序的概念與聯(lián)系,給大家分享了多種方式查看MYSQL支持的字符集。具體內(nèi)容詳情大家參考下本文
    2018-01-01
  • mysql數(shù)據(jù)庫的全量與增量的備份以及恢復(fù)方式

    mysql數(shù)據(jù)庫的全量與增量的備份以及恢復(fù)方式

    在數(shù)據(jù)庫管理中,全量備份與恢復(fù)是將整個數(shù)據(jù)庫的數(shù)據(jù)導(dǎo)出并在需要時完整地恢復(fù),這通常使用mysqldump工具完成,增量備份則是在全量備份的基礎(chǔ)上,只備份那些自上次全量備份后發(fā)生變化的數(shù)據(jù),這需要數(shù)據(jù)庫的二進(jìn)制日志(binlog)開啟
    2024-09-09
  • 解決mysql創(chuàng)建數(shù)據(jù)庫后出現(xiàn):Access denied for user ''root''@''%'' to database ''xxx''的問題

    解決mysql創(chuàng)建數(shù)據(jù)庫后出現(xiàn):Access denied for user ''root''@''%'' to dat

    這篇文章主要給大家介紹了如何解決mysql在創(chuàng)建數(shù)據(jù)庫后出現(xiàn):Access denied for user 'root'@'%' to database 'xxx'的錯誤提示,文中介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-05-05
  • 圖解MySQL中樂觀鎖扣減庫存原理

    圖解MySQL中樂觀鎖扣減庫存原理

    這篇文章主要為大家詳細(xì)介紹了MySQL中樂觀鎖扣減庫存原理的相關(guān)知識,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起了解一下
    2023-04-04
  • 解決mysql報錯:Data?source?rejected?establishment?of?connection,?message?from?server:?\"Too?many?connectio

    解決mysql報錯:Data?source?rejected?establishment?of?connect

    這篇文章主要給大家介紹了關(guān)于如何解決mysql報錯:Data?source?rejected?establishment?of?connection,?message?from?server:?\"Too?many?connectio的相關(guān)資料,文中通過實例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-02-02
  • 用Autoconf檢測MySQL軟件包的教程

    用Autoconf檢測MySQL軟件包的教程

    這篇文章主要介紹了用Autoconf檢測MySQL軟件包的教程,主要使用編寫好的ax_lib_mysql腳本進(jìn)行操作,需要的朋友可以參考下
    2015-06-06
  • MySQL?count(*)統(tǒng)計總數(shù)問題匯總

    MySQL?count(*)統(tǒng)計總數(shù)問題匯總

    在日常開發(fā)工作中,我經(jīng)常會遇到需要統(tǒng)計總數(shù)的場景,比如:統(tǒng)計訂單總數(shù)、統(tǒng)計用戶總數(shù)等,這篇文章主要介紹了MySQL?count(*)統(tǒng)計總數(shù)的問題解析,需要的朋友可以參考下
    2022-09-09

最新評論

陕西省| 伊川县| 江阴市| 汨罗市| 汝州市| 桦甸市| 凌海市| 黄龙县| 田东县| 江华| 岗巴县| 十堰市| 化隆| 清新县| 会东县| 曲松县| 当涂县| 弋阳县| 乐都县| 定边县| 汉寿县| 射阳县| 蒙城县| 张家界市| 大田县| 平湖市| 郓城县| 长乐市| 曲周县| 通城县| 来凤县| 河北区| 咸宁市| 天气| 德钦县| 蚌埠市| 香河县| 都匀市| 哈尔滨市| 贵德县| 共和县|