1.1 MySQL邏輯架構(gòu)
第一層服務(wù)并非MySQL獨(dú)有,大多數(shù)基于網(wǎng)絡(luò)的客戶端惹盼、服務(wù)端的工具或者服務(wù)都有類似的框架妄辩。
第二層為MySQL的核心服務(wù)功能惑灵,查詢解析、分析眼耀、優(yōu)化英支、緩存以及內(nèi)置函數(shù),并且包括存儲(chǔ)過程哮伟、觸發(fā)器干花、視圖等。
第三層為存儲(chǔ)引擎楞黄,主要負(fù)責(zé)MySQL中數(shù)據(jù)的存儲(chǔ)和提取池凄。
1.1.1 連接管理與安全性
每個(gè)客戶端連接都會(huì)在服務(wù)器進(jìn)程中擁有一個(gè)線程,這個(gè)連接的查詢只會(huì)在這個(gè)單獨(dú)的線程中執(zhí)行鬼廓,且輪流使用CPU肿仑。服務(wù)器負(fù)責(zé)緩存線程,無需為每個(gè)連接創(chuàng)建或者銷毀線程碎税。
當(dāng)客戶端連接到MySQL服務(wù)器時(shí)尤慰,服務(wù)器會(huì)對(duì)其進(jìn)行驗(yàn)證。如果使用了安全套字節(jié)(SSL)連接方式雷蹂,還可以使用X.509證書認(rèn)證伟端。驗(yàn)證成功后,服務(wù)器會(huì)繼續(xù)驗(yàn)證該客戶端是否具有某個(gè)特定查詢的權(quán)限匪煌。
1.1.2 優(yōu)化與執(zhí)行
MySQL會(huì)解析查詢责蝠,并創(chuàng)建內(nèi)部數(shù)據(jù)結(jié)構(gòu)党巾,并對(duì)其進(jìn)行優(yōu)化,包括重寫查詢霜医、決定表的讀取順序昧港,以及選擇合適的索引等。用戶可以通過關(guān)鍵詞 hint 提示優(yōu)化器支子,影響它的決策過程创肥。也可以請(qǐng)求優(yōu)化器解釋(explain)優(yōu)化過程的各個(gè)因素,提供一個(gè)參考基準(zhǔn)值朋。
優(yōu)化器并不關(guān)心使用的是什么存儲(chǔ)引擎叹侄,但存儲(chǔ)引擎對(duì)于優(yōu)化查詢是有影響的。
1.2 并發(fā)控制
服務(wù)器層與存儲(chǔ)引擎層
1.2.1 讀寫鎖
解決并發(fā)問題的方法就是并發(fā)控制昨登。再處理并發(fā)讀或者寫時(shí)趾代,可以通過實(shí)現(xiàn)一個(gè)由兩種類型的鎖組成的系統(tǒng)來解決問題。兩種類型的鎖通常被稱為供共享鎖(shared lock)和 排他鎖(exclusive lock)丰辣,也叫讀鎖(read lock)和 寫鎖(write lock)撒强。
讀鎖是共享的,同一時(shí)刻可以同時(shí)讀取同一個(gè)資源笙什,互不干擾飘哨。
寫鎖是排他的,一個(gè)寫鎖會(huì)堵塞其他的寫鎖和讀鎖琐凭。只有這樣芽隆,才能確保在給定時(shí)間里,只有一個(gè)用戶能執(zhí)行寫入统屈,防止其他用戶讀取正在寫入的統(tǒng)一資源胚吁。
1.2.2 鎖粒度
一種提高共享資源并發(fā)性的方式就是讓鎖定對(duì)象更有選擇性,盡量只鎖定需要修改的部分?jǐn)?shù)據(jù)愁憔,而不是所有的資源腕扶。
表鎖(table lock)
表鎖是MySQL中最基本的鎖策略,并且是開銷最小的策略吨掌。
行級(jí)鎖(row lock)
行級(jí)鎖可以最大程度的支持并發(fā)處理半抱,并且?guī)碜畲蟮拈_銷。行級(jí)鎖旨在存儲(chǔ)引擎層實(shí)現(xiàn)思犁。
1.3 事物
事物就是一組原子性的SQL查詢代虾。要不全部執(zhí)行成功进肯,要么全部執(zhí)行失敗激蹲。
一個(gè)運(yùn)行良好的事務(wù)處理系統(tǒng),必須具備ACID特征江掩。
原子性(atomicity)
一個(gè)事務(wù)必須被視為一個(gè)不可分割的最小工作單元学辱,不能只執(zhí)行其中的一部分操作乘瓤。
一致性(consistency)
數(shù)據(jù)庫總是從一個(gè)一致性的狀態(tài)轉(zhuǎn)換到另一個(gè)一致性的狀態(tài)。
隔離性(isolation)
持久性(durability)
1.3.1 隔離級(jí)別
四個(gè)隔離級(jí)別
1.READ UNCOMMITTED(未提交讀)
事務(wù)中的修改策泣,即使沒提交衙傀,其他事務(wù)也是可見的。事務(wù)可以讀取未提交的數(shù)據(jù)萨咕,這種被稱為臟讀(Dirty Read)统抬。
2.READ COMMITTED(提交讀)
只能看到已提交的事務(wù)所做的修改,其他事務(wù)均不可見危队。
3.REPEATABLE READ(可重復(fù)讀)
保證了同一個(gè)事物中多次讀取同樣的記錄的結(jié)果是一致的聪建。但是無法解決幻讀(Phantom Read)
幻讀,指當(dāng)某個(gè)事務(wù)在讀取某個(gè)范圍的內(nèi)容時(shí)茫陆,另外一個(gè)事務(wù)又在該范圍插入了新的紀(jì)錄金麸。
4.SERIALIZABLE(可串行化)
使事務(wù)強(qiáng)制串行,避免幻讀問題簿盅。會(huì)在讀取的每一行數(shù)據(jù)上都加鎖挥下。
1.3.2 死鎖
多個(gè)事務(wù)同時(shí)在同一資源上互相占用,并請(qǐng)求鎖定對(duì)方占用的資源桨醋,從而導(dǎo)致惡性循環(huán)的現(xiàn)象棚瘟。大多數(shù)情況下只需要重新執(zhí)行因死鎖回滾的事務(wù)即可。
1.3.3 事務(wù)日志
事務(wù)日志可以幫助提高事務(wù)的效率喜最。使用事務(wù)日志解取,存儲(chǔ)引擎在修改標(biāo)的數(shù)據(jù)時(shí)只需要修改其內(nèi)存拷貝,再把該修改行行為記錄到持久的硬盤上的事務(wù)日志中返顺,而不是每次都將修改的數(shù)據(jù)本身持久到磁盤禀苦。事務(wù)日志采用的是追加的方式,因此寫日志的操作是磁盤上一小塊區(qū)域內(nèi)的順序I/O遂鹊,因此會(huì)快很多振乏。
如果數(shù)據(jù)的修改已經(jīng)記錄到事務(wù)日志并持久化,但數(shù)據(jù)本身還沒有寫會(huì)磁盤秉扑,此時(shí)系統(tǒng)崩潰慧邮,存儲(chǔ)引擎在重啟時(shí)能夠自動(dòng)回復(fù)這部分修改的數(shù)據(jù)。
1.3.4 MySQL中事務(wù)
提供了兩種事務(wù)型的存儲(chǔ)引擎:InnoDB 和 NDB Cluster
自動(dòng)提交(AUTOCOMMIT)
MySQL默認(rèn)采用自動(dòng)提交模式舟陆,每個(gè)查詢都被當(dāng)作一個(gè)事務(wù)误澳。
可以通過命令查看并且進(jìn)行設(shè)置,1或者ON表示啟動(dòng)秦躯,0或者OFF表示禁用忆谓。
mysql> SHOW VARIABLES LIKE 'AUTOCOMMIT';
mysql> SET AUTOCOMMIT = 1;
通過命令也可以設(shè)置隔離級(jí)別:
mysql> SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
在事務(wù)中混合使用存儲(chǔ)引擎
MySQL服務(wù)器不管理事務(wù),事務(wù)是由下層的存儲(chǔ)引擎實(shí)現(xiàn)的踱承。當(dāng)在同一個(gè)事務(wù)中倡缠,使用多種存儲(chǔ)引擎是不可靠的哨免。
當(dāng)事務(wù)回滾時(shí),非事務(wù)型的變更無法撤銷昙沦,會(huì)導(dǎo)致數(shù)據(jù)庫處于不一致的狀態(tài)琢唾,而且難修復(fù)。
隱式和現(xiàn)式鎖定
InnoDB采用的是兩階段鎖定協(xié)議( two-phase locking protocol)盾饮。在事務(wù)執(zhí)行過程中采桃,隨時(shí)都可以執(zhí)行鎖定,鎖只有在執(zhí)行COMMIT或者ROLLBACK的時(shí)候才會(huì)釋放丘损,并且所有的鎖是在同一時(shí)刻被釋放芍碧。
1.4 多版本并發(fā)控制
MySQL的大多數(shù)事務(wù)型存儲(chǔ)引擎實(shí)現(xiàn)的都不是簡(jiǎn)單的行級(jí)鎖『爬基于提升并發(fā)性能的考慮泌豆,它們一般都同時(shí)實(shí)現(xiàn)了多版本并發(fā)控制(MVCC)。
可以認(rèn)為MVCC是行級(jí)鎖的一個(gè)變種吏饿,但是他在很多情況下避免了加鎖操作踪危。因此開銷更低。
InnoDB的MVCC是如何工作的
通過在每行記錄后面保存兩個(gè)隱藏的列來實(shí)現(xiàn)猪落,分別為創(chuàng)建時(shí)間和過期時(shí)間贞远,實(shí)際是系統(tǒng)版本號(hào)。
Select
1.查詢?cè)缬诋?dāng)前事務(wù)版本號(hào)的數(shù)據(jù)行笨忌,這個(gè)可以確保事務(wù)讀取的行蓝仲,要么是在事務(wù)開始前已經(jīng)存在,要么是開始之前未被刪除官疲。
2.行的刪除版本要么未定義袱结,要么大于當(dāng)前事務(wù)版本號(hào)。
Insert
保存當(dāng)前系統(tǒng)版本號(hào)為行版本號(hào)
Delete
保存當(dāng)前系統(tǒng)版本號(hào)為行刪除標(biāo)識(shí)
Update
保存當(dāng)前系統(tǒng)版本號(hào)為行版本號(hào)途凫,同時(shí)修改當(dāng)前系統(tǒng)版本號(hào)為行刪除標(biāo)識(shí)