mysql 安全鎖 Mysql Mysql中的鎖

2021-10-20 01:38:21 字數 3527 閱讀 8173

什麼是鎖

鎖是應對併發領域中常見的一種手段,比如在多執行緒程式設計中多個執行緒對同乙個資源進行讀寫,這時候鎖可以將並行化的訪問變成序列化,來保證資料的安全。所以鎖的主要作用是管理共享資源的併發時候的訪問。mysql中的鎖是用於實現事務中的隔離性(isolation)。

mysql中的鎖

mysql鎖的實現是由mysql各個儲存引擎來實現的,每個儲存引擎實現具體的鎖機制。比如innodb支援行鎖,而mysiam只支援表鎖。

mysql鎖的型別

共享鎖(也稱讀鎖):簡稱s鎖,多個執行緒可以在同一時間讀取同一資源而不相互干擾。

獨佔鎖(也稱寫鎖):簡稱x鎖,出於資料完整性的考慮,獨佔所是排他的會阻塞其他的寫鎖和讀鎖,這樣才能保證在同一時刻只有乙個執行緒能寫入資料,並防止其他執行緒讀取正在寫入的資料,這也是事務隔離性的體現。寫鎖和其他的鎖是不相容的。

注意:innode的鎖都是行鎖,相容性是指同一行記錄。

鎖的粒度

鎖的粒度是指鎖的策略,指的是被加鎖的最小資源單位,比如在行上加鎖,那麼加鎖的最小單位指的就是行,這樣的鎖就稱之為行級鎖。如果鎖的資源是資料頁,那麼久稱為頁級別鎖,同理如果鎖的最小單位是表,那麼就是表級鎖。為了能提高併發性,鎖定資源盡肯能的小,最理想的方式就是只需要對要修改的資料進行精確的鎖定。

mysql提供兩種鎖的粒度,一種是表級鎖(table-level),是mysql最基本的鎖策略,開銷小(併發性底),表鎖在加鎖時會鎖定整張表,乙個使用者在寫資料前要獲得表鎖去阻塞其他使用者對錶的操作,只有沒有寫鎖時其他讀取的使用者才能取得讀鎖。另一種是行級鎖(row-level),行級鎖可以最大程度支援併發,不過開銷比較大,而且是儲存引擎實現。

根據鎖的粒度鎖可分為:

1. 行級鎖

開銷大,加鎖慢;會出現死鎖;鎖定粒度最小,發生鎖衝突的概率最低,併發度也最高。

2. 頁級鎖

開銷和加鎖時間界於表鎖和行鎖之間;會出現死鎖;鎖定粒度界於表鎖和行鎖之間,併發度一般。

3. 表級鎖

開銷小,加鎖快;不會出現死鎖;鎖定粒度大,發生鎖衝突的概率最高,併發度最低。

mysql的表級鎖有兩種模式:表共享讀鎖(table read lock)和表獨佔寫鎖(table write lock)。

表級鎖和行級鎖對比:

表級鎖: mysql中鎖定 粒度最大 的一種鎖,對當前操作的整張表加鎖,實現簡單,資源消耗也比較少,加鎖快,不會出現死鎖。其鎖定粒度最大,觸發鎖衝突的概率最高,併發度最低,myisam和 innodb引擎都支援表級鎖。

行級鎖: mysql中鎖定 粒度最小 的一種鎖,只針對當前操作的行進行加鎖。 行級鎖能大大減少資料庫操作的衝突。其加鎖粒度最小,併發度高,但加鎖的開銷也最大,加鎖慢,會出現死鎖。

頁級鎖: mysql中鎖定粒度介於行級鎖和表級鎖中間的一種鎖。表級鎖速度快,但衝突多,行級衝突少,但速度慢。頁級進行了折衷,一次鎖定相鄰的一組記錄。bdb支援頁級鎖。開銷和加鎖時間界於表鎖和行鎖之間,會出現死鎖。鎖定粒度界於表鎖和行鎖之間,併發度一般。

鎖模式共享鎖(s):又稱讀鎖,若事務t對資料物件a加上s鎖,則事務t可以讀a但不能修改a,其他事務只能再對a加s鎖,而不能加x鎖,直到t釋放a上的s鎖。這保證了其他事務可以讀a,但在t釋放a上的s鎖之前不能對a做任何修改。

排他鎖(x):又稱寫鎖。若事務t對資料物件a加上x鎖,事務t可以讀a也可以修改a,其他事務不能再對a加任何鎖,直到t釋放a上的鎖。這保證了其他事務在t釋放a上的鎖之前不能再讀取和修改a。

