<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          你真的了解mysql中的鎖嗎

          共 3713字,需瀏覽 8分鐘

           ·

          2021-11-30 06:08

          hello大家好 我是大家的學習成長小伙伴Captain



          大家在學習mysql的時候,估計也聽說過數(shù)據(jù)庫中的鎖


          鎖,大家應該是很熟悉的了吧,就是多個線程同時對共享資源的訪問的競爭


          那么大家對于mysql中的鎖又有多少了解呢


          先說一下mysql中的幾種語言,SQL語言共分為四大類


          數(shù)據(jù)查詢語言DQL,數(shù)據(jù)操縱語言DML,數(shù)據(jù)定義語言DDL,數(shù)據(jù)控制語言DCL。

          ?

          1. 數(shù)據(jù)查詢語言DQL:數(shù)據(jù)查詢語言DQL基本結構是由SELECT子句,FROM子句,WHERE

          ?

          2 .數(shù)據(jù)操縱語言DML:數(shù)據(jù)操縱語言DML主要有三種形式,插入,更新,刪除。

          ?

          3. 數(shù)據(jù)定義語言DDL:數(shù)據(jù)定義語言DDL用來創(chuàng)建數(shù)據(jù)庫中的各種對象如:表 視圖 索引 同義詞 簇。DDL操作是隱性提交的,不能rollback

          ?

          4. 數(shù)據(jù)控制語言DCL:數(shù)據(jù)控制語言DCL用來授予或回收訪問數(shù)據(jù)庫的某種特權,并控制數(shù)據(jù)庫操縱事務發(fā)生的時間及效果,對數(shù)據(jù)庫實行監(jiān)視等。


          ?

          鎖是并發(fā)訪問同一個共享資源時的同步機制,Synchronized、ReentrantLock和ReentrantReadWriteLock都用過的吧,都是一樣的道理

          ?

          MySQL的鎖是在服務器層或者存儲引擎層實現(xiàn)的,保證數(shù)據(jù)訪問的一致性和有序性

          ?

          ?

          按模式分類為:樂觀鎖與悲觀鎖。

          ?

          按粒度分可以分為全局鎖、表級鎖、頁級鎖、行級鎖。

          ?

          按屬性可以分為:共享鎖、排它鎖。

          ?

          按狀態(tài)分為:意向共享鎖、意向排它鎖。

          ?

          按算法分為:間隙鎖、臨鍵鎖、記錄鎖。



          樂觀鎖?

          ?

          一種思想,樂觀鎖建設數(shù)據(jù)一般情況下不會產(chǎn)生沖突,在數(shù)據(jù)的操作過程中不會對數(shù)據(jù)做任何鎖定,只有當數(shù)據(jù)進行提交跟新的時候,才會正式對數(shù)據(jù)的沖突與否進行檢測

          ?

          如果發(fā)生沖突了,則返回錯誤,調(diào)用者決定如何操作,是回滾還是重試

          ?

          比較適用于讀多寫少的情況,如果寫場景比較多,寫沖突的可能性比較高,可能需要不斷重試,這樣會大大降低系統(tǒng)性能

          ?

          這種可以通過增加一個數(shù)據(jù)版本字段Version來實現(xiàn),讀取數(shù)據(jù)的時候把這個字段一起讀出來,數(shù)據(jù)每更新一次,對Version字段加一,當我們提交更新數(shù)據(jù)的時候,判斷數(shù)據(jù)庫表中的對應記錄的版本信息和第一次取出來的Version是否一致,一致則可以更新,不一致則過期

          ?

          悲觀鎖

          ?

          這個也是一種思想,悲觀的看法,認為每次去取數(shù)據(jù)的時候都會有別人去修改,所以在整個數(shù)據(jù)處理過程中,數(shù)據(jù)處于鎖定狀態(tài)

          ?

          適用于并發(fā)量不大,寫入操作比較頻繁,數(shù)據(jù)一致性比較高的場景,MySQL中,共享鎖和排他鎖都是屬于悲觀鎖的不同實現(xiàn)

          ?

          全局鎖

          ?

          對整個數(shù)據(jù)庫實例進行加鎖,一般用于全庫的邏輯備份

          ?

          MySQL 提供了一個加全局讀鎖的方法,命令是Flush tables with read lock (FTWRL)。使用這個命令之后,整個庫處于只讀狀態(tài),其它線程的更新語句都會被阻塞

          ?

          主庫備份,需要考慮影響業(yè)務系統(tǒng),從庫備份,在備份期間不能執(zhí)行主庫同步過來的binlog,主從同步會有延遲

          ?

          解決辦法,mysqldump使用參數(shù)--single-transaction,啟動一個事務,確保拿到一致性視圖。而由于MVCC的支持,這個過程中數(shù)據(jù)是可以正常更新的。

          ?

          表級鎖

          ?

          對操作的數(shù)據(jù)表加鎖,MyISAM和InnoDB引擎都支持表級鎖定,這里分為兩種,一種是表鎖,一種是元數(shù)據(jù)鎖,即meat?data lock,MDL鎖

          lock?tables?表名?read?#該表可以讀,不能ddl?和?dml?中增刪改,只能讀取表數(shù)據(jù)lock tables 表名 write # 既不能讀,也不能寫

          ?

          表鎖的語法是 lock tables …?read/write。與?FTWRL?類似,可以用?unlock tables?主動釋放鎖,也可以在客戶端斷開的時候自動釋放。需要注意,lock tables?語法除了會限制別的線程的讀寫外,也限定了本線程接下來的操作對象。

          ?

          MDL鎖

          ?

          防止DDL和DML并發(fā)的沖突,你想啊,一個查詢正在遍歷表中數(shù)據(jù),而執(zhí)行期間另一個線程對這個表結構進行了變更,刪除了一列,查詢線程拿到的結果跟表結構對不上,就亂套了

          ?

          MDL鎖不是顯示的,MDL鎖是在5.5版本引入的

          ?

          對一個表做增刪改查操作的時候,加MDL讀鎖,讀鎖之間不沖突,所以多個線程可以同時對一個表進行增刪改查

          ?

          當要對表結構變更操作的時候,加MDL寫鎖,讀鎖和寫鎖、寫鎖和寫鎖都是沖突的,用來保證變更結構操作的安全性

          ?

          兩個線程同時對一個表中加字段,其中一個要等另一個執(zhí)行完才可以開始。一個線程A先在查詢數(shù)據(jù),另一個線程B想要加一列數(shù)據(jù),需要等A線程執(zhí)行完才可以執(zhí)行線程B,就解決了上面的問題

          ?

          MDL鎖是系統(tǒng)默認加的,我們理解了上面的機制之后,一定要注意MDL寫鎖之后的讀鎖和寫鎖都會阻塞,所以在給一些表加字段的時候一定要注意,盡量避開業(yè)務系統(tǒng)比較繁忙的時候

          ?

          即使小表,操作不慎,如果一個表的查詢語句頻繁,而且客戶端有重試機制,也就是超時之后還會再起一個新session,庫的線程很容易就慢了,這時系統(tǒng)就崩了

          ?

          千萬不要在長事務中對表結構進行修改,事務不提交會一直占用MDL寫鎖,那后面的語句就需要一直等待

          ?

          頁級鎖

          ?

          頁級鎖是 MySQL 中鎖定粒度介于行級鎖和表級鎖中間的一種鎖。表級鎖速度快,但沖突多,行級沖突少,但速度慢。因此,采取了折衷的頁級鎖,一次鎖定相鄰的一組記錄。BDB?引擎支持頁級鎖。

          ?

          行級鎖

          ?

          MySQL中只有InnoDB支持行級鎖,行級鎖分為共享鎖和排他鎖。

          ?

          行級鎖是粒度最低的鎖,鎖沖突概率最低。但加鎖慢、開銷大,容易發(fā)生死鎖現(xiàn)象。

          ?

          行鎖并不是直接鎖記錄,而是鎖索引

          ?

          索引分為主鍵索引和非主鍵索引,一條sql語句操作了主鍵索引,MySQL就會鎖定這條主鍵索引;如果一條語句操作了非主鍵索引,MySQL會先鎖定該非主鍵索引,再鎖定相關的主鍵索引

          ?

          共享鎖

          ?

          共享鎖,也就是我們常說的讀鎖,一個事務對數(shù)據(jù)加上讀鎖之后,其它事務只能對該數(shù)據(jù)加讀鎖,不能做任何修改,不能加寫鎖

          ?

          這樣可以更好的支持并發(fā)中的讀取數(shù)據(jù),讀取數(shù)據(jù)的時候,不允許其他事物對當前數(shù)據(jù)進行修改操作,從而避免不可重復讀的問題的出現(xiàn)

          select … lock in share mode

          排它鎖


          排它鎖,也就是寫鎖,當對數(shù)據(jù)加上寫鎖之后,其它事務不能對該數(shù)據(jù)讀寫,這個時候讀鎖和寫鎖都不可以加了,也就是全部阻塞了

          ?

          寫鎖就是為了解決在數(shù)據(jù)修改的時候,不允許其它事務對當前數(shù)據(jù)進行修改和讀取操作,從而可以避免臟讀問題的產(chǎn)生

          ?

          共享鎖可以避免不可重復讀的問題,排它鎖可以避免臟讀問題的產(chǎn)生

          ?

          意向共享鎖和意向排它鎖

          ?

          意向鎖的出現(xiàn)就是為了協(xié)調(diào)表鎖和行鎖,支持多粒度的并存

          ?

          事務A有行鎖的時候,MySQL會自動給該表加上意向鎖,事務B如果想申請整個表的寫鎖,就不用遍歷去每一行判斷是否存在行鎖,只需要判斷是否存在意向鎖,即可決定是否可以加表的寫鎖

          ?

          意向鎖的互斥性


          當然,表格中的共享鎖和排他鎖都是表鎖,即表鎖和意向鎖的關系

          ?

          意向鎖是不會和行級的共享排他鎖互斥的

          ?

          給大家再解釋一下,就是有行級共享鎖,那就加上意向共享鎖,當需要加表級的共享鎖的時候,兼容,即行讀表讀共存;相反,表級的排他鎖加不上,也就是行讀表寫不共存

          ?

          相應的行級的排他鎖,也就是寫鎖加上之后,表級的讀鎖和寫鎖都是不能加上的了,也就是行寫表既不可讀也不可寫

          ?

          總結

          ?

          行讀表讀共存


          行讀表寫不共存


          行寫既不可讀也不可寫????


          ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

          ?

          記錄鎖


          記錄鎖是封鎖記錄,記錄鎖也叫行鎖


          間隙鎖


          間隙鎖基于非唯一索引,它鎖定一段范圍內(nèi)的索引記錄。使用間隙鎖鎖住的是一個區(qū)間,而不僅僅是這個區(qū)間中的每一條數(shù)據(jù)

          ?

          臨鍵鎖

          ?

          臨鍵鎖,是記錄鎖與間隙鎖的組合,它的封鎖范圍,既包含索引記錄,又包含索引區(qū)間,是一個左開右閉區(qū)間。臨鍵鎖的主要目的,也是為了避免幻讀(Phantom Read)。如果把事務的隔離級別降級為RC,臨鍵鎖則也會失效。

          ?

          每個數(shù)據(jù)行上的非唯一索引列上都會存在一把臨鍵鎖,當某個事務持有該數(shù)據(jù)行的臨鍵鎖時,會鎖住一段左開右閉區(qū)間的數(shù)據(jù)。


          需要強調(diào)的一點是,InnoDB 中行級鎖是基于索引實現(xiàn)的,臨鍵鎖只與非唯一索引列有關,在唯一索引列(包括主鍵列)上不存在臨鍵鎖。

          ??結束語



          Captain養(yǎng)現(xiàn)續(xù),,


          ,,,。


          Captain續(xù),Java,,、


          ,續(xù)


          https://github.com/DayuMM2021/Java






          瀏覽 76
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  亚洲在线无码不卡视频 百度一下 | 亚洲欧美福利 | 手机av免费 | 色色丁香网 | 欧美成人性爱免费在线 |