高性能MySQL之運行機制

本文來自于拜讀《高性能MySQL(第三版)》時的讀書筆記
作者:安明哲
轉載時請注明部分內容來自《高性能MySQL(第三版)》

MySQL的邏輯構架

MySQL服務器邏輯架構
  • 最上層:鏈接處理,授權認證,安全等處理

  • 第二層:查詢解析、分析、優化、緩存以及內置函數(如:日期,時間,數學和加密函數)

  • 第三層:包含了存儲引擎,存儲引擎負責數據的存儲和提取。

鏈接管理和安全性

每一個客戶端鏈接都在MySQL服務器進程中擁有一個多線程,在CPU中輪詢運行,服務器會負責緩存線程,因此不需要為每一個新建的鏈接創建或者銷毀線程。

MySQL5.5以后支持線程池插件,可以使用池中少量的線程來服務大量的連接。

客戶端連接到MySQL之后,服務器會對其進行認證,認證基于用戶名,密碼和原始主機信息,如何使用了SSL連接,還可以使用證書認證。一旦連接成功,服務器會繼續驗證客戶端的權限。

通常我們通過一個用戶名和密碼外加一個數據庫的地址連接數據庫,連接數據庫的指令可能如下:

mysql -u username -h 192.168.1.100 -p *****

當我們鏈接MySQL-Server時,他可能會檢查我們的用戶名密碼,除此之外還會檢查我們的主機地址,通過主機地址判斷是否允許我們登錄,比如大部分小型站點會把MySQL和站點文檔放置在一個服務器,而且MySQL拒絕了localhost之外的所有連接(不允許遠程連接),其次我們還可以在MySQL內設置用戶的權限,比如僅允許select(只讀)。

優化與執行

MySQL會解析查詢,并創建內部數據結構,然后進行各種優化,包括重寫查詢、決定表的讀取順序,以及選擇合適的索引等。

對于SELECT語句,MySQL內部會有一個Query Cache,如果這個緩存內能夠找到對應的查詢,MySQL則會省去解析和優化工作,直接返回結果。

并發控制

MySQL共有兩個層面的并發控制,服務器層存儲引擎層

讀寫鎖

當有多個連接同時修改一個數據庫的某一個表的某一行的時候,會發生什么結果是不確定的。

這有點類似于多線程編程下的線程同步和死鎖,事實上MySQL問題的本質似乎也就在這里。

解決這類問題的方法就是并發控制,MySQL在處理這類并發操作的時候可以實現一個由兩種類型的鎖組成的索系統來解決問題。這兩種類型的鎖一般被稱為共享鎖排它鎖

共享鎖是互不阻塞的,也就是多個用戶可以同時讀取一個資源,所以也叫做讀鎖。

排它鎖是一個寫鎖會阻塞其他寫入和讀取操作,只有這樣才能保證同一時間只會存在呢一個連接在想數據庫內寫入,所以也被稱作寫鎖

粒度鎖

一種提高共享資源并發性的方式就是讓鎖定得對象更具有選擇性。盡量只鎖定需要修改的部分數據,而不是所有資源。更理想的方式是,只會對要修改的數據片進行精確的鎖定。

那么,理論上鎖定的資源越小,鎖定范圍越精確,那么并發性能就會越高。但是事實上,創建一個數據鎖也會造成系統的開銷,如果系統通過大量的時間來管理鎖,而不是存取數據,系統的性能反而會降低。

表鎖

粒度鎖的精確度是根據需求來決定的,很多時候我們都是在尋找精度和鎖開銷之間的一個平衡點。

表鎖是MySQL中基本的鎖策略,并且是開銷最小的策略。當用戶在對一張表進行寫操作之前,首先獲得寫鎖,于是,它阻塞了其他鏈接的讀取和寫入操作,只有寫鎖接觸的時候,其他鏈接才能獲得讀鎖。
不僅如此,MySQL還設置了鎖的優先級,在操作列隊中MySQL可能會把寫入操作插入到讀取操作之前。

