mysql鎖的操作 MySQL的鎖操作

2021-10-19 06:37:37 字數 2828 閱讀 6071

mysql  innodb引擎中鎖的介紹

1.    共享鎖:允許事務讀一行資料

2.     排他鎖:允許事務刪除或者更新一行資料

3.     意向共享鎖:事務想要獲得表中某幾行的共享鎖,是表級鎖

4.     意向排他鎖:事務想要表中某幾行的排他鎖

查詢鎖資訊的方法

檢視當前請求鎖定的資訊:show engine innodb status

檢視鎖的具體資訊:select * frominformation_schema.innodb_locks

檢視鎖的等待訊息:select * from information_schema.innodb_lock_waits

innodb的非鎖定讀工作原理

innodb的select操作使用的是一致性非鎖定讀,即如果讀取的行正在執行delete  update操作,這時讀取操作不會等待行上鎖的釋放,而是去讀取行的乙個快照資料,快照資料是指在行修改之前的版本的資料,該實現是通過undo段實現的,但是不同事物隔離級別下,讀取的方式不同,並不是每個事物隔離級別的讀取都是一致性讀。

例如:read committed級別,總是讀取行的最新版本,如果行被鎖定了,讀取該行版本的最新乙個快照,乙個事務在開始時只能看見已經提交的事務所做的改變,在事務提交前所做的任何資料都是不可見的;repetable read(預設事務級別)總是讀取事務開始時的行資料,但會導致幻讀,比如當使用者讀取某一範圍內的資料行時,另乙個事務又在該範圍內插入了新行,當使用者再次讀取該範圍內的資料行時,會發現有新的幻影行,不過innodb的多版本併發控制機制可解決幻讀問題;read uncommitted級別所有事務都能看見為提交事務的執行結果,這樣可能會產生很多問題,比如髒讀,建議不採納這種隔離級別;serializable是最高的隔離級別,它通過強制事務排序,使之不可能發生相互衝突,從而解決幻讀問題,也就是它在每個讀的資料行上加鎖。但在這個級別肯能導致大量地超時現象和鎖競爭現象,很少採納,除非是使用者的應用是為了資料的穩定性,需要強制減少併發的情況下。

顯示加鎖的方法

非鎖定讀大大提高了資料讀取的併發性,這時預設讀取方式,也可以顯示地給select加鎖,方法如下:

select …. for  update  對讀取的行記錄加乙個x鎖,其他事務想在這些行上加鎖會被阻塞;

select …. lock in share mode  對讀取的行記錄加乙個s鎖,其他事務可以對鎖定的記錄加s鎖,但不能加x鎖

innodb的行鎖演算法

innodb有3种行鎖的鎖的演算法,分別是

record lock:單個行記錄上的鎖

gap lock:間隙鎖,鎖定乙個範圍,但不包含記錄本身

next-key lock(預設):鎖定乙個範圍,並且包括記錄本身,相當於reacord+gap

下面通過乙個例子演示一下next-key lock演算法:

先建一張表testlock,向其中插入資料1,2,3,4,7,8

開啟會話a:開啟乙個事務但不提交,**如下:

set autocommit = 0;

start transaction;

select * from test.locktest where idlocktest< 7 lock in share mode;

開啟會話b,插入乙個值為10的資料:

insert into test.locktest values (10);

insert into test.locktest values (6);

結果發現資料10 能插入,6 不能插入,一直在執行,因為該鎖演算法鎖定的是乙個範圍,而6在範圍內,這時在會話a commit,此時就發現會話b中執行完成了~~

鎖帶來的問題

1.     丟失更新,讓事務變成序列操作,而不是併發的操作,即對每個事務開始就對讀取記錄加排他鎖

2.     髒讀:乙個事務讀到另乙個事務中為提交的資料,發生的條件是read uncommitted

3.     不可重複讀:讀的是已經提交的資料。可忽略。

樂觀鎖和悲觀鎖

悲觀鎖:指的是假設併發更新衝突會發生,所以不管衝突是否真的發生,都會用鎖機制,完成下面功能:鎖住讀取的記錄,防止其他事務讀取和更新這些記錄,其他事務會一直被阻塞,直到這個事務結束,可用repeatable read事務實現,還可以用for update語句實現

樂觀鎖:不會鎖住任何東西,也就是說它不依賴資料庫的事務機制,樂觀鎖完全是應用系統層面的東西,使用樂觀鎖必須加版本字段,否則只能比較所有字段,但因為浮點型別不能比較,所以實際上沒有版本欄位是不行的。

locktables 和unlock tables指令

注意點:mysql支援locktables 和unlock tables指令,這是由伺服器實現的,和儲存引擎無關,當乙個應用從myisam轉成innodb時沒必要使用這些指令了,因為innodb支援行級鎖,況且這種命令會影響伺服器的效能。

多版本併發控制(mvcc)

select:

必須確保符合兩個標準:

1 innodb只查詢版本早於當前事務版本的資料行,這確保了當前事務讀取的行都是在事務開始前已經存在的或是當前事務建立和修改的行

2 資料行的刪除版本必須是未定義的,或大於事務版本,這確保了事務讀取的行,在事務開始時是未被刪除的

insert: innodb為每個新增行記錄下當前系統版本號

delete:innodb為每個刪除行記錄下當前系統版本號作為刪除標示

update:為每個需要更新的行,建立乙個新的行拷貝,並且為新的行拷貝記錄當前的系統版本號,同時也為更新前的舊行記錄了系統的版本號,作為舊行的刪除版本標示

這樣做的好處是使得大多數讀操作不必申**鎖,使得讀操作盡可能地快,併發程度就提高了,缺點是必須為每行資料儲存更多的額外資料,做更多的行檢查工作。mvcc只支援read和committed兩個隔離級別!

mysql的悲觀鎖 mysql悲觀鎖

1.create database lock test db 2.create user test 1 identified by 123456 3.grant all privileges on lock test db.to test 1 identified by 123456 4.flush...

mysql間隙鎖 mysql的間隙鎖

最近學習了mysql的各種鎖,有點暈,打算通過文章的方式捋一捋。在學習了mvcc後,我就想,他已經很好的解決了併發讀寫了,但我也知道innodb提供了多種型別的鎖,所以很好奇這些鎖有什麼用,為什麼這些鎖的功能是mvcc做不到的?本文討論的都是rr級別下的鎖 我先建立乙個表,並插入幾行資料,如下圖 插...

mysql鎖的使用 MySQL之鎖的使用

mysql表級鎖的鎖模式 mysql的表級鎖有兩種模式 表共享讀鎖 table read lock 和表獨佔寫鎖 table write lock 鎖模式的相容性 對myisam表的讀操作,不會阻塞其他使用者對同一表的讀請求,但會阻塞對同一表的寫請求 對 myisam表的寫操作,則會阻塞其他使用者對...