數(shù)據(jù)庫的鎖
按范圍劃分,mysql里面的鎖大致分為全局鎖,表級鎖和行級鎖
全局鎖
Flush tables with read lock;
使用命令FTWRL后,整個(gè)庫處于只讀狀態(tài).
全局鎖的典型使用場景是,做全庫邏輯備份.
當(dāng) mysqldump 使用參數(shù)–single-transaction的時(shí)候甚侣,導(dǎo)數(shù)據(jù)之前就會啟動一個(gè)事務(wù)间学,來確保拿到一致性視圖。而由于 MVCC 的支持低葫,這個(gè)過程中數(shù)據(jù)是可以正常更新的.如果直接使用mysqldump的話,會導(dǎo)致加上全局鎖,業(yè)務(wù)基本不可用.
開啟事務(wù)(可重復(fù)讀)即可得到一致性視圖.但是需要引擎支持
當(dāng)引擎不支持的情況下,FTWRL就很有必要了.
表級鎖
表鎖一般是在數(shù)據(jù)庫引擎不支持行鎖的時(shí)候才會被用到的嘿悬。
表鎖
lock tables … read/write
unlock tables
元數(shù)據(jù)鎖
meta data lock,MDL
MDL 不需要顯式使用窒盐,在訪問一個(gè)表的時(shí)候會被自動加上钢拧。MDL 的作用是防止DDL和DML并發(fā)引發(fā)沖突.
事務(wù)中的 MDL 鎖,在語句執(zhí)行開始時(shí)申請葡粒,但是語句結(jié)束后并不會馬上釋放膜钓,而會等到整個(gè)事務(wù)提交后再釋放。
如何安全地給小表加字段颂斜?
資源首先我們要解決長事務(wù),事務(wù)不提交掌唾,就會一直占著 MDL 鎖忿磅。在 MySQL 的information_schema 庫的 innodb_trx 表中,你可以查到當(dāng)前執(zhí)行中的事務(wù)撩扒。如果你要
做 DDL 變更的表剛好有長事務(wù)在執(zhí)行,要考慮先暫停 DDL搓谆,或者 kill 掉這個(gè)長事務(wù)。
行級鎖
mysql的行鎖是在引擎層由各個(gè)引擎自己實(shí)現(xiàn)的.行級鎖即InnoDB的行鎖.
鎖的釋放
在事務(wù)當(dāng)中,行鎖在需要時(shí)加上,因?yàn)閮呻A段提交的緣故,在事務(wù)結(jié)束時(shí)釋放.所以在事務(wù)當(dāng)中,最可能造成鎖沖突,最可能影響并發(fā)度的鎖盡量往后放.
死鎖和死鎖檢測
事務(wù)互相等待資源釋放并持有資源時(shí),會出現(xiàn)死鎖.
死鎖解決方案:
- 設(shè)置等待超時(shí),這個(gè)超時(shí)時(shí)間可以通過參數(shù)innodb_lock_wait_timeout 來設(shè)置黔寇。
- 發(fā)起死鎖檢測斩萌,發(fā)現(xiàn)死鎖后,主動回滾死鎖鏈條中的某一個(gè)事務(wù)憋飞,讓其他事務(wù)得以繼續(xù)執(zhí)行將參數(shù) innodb_deadlock_detect 設(shè)置為 on姆吭,表示開啟這個(gè)邏輯
熱點(diǎn)行更新解決方案:
控制訪問相同資源的并發(fā)事務(wù)量。
- 關(guān)閉死鎖檢測,但要保證業(yè)務(wù)一定不會出現(xiàn)死鎖(有風(fēng)險(xiǎn))
- 控制并發(fā)度,對于相同行的更新检眯,在進(jìn)入引擎之前排隊(duì).實(shí)現(xiàn)在數(shù)據(jù)庫服務(wù)端/中間件上.
- 邏輯行拆分,一行拆為多行,然后進(jìn)行上層邏輯隨機(jī)命中物理行.