鎖機制用於管理對共享資源的併發訪問,而數據庫自己做爲共享資源的集合,內部須要提供必定的鎖機制來保證事務的隔離性。本文探討的是MySQL(5.7)InnoDB引擎下的鎖機制。html
共享鎖也稱爲讀鎖,容許事務讀一行數據。共享鎖之間是兼容的,也就是說多個事務能夠針對同一行數據加共享鎖。mysql
共享鎖也稱爲寫鎖,容許事務刪除或更新一行數據。排他鎖之間以及排他鎖和共享鎖是不兼容的。sql
表鎖(table lock)對整個表加鎖,影響表的全部記錄數據庫
行鎖(row lock)併發
共享鎖app
排他鎖性能
由於表鎖覆蓋了行鎖的數據,因此表鎖和行鎖也會產生衝突,爲了方便檢測表級鎖和行級鎖之間的衝突,就引入了意向鎖。spa
表級鎖兼容矩陣以下:code
Table-level lock type compatibility is summarized in the following matrix.orm
間隙鎖(Gap Lock)是鎖定索引記錄之間的間隙,鎖定在第一個以前或最後一個索引記錄以後的間隙上。
能夠經過如下兩種方式顯式關閉Gap Lock
Record Lock + Gap Lock 的結合
在InnoDB的默認的可重複讀(REPEATABLE-READ)隔離級別下,存在如下的加鎖規則:
Online DDL 修改表結構
Online DDL and pt-online-schema-change for some alter operations applied on a table contains 1,078,880 rows
隔離級別 | 髒 讀 | 不可重複讀 | 幻 讀 |
---|---|---|---|
未提交讀(Read uncommitted) | 可能 | 可能 | 可能 |
已提交讀(Read committed) | 不可能 | 可能 | 可能 |
可重複讀(Repeatable read) | 不可能 | 不可能 | 可能 |
可串行化(Serializable ) | 不可能 | 不可能 | 不可能 |
丟失更新分爲兩個層面
髒讀指的是讀取到其餘事務未提交的數據,在讀已提交及以上的隔離級別下就避免該問題。
不可重複讀指的是同一事務下兩次讀取同一行的數據不一致。InnoDB使用的MVCC機制來實現的。
幻讀指的是同一個事務下兩次查詢,返回的記錄數不一致。InnoDB使用的MVCC機制和Next-Key Lock來實現的。
當發生鎖定時,能夠查下information_schema 庫的相關表來查看事務的鎖定狀況來快速定位問題。
查看當前鎖狀況
SELECT
w.requesting_trx_id,
t1.trx_state,
t1.trx_query,
t1.trx_started,
t1.trx_wait_started,
w.requested_lock_id,
l1.lock_mode,
l1.lock_type,
l1.lock_table,
l1.lock_index,
l1.lock_data,
w.blocking_trx_id,
t2.trx_state,
w.blocking_lock_id,
l2.lock_mode,
l2.lock_type,
l2.lock_table,
l2.lock_index,
l2.lock_data
FROM
INNODB_LOCK_WAITS AS w
LEFT JOIN INNODB_TRX t1 ON w.requesting_trx_id = t1.trx_id
LEFT JOIN INNODB_TRX t2 ON w.blocking_trx_id = t2.trx_id
LEFT JOIN INNODB_LOCKS l1 ON w.requested_lock_id = l1.lock_id
LEFT JOIN INNODB_LOCKS l2 ON w.blocking_lock_id = l2.lock_id
WHERE
t1.trx_state = 'LOCK WAIT'
LIMIT 1;
複製代碼