1.鎖的分類
全局鎖:對整個數(shù)據(jù)庫實例進(jìn)行加鎖,F(xiàn)lush tables with read lock (FTWRL),(set global readonly=true)之后其他線程的以下語句會被阻塞:數(shù)據(jù)更新語句(數(shù)據(jù)的增刪改)、數(shù)據(jù)定義語句(包括建表、修改表結(jié)構(gòu)等)和更新類事務(wù)的提交語句。
全局鎖的典型使用場景是,做全庫邏輯備份。
但是讓整庫都只讀,聽上去就很危險:
如果你在主庫上備份,那么在備份期間都不能執(zhí)行更新,業(yè)務(wù)基本上就得停擺;
如果你在從庫上備份,那么備份期間從庫不能執(zhí)行主庫同步過來的binlog,會導(dǎo)致主從延遲。
一致性讀是好,但前提是引擎要支持這個隔離級別
?官方自帶的邏輯備份工具是mysqldump。當(dāng)mysqldump使用參數(shù)–single-transaction的時候,導(dǎo)數(shù)據(jù)之前就會啟動一個事務(wù),來確保拿到一致性視圖。而由于MVCC的支持,這個過程中數(shù)據(jù)是可以正常更新的。
2.表級鎖
表鎖:
lock table read/write unlock tables?
也可以在客戶端斷開連接的時候釋放鎖,事務(wù)提交時并不會釋放表鎖,但是unlock table會釋放鎖,事務(wù)也會自動提交。
特點:
1.當(dāng)一個線程獲得對一個表的寫鎖后,只有持有鎖的線程可以對表進(jìn)行更新操作。其他線程的讀、寫操作都會等待,直到鎖被釋放為止。
2.在用LOCK TABLES 給表顯式加表鎖時,必須同時取得所有涉及到表的鎖,并且 MySQL 不 支持鎖升級(不能訪問其他表,持有讀鎖,只能讀取)
Myisam特點:
1.MyISAM 在執(zhí)行查詢語句(SELECT)前,會自動給涉及的所有表加讀鎖,在執(zhí)行更新操作 (UPDATE、DELETE、INSERT 等)前,會自動給涉及的表加寫鎖.
2.MyISAM表也支持查詢和插入操作的并發(fā)進(jìn)行.
concurrent_insert=0 不允許并發(fā)插入
concurrent_insert=1 如果MyISAM表中沒有空洞(即表的中間沒有被刪除的 行),MyISAM允許在一個進(jìn)程讀表的同時,另一個進(jìn)程從表尾插入記錄。這也是MySQL 的默認(rèn)設(shè)置。
concurrent_insert=2 允許并發(fā)插入
3.鎖調(diào)度:即使讀請求先到鎖等待隊列,寫請求后到,寫鎖也會插 到讀鎖請求之前。不適用于大量的更新操作和查詢應(yīng)用的。
MDL(元數(shù)據(jù)鎖)
加鎖:當(dāng)對一個表做增刪改查操作的時候,加MDL讀鎖;當(dāng)要對表做結(jié)構(gòu)變更操作的時候,加MDL寫鎖。
釋放鎖:事務(wù)結(jié)束后自動釋放。
如何進(jìn)行online DDL?
3.行鎖(innodb)
S : lock in share mode
X: for update
UPDATE、DELETE 和 INSERT 語句,InnoDB 會自動給涉及數(shù)據(jù)集加排他鎖(X);對于普通 SELECT 語句,InnoDB 不會加任何鎖
事務(wù)結(jié)束后自動釋放。
實現(xiàn)方式:?InnoDB 行鎖是通過給索引上的索引項加鎖來實現(xiàn)的,只有通過 索引條件檢索數(shù)據(jù),InnoDB 才使用行級鎖,否則,InnoDB 將使用表鎖。只有通過 索引條件檢索數(shù)據(jù),InnoDB 才使用行級鎖,否則,InnoDB 將使用表鎖
兩階段協(xié)議:在InnoDB事務(wù)中,行鎖是在需要的時候才加上的,但并不是不需要了就立刻釋放,而是要等到事務(wù)結(jié)束時才釋放。這個就是兩階段鎖協(xié)議。
4.間隙鎖(innodb)
解決幻讀?
幻讀指的是一個事務(wù)在前后兩次查詢同一個范圍的時候,后一次查詢看到了前一次查詢沒有看到的行。
1.在可重復(fù)讀隔離級別下,普通的查詢是快照讀,是不會看到別的事務(wù)插入的數(shù)據(jù)的。因此,幻讀在“當(dāng)前讀”下才會出現(xiàn)。
2.上面session B的修改結(jié)果,被session A之后的select語句用“當(dāng)前讀”看到,不能稱為幻讀?;米x僅專指“新插入的行”。
什么是間隙鎖:
產(chǎn)生幻讀的原因是,行鎖只能鎖住行,但是新插入記錄這個動作,要更新的是記錄之間的“間隙”。因此,為了解決幻讀問題,InnoDB只好引入新的鎖,也就是間隙鎖(Gap Lock)。顧名思義,間隙鎖,鎖的就是兩個值之間的空隙
加鎖規(guī)則:
https://blog.csdn.net/xmtblog/article/details/92470543
死鎖:
當(dāng)并發(fā)系統(tǒng)中不同線程出現(xiàn)循環(huán)資源依賴,涉及的線程都在等待別的線程釋放資源時,就會導(dǎo)致這幾個線程都進(jìn)入無限等待的狀態(tài),稱為死鎖。
1.一種策略是,直接進(jìn)入等待,直到超時。這個超時時間可以通過參數(shù)innodb_lock_wait_timeout來設(shè)置。
2.另一種策略是,發(fā)起死鎖檢測,發(fā)現(xiàn)死鎖后,主動回滾死鎖鏈條中的某一個事務(wù),讓其他事務(wù)得以繼續(xù)執(zhí)行。將參數(shù)innodb_deadlock_detect設(shè)置為on,表示開啟這個邏輯。