1. 程式人生 > 資料庫 >MySQL學習筆記5---MySQL 鎖機制

MySQL學習筆記5---MySQL 鎖機制

8、MySQL 鎖機制

8.1、概述

鎖的分類

從資料操作的型別(讀、寫)分

  • 讀鎖(共享鎖):針對同一份資料,多個讀操作可以同時進行而不會互相影響
  • 寫鎖(排它鎖):當前寫操作沒有完成前,它會阻斷其他寫鎖和讀鎖。

從對資料操作的顆粒度

  • 表鎖
  • 行鎖

8.2、表鎖

特點:偏向MyISAM儲存引擎,開銷小,加鎖快,無死鎖,鎖定粒度大,發生鎖衝突的概率最高,併發最低。

8.2.1、讀鎖

create table mylock (
id int not null primary key auto_increment,
name varchar(20) default ''
) engine myisam;
insert into mylock(name) values('a');
insert into mylock(name) values('b');
insert into mylock(name) values('c');
insert into mylock(name) values('d');
insert into mylock(name) values('e');

select * from mylock;

在這裡插入圖片描述
在這裡插入圖片描述

8.2.2、寫鎖

在這裡插入圖片描述
在這裡插入圖片描述

SHOW STATUS like 'table%';

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-do9lCoyf-1606016580077)(images5/image-20201121200359316.png)]

  • MyISAM 的讀寫鎖排程是寫優先,所以不適合作為以寫為主的引擎。因為寫鎖後,其他執行緒不能做任何操作,大量的更新會使查詢很難得到鎖,從而造成永久阻塞。

8.3、行鎖

特點:偏向InnoDB儲存引擎,開銷大,加鎖慢;會出現死鎖;鎖定粒度最小,發生鎖衝突的概率最低,併發度也最高。

InnoDB與MyISAM的最大不同有兩點:一是支援事務(TRANSACTION);二是採用了行級鎖

CREATE TABLE test_innodb_lock (a INT(11),b VARCHAR(16))ENGINE=INNODB;
INSERT INTO test_innodb_lock VALUES(1,'b2');
INSERT INTO test_innodb_lock VALUES(3,'3');
INSERT INTO test_innodb_lock VALUES(4, '4000');
INSERT INTO test_innodb_lock VALUES(5,'5000');
INSERT INTO test_innodb_lock VALUES(6, '6000');
INSERT INTO test_innodb_lock VALUES(7,'7000');
INSERT INTO test_innodb_lock VALUES(8, '8000');
INSERT INTO test_innodb_lock VALUES(9,'9000');
INSERT INTO test_innodb_lock VALUES(1,'b1');
CREATE INDEX test_innodb_a_ind ON test_innodb_lock(a);
CREATE INDEX test_innodb_lock_b_ind ON test_innodb_lock(b);
SELECT * from test_innodb_lock;

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-4MHq1K1r-1606016580078)(images5/image-20201121203017329.png)]

  • 索引失效導致行鎖變表鎖

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-p2OvsYmb-1606016580080)(images5/image-20201121204732808.png)]

8.4、間隙鎖

什麼是間隙鎖?

當我們用範圍條件而不是相等條件檢索資料,並請求共享或排他鎖時,InnoDB會給符合條件的已有資料記錄的索引項加鎖;對於鍵值在條件範圍內但並不存在的記錄,叫做“間隙”;

InnoDB也會對這個“間隙”加鎖,這種鎖機制就是所謂的間隙鎖(Next-Key鎖)。

面試題:如何鎖定一行?

  • select * from test where a = 8 for update   #其他session對這行的操作將被阻塞
    

8.5、優化建議

  • 儘可能讓所有資料檢索都通過索引來完成,避免無索引行鎖升級為表鎖
  • 合理設計索引,儘量縮小鎖的範圍
  • 儘可能較少檢索條件,避免間隙鎖
  • 儘量控制事務大小,減少鎖定資源量和時間長度
  • 儘可能低級別事務隔離

據檢索都通過索引來完成,避免無索引行鎖升級為表鎖

  • 合理設計索引,儘量縮小鎖的範圍
  • 儘可能較少檢索條件,避免間隙鎖
  • 儘量控制事務大小,減少鎖定資源量和時間長度
  • 儘可能低級別事務隔離