日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

mysql update用not in太慢了_MySQL 加锁和死锁解析

發布時間:2025/3/19 数据库 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mysql update用not in太慢了_MySQL 加锁和死锁解析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

目錄

  • 產生死鎖的必要條件

  • 常規鎖模式

  • 鎖的屬性

  • 鎖組合(屬性+模式)

  • 鎖沖突矩陣

  • 鎖是加在那里的?

  • 操作與加鎖的對照關系

    • 那些操作會加GAP鎖?

    • 如何去掉GAP鎖?

    • Insert

    • Delete

    • Update

    • GAP鎖

    • 什么時候加next-key lock?

    • Insert Intention Lock

  • 總結

產生死鎖的必要條件

  • 多個并發事務(2個或者以上)

  • 每個事物都持有了鎖(或者是已經在等待鎖)

  • 每個事務都需要再繼續持有鎖(為了完成事務邏輯,還必須更新更多的行)

  • 事物之間產生加鎖的循環等待,形成死鎖

常規鎖模式

  • LOCK_S(讀鎖,共享鎖)

  • LOCK_X(寫鎖,排它鎖)

鎖的屬性

  • LOCK _REC_NOT_GAP(鎖記錄)

  • LOCK_GAP(鎖記錄前的GAP)

  • LOCK_ORDINARY(同時鎖記錄+記錄前的GAP,Next key鎖)

  • LOCK_INSERT_INTETION(插入意向鎖)

鎖組合(屬性+模式)

可以任意組合

鎖沖突矩陣

鎖是加在哪里的?

  • 根據主鍵查找-鎖加在主鍵上
    如 begin;select * from tt_copy where id=4 for update;

    加鎖情況

index PRIMARY of table test.tt_copy trx id 1101588 lock_mode X locks rec but not gap
  • 根據普通索引查找-鎖加在普通索引和主鍵上
    如 begin;select * from tt_copy force index(idx_a) where a=4 for update;加鎖情況

index idx_a of table test.tt_copy trx id 1101590 lock_mode X locks rec but not gap
index PRIMARY of table test.tt_copy trx id 1101590 lock_mode X locks rec but not gap操作與加鎖的對照關系以下沒特殊說明都為RC隔離級別Insert
  • 無Unique key,插入后 :

    無論RC或RR隔離級別都是對主鍵加 LOCK_X+LOCK_REC_NOT_GAP

  • 有Unique key

插入前,唯一約束檢查:LOCK_S+LOCK_ORDINARY
插入前,插入的位置有GAP鎖:LOCK_INSERT_INTETION
插入后,新數據插入:LOCK_X+LOCK_REC_NOT_GAP

Delete

滿足刪除條件的所有記錄:LOCK_X+LOCK_REC_NOT_GAP

Update

**Update操作分解 **

  • Step ?1:

    定位到 下一條滿足查詢條件的記錄(查詢過程,類似于Select/Delete)

  • Step ?2:

    刪除當前定位到的記錄(標記為刪除狀態)

  • Step ?3:

    拼裝更新后項,根據更新后項定位到 新的插入位置

  • Step ?4:

    在新的插入位置,判斷是否存在 Unique ?沖突( 存在Unique ?Key 時)

  • Step ?5:

    插入更新后項(不存在Unique沖突時)

  • Step ?6:

    重復Step ?1 到Step ?5 的操作,直至掃描完整個查詢范圍

Update操作分析

  • Step ?1,Step ?2:

    Delete

  • Step ?3,Step ?4,Step ?5:

    Insert

Update

  • 無Unique key:

  • 查詢范圍中的所有記錄,LOCK_X ?+ ?LOCK_REC_NOT_GAP

  • 有Unique key:

  • 查找滿足條件的記錄:

    查詢范圍內的所有記錄, LOCK_X ?+ ?LOCK_REC_NOT_GAP

  • 更新后項存在唯一性沖突:

    沖突項上的加鎖,LOCK_S ?+ ?LOCK_ORDINARY

  • 更新后項不存在唯一性沖突:

    更新位置后項加鎖,LOCK_S ?+ ?LOCK_GAP (省略)

  • 實際更新操作:

    可看做插入了一條新紀錄,LOCK_X ?+ ?LOCK_REC_NOT_GAP

GAP鎖那些操作會加GAP鎖?

  • Read ?Committed (RC) ) :

    Unique ?Key 唯一約束檢查;

    Purge操作;

  • Repeatable ?Read (RC ):

    RC的基礎上,所有需要加鎖的索引范圍掃描和索引查找(Update/Delete…)

  • 還有一種會加GAP鎖:

    RR隔離級別下,對有唯一索引的表執行insert on ?duplicate update操作,除了會對新插入的記錄加x not gap外,還會對相鄰記錄加x gap

如何去掉GAP鎖?

change the transaction isolation level to READ COMMITTED or enable the innodb_locks_unsafe_for_binlog system variable (which is now deprecated)

什么時候加next-key lock?

By default, InnoDB operates in REPEATABLE READ transaction isolation level. In this case, InnoDB uses next-key locks for searches and index scans, which prevents phantom rows

Insert Intention Lock

An insert intention lock is a type of gap lock set by INSERT operations prior to(在...之前) row insertion.

總結

? ?原則之一

  • 要分析一個死鎖,必須深入業務,了解整個事務的邏輯(閉門無法造車)

? ?原則之二`

  • GAP鎖很復雜,為了減少GAP鎖,減少GAP導致的死鎖,盡量選擇Read ?Committed隔離級別(RC + ?row ?based ?binlog,基本上能夠解決所有問題,無需使用Repeatable ?Read)

  • 適當的 減少Unique 索引,能夠減少GAP鎖導致的死鎖(根據業務情況而定)

? ?原則之三

  • 在MySQL 中,以不同索引的過濾條件, 來操作相同的記錄(Update/Delete ),很容易產生死


    鎖。

? ?原則之四

  • RC隔離級別下,如果死鎖中出現Next ?Key(Gap鎖),說明表中一定存在unique索引

  • 多語句事務產生的死鎖,確保每條語句操作記錄的順序性,能夠極大減少死鎖

作者:jiaxin

出處:cnblogs.com/YangJiaXin/

總結

以上是生活随笔為你收集整理的mysql update用not in太慢了_MySQL 加锁和死锁解析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。