那么,可以想象一下MySQL的后臺實現,可能表鎖的是這樣是實現的(僅僅是本人猜想):

//下面的代碼類似于偽代碼,沒有參考MySQL源碼
//僅僅是本人為了為了理解MySQL表鎖的臆測:
struct table_lock
{
      /*一個表鎖的結構體*/
     char* table_name;
     char* host;
};
//實例化一個鏈接
int* instance = getInstance();
//當執行讀取操作的時候,可能需要傳遞一個table_name
instance->readTable(table_name)
{
    //讀取操作時候首先要獲取表鎖的所有權
    table_lock.name = table_name;
    table_lock.host = instance;
}
行級鎖

行級鎖可以最大程度的支持并發處理(同時也帶來了最大的鎖開銷)。行級鎖只在存儲引擎中實現。

行級鎖比表鎖更加精確,他把鎖的對象精確到了對象的某一行,但也就意味著需要創建更多的鎖。

事務

事務其實就是一個獨立的工作單元。如果數據庫引擎能夠完成事務中的每一項操作,那么全組的SQL語句都會被執行,如果任何一條語句因為崩潰或者其他原因無法執行,那么所有語句都不執行。

最簡單的例子就是我們銀行的轉賬系統,一個轉賬操作實際上是從用戶賬戶表里減去對A的賬戶余額進行修改,同時再去修改B的賬戶余額,最后再在記錄表被記錄下這一條操作。SQL語句大致如下:

START TRANSACTION;
SELECT balance FROM checking WHERE customer_id = 1010001;
UPDATE checking SET balance = balance-200.00 WHERE customer_id = 1010001;
UPDATE checking SET balance = balance+200.00 WHERE customer_id = 1010002;
INSERT INTO record VALUES('1010001', '1010002', 200.00);
COMMIT;

這個時候如果執行到第三條語句的時候發現1010002這個賬戶已經被凍結了,無法接受轉賬,這個時候按照正常的邏輯,數據庫內部10010001這個用戶平白無故的就少去了200元,但是10010002并沒有收到。
使用事務就完美的解決了這個問題,如果一條語句執行失敗,沒關系,最終沒有commit之前,MySQL是不會進行寫入操作的。

ACID

那么有一個專業的名詞來描繪這種需求,他叫做ACID:
A---atomicity(原子性):一個事務必須被視為一個不可分割最小工作單元,事務中的操作只要有一個失敗則全部回滾(可以理解為,一件事情,要么全做,有一點調點不具備那么全部都不做。)

C---Consistency(一致性):在一個轉賬事務中,A賬戶的減少必定對應著B賬戶的增加,這個狀態轉換的過程必須保持一致,那么這就是事務的一致性。

I---Isolation(隔離性):通常來說,一個事物所做的修改在最終提交之前,對其他事務是不可兼得。也就是說,事務內部的操作是不會被外部所看到的,只有最終提交之后,我們才能在銀行系統中看到兩個賬戶金額的變化(這個時候如何還有一個事務在執行同樣的轉賬操作,那么們是相互隔離的,這看起來并不嚴謹,事實這里還設計一個隔離級別的問題,這個以后再談)。

D---durability(持久性):一旦失誤提交,所有的修改會永久的保存在數據庫中,即使系統崩潰,服務器被損壞,只要硬盤還在,數據就依舊存在。

事務的ACID看起來很簡單,但是在應用邏輯中要實現這一點非常難,因為還有相當一部分涉及到用戶體驗的考慮,你必須保證數據同步的問題,保證數據的一致性和持久性同時還要讓用戶覺察不到這么復雜的工作。而且,事務所做的操作正如鎖一樣,需要更多的系統資源,你還需要更強的CPU、更大的內存和更多的磁盤空間。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,117評論 6 537
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,860評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,128評論 0 381
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,291評論 1 315
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,025評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,421評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,477評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,642評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,177評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,970評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,157評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,717評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,410評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,821評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,053評論 1 289
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,896評論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,157評論 2 375

推薦閱讀更多精彩內容