tft每日頭條

 > 生活

 > mysql中的鎖機制詳解

mysql中的鎖機制詳解

生活 更新时间:2024-07-30 16:16:32

前言

本文講述mysql鎖定義,lock與latch區别,Innodb中的鎖,強制開啟S/X鎖,自增長鎖,行鎖的3中算法,鎖升級等,主要參照來自《MYSQL技術内幕 第2版》這本書,以及參雜了自己的一些理解。

鎖定義/作用

為支持對 共享資源 的并發訪問,保證數據的 一緻性 與 完整性 ,數據庫所提供的一種 約束機制 。不同的數據庫和不同的引擎有着不同實現方式及支持度,可分為行,頁,表鎖。(MyISAM是表鎖,SQL SERVER是行級鎖,InnoDB默認也是行級鎖)

mysql中的鎖機制詳解(MYSQL鎖機制)1

前三個都是MYSQL的不同引擎。

lock與latch(門闩shuan)

latch适用于短期鎖定的 輕量級鎖 (門闩不防盜嘛),鎖定時間過長時,性能會非常差。

lock的對象是事務,鎖定的是數據庫中的對象:行、頁、表,鎖在commit或rollback時才會釋放。

latch分為mutex(互斥鎖)和rwlock(讀寫鎖),用于保證 并發線程 操作臨界資源(可以理解為共享資源)的正确性。

latch是面向數據庫系統底層的,目前沒找供用戶開發的api,除非DBA,普通開發者基本用不到,了解即可。

mysql中的鎖機制詳解(MYSQL鎖機制)2

mysql innodb中: 查看latch命令: `show engine innodb latch` 查看lock命令: `show engine innodb status`

Innodb引擎中的鎖

innodb支持行鎖和表鎖(不支持表鎖),默認為行鎖。

兩種行級鎖:

  1. 共享鎖(S lock):允許事務讀1行
  2. 排他鎖(X lock):允許事務删除或更新1行

在A獲得S鎖後,B可獲S鎖,但不能加X,否則A會阻塞。(讀不影響數據)

在A獲得X鎖後,B不能再獲得任何鎖。(修改必須獨占)

S鎖可以理解為讀鎖,X鎖可以理解為獨占鎖,且X優先級高于S。

Innodb支持多粒度鎖定,允許行級、表級上的鎖同時存在。(Innodb不支持頁級鎖)為此推出一種新的鎖方式 意向鎖 (Intention Lock):将鎖定的對象分為多個層次,以滿足事務在更細的細粒度上加鎖。

一句話概括就是,對上層對象(頁,表)加同樣的意向鎖(IS/IX)。同樣的意思就是記錄加S,上層對象就加IS;同理,記錄加X,上層對象就加IX。

mysql中的鎖機制詳解(MYSQL鎖機制)3

所有兼容情況:(兼容就是能獲取,不兼容就是要等待阻塞)

很明顯,是對稱矩陣哦

mysql中的鎖機制詳解(MYSQL鎖機制)4

一緻性非鎖定讀

一緻性非鎖定讀(consistent nolocking read):指的是在讀取被加X鎖的行時,不需要等待行鎖的釋放,會去讀它的快照(snapshot)。

mysql中的鎖機制詳解(MYSQL鎖機制)5

一個行有多個快照數據,究竟讀哪一個呢?

READ COMMITED是讀最新的,READ REPEATEABLE(Innodb默認隔離級别)是讀的是 自己 事務begin前的。(這裡的場景是開啟兩個事務,一個查,一個改,有先後。)READ COMMITD會破壞隔離性(Isolation)

一緻性鎖定讀--強制開啟鎖

雖然可重複讀(默認隔離級别)保證了隔離性,但為了确保數據的一緻性,我們可以顯式 強制加鎖 :

  • SELECT ... IN SHARE MODE
  • SELECT ... FOR UPDATE

上面的 in share mode 是加的S鎖。 for update 是加的X鎖。

自增長鎖

對字段設置auto_incrment時,自增計算器會保存在表中,鎖會在insert語句之後,事務commit之前釋放。(特殊的機制,為提高插入性能,沒有選擇事務結束再釋放,而是Insert後)。後面MYSQL還新增了 innodb_autoinc_mode 來進一步控制自增長。

注:Innodb下自增列必須是索引,而且是索引的第一列(組合索引情況下),否則抛出異常。MyISAM沒有這要求。

行鎖的3種算法

  • Record Lock :記錄鎖,鎖定自己的記錄
  • Gap Lock:溝鎖,鎖自己附近的範圍,不包括自己記錄(開區間)
  • Next-key Lock :範圍 自己,Record Gap結合(閉區間)

Record Lock是鎖住 索引記錄 ,主鍵也是索引之一。

Next-key是 行查詢 select默認采用的鎖算法 ,如有索引:10,13,20。則鎖區間為:(-∞,10],(10,13],(13,20],(20, ∞)。

顯知,gap的話就包含自己,]變成了)。

next-key這裡的next指的就是右區間為閉區間,推理:previous-key指的是左區間閉合。

注:自動降級:若索引中含有唯一屬性(**唯一**索引),則next-key會自動降級為record-key。(範圍鎖——>隻鎖自己)

next-key機制的發明是為了解決 Phantom problem (幻像問題),是的mysql可以不到serializable就可以解決幻讀。

幻像:一個事務A在未提交時,兩次sql的執行的結果的 數據條數 不一樣,B向其中修改的數據被A在第二次讀走了。違背了隔離性。

髒讀:A讀到了B中 未提交 的數據,若B之後回滾了,則讀到了髒數據。

不可重複讀:B對A讀到的值進行了修改,A第二次讀到的 數據值 變了。

鎖升級(lock escalation)

定義:鎖的粒度降低。如:行鎖——>頁鎖——>表鎖

作用: 鎖是稀有資源,升級是為了提高效率,防止系統使用太多内存來維護鎖。

Innodb存儲引擎不存在鎖升級。因為它不是根據記錄來産生行鎖,而是根據事務訪問的每個頁來管理鎖,采用 位圖 方式。鎖住一個頁的一條與鎖住多條的開銷一樣。

這裡的`頁來管理鎖`和上面`innodb不支持頁鎖`有點繞,我也沒理解,我後面去查證一下。

,

更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!

查看全部

相关生活资讯推荐

热门生活资讯推荐

网友关注

Copyright 2023-2024 - www.tftnews.com All Rights Reserved