本文章記錄在讀《高性能mysql》時的筆記,持續(xù)更新萍膛。章節(jié)內(nèi)容會按照書中章節(jié)進行梳理验懊。
一擅羞、Mysql 架構(gòu)與歷史
1.1Mysql邏輯架構(gòu)
- 最上層負(fù)責(zé)鏈接處理、認(rèn)證授權(quán)义图、安全等
- 中間一層涵蓋了mysql的大多數(shù)核心功能减俏。包括查詢解析、分析碱工、優(yōu)化娃承、緩存奏夫、內(nèi)置函數(shù);所有的夸存儲引擎的功能都在這一層實現(xiàn)(存儲過程草慧、觸發(fā)器桶蛔、視圖等)
- 第三層包含了存儲引擎匙头,存儲引擎與上層使用API進行通訊漫谷,引擎之間不會有交互。
1.1.1連接管理與安全性
每個客戶端對應(yīng)著服務(wù)器的一個線程蹂析,客戶端的請求會單獨的在這個線程中執(zhí)行舔示。安全認(rèn)證基于用戶名密碼或SSL。
1.1.2優(yōu)化與執(zhí)行
mysql會即系查詢电抚,并創(chuàng)建內(nèi)部解析樹用于進行各種優(yōu)化操作惕稻。可使用explain
或hint
進行查看解析蝙叛、優(yōu)化過程俺祠。如果執(zhí)行時,發(fā)現(xiàn)查詢引擎中有對應(yīng)的查詢借帘,則直接返回結(jié)果蜘渣,不會再進行查詢解析、優(yōu)化肺然、執(zhí)行等步驟蔫缸。
1.2 并發(fā)控制
并發(fā)控制在任何一個領(lǐng)域都是一個重要的話題,數(shù)據(jù)庫尤其明顯际起。
1.2.1 讀寫鎖
當(dāng)一個數(shù)據(jù)多線程在讀拾碌,則不會發(fā)生問題。但是當(dāng)出現(xiàn)了有的線程在寫街望,有的線程在讀的情況校翔,則會發(fā)生問題(不一致、臟數(shù)據(jù))灾前。使用共享鎖(share lock)防症、排它鎖(exclusive lock)、讀寫鎖可以解決問題豫柬。讀鎖之間是不互斥的告希,寫鎖和其他的寫鎖和讀鎖互斥。
1.2.2 鎖粒度
大多數(shù)數(shù)據(jù)庫直接使用行級鎖(row-level lock)更細(xì)粒度的鎖能保證更高的性能烧给,但是會帶來更復(fù)雜的開銷燕偶。mysql提供靈活定制的鎖策略。
表鎖
開銷最小的鎖策略础嫡,但是某種程度上性能會最差(因為執(zhí)行某些操作會鎖死整張表)指么,當(dāng)執(zhí)行比如ALERT TABLE
時酝惧,會使用表鎖。并且表的寫鎖比讀鎖有更高的優(yōu)先級伯诬。服務(wù)器可能會使用表鎖晚唇。
行級鎖
行級鎖并發(fā)性能最好,但是鎖開銷也最大盗似。行級鎖僅僅在存儲引擎層實現(xiàn)哩陕,服務(wù)器層不關(guān)心行級鎖內(nèi)容。
1.3事務(wù)
事務(wù)內(nèi)的語句赫舒,要么全成功悍及,要么全失敗。
ACID接癌,原子性心赶、一致性、隔離性缺猛、持久性是一個事務(wù)處理系統(tǒng)必備的條件缨叫。
1.3.1 隔離級別
較低的隔離級別代表著更高的并發(fā)性,系統(tǒng)開銷也更低荔燎。
READ UNCOMMITED
(讀未提交)
即使沒有提交耻姥,對其他事務(wù)也是可見的。也成為臟讀(DIRTY READ)READ COMMIT
(讀提交)
一個事務(wù)從開始到提交前湖雹,任何操作對其他事務(wù)都是不可見的咏闪。
也叫作不可重復(fù)讀(NONREPEATABLE READ)REPEATABLE READ
(可重復(fù)讀)
同一個事務(wù)中多次讀取同樣的記錄的結(jié)果是一致的
mysql默認(rèn)采用該事物隔離級別SERIALIZABLE
(可串行化)
所有事務(wù)串行執(zhí)行。采用
1.3.2死鎖
兩個及以上事務(wù)在同一資源上相互占用摔吏。
Tx1:
START TRANSACTIOIN;
UPDATE T SET NAME = "A" WHERE ID = 1;
UPDATE T SET NAME = "B" WHERE ID = 2;
COMMIT;
Tx2:
START TRANSACTION;
UPDATE T SET NAME = "C" WHERE ID = 2;
UPDATE T SET NAME = "D" WHERE ID = 1;
COMMIT;
如果兩個事務(wù)都執(zhí)行了第一個語句鸽嫂,同時也鎖定了該數(shù)據(jù),接著嘗試去執(zhí)行第二個語句征讲,就會發(fā)生死鎖据某。除非有外部因素介入,不然死鎖會一直持續(xù)诗箍。
InnoDB解決死鎖的辦法是:將持有最少排它鎖的事務(wù)進行回滾癣籽。