1. 程式人生 > 實用技巧 >【mysql】- 鎖篇(下)

【mysql】- 鎖篇(下)

InnoDB儲存引擎中的鎖

  • 表級鎖
    • 表級別的S鎖X鎖
      • 在對某個表執行SELECTINSERTDELETEUPDATE語句時,InnoDB儲存引擎是不會為這個表新增表級別的S鎖或者X鎖
    • 表級別的IS鎖IX鎖
      • 當我們在對使用InnoDB儲存引擎的表的某些記錄加S鎖之前,那就需要先在表級別加一個IS鎖,當我們在對使用InnoDB儲存引擎的表的某些記錄加X鎖之前,那就需要先在表級別加一個IX鎖IS鎖IX鎖的使命只是為了後續在加表級別的S鎖X鎖時判斷表中是否有已經被加鎖的記錄,以避免用遍歷的方式來查看錶中有沒有上鎖的記錄
    • 表級別的AUTO-INC鎖
      • 在使用MySQL過程中,我們可以為表的某個列新增AUTO_INCREMENT
        屬性,之後在插入記錄時,可以不指定該列的值,系統會自動為它賦上遞增的值
  • 行級鎖:
    • 行鎖,也稱為記錄鎖,顧名思義就是在記錄上加的鎖
    • 行鎖型別
      • Record Locks:有S鎖X鎖之分,當一個事務獲取了一條記錄的S型記錄鎖後,其他事務也可以繼續獲取該記錄的S型記錄鎖,但不可以繼續獲取X型記錄鎖;當一個事務獲取了一條記錄的X型記錄鎖後,其他事務既不可以繼續獲取該記錄的S型記錄鎖,也不可以繼續獲取X型記錄鎖
      • Gap Locks:可以用於解決可重複讀級別下的幻讀問題,防止插入幻影記錄
      • Next-Key Locks: 鎖住某條記錄同時又可以阻止其他事務在該條記錄前邊的間隙插入新紀錄,其是Record Locks
        gap Locks的合體它既能保護該條記錄,又能阻止別的事務將新記錄插入被保護記錄前邊的間隙
      • Insert Intention Locks:一個事務在插入一條記錄時需要判斷一下插入位置是不是被別的事務加了所謂的gap鎖,若存在,插入操作需要等待,直到擁有的gap鎖對應的事務提交,事務在等待的時候也需要在記憶體中生成一個鎖結構,表明有事務想在某個間隙中插入新紀錄,但是現在在等待。這種型別的鎖命名為Insert Intention Locks,也成為插入意向鎖
      • 隱式鎖:一個事務在執行INSERT操作時,如果即將插入的間隙已經被其他事務加了gap鎖,那麼本次INSERT操作會阻塞,並且當前事務會在該間隙上加一個插入意向鎖
        ,否則一般情況下INSERT操作是不加鎖的

記憶體結構

  • 加鎖的本質就是在記憶體中建立一個鎖結構與之關聯
    • 對於需要放在同一個鎖結構中的情況
      • 在同一個事務中進行加鎖操作
      • 被加鎖的記錄在同一個頁面中
      • 加鎖的型別是一樣的
      • 等待狀態是一樣的
  • 鎖結構
    • 鎖所在的事務資訊: 不論是表鎖還是行鎖,都是在事務執行過程中生成的,哪個事務生成了這個鎖結構,這裡就記載著這個事務的資訊。其本質是一個指標,通過該指標可以找到記憶體中關於該事務的更多資訊
    • 索引資訊:對於行鎖來說,需要記錄一下加鎖的記錄是屬於哪個索引的
    • 表鎖/行級資訊
      • 表鎖:記載著這是對哪個表加的鎖,還有其他的一些資訊
      • 行鎖:記載了三個重要的資訊
        • Space ID :記錄所在表空間。
        • Page Number :記錄所在頁號。
        • n_bits :對於行鎖來說,一條記錄就對應著一個位元位,一個頁面中包含很多記錄,用不同的位元位來區分到底是哪一條記錄加了鎖。為此在行鎖結構的末尾放置了一堆位元位,這個n_bits屬性代表使用了多少位元位
    • type_mode:這是一個32位的數,被分成了lock_modelock_typerec_lock_type三個部分
      • 鎖的模式( lock_mode ),佔用低4位
        • LOCK_IS(十進位制的0):表示共享意向鎖,也就是IS鎖
        • LOCK_IX(十進位制的1):表示獨佔意向鎖,也就是IX鎖
        • LOCK_S(十進位制的2):表示共享鎖,也就是S鎖
        • LOCK_X(十進位制的3):表示獨佔鎖,也就是X鎖
        • LOCK_AUTO_INC(十進位制的4):表示AUTO-INC鎖
      • 鎖的型別( lock_type ),佔用第5〜8位,不過現階段只有第5位和第6位被使用:
        • LOCK_TABLE(十進位制的16),也就是當第5個位元位置為1時,表示表級鎖。
        • LOCK_REC(十進位制的32),也就是當第6個位元位置為1時,表示行級鎖
      • 行鎖的具體型別(rec_lock_type),使用其餘的位來表示。只有在lock_type的值為LOCK_REC時,也就是隻有在該鎖為行級鎖時,才會被細分為更多的型別:
        • LOCK_ORDINARY(十進位制的0):表示next-key鎖 。
        • LOCK_GAP(十進位制的512):也就是當第10個位元位置為1時,表示gap鎖
        • LOCK_REC_NOT_GAP(十進位制的1024):也就是當第11個位元位置為1時,表示記錄鎖
        • LOCK_INSERT_INTENTION(十進位制的2048):也就是當第12個位元位置為1時,表示插入意向鎖