分類信息網(wǎng)站有哪些關(guān)鍵詞優(yōu)化案例
文章目錄
- 1. 概述
- 2. 分類
- 3. 全局鎖
- 4. 表級(jí)鎖
- 5. 行級(jí)鎖
1. 概述
鎖是計(jì)算機(jī)協(xié)調(diào)多個(gè)進(jìn)程或線程并發(fā)訪問某一資源的機(jī)制。在數(shù)據(jù)庫中,除傳統(tǒng)的計(jì)算資源(CPU、RAM、I/O)的爭(zhēng)用以外,數(shù)據(jù)也是一種供許多用戶共享的資源。如何保證數(shù)據(jù)并發(fā)訪問的一致性、有效性是所有數(shù)據(jù)庫必須解決的一個(gè)問題,鎖沖突也是影響數(shù)據(jù)庫并發(fā)訪問性能的一個(gè)重要因素。從這個(gè)角度來說,鎖對(duì)數(shù)據(jù)庫而言顯得尤其重要,也更加復(fù)雜。
2. 分類
mysql中的鎖,按照鎖的粒度分,分為一下三類:
- 全局鎖:鎖定數(shù)據(jù)庫中的所有表
- 表級(jí)鎖:每次操作鎖住整張表
- 行級(jí)鎖:每次操作鎖住對(duì)應(yīng)的行數(shù)據(jù)
3. 全局鎖
全局鎖是對(duì)整個(gè)數(shù)據(jù)庫實(shí)例加鎖,加鎖后整個(gè)實(shí)例處于只讀狀態(tài),后續(xù)的DML的寫語句,DDL語句,已經(jīng)更新的事務(wù)操作提交語句都將被阻塞。其典型的應(yīng)用場(chǎng)景是做全庫的邏輯備份,對(duì)所有的表進(jìn)行鎖定,從而獲取一致性視圖,保證數(shù)據(jù)的完整性。
- 加全局鎖
flush table with read lock;
- 使用mysqldump工具對(duì)數(shù)據(jù)庫進(jìn)行備份
mysqldump -uroot -p1234 itcast(備份的數(shù)據(jù)庫名) > itcast.sql
- 解鎖
unlock tables;
- 通過全局鎖實(shí)現(xiàn)數(shù)據(jù)庫備份操作
- 創(chuàng)建三個(gè)終端,來模擬三個(gè)數(shù)據(jù)庫連接
2. 加全局鎖
flush table with read lock;
3. 執(zhí)行數(shù)據(jù)庫備份(在window命令行下)
mysqldump -h127.0.0.1 -uroot -p123456 mysql_learn > /Users/jackchai/Desktop/Self-study-notes/test/db011.sql
4. 釋放鎖
unlock tables;
數(shù)據(jù)庫中加入全局鎖,是一個(gè)比較重的操作,存在以下問題:
- 如果在主庫上備份,那么在備份期間都不能執(zhí)行更新,業(yè)務(wù)基本上就得停擺
- 如果在主庫上備份,那么備份期間從庫不能執(zhí)行主庫同步過來的二進(jìn)制日志(binlog),會(huì)導(dǎo)致主從延遲
在innodb存儲(chǔ)引擎中,我們可以在備份時(shí)加上參數(shù)--single-transaction參數(shù)來完成不加鎖的一致性備份
mysqldump --single-transaction -uroot -p123456 itcast > itcast.sql
4. 表級(jí)鎖
表級(jí)鎖,每次操作鎖住整張表。鎖定粒度大,發(fā)生鎖沖突的概率最高,并發(fā)度最低。應(yīng)用在MyIsam、innoDB、BDB等存儲(chǔ)引擎中。對(duì)于表級(jí)鎖,主要分為三類:
- 表鎖
- 元數(shù)據(jù)鎖(meta data lock,MDL)
- 意向鎖
- 表鎖
對(duì)于表鎖,分為兩類:
- 表共享讀鎖(read lock)
- 表獨(dú)占寫鎖 (write lock)
語法:
- 加鎖:lock tables 表名… read/write
- 釋放鎖:unlock tables / 客戶端斷開連接
- 測(cè)試
一個(gè)客戶端加讀鎖,所有客戶端可讀數(shù)據(jù)庫(但不能更新數(shù)據(jù)庫)
一個(gè)客戶端加表鎖,該客戶端可讀可寫,其它客戶端不能進(jìn)行任何操作
讀鎖不會(huì)阻塞其他客戶端的讀,但是會(huì)阻塞寫。寫鎖既會(huì)阻塞其它客戶的讀,又會(huì)阻塞其他客戶端的寫
- 元數(shù)據(jù)鎖(MDL)
MDL加鎖過程是系統(tǒng)自動(dòng)控制的,無需顯示使用,在訪問一張表的時(shí)候會(huì)自動(dòng)加上。MDL鎖主要作用是維護(hù)元數(shù)據(jù)(表結(jié)構(gòu))的數(shù)據(jù)一致性,在表上有活動(dòng)事務(wù)的時(shí)候,不可以對(duì)元數(shù)據(jù)進(jìn)行寫入操作。
在Mysql 5.5 中引入了MDL,當(dāng)對(duì)一張表進(jìn)行增刪改查的時(shí)候,加MDL讀鎖(共享),當(dāng)對(duì)表結(jié)構(gòu)進(jìn)行變更操作時(shí),加MDL寫鎖(排他)
對(duì)應(yīng)SQL | 鎖類型 | 說明 |
---|---|---|
lock tables xxx read/write | shared_read_only/shared_no_read_write | |
select、select…lock in share mode | shared_read | 與shared_read、shared_write兼容,與Exclusive互斥 |
insert、update、delete、select…for update | shared_write | 與shared_read、shared_write兼容,與Exclusive互斥 |
alter table… | exclusive | 與其他的MDL互斥 |
- 案例
一個(gè)數(shù)據(jù)庫連接加上shared_read鎖或shared_write和其他連接是共享的
一個(gè)連接加上shared_read/shared_write時(shí)另一個(gè)連接不能加上exclusive鎖
查看元數(shù)據(jù)鎖
select object_type, object_schema,object_name,lock_type,lock_duration from performance_schema.metadata_locks
- 意向鎖
為了避免DML在執(zhí)行時(shí),加的行鎖與表鎖沖突,在innoDB引入了意向鎖,使用表鎖不用檢查每行數(shù)據(jù)是否加鎖,使用意向鎖來減少表鎖的檢查。(加入行鎖的時(shí)候會(huì)給表加個(gè)意向鎖,加表鎖的時(shí)候會(huì)判斷意向鎖和表鎖是否兼容來決定是否加表鎖)
意向共享鎖(IS):由語句select…lock in share mode添加
意向排他鎖(IX):由insert、update、delete、select… for update添加。
通過以下sql,查看意向鎖及行鎖的加鎖情況
select object_schema,object_name,index_name,lock_type,lock_mode,lock_data from performance_schema.data_locks;
- 案例
加IS鎖
加IX鎖
5. 行級(jí)鎖
行級(jí)鎖,每次操作鎖住對(duì)應(yīng)的數(shù)據(jù)行。鎖定粒度最小,發(fā)生沖突的概率最低,并發(fā)度最高。應(yīng)用在innoDB存儲(chǔ)引擎中。InnoDB的數(shù)據(jù)時(shí)基于索引組織的,行鎖時(shí)通過對(duì)索引上的索引項(xiàng)來實(shí)現(xiàn)的,而不是對(duì)記錄加的鎖。對(duì)于行級(jí)鎖,主要分為以下三類:
- 行鎖(Record Lock):鎖定單個(gè)記錄的鎖,防止其他事務(wù)對(duì)此進(jìn)行update和delete。在RC、RR隔離級(jí)別下支持。
- 間隙鎖(Gap Lock):鎖定索引記錄間隙(不含該記錄),確保索引記錄間隙不變,防止其他事務(wù)在這個(gè)間隙進(jìn)行insert,產(chǎn)生幻讀。在RR隔離級(jí)別下支持。
- 臨鍵鎖(Next-key Lock):行鎖和間隙鎖的組合,同時(shí)鎖住數(shù)據(jù),并鎖住數(shù)據(jù)前面的間隙GAP。在RR隔離級(jí)別下支持。
- 行鎖
innoDB存儲(chǔ)引擎實(shí)現(xiàn)了一下兩種類型的行鎖:
- 共享鎖(S):允許一個(gè)事務(wù)去讀一行,阻止其他事務(wù)獲得相同數(shù)據(jù)集的排他鎖。
- 排他鎖(X):允許獲取排他鎖的事務(wù)更新數(shù)據(jù),阻止其他事務(wù)獲得相同數(shù)據(jù)集的共享鎖和排他鎖。
SQL | 行鎖類型 | 說明 |
---|---|---|
insert | 排他鎖 | 自動(dòng)加鎖 |
update | 排他鎖 | 自動(dòng)加鎖 |
delete | 排他鎖 | 自動(dòng)加鎖 |
select | 不加任何鎖 | |
select lock in share mode | 共享鎖 | 需要手動(dòng)在select之后加lock in share mode |
select for update | 排他鎖 | 需要手動(dòng)在select之后加for update |
默認(rèn)情況下,innoDB在Repeatable read 事務(wù)隔離級(jí)別運(yùn)行,innoDB使用next-key鎖進(jìn)行搜索和索引掃描,以防止幻讀
- 針對(duì)唯一索引進(jìn)行檢索時(shí),對(duì)已存在的記錄進(jìn)行等值匹配時(shí),將會(huì)自動(dòng)優(yōu)化為行鎖
- innoDB的行鎖時(shí)針對(duì)索引加的鎖,不通過索引條件檢索數(shù)據(jù),那么innoDB將對(duì)表中的所有記錄加鎖,此時(shí)就會(huì)升級(jí)為表鎖
通過一下SQL,查看意向鎖及行鎖的加鎖情況
select object_schema,object_name,index_name,lock_type,lock_mode,lock_data from performance_schema.data_locks;
- 間隙鎖/臨鍵鎖
默認(rèn)情況下,innoDB在Repeatable raed事務(wù)隔離級(jí)別,InnoDB使用next-key鎖進(jìn)行搜索和索引掃描,以防止幻讀
- 索引上的等值查詢(唯一索引),給不存在的記錄加鎖時(shí),優(yōu)化為間隙鎖
- 索引上的等值查詢(普通索引),向右遍歷時(shí)最后一個(gè)值不滿足查詢需求時(shí),next-key lock退化為間隙鎖
- 索引上的范圍查詢(唯一索引,會(huì)訪問到不滿足條件的第一個(gè)值為止
注意:間隙鎖唯一的目的是防止其他事務(wù)插入間隙,間隙鎖可以共存,一個(gè)事務(wù)采用的間隙鎖不回阻止另一個(gè)事務(wù)在同一個(gè)間隙上采用間隙鎖