0、 查看方式
innodb鎖:
select * from information_schema.innodb_trx\Ginnodb引擎狀態(tài)查鎖:
set global innodb_status_output_locks=1;
show engine innodb status\G行鎖:
select * from performance_schema.data_locks\G行鎖等待:
select * from performance_schema.data_lock_waits\Gmdl鎖:
select * from performance_schema.metadata_locks\G鎖等待:
select * from sys.schema_table_lock_waits;
show processlist;
show engine innodb status\G
sys var:innodb_status_output&innodb_status_output_locks
sys.innodb_lock_waits
sys.schema_table_lock_waits
pfs.data_locks
pfs.data_lock_waits
pfs.metadata_locks
1、 共享鎖
加鎖:
select ... [for share]|[lock in share mode]查看:
select * from information_schema.innodb_trx\G
2、 排他鎖
select .. for update
3、 意向鎖
加在鎖上面。IS 意向共享鎖, IX意向排他鎖。
意向鎖是加載在數(shù)據表B+樹根節(jié)點,也就是說對整個表加意向鎖。
意向鎖的作用:避免在執(zhí)行DML時,對表執(zhí)行DDL操作,導致數(shù)據不一致
4、行鎖案列
- 排他鎖與任何鎖沖突
- 排他鎖不影響一致性讀
- 無索引的列,鎖全表
- 有索引的列,空記錄共享 gap lock
- 意向插入鎖被gap lock阻塞
- 有索引,相同條件互斥
- 注意每個列鎖的位置
- 范圍掃描,加 lock_ordinary
5、InnoDB鎖實現(xiàn)
5.1 InnoDB行鎖實現(xiàn)機制
基于索引實現(xiàn)
逐行檢查,逐行加鎖
沒有索引的列上需要加鎖時,會先對所有記錄加鎖,再根據實際情況決定是否釋放鎖
輔助索引上加鎖時,同時要回溯到主鍵索引上再加一次鎖
5.2 InnoDB行鎖之共享鎖
共享鎖,不允許其它事務修改被鎖定的行,只能讀
select .. from... for [share]|[lock in share mode]
自動提交模式下的普通select是一致性非鎖定讀,不加鎖
5.3 InnoDB行鎖之排它鎖
對一行記錄進行DML時,需至少加上排它鎖
鎖范圍視情況而定,可能是record lock、next-key lock,或者可能只有gap lock
執(zhí)行DML,或 select ... for update
5.4 InnoDB行鎖之意向鎖
IS(intention shared),事務T想要獲得表中某幾行的共享鎖
IX(intention exclusive),事務T想要獲得表中某幾行的排它鎖
意向鎖是加載在數(shù)據表B+樹結構的根節(jié)點,也就是對整個表加意向鎖
意向鎖的作用:避免在執(zhí)行DML時,對表執(zhí)行DDL操作,導致數(shù)據不一致。
5.5 lock_ordinary
著名的next-key lock,鎖住記錄本身,及其GAP
在RR級別下,利用next-key lock 來避免產生幻讀
當innodb_locks_unsafe_for_binlog=1時,會降級為lock_rec_not_gap,相當于降級到RC
8.0之后廢棄了innodb_locks_unsafe_for_binlog參數(shù)。
5.6 lock_rec_not_gap
僅記錄鎖,僅鎖住記錄本身,不鎖其前面的GAP
RC下的行鎖大多數(shù)都是這個鎖類型
RR下的主鍵、唯五索引等值條件下加鎖通常也是這個鎖類型
RR下非唯一索引加鎖時(lock_ordinary),也會同時回溯到主鍵上加lock_rec_not_gap鎖。當唯一性約束檢測時,即使在RC下,總是要先加lock_s | lock_ordinary鎖。
5.7 lock_gap
避免發(fā)生幻讀。
間隙鎖,只鎖住索引記錄之間、或第一條索引記錄(infimum)之前、又或最后一條索引記錄(supremum)之后的范圍,并不鎖住記錄本身
5.8 lock_insert_intention
插入意向鎖,是一種特殊的gap lock,當插入索引記錄的時候用來判斷是否有其他事務的范圍沖突,如果有就需要等待。
同一個gap中,只要不是同一個位置就可以有多個插入意向鎖并存
例如[5]~[10]區(qū)間中,同時插入[6]、[8]就不會相互沖突阻塞,而同時插入兩個[9]就會引發(fā)沖突阻塞等待
但是lock_insert_intention 和 lock_gap并不兼容。