這篇文章主要為大家展示了“InnoDB中select查詢是行鎖還是表鎖”,內(nèi)容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領(lǐng)大家一起研究并學習一下“InnoDB中select查詢是行鎖還是表鎖”這篇文章吧。
10年積累的成都網(wǎng)站制作、做網(wǎng)站經(jīng)驗,可以快速應(yīng)對客戶對網(wǎng)站的新想法和需求。提供各種問題對應(yīng)的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認識你,你也不認識我。但先做網(wǎng)站后付款的網(wǎng)站建設(shè)流程,更有青銅峽免費網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。
之前說InnoDB 的 select 查詢會鎖表,有的人不信。然而有的人學習能力很強,立馬在官方網(wǎng)站上找到了,select 查詢會鎖表,就看你怎么使用,并不是說所有的 select 查詢都會鎖表。具體看你的事務(wù)隔離級別,和編寫的查詢語句的形式。
MySQL 最常見的坑就是 InnoDB 是行鎖,這是大家都知道的事,但是有時候它卻會鎖表,你說奇怪不奇怪。
其實只要你懂它了之后,一點也不會覺得奇怪。只有你不懂,才會覺得它奇怪。InnoDB 的行鎖是實現(xiàn)在索引上的,而不是鎖在物理行記錄上。潛臺詞是,如果訪問沒有命中索引,也無法使用行鎖,將要退化為表鎖。這一點和 Oracle 的行鎖實現(xiàn)機制略有不同。
例如下面的表:
1 |
|
id PK(主鍵),無其他索引,即其他列都沒有索引。
1 |
|
命中索引,行鎖。
1 |
|
未命中索引,表鎖。
1 |
|
無索引,表鎖。
啟示:InnoDB 務(wù)必建好索引,否則鎖粒度較大,會影響并發(fā)。
再說一下 select,如果查詢沒有命中索引,也將退化為表鎖。下面我們結(jié)合 InnoDB 的三種鎖(記錄鎖(Record Locks)、間隙鎖(Gap Locks)、臨鍵鎖(Next-Key Locks))來說明它。再講這三種鎖的前提條件是默認的事務(wù)隔離級別為可重復讀(Repeated Read, RR)。
記錄鎖,它封鎖索引記錄,例如下面的查詢語句:
1 |
|
它會在 id=1 的索引記錄上加鎖,以阻止其他事務(wù)插入,更新,刪除 id=1 的這一行。
需要說明的是,如果是下面的查詢語句:
1 |
|
則是快照讀(SnapShot Read),它并不加鎖。
間隙鎖,它封鎖索引記錄中的間隔,或者第一條索引記錄之前的范圍,又或者最后一條索引記錄之后的范圍。例如下面的 SQL 語句:
1 |
|
會封鎖區(qū)間 id 為 8 到 15 的記錄。以阻止其他事務(wù),如:id=10 的記錄插入。
如果不阻止 id=10 的記錄插入,則會產(chǎn)生幻讀。如果能夠插入成功,同一個事務(wù)執(zhí)行相同的 SQL 語句,會發(fā)現(xiàn)結(jié)果集多出了一條記錄,即幻讀數(shù)據(jù)。
間隙鎖的主要目的,就是為了防止其他事務(wù)在間隔中插入數(shù)據(jù),以導致“不可重復讀”。
如果把事務(wù)的隔離級別降級為讀提交(Read Committed, RC),間隙鎖則會自動失效。
臨鍵鎖,是記錄鎖與間隙鎖的組合,它的封鎖范圍,既包含索引記錄,又包含索引區(qū)間。臨鍵鎖會封鎖索引記錄本身,以及索引記錄之前的區(qū)間。
如果一個會話占有了索引記錄 Record 的共享/排他鎖,其他會話不能立刻在 Record 之前的區(qū)間插入新的索引記錄。臨鍵鎖的主要目的,也是為了避免幻讀(Phantom Read)。如果把事務(wù)的隔離級別降級為RC,臨鍵鎖則也會失效。
最后說一下,怎么測試當前的查詢到底是行鎖還是表鎖呢?
以我們之前發(fā)生事故來說,首先是 select 查詢不能有索引。然后 dev 環(huán)境和 sit 環(huán)境連接同一個數(shù)據(jù)庫,dev 對某個事務(wù)中的查詢?nèi)帱c,讓它停在查詢操作上;sit 環(huán)境則對同一個表進行插入、更新、刪除操作。查看日志,就會發(fā)現(xiàn)有 time out 日志。具體為事務(wù)無法提交,超時結(jié)束,因為這個表已經(jīng)被鎖住了,獲取不到鎖,就會發(fā)生超時。
總結(jié):InnoDB 的鎖,與索引類型,事務(wù)的隔離級別相關(guān)。InnoDB 到底是行鎖還是表鎖取決于你的 SQL 語句。如果查詢沒有命中索引,也將退化為表鎖。InnoDB 的行鎖是實現(xiàn)在索引上的,而不是鎖在物理行記錄上。所以如果訪問沒有命中索引,也無法使用行鎖,將要退化為表鎖。
以上是“InnoDB中select查詢是行鎖還是表鎖”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學習更多知識,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!