1. 程式人生 > >MySQL鎖小結

MySQL鎖小結

是個 互斥量 一個 cor 樹結構 系統 ron 全部 mysql鎖

鎖的作用:避免並發請求時對同一個數據對象同時修改,導致數據不一致。 怎麽加鎖: 1.事務T1在對某個數據對象R1操作之前,先向系統發出請求,對其加鎖L1. 2.之後,事務T1對該數據對象R1有了相應的控制,在T1釋放L1之前,其它事務不能修改R1. 鎖類型: 1.排它鎖(X)。 2.共享鎖(S)。 通常的鎖範圍: 1.全局鎖(global lock)。 2.表鎖(table lock)。 3.行鎖(row lock)。 InnoDB行鎖範圍(粒度): 1.record lock. 2.gap lock. 3.next-key lock = record lock + gap lock. RC級別下,只有record lock,沒有next key lock。 RR級別下,除非primary key或unique key是record lock,其余都是next key lock。 加鎖對數據庫的影響: 1.鎖等待,鎖L1鎖定某個對象R1,鎖L2等待該鎖釋放,如果不釋放,會一直等待,或者達到系統預設的超時閾值後告錯(回滾整個事務或只回滾當前SQL)。 2.死鎖,鎖資源請求產生了回路,例如:L1等待L2釋放,L2等待L3釋放,L3等待L1釋放,死循環。 MyISAM鎖
默認是表鎖,讀寫互斥,僅只讀共享。 讀鎖,LOCK TABLE user READ,自身只讀,不能寫;其他線程仍可讀,不能寫。多個線程都可提交read lock。 寫鎖,LOCK TABLE user WRITE,自身可讀寫;其他線程完全不可讀寫。 寫鎖優先級高於讀鎖。 SELECT自動加讀鎖(共享鎖)。 其他DML、DDL自動加寫鎖(排他鎖)。 釋放鎖,UNLOCK TABLES。 特例:單線程往MyISAM表最後空閑位置串行寫入新數據不被鎖(而寫入中間的空洞位置還是會加鎖的)。 InnoDB鎖 默認是行鎖(row lock)。 InnoDB是通過在索引記錄上加鎖,實現行鎖。 因此,沒有索引時就無法實現行鎖,而升級成全表記錄鎖,等同於表鎖。 鎖類型: 1.共享鎖。 2.排他鎖。 3.意向鎖,InnoDB特有,加載在表級別上的鎖。 其他鎖
全局鎖(1.global read lock,2.query cache lock.) MDL表鎖。 自增互斥量(mutex),用來管理Auto-increment InnoDB自旋鎖,spinlock。 全局鎖 global read lock 加鎖:FTWRL,FLUSH TABLES WITH READ LOCK。 關閉實例下的所有包,並加上全局讀鎖,防止被修改,直到提交UNLOCK TABLES。 一般用於備份,mysqldump、xtrabackup都會發起。 xtrabackup時可分開備份InnoDB和MyISAM,或者不執行 --master-data。 query cache lock 全局query cache鎖(mutex),最好關閉query cache。 對QC中的數據有更新時,都會引發query cache lock。 狀態:watiting for query cache lock。

關閉query cache:

query_cache_type=0 (實例啟動前設置)

query_cache_size=0。

MDL鎖 MDL,meta data lock 事務內的表級鎖 5.5開始引入 5.6.6前,事務開啟後,會鎖定表的meta data lock,其他會話對表有DDL操作時,均需等待MDL釋放後方可繼續。 5.6.6後,不再阻塞其他會話執行DDL,但原來的會話再次訪問數據表時,會有error提示:Table definition has changed,please retry transaction 超時閾值定義:lock_wait_timeout。 自增鎖 其實是個輕量級的互斥量(MUTEX) 相關選項 innodb_autoinc_lock_mode 1,默認值,可預判行數時使用新方式,不可預判時仍舊使用表鎖,會造成autoinc列自增空洞,不過影響很小。 0,即沿用舊的表級鎖模式,每次請求都會等待表鎖,不過也非常快。不會影響整個事務,只影響當前的INSERT語句。 2,直接全部使用新方式,不安全,不適合replication環境。 InnoDB spin lock,自旋鎖 保護共享資源而提出的一種鎖機制,和互斥鎖類型,任何時刻下都只能有一個持有者,控制事務並發時的CPU時間片分配。 用於控制InnoDB內部線程調度而生的輪詢檢測。 InnoDB_spin_wait_delay,控制輪詢間隔,默認6秒。 事務並發非常高,CPU忙不過來的時候,事務處於sleep狀態,spin round可能也會很高。 show engine innodb status Mutex spin waits 5970888,rounds 19812448,OS wait 375285 InnoDB鎖之共享鎖 共享鎖,不允許其他事務修改被鎖定的行,只能讀。 SELECT ...LOCK IN SHARE MODE。 不在事務中的SELECT 是一致性非鎖定讀,不加鎖。 InnoDB鎖之排他鎖 對一行記錄進行DML時,需至少加上排它鎖。 鎖範圍視情況而定,可能是record lock、next-key lock,或者可能只有gap lock。 執行DML,或者SELECT ...FOR UPDATE。 InnoDB鎖之意向鎖 IS,事務T想要獲得表中某幾行的共享鎖。 IX,事務T想要獲得表中某幾行的排它鎖。 意向鎖是加載在數據表B+樹結構的根節點,也就是對整個表加意向鎖。 意向鎖的作用:避免在執行DML時,對表執行DDL操作,導致數據不一致。 InnoDB鎖
X IX S IS
X 沖突 沖突 沖突 沖突
IX 沖突 兼容 沖突 兼容
S 沖突 沖突 兼容 兼容
IS 沖突 兼容 兼容 兼容

MySQL鎖小結