另外,為了允許行鎖和表鎖共存,實現多粒度鎖機制,innodb還有兩種內部使用的意向鎖(intention locks),這兩種意向鎖都是表鎖。

意向共享鎖(is):事務打算給資料行加行共享鎖,事務在給乙個資料行加共享鎖前必須先取得該錶的is鎖。

意向排他鎖(ix):事務打算給資料行加行排他鎖,事務在給乙個資料行加排他鎖前必須先取得該錶的ix鎖。

意向鎖僅僅用於表鎖和行鎖的共存使用。如果我們的操作僅僅涉及行鎖,那麼意向鎖不會對我們的操作產生任何影響。在任一操作給表a的一行記錄加鎖前,首先要給該錶加意向鎖,如果獲得了意向鎖,然後才會加行鎖,並在加行鎖時判斷是否衝突。如果現在有乙個操作要獲得表a的表鎖,由於意向鎖的存在,表鎖獲取會失敗(如果沒有意向鎖的存在,加表鎖之前可能要遍歷整個聚簇索引,判斷是否有行鎖存在,如果沒有行鎖才能加表鎖)。

同理,如果某一操作已經獲得了表a的表鎖,那麼另一操作獲得行鎖之前,首先會檢查是否可以獲得意向鎖,並在獲得意向鎖失敗後,等待表鎖操作的完成。也就是說:1.意向鎖是表級鎖,但是卻表示事務正在讀或寫某一行記錄;2.意向鎖之間不會衝突, 因為意向鎖僅僅代表要對某行記錄進行操作,在加行鎖時,會判斷是否衝突;3.意向鎖是innodb自動加的,不需使用者干預。

innodb儲存引擎中的鎖

1. 共享/排他鎖(shared and exclusive locks)

2. 意向鎖(intention locks)

3. 記錄鎖(record locks)

只鎖記錄。表現為僅僅鎖著單獨的一行記錄。

4. 間隙鎖(gap locks)

只鎖間隙。表現為鎖住乙個區間(注意這裡的區間都是開區間,也就是不包括邊界值)。

5. 臨鍵鎖(next-key locks)

同時鎖住記錄和間隙。從實現的角度為record lock+gap lock,而且兩種鎖有可能只成功乙個,所以next-key是半開半閉區間,且是下界開,上界閉。一張表中的next-key鎖包括:(負無窮大,最小的第一條記錄],(記錄之間],(最大的一條記錄,正無窮大)。

6. 插入意向鎖(insert intention locks)

插入操作時使用的鎖。在**中,插入意圖鎖實際上是gap鎖上加了乙個lock_insert_intention的標記。也就是說insert語句會對插入的行加乙個x記錄鎖,但是在插入這個行的過程之前,會設定乙個insert intention的gap鎖,叫做insert intention鎖。

7. 自增鎖(auto-inc locks)

針對自增列自增長的乙個特殊的表級別鎖。可以使用如下語句檢視 :

show variables like 'innodb_autoinc_lock_mode';

檢視innodb鎖情況

#有加鎖的情況這裡可以檢視到show full processlist;#可以檢視innodb引擎相關鎖的狀態,是否有死鎖等

show engine innodb status;

#檢視當前鎖的資訊select * frominformation_schema.innodb_locks;

#檢視鎖等待資訊select * from information_schema.innodb_locks_waits;

一致性非鎖定讀與一致性鎖定讀

一致性非鎖定讀(consistent nonlocking read):指的是如果一條記錄被加了x鎖,其他事務還能讀取這條記錄。

一致性鎖定讀(consistent locking read):指的是乙個事務可以通過select語句給某條記錄加x鎖或者x鎖。

#會對查詢的行及相關聯的索引記錄加x鎖,其他事務請求的s鎖或x鎖都會被阻塞。

select...for update

#對讀取的行新增s鎖,其他事物可以對這些行新增s鎖,若新增x鎖,則會被阻塞。

select...lock in share mode

mysql會話鎖 Mysql鎖機制 寫鎖

1 準備資料 1.1 建表 1.1.1 建立 employee表 drop table if existsemployee create table if not existsemployee idint primary keyauto increment,namevarchar 40 dept i...

mysql 查詢鎖 MySQL 鎖查詢

一 從檢視檢視 檢視程序 show processlist 檢視是否鎖表 show open tables where in use 0 1 檢視當前的事務 select from information schema.innodb trx 2 檢視當前鎖定的事務 select from infor...

mysql鎖機制 mysql 鎖機制

一 概述 mysql有三種鎖的級別 頁級 表級 行級。myisam和memory儲存引擎採用的是表級鎖 table level locking bdb儲存引擎採用的是頁面鎖 page level locking 但也支援表級鎖 innodb儲存引擎既支援行級鎖 row level locking 也...