高性能MySQL(1)——MYSQL架构
MySQL最重要、最與眾不同的特性是它的存儲(chǔ)引擎架構(gòu),這種架構(gòu)將查詢處理與數(shù)據(jù)的存儲(chǔ)/提取相分離,使得可以在使用時(shí)根據(jù)不同的需求來選擇數(shù)據(jù)存儲(chǔ)的方式。
一、Mysql邏輯架構(gòu)
如果能在頭腦中構(gòu)建出一幅MySQL各組件之間如何協(xié)同工作的架構(gòu)圖,就會(huì)有助于深入理解MySQL服務(wù)器。
mysql 數(shù)據(jù)庫的邏輯架構(gòu)如下圖
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-Jx9utej6-1603348859176)(/Users/marron27/Documents/lizhengi/MySQL/高性能MySQL/T.Mysql邏輯圖.png)]
從上圖可以看出My SQL邏輯結(jié)構(gòu)大致可以分為三層:
第一層結(jié)構(gòu)主要處理客戶端與mysql服務(wù)端的連接、授權(quán)認(rèn)證、安全等;
第二層是Mysql服務(wù)端的核心,功能包括查詢解析、分析、優(yōu)化、緩存等,所有跨存儲(chǔ)引擎的功能都在這一層實(shí)現(xiàn):存儲(chǔ)過程、觸發(fā)器、視圖等都在這一層實(shí)現(xiàn);
第三層的存儲(chǔ)引擎主要負(fù)責(zé)數(shù)據(jù)存儲(chǔ)和提取,服務(wù)器通過API與存儲(chǔ)引擎進(jìn)行通信,存儲(chǔ)引擎API包含幾十個(gè)底層函數(shù),用于執(zhí)行諸如“開始一個(gè)事務(wù)”或者“根據(jù) 主鍵提取一行記錄”等操作。但存儲(chǔ)引擎不會(huì)去解析sql,不同存儲(chǔ)引擎之間不會(huì)通訊,只會(huì)簡(jiǎn)單地響應(yīng)上層服務(wù)器的請(qǐng)求
1.1、連接管理
每個(gè)客戶端連接成功,都會(huì)在服務(wù)器進(jìn)程中擁有一個(gè)線程,服務(wù)器會(huì)緩存線程,該線程只能輪流在某個(gè)CPU中運(yùn)行,所以不需要?jiǎng)?chuàng)建和銷毀線程。
1.2、安全性
當(dāng)客戶端(應(yīng)用)連接到MySQL服務(wù)器時(shí),服務(wù)器需要對(duì)其進(jìn)行認(rèn)證。認(rèn)證基于用戶名、原始主機(jī)信息和密碼等信息。
一旦客戶端連接成功,服務(wù)器會(huì)繼續(xù)驗(yàn)證該客戶端是否具有執(zhí)行某個(gè)特定查詢的權(quán)限
1.3、解析優(yōu)化查詢
MySQL會(huì)解析査詢,并創(chuàng)建內(nèi)部數(shù)據(jù)結(jié)構(gòu)(解析樹),然后對(duì)其進(jìn)行各種優(yōu)化,包括重 寫查詢、決定表的讀取順序,以及選擇合適的索引等。
對(duì)于SELECT查詢語句,解析查詢之前會(huì)先查詢緩存,如果緩存能找到是不會(huì)去解析的,如果緩存查找不到,就會(huì)重現(xiàn)解析查詢,創(chuàng)建解析樹,然后對(duì)其進(jìn)行查詢優(yōu)化、決定表的讀取順序、選擇合適的索引等
二、并發(fā)控制
無論何時(shí),只要有多個(gè)査詢需要在同一時(shí)刻修改數(shù)據(jù),都會(huì)產(chǎn)生并發(fā)控制的問題。
并發(fā)即指在同一時(shí)刻,多個(gè)操作并行執(zhí)行。MySQL對(duì)并發(fā)的處理主要應(yīng)用了兩種機(jī)制——是"鎖"和"多版本控制"。
2.1、鎖機(jī)制
在處理并發(fā)讀或者寫時(shí),可以 通過實(shí)現(xiàn)一個(gè)由兩種類型的鎖組成的鎖系統(tǒng)來解決問題:
- 共享鎖:也稱為讀鎖,讀鎖允許多個(gè)連接可以同一時(shí)刻并發(fā)的讀取同一資源,互不干擾;
- 排他鎖:也稱為寫鎖,一個(gè)寫鎖會(huì)阻塞其他的寫鎖或讀鎖,保證同一時(shí)刻只有一個(gè)連接可以寫入數(shù)據(jù),同時(shí)防止其他用戶對(duì)這個(gè)數(shù)據(jù)的讀寫。
2.2、鎖粒度
所謂的鎖策略,就是在鎖的開銷和數(shù)據(jù)的安全性之間尋求平衡,這種平衡當(dāng)然也會(huì)影響到性能。
MySQL提供兩個(gè)級(jí)別的并發(fā)控制:服務(wù)器級(jí)(the server level)和存儲(chǔ)引擎級(jí)(the storage engine level)。加鎖是實(shí)現(xiàn)并發(fā)控制的基本方法,MySQL中鎖的粒度:
- 表級(jí)鎖(服務(wù)器層):MySQL獨(dú)立于存儲(chǔ)引擎提供表鎖,例如,對(duì)于ALTER TABLE語句,服務(wù)器提供表鎖(table-level lock)。表鎖是最基本也是開銷最小的策略;
- 行級(jí)鎖(引擎層):InnoDB和Falcon存儲(chǔ)引擎提供行級(jí)鎖,此外,BDB支持頁級(jí)鎖。行級(jí)鎖可以最大程度地支持并發(fā)處理(同時(shí)也帶來了最大的鎖開銷)。
另外,值得一提的是,MySQL的一些存儲(chǔ)引擎(如InnoDB、BDB)除了使用封鎖機(jī)制外,還同時(shí)結(jié)合MVCC機(jī)制,即多版本并發(fā)控制(Multi-Version Concurrent Control),來實(shí)現(xiàn)事務(wù)的并發(fā)控制,從而使得只讀事務(wù)不用等待鎖,提高了事務(wù)的并發(fā)性。
2.3、多版本并發(fā)控制
MVCC的實(shí)現(xiàn):通過保存數(shù)據(jù)資源在不同時(shí)間點(diǎn)的快照實(shí)現(xiàn)的。根據(jù)事務(wù)開始的時(shí)間不同,每個(gè)事務(wù)看到的數(shù)據(jù)快照版本是不一樣的。
InnoDB中的MVCC實(shí)現(xiàn):通過在每行記錄后面保存兩個(gè)隱藏的列來實(shí)現(xiàn),一個(gè)保存了行的創(chuàng)建時(shí)間,一個(gè)保存了行的過期時(shí)間。
-
SELECT
當(dāng)讀取記錄時(shí),存儲(chǔ)引擎會(huì)選取滿足下面兩個(gè)條件的行作為讀取結(jié)果。
讀取記錄行的開始版本號(hào)必須早于當(dāng)前事務(wù)的版本號(hào)。也就是說,在當(dāng)前事務(wù)開始之前,這條記錄已經(jīng)存在。在事務(wù)開始之后才插入的行,事務(wù)不會(huì)看到。
讀取記錄行的過期版本號(hào)必須晚于當(dāng)前事務(wù)的版本號(hào)。也就是說,當(dāng)前事務(wù)開始的時(shí)候,這條記錄還沒有過期。在事務(wù)開始之前就已經(jīng)過期的數(shù)據(jù)行,該事務(wù)也不會(huì)看到。
-
INSERT
存儲(chǔ)引擎為新插入的每一行保存當(dāng)前的系統(tǒng)版本號(hào)作為這一行的開始版本號(hào)。
-
UPDATE
存儲(chǔ)引擎會(huì)新插入一行記錄,當(dāng)前的系統(tǒng)版本號(hào)就是新記錄行的開始版本號(hào)。同時(shí)會(huì)將原來行的過期版本號(hào)設(shè)為當(dāng)前的系統(tǒng)版本號(hào)。
-
DELETE
存儲(chǔ)引擎將刪除的記錄行的過期版本號(hào)設(shè)置為當(dāng)前的系統(tǒng)版本號(hào)。
MVCC只在 REPEATABLE READ 和 READ COMMITTED 兩個(gè)隔離級(jí)別下工作。
三、事務(wù)
3.1、事務(wù)的ACID特性
數(shù)據(jù)庫的事務(wù)處理的原則是保證ACID的正確性。
事務(wù)是由一組SQL語句組成的邏輯處理單元,事務(wù)具有以下4個(gè)屬性:
- 原子性(Atomicity):事務(wù)是一個(gè)原子操作單元,其對(duì)數(shù)據(jù)的修改,要么全都執(zhí)行,要么全都不執(zhí)行,不可能只執(zhí)行其中的一部分。(不可分割)
- 一致性(Consistent):在事務(wù)開始和完成時(shí),數(shù)據(jù)都必須保持一致狀態(tài)。這意味著所有相關(guān)的數(shù)據(jù)規(guī)則都必須應(yīng)用于事務(wù)的修改,以保持?jǐn)?shù)據(jù)的完整性;事務(wù)結(jié)束時(shí),所有的內(nèi)部數(shù)據(jù)結(jié)構(gòu)(如B樹索引或雙向鏈表)也都必須是正確的。(狀態(tài)更改一致性)
- 隔離性(Isolation):數(shù)據(jù)庫系統(tǒng)提供一定的隔離機(jī)制,保證事務(wù)在不受外部并發(fā)操作影響的“獨(dú)立”環(huán)境執(zhí)行。這意味著事務(wù)處理過程中的中間狀態(tài)對(duì)外部是不可見的。(執(zhí)行過程隔離不可見)
- 持久性(Durable):事務(wù)完成之后,它對(duì)于數(shù)據(jù)的修改是永久性的,即使出現(xiàn)系統(tǒng)故障也能夠保持。(持久生效)
3.2、事務(wù)處理帶來的問題
由于事務(wù)的并發(fā)執(zhí)行,帶來以下一些著名的問題:
3.3、Mysql隔離級(jí)別
READ UNCOMMITTED :事務(wù)可以看到其他事務(wù)沒有被提交的數(shù)據(jù)(臟數(shù)據(jù))。
READ COMMITTED :事務(wù)可以看到其他事務(wù)已經(jīng)提交的數(shù)據(jù)。
REPEATABLE READ :保證事務(wù)中多次查詢的結(jié)果相同(Innodb默認(rèn)級(jí)別),會(huì)出現(xiàn)幻讀。
SERIALIZABLE :所有事務(wù)順序執(zhí)行,對(duì)所有read操作加鎖。保證一致性。
四、總結(jié)
MySQL擁有分層的架構(gòu)。上層是服務(wù)器層的服務(wù)和査詢執(zhí)行引擎,下層則是存儲(chǔ)引擎。 雖然有很多不同作用的插件API,但存儲(chǔ)引擎API還是最重要的。如果能理解MySQL 在存儲(chǔ)引擎和服務(wù)層之間處理查詢時(shí)如何通過API來回交互,就能抓住MySQL的核心 基礎(chǔ)架構(gòu)的精髓。
參考:
《高性能 MySQL 第三版》
MySQL邏輯架構(gòu)簡(jiǎn)介
mysql的并發(fā)控制
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的高性能MySQL(1)——MYSQL架构的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Redis与MySQL双写一致性如何保证
- 下一篇: 定期备份数据库脚本