欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

MySQL中InnoDB存儲引擎的鎖的基本使用教程

 更新時間:2015年11月23日 09:47:39   作者:一寧  
這篇文章主要介紹了MySQL中InnoDB存儲引擎的鎖的基本概念,是MySQL入門學習中的基礎知識,需要的朋友可以參考下

MyISAM和MEMORY采用表級鎖(table-level locking)

BDB采用頁面鎖(page-leve locking)或表級鎖,默認為頁面鎖

InnoDB支持行級鎖(row-level locking)和表級鎖,默認為行級鎖

各種鎖特點

表級鎖:開銷小,加鎖快;不會出現(xiàn)死鎖;鎖定粒度大,發(fā)生沖突的概率最高,并發(fā)度最低

行級鎖:開銷大,加鎖慢;會出現(xiàn)死鎖;鎖定粒度最小,發(fā)生鎖沖突的概率最低,并發(fā)度也最高

頁面鎖:開銷和加鎖時間介于表鎖和行鎖之間;會出現(xiàn)死鎖;鎖定粒度介于表鎖和行鎖之間,并發(fā)度一般

InnoDB存儲引擎的鎖

InnoDB存儲引擎實現(xiàn)了如下兩種鎖

1、共享鎖(S Lock),允許事務讀一行數(shù)據(jù)

2、排他鎖(X Lock),允許事務更新或者刪除一行數(shù)據(jù)

共享鎖和排他鎖的兼容如下圖所示
2015112394727173.png (688×118)

一致性的非鎖定讀

一致性的非鎖定行讀(consistent nonlocking read)是指InnoDB存儲引擎通過行多版本控制(multi versioning)的方式來讀取當前執(zhí)行時間數(shù)據(jù)庫中行的數(shù)據(jù)。如果讀取的行正在執(zhí)行DELETE、UPDATE操作,這是讀取操作不會因此而會等待行上鎖的釋放,相反,InnoDB會去讀取行的一個快照數(shù)據(jù)。

之所以稱其為非鎖定讀,因為不需要等待訪問的行上X鎖的釋放。快照數(shù)據(jù)是指改行之前版本的數(shù)據(jù),該實現(xiàn)是通過undo段來實現(xiàn)的。但是在不同事務隔離級別下,讀取的方式不同,并不是每個事務隔離級別下讀取的都是一致性讀。

例如:

對于read committed的事務隔離級別,他總是讀取行的最新版本,如果行被鎖定了,則讀取該行版本的最新一個快照。

對于repeatable read(innoDB存儲引擎的默認隔離級別),總是讀取事務開始時的行數(shù)據(jù)。

 非鎖定讀的機制大大提高了數(shù)據(jù)讀取的并發(fā)性,在Innodb存儲引擎默認設置下,這是默認的讀取方式,但是在某些情況下,可以對讀進行加鎖,比如:

1、顯式對讀進行加鎖,如使用 select --- for update ;select --- lock in share mode

2、在外鍵的插入和更新上,因為在外鍵的插入和更新上,對于數(shù)據(jù)的隔離性要求較高,在插入前需要掃描父表中的記錄是否存在,所以,在外鍵的插入刪除上,InnoDB會使用加S鎖的方式來實現(xiàn)。

InnoDB鎖的算法

1、Record Lock:單個行記錄上的鎖

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

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

Record Lock總是會去鎖住索引記錄,如果InnoDB存儲引擎表建立的時候沒有設置任何一個索引,這時InnodB存儲引擎會使用隱式的主鍵來進行鎖定,在Repeatable Read隔離級別下,Next-key Lock 算法是默認的行記錄鎖定算法。

鎖帶來的問題

1、丟失更新

如何避免丟失更新:讓事務變成串行操作,而不是并發(fā)的操作,即對每個事務開始---對讀取記錄加排他鎖。

2、臟讀

臟讀即一個事務可以讀到另一個事務中未提交的數(shù)據(jù),這違反了數(shù)據(jù)庫的隔離性。

臟讀發(fā)生的條件是需要事務的隔離級別為Read uncommitted。

3、不可重復讀

不可重復讀與臟讀的區(qū)別是:臟讀是讀到未提交的數(shù)據(jù),而不可重復讀讀到的是已經提交的數(shù)據(jù)。

一般來說,不可重復讀是可以接受的,在InnoDB存儲引擎中,通過使用Next-Key Lock算法來避免不可重復讀的問題。

