一、MySql 基礎架構
目錄
[toc]
1.1Mysql邏輯架構
如上圖:
展示了mysql邏輯的架構圖辜限。
- 最上層:處理一些連接皇拣,授權認證和安全等。
- 第二層:包含了查詢緩存薄嫡,解析器和優(yōu)化器氧急。大多數(shù)的核心服務功能都在這一層,包括查詢解析毫深、分析吩坝、優(yōu)化、緩存以及所有的內置函數(shù)哑蔫,還有一些跨存儲引擎的功能都在這一層實現(xiàn):存儲過程钉寝、觸發(fā)器、視圖等闸迷。
- 第三層:包含了存儲引擎瘩蚪。主要負責的是數(shù)據的存儲和提取。mysql支持很多引擎稿黍,每個引擎都有它的優(yōu)勢和劣勢疹瘦。存儲引擎API包含了幾十個底層函數(shù),用于執(zhí)行諸如“開始一個事務”或者“根據主鍵提取一行記錄”等操作巡球。但它不會解析SQL言沐,不同存儲引擎之間也不會相互通信,而只是簡單的響應上層服務器的請求酣栈。
1.1.1 連接管理與安全
每個客戶端連接都會在服務器進程中擁有一個線程险胰,這個連接的查詢只會在這個單獨的線程中執(zhí)行,該線程只能輪流在某個CPU核心或者CPU中運行矿筝。服務器會緩存線程起便,因此不需要為每個新建的連接創(chuàng)建或者銷毀線程。當客戶端連接mysql服務器時,服務器需要對其進行認證榆综。
1.1.2 優(yōu)化與執(zhí)行
Mysql會解析查詢妙痹,并創(chuàng)建內部數(shù)據結構(解析樹),然后對其進行各種優(yōu)化鼻疮,包括重寫查詢怯伊、決定表的讀取順序,以及選擇合適的索引等判沟。用戶可以通過特殊的關鍵字提示(hint)優(yōu)化器耿芹,影響他的決策過程。也可以請求優(yōu)化器解釋(explain)優(yōu)化過程的各個因素挪哄,讓用戶可以知道服務器是如何進行優(yōu)化決策的吧秕。
- 特殊的關鍵字提示(hint)優(yōu)化器 SELECT select_list FROM table_name USE INDEX(index_list) WHERE condition;
- 優(yōu)化器并不關心使用的是什么存儲引擎,但存儲引擎對于優(yōu)化查詢還是有影響的迹炼。
- 對于SELECT語句寇甸,在解析查詢之前,服務器會優(yōu)先檢查查詢緩存疗涉,如果能夠在其中找到對應的查詢,服務器就不必再執(zhí)行解析吟秩、優(yōu)化和執(zhí)行的整個過程咱扣,惹事直接返回結果集。
1.2 并發(fā)控制
只要有多個查詢需要在同一時刻中修改數(shù)據涵防,都會產生并發(fā)控制的問題闹伪。大多數(shù)系統(tǒng),都會利用鎖機制來解決這些問題壮池。
1.2.1 讀寫鎖
在處理并發(fā)讀或者寫時偏瓤,可以通過一個由兩種類型的鎖組成的鎖系統(tǒng)來解決問題。這兩種類型的鎖通常被稱為共享鎖和排他鎖椰憋。也叫讀鎖和寫鎖厅克。
讀鎖是共享的,或者說是相互不阻塞的橙依。多個客戶在同一時刻同時讀取同一個資源而不會相互干擾证舟。而些許哦是排他的,也就是說一個寫鎖會阻塞其他的寫鎖或者讀鎖窗骑,這是出于安全策略的考慮女责,這樣可以保證只有一個用戶執(zhí)行寫入,并防止其他暈乎讀取正在寫入的同一資源而發(fā)生錯誤的結果创译。
1.2.2 鎖粒度
- 表鎖:表鎖是mysql中最基本的鎖策略抵知,并且是鎖開銷最小的策略。因為鎖越多,代表著越要消耗資源刷喜,所得各種操作残制,包括獲得鎖,檢查鎖是否已經解除吱肌,釋放鎖等痘拆,都會增加系統(tǒng)開銷。表鎖會鎖定整張表氮墨。一個用戶對表進行寫操作前(插入纺蛆、刪除和更新),需要先獲取寫鎖规揪,這回阻塞用戶對改變的所有讀寫操作桥氏。知識沒有寫鎖時,其他讀取的用戶才能獲取讀鎖猛铅,讀鎖之間是不相互阻塞的字支。
- 行鎖:行鎖可以最大程度的支持并發(fā)處理(同時也帶來了最大的鎖開銷)。InnoDbB和XtraDB實現(xiàn)了行鎖奸忽。行級鎖只在存儲引擎實現(xiàn)堕伪,而mysql服務器層沒有實現(xiàn)。
1.3 事務
事務就是一組原子性的SQL操作栗菜,或者說是一個獨立的工作單元欠雌。如果數(shù)據庫引擎能夠成功地對數(shù)據庫應用該組的全部語句,那么就執(zhí)行疙筹。如果其中任何一條語句因為崩潰或者其他原因無法執(zhí)行富俄,那么所有的語句都不會執(zhí)行。也就是說:事務內的語句而咆,要么全部執(zhí)行成功霍比,要么全部執(zhí)行失敗。
1.3.1 事務的特性(ACID)
- 原子性(atomicity)一個事務必須視為一個不可分割的最小工作單元暴备,整個事務中的所有操作要么全部成功悠瞬,要么全部失敗回滾,對于一個事務來說涯捻,不可能只執(zhí)行其中的某一部分操作阁危。
- 一致性(consistency)數(shù)據庫總是從一個一致性的狀態(tài)轉換到另一個一致性的狀態(tài)。假如事務沒有提交汰瘫,所有事務中所做的修改也不會保存到數(shù)據庫中狂打。
- 隔離性(isolation)一個事務所做的修改,在最終提交之前混弥,對其他事務是不可見的趴乡。
- 持久性(durability)一旦事務提交对省,則其所做的改變就會永久的保存于數(shù)據庫中。此時晾捏,即使數(shù)據庫崩潰蒿涎,數(shù)據也不會丟失。
1.3.2 隔離級別
針對隔離性惦辛,衍生出了隔離級別的概念劳秋,因為它復雜的多。在SQL標準中胖齐,定義了四種隔離級別玻淑。較為低級的隔離級別通常可以執(zhí)行更高的并發(fā)呀伙,系統(tǒng)的開銷也更低补履。
- 讀未提交(READ UNCOMMITTED)指的是事務中的修改,即使沒有提交剿另,對其他事務也都是可見的箫锤。事務可以讀取到未提交的數(shù)據,這也被稱為臟讀雨女。
- 讀已提交(READ COMMITTED)一個事務開始時谚攒,只能“看見”已經提交的事務所做的修改。解決了臟讀的問題氛堕,但是它也被叫做不可重復讀馏臭,因為兩次執(zhí)行同樣的查詢,可能會得到不一樣的結果岔擂。
- 可重復讀(REPEATABLE READ)Mysql默認隔離級別。解決了不可重復讀和臟讀的問題浪耘。該級別保證了在同一個事務中多次讀取同樣的記錄的結果是一致的乱灵。但是,它無法解決幻讀的問題七冲。所謂幻讀痛倚,就是指當某個事務在讀取范圍內的記錄時,另一個事務又在該范圍內插入了新的記錄澜躺,當之前的事務再次讀取該范圍的記錄時蝉稳,可能會產生幻行。innoDB通過多版本并發(fā)控制(MVCC)解決了幻讀的問題掘鄙。
- 可串行化(SERIALIZABLE)最高的隔離級別耘戚。它讓事務串行的執(zhí)行,避免了幻讀的問題操漠。它會在讀取的每一行數(shù)據都加鎖收津,所以可能會導致大量的鎖競爭和超時的問題。性能 最差。
1.3.3 死鎖
死鎖是指兩個或者多個事務在同一資源相互占用撞秋,并請求鎖定對方占用的資源长捧,從而導致惡性循環(huán)的現(xiàn)象。當多個事務試圖以不同的順序鎖定資源時吻贿,就可能會產生死鎖串结。多個事務同時鎖定同一個資源,也會產生死鎖舅列。
為了解決死鎖的問題肌割,數(shù)據庫系統(tǒng)實現(xiàn)了各種死鎖檢測和死鎖超時機制。比如InnoDB,能檢測到死鎖的循環(huán)依賴剧蹂,將持有的最少行級排他鎖的事務進行回滾声功。死鎖發(fā)生以后,只有部分或者完全回滾其中一個事務宠叼,才能打破死鎖先巴。
1.3.4 Mysql中的事務
Mysql提供了兩種事務型的存儲引擎,InnoDB和NDB Cluseter. mysql中的事務有以下特點:
- 自動提交冒冬。mysql默認采用自動提交的方式伸蚯。如果不顯式地開始一個事務,則每個查詢都被當做一個事務執(zhí)行提交操作简烤。
- 隱式和顯式鎖定剂邮。InnoDB采用的是兩階段鎖定協(xié)議。在事務執(zhí)行過程中横侦,隨時都可以執(zhí)行鎖定挥萌,鎖只有在執(zhí)行了commit或者rollback后才會釋放,并且所有的鎖是在同一時刻被釋放枉侧。
SELECT ... LOCK IN SHARE MODE
SELECT ... FOR UPDATE
Mysql中以上了兩種特定的語句引瀑,可以進行顯式鎖定。
1.4多版本并發(fā)控制(MVCC)
MVCC是行級鎖的一種變種榨馁,但是它在很多情況下避免了加鎖的操作憨栽,因此開銷更低。InnoDB中的MVCC翼虫,是通過在每行記錄中保存了兩個隱藏的列來實現(xiàn)的屑柔。這兩個列,一個保存了行的創(chuàng)建時間珍剑,另一個保存的是過期時間(或刪除時間)掸宛。不是存儲的實際的時間值,而是版本號招拙。每開始一個新的事務旁涤,系統(tǒng)版本號都會自動遞增翔曲。事務開始時刻的系統(tǒng)版本號作為事務的版本號,用來和查詢到的每行記錄的版本號進行比較劈愚。
MVCC的基本原理是:在事務中保存數(shù)據的快照瞳遍,這意味著在一個事物里能夠看到數(shù)據一致的視圖,而不用擔心這個事務運行多長時間菌羽,同時也意味著在同一個時刻不同事務看到的相同表里的數(shù)據可能是不同的掠械。
MVCC的基本特征:
- 每行數(shù)據都存在一個版本,每次數(shù)據更新時都更新該版本
- 修改時Copy出當前版本隨意修改注祖,各個事務之間無干擾
- 保存時比較版本號猾蒂,如果成功(commit),則覆蓋原記錄是晨;失敗則放棄copy(rollback)
InnoDB存儲引擎MVCC的實現(xiàn)策略:在每一行數(shù)據中額外保存兩個隱藏字段:當前行創(chuàng)建時的版本號和刪除時的版本號(可能為空)肚菠。每個事務又有自己的版本號,這樣事務內執(zhí)行CRUD操作時罩缴,就通過版本號的比較來達到數(shù)據版本控制的目的蚊逢。具體做法見下面的示意圖。?
1.5 Mysql的存儲引擎
1.5.1 InnoDB存儲引擎
InnoDB是Mysql默認的事務型存儲引擎箫章,也是最重要烙荷,使用最廣泛的存儲引擎。它被設計用來處理大量的短期事務檬寂,短期事務大部分情況下是正常提交的终抽,很少會被回滾。InnoDB性能上的優(yōu)越和自動崩潰恢復的特性桶至,使得它很流行昼伴。
InnoDB的數(shù)據存儲在表空間中,表空間是由InnoDB管理的一個黑匣子镣屹,由一系列的數(shù)據文件組成圃郊。
InnoDB采用MVCC來支持高并發(fā),并且實現(xiàn)了四個標志的隔離級別野瘦。其默認級別為REPETABLE READ(可重復讀)描沟,并且通過間隙鎖(next-key locking)策略防止幻讀的出現(xiàn)飒泻。間隙鎖使得InnoDB不僅僅鎖定查詢涉及的行鞭光,還會對索引中的間隙進行鎖定,以防止幻影行的插入泞遗。
InnoDB表是基于聚簇索引建立的惰许,聚簇索引對主鍵查詢有很高的性能。不過它的二級索引(非主鍵索引)中必須包含主鍵列史辙,所以主鍵列很大的或汹买,其他索引也會很大佩伤。因此索引較多的話,盡量采用較小的主鍵晦毙。
支持熱備份
支持可預測性的讀生巡,能夠自動在內存中創(chuàng)建hash索引以加速讀操作的自適應哈希索引。
1.5.2 MyISAM存儲引擎
非事務型存儲引擎见妒。提供了大量的特性孤荣,包括全文索引,壓縮须揣,空間函數(shù)等盐股。不支持事務和行級鎖,而且在崩潰后無法安全恢復耻卡。
- 加鎖與并發(fā)疯汁。針對整張表進行加鎖,而不是某一行卵酪。讀取時會對需要讀到的所有表加共享鎖幌蚊,寫入時則對表加排他鎖。
- 支持全文索引凛澎,是一種基于分詞創(chuàng)建的所有霹肝,可以支持復雜的查詢
- 壓縮表。如果表在創(chuàng)建并導入數(shù)據庫以后塑煎,不會再進行修改操作沫换,那么這樣的表或許可以采用MyISAM壓縮表。