1. 程式人生 > >mysql高階之鎖(1)

mysql高階之鎖(1)

簡介

鎖從力度上可以分為表鎖、頁鎖、行鎖。表鎖是將整張表鎖了,行鎖是將那一行鎖了。從對資料的操作角度來分,可以分為讀鎖和寫鎖。但是個人覺得,讀鎖和寫鎖是針對表鎖而言的,行鎖好像沒有這個區別。

行鎖:

可以參考我下一篇部落格:https://blog.csdn.net/tuesdayma/article/details/81910117

表鎖

概述: 表鎖主要正針對於myisam(mysql5.5之前預設儲存引擎)的儲存引擎而言的,每次對資料庫操作都會進行表鎖。

特點:

1、開銷小,加鎖快,無死鎖;發生鎖衝突的概率高,併發度很低。

2、讀鎖會阻塞其他session的寫,但是不會阻塞其他session的讀。

3、寫鎖會阻塞其他session的讀寫。

表上加讀鎖:

操作 當前session(加鎖的session) 其他session
讀加鎖的表
讀其他表 不能(解鎖之後才能,加鎖的時候會報錯)
寫加鎖的表 不能 會阻塞,但是鎖一旦釋放之後,就立刻執行
寫其他表 不能

表上加寫鎖:

操作 當前session(加鎖的session) 其他session
讀加鎖的表 不能
讀其他表 不能(解鎖之後才能,加鎖的時候會報錯)
寫加鎖的表 不能 會阻塞,但是鎖一旦釋放之後,就立刻執行
寫其他表 不能

注意: myisam的讀寫鎖排程是寫鎖比讀鎖優先。寫鎖後,其他執行緒不能對該表做任何操作,會阻塞在那邊,如果大量的更新操作會讓讀操作很難拿到鎖,嚴重的時候會使讀操作永久阻塞,這就是為什麼myisam不適合做大量寫操作業務資料庫的引擎。

演示:

1、準備工作: 建立一張儲存引擎為myisam的test02表。
這裡寫圖片描述

2、關閉自動提交:

set autocommit=0; show variables like 'autocommit';
這裡寫圖片描述

3、給test02表加一個讀鎖

給test02表加一個讀鎖:lock table 表名 read(write);

檢視當前加鎖的表:show open tables where in_use>0;
這裡寫圖片描述
4、結論1:表上加讀鎖,所有session都能查詢
這裡寫圖片描述
5、結論2:表上加讀鎖,當前session無法對錶進行編輯(增刪改),其他session對錶進行編輯會阻塞(右邊阻塞了)
這裡寫圖片描述
這裡寫圖片描述
6、結論3:表上加讀鎖,當前session是無法操作其他表,其他session可以操作其他表
這裡寫圖片描述

Table ‘test01’ was not locked with LOCK TABLES 從字面上的意思是test01不是被鎖的表,可以從兩個方面去考慮,是不是把test01也鎖了就能操作了,還是說當前鎖的不是test02而不是test01所以才不能操作。
這裡寫圖片描述
補充:個人猜想,當前session只能鎖一張表,如果鎖了一張表之後又去鎖另一張表,會釋放前者,鎖後者。

7、表上加寫鎖: 在加鎖之前必須要保證其他session所有的編輯都提交了,不然會阻塞。
這裡寫圖片描述
8、結論4:表上加寫鎖,當前session未編輯的時候,其他session是可以查詢的,但是當前session編輯之後未提交事務,其他session對鎖定的表進行操作就會阻塞,直到鎖被釋放之後才能操作出來。
這裡寫圖片描述
9、結論5:表上加寫鎖,當前session可以對鎖定的表進行增刪改查,但是不能對其他表進行操作。
這裡寫圖片描述
10、結論6:表上加寫鎖,當前session可以對鎖定的表進行編輯之後,不提交事務,然後直接釋放鎖,預設好像是直接提交了事務(開頭是將自動提交事務關閉的)。
這裡寫圖片描述

11:分析表鎖定:show status like 'table%';
這裡寫圖片描述

Table_locks_immediate:表示可以立即獲取鎖的查詢次數,每立即獲取鎖,這個值就加一。

Table_locks_waited:表示不能立即獲取鎖的次數,如果不能立即獲取所(即需要等待的話),這個值就加一。這個值往往是反應併發量的關鍵,如果值越大,則併發量越大(因為等待了很多次)。