值得注意的是,默認情況下InnoDB存儲引擎不會回滾超時引發(fā)的錯誤異常。

死鎖的相關問題

1、死鎖發(fā)生的條件

互斥條件:一個資源每次只能被一個進程使用;請求與保持條件:一個進程因請求資源而阻塞時,對已獲得的資源保持不放;不剝奪條件:進程已獲得的資源,在末使用完之前,不能強行剝奪;循環(huán)等待條件:若干進程之間形成一種頭尾相接的循環(huán)等待資源關系。

2、死鎖檢測(根據(jù)網(wǎng)上的經驗)

Innodb檢測死鎖有兩種情況,一種是滿足循環(huán)等待條件,還有另一種策略:鎖結構超過mysql配置中設置的最大數(shù)量或鎖的遍歷深度超過設置的最大深度時,innodb也會判斷為死鎖(這是提高性能方面的考慮,避免事務一次占用太多的資源)。

因循環(huán)等待條件而產生的死鎖只有可能是四種形式:兩張表兩行記錄交叉申請互斥鎖、同一張表則存在主鍵索引鎖沖突、主鍵索引鎖與非聚簇索引鎖沖突、鎖升級導致的鎖等待隊列阻塞。

3、死鎖避免(根據(jù)網(wǎng)上的經驗)

1.如果使用insert…select語句備份表格且數(shù)據(jù)量較大,在單獨的時間點操作,避免與其他sql語句爭奪資源,或使用select into outfile加上load data infile代替 insert…select,這樣不僅快,而且不會要求鎖定
2. 一個鎖定記錄集的事務,其操作結果集應盡量簡短,以免一次占用太多資源,與其他事務處理的記錄沖突。
3.更新或者刪除表格數(shù)據(jù),sql語句的where條件都是主鍵或都是索引,避免兩種情況交叉,造成死鎖。對于where子句較復雜的情況,將其單獨通過sql得到后,再在更新語句中使用。
4. sql語句的嵌套表格不要太多,能拆分就拆分,避免占有資源同時等待資源,導致與其他事務沖突。
5. 對定點運行腳本的情況,避免在同一時間點運行多個對同一表進行讀寫的腳本,特別注意加鎖且操作數(shù)據(jù)量比較大的語句。
6.應用程序中增加對死鎖的判斷,如果事務意外結束,重新運行該事務,減少對功能的影響。

4、死鎖解決

1)先執(zhí)行show processlist找到死鎖線程號.然后Kill pid

2)Show innodb status檢查引擎狀態(tài) ,可以看到哪些語句產生死鎖

3)查看information_schema架構下的innodb_locks、innodb_trx、innodb_lock_waits等表

 
PS:Mysql死鎖

既然談到死鎖,那附帶地就專門說一下。
何為死鎖?
 
死鎖是對資源的分配和使用不當而造成的。是兩個進程爭奪某一資源而出現(xiàn)相互等待的現(xiàn)象。具體的來講,出現(xiàn)死鎖需要滿足四個必要條件:
(1)互斥條件:每一個資源都只能被一個進程使用
(2)請求與保持條件:一個進程因請求資源而阻塞時,對已獲得的資源保持不放
(3)不剝奪條件:進程已獲得的資源,在末使用完之前,不能強行剝奪。
(4)循環(huán)等待條件:若干進程之間形成一種頭尾相接的循環(huán)等待資源關系。
很顯然,出現(xiàn)死鎖需要兩個或者兩個以上的進程,換句話說,死鎖發(fā)生在并發(fā)的程序中。在Mysql中,由于目前只有InnoDB引擎使用事務(InnoDB支持鎖),便有了InnoDB和死鎖的曠世基情。
死鎖的檢測
 
1、通過使用Show innodb status檢查引擎狀態(tài) ,可以看到哪些語句產生deadlock
2、MySQL提供了一個information_schema,通過查看innodb_locks、innodb_trx、innodb_lock_waits這幾個表檢測死鎖。
因循環(huán)等待條件而產生的死鎖只有可能是四種形式:兩張表兩行記錄交叉申請互斥鎖、同一張表則存在主鍵索引鎖沖突、主鍵索引鎖與非聚簇索引鎖沖突、鎖升級導致的鎖等待隊列阻塞。

死鎖避免

1.如果使用insert…select語句備份表格且數(shù)據(jù)量較大,在單獨的時間點操作,避免與其他sql語句爭奪資源,或使用select into outfile加上load data infile代替 insert…select,這樣不僅快,而且不會要求鎖定
2. 一個鎖定記錄集的事務,其操作結果集應盡量簡短,以免一次占用太多資源,與其他事務處理的記錄沖突。
3.更新或者刪除表格數(shù)據(jù),sql語句的where條件都是主鍵或都是索引,避免兩種情況交叉,造成死鎖。對于where子句較復雜的情況,將其單獨通過sql得到后,再在更新語句中使用。
4. sql語句的嵌套表格不要太多,能拆分就拆分,避免占有資源同時等待資源,導致與其他事務沖突。
5. 對定點運行腳本的情況,避免在同一時間點運行多個對同一表進行讀寫的腳本,特別注意加鎖且操作數(shù)據(jù)量比較大的語句。
6.應用程序中增加對死鎖的判斷,如果事務意外結束,重新運行該事務,減少對功能的影響。

相關文章

  • mysql root用戶的密碼修改和消除

    mysql root用戶的密碼修改和消除

    本文主要針對于Windows環(huán)境下root用戶密碼的修改以及密碼的消除
    2009-06-06
  • MySQL與Mongo簡單的查詢實例代碼

    MySQL與Mongo簡單的查詢實例代碼

    本文通過一個實例給大家用MySQL和mongodb分別寫一個查詢,本文圖片并茂給大家介紹的非常詳細,感興趣的朋友參考下吧
    2016-10-10
  • MySQL的日志基礎知識及基本操作學習教程

    MySQL的日志基礎知識及基本操作學習教程

    這篇文章主要介紹了MySQL的日志基礎知識學習教程,包括MySQL中日志相關常用的服務器變量說明,極力推薦!需要的朋友可以參考下
    2015-11-11
  • mysql 存儲過程詳解

    mysql 存儲過程詳解

    這篇文章主要介紹了mysql 存儲過程詳解的相關資料,需要的朋友可以參考下
    2016-09-09
  • MySQL數(shù)據(jù)庫索引的弊端及合理使用

    MySQL數(shù)據(jù)庫索引的弊端及合理使用

    索引可以說是數(shù)據(jù)庫中的一個大心臟了,如果說一個數(shù)據(jù)庫少了索引,那么數(shù)據(jù)庫本身存在的意義就不大了,和普通的文件沒什么兩樣,本文從細節(jié)和實際業(yè)務的角度看看在MySQL中B+樹索引好處
    2021-11-11
  • windows10下 MySQL msi安裝教程圖文詳解

    windows10下 MySQL msi安裝教程圖文詳解

    這篇文章主要介紹了windows10 MySQL msi安裝教程,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-03-03
  • Mysql數(shù)據(jù)庫分庫和分表方式(常用)

    Mysql數(shù)據(jù)庫分庫和分表方式(常用)

    本文主要給大家介紹Mysql數(shù)據(jù)庫分庫和分表方式(常用),涉及到mysql數(shù)據(jù)庫相關知識,對mysql數(shù)據(jù)庫分庫分表相關知識感興趣的朋友一起學習吧
    2016-03-03
  • MySQL多個字段拼接去重的實現(xiàn)示例

    MySQL多個字段拼接去重的實現(xiàn)示例

    在MySQL中,我們經常會遇到需要將多個字段進行拼接并去重的情況,本文就來介紹一下MySQL多個字段拼接去重的實現(xiàn)示例,具有一定的參考價值,感興趣的可以了解一下
    2024-01-01
  • Centos7.3下mysql5.7.18安裝并修改初始密碼的方法

    Centos7.3下mysql5.7.18安裝并修改初始密碼的方法

    這篇文章主要為大家詳細介紹了Centos7.3下mysql5.7.18安裝并修改初始密碼的方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-06-06
  • MySQL數(shù)據(jù)庫添加外鍵的四種方式

    MySQL數(shù)據(jù)庫添加外鍵的四種方式

    這篇文章主要介紹了ysql數(shù)據(jù)庫添加外鍵的四種方式, 建表時直接使用FOREIGN KEY,建表時使用CONSTRAINT,在建表以后使用ALTER語句以及 使用第三方工具這四種方式,需要的朋友可以參考下
    2024-03-03

最新評論