MySql運行機制原理和架構

原文地址:MySQL運行機制原理&架構

主要補充了一些事務隔離級別會帶來的問題以及可以避免什麼問題,還有就是MYSQL內部優化語法樹的規則。

目錄

一、MySQL知識普及

二、MySQL邏輯架構

三、併發控制和鎖的概念

四、事務

五、MySQL存儲引擎及應用方案


一、MySQL知識普及

MySQL是一個開放源代碼的關係數據庫管理系統。

MySQL架構可以在多種不同場景中應用併發揮良好作用。主要體現在存儲引擎的架構上,插件式的存儲引擎架構將查詢處理和其它的系統任務以及數據的存儲提取相分離。

二、MySQL邏輯架構

1.Connectors

MySQL首先是一個網絡程序,其在TCP之上定義了自己的應用層協議。所以要使用MySQL,我們可以編寫代碼,跟MySQL Server建立TCP連接,之後按照其定義好的協議進行交互。當然這樣比較麻煩,比較方便的辦法是調用SDK,比如Native C API、JDBC、PHP等各語言MySQL Connector,或者通過ODBC。但通過SDK來訪問MySQL,本質上還是在TCP連接上通過MySQL協議跟MySQL進行交互。

2.Connection Management

每一個基於TCP的網絡服務都需要管理客戶端鏈接,MySQL也不例外。MySQL會爲每一個連接綁定一個線程,之後這個連接上的所有查詢都在這個線程中執行。爲了避免頻繁創建和銷燬線程帶來開銷,MySQL通常會緩存線程或者使用線程池,從而避免頻繁的創建和銷燬線程。

客戶端連接到MySQL後,在使用MySQL的功能之前,需要進行認證,認證基於用戶名、主機名、密碼。如果用了SSL或者TLS的方式進行連接,還會進行證書認證。

3.SQL Interface

MySQL支持DML(數據操作語言)、DDL(數據定義語言)、存儲過程、視圖、觸發器、自定義函數等多種SQL語言接口。

4.Parser

MySQL會解析SQL查詢,併爲其創建語法樹,並根據數據字典豐富查詢語法樹,會驗證該客戶端是否具有執行該查詢的權限。創建好語法樹後,MySQL還會對SQl查詢進行語法上的優化,進行查詢重寫。

關於MySql如何對語法樹進行優化,可以參考這篇文章(MySql內部如何優化SQL語句),在查詢優化器中,分別講述了邏輯優化和物理優化的規則,包括MySql遇見關鍵字like、group by、函數等優化的規則,下面是一些例子:

5.Optimizer

語法解析和查詢重寫之後,MySQL會根據語法樹和數據的統計信息對SQL進行優化,包括決定表的讀取順序、選擇合適的索引等,最終生成SQL的具體執行步驟。這些具體的執行步驟裏真正的數據操作都是通過預先定義好的存儲引擎API來進行的,與具體的存儲引擎實現無關。

6.Caches & Buffers

MySQL內部維持着一些Cache和Buffer,比如Query Cache用來緩存一條Select語句的執行結果,如果能夠在其中找到對應的查詢結果,那麼就不必再進行查詢解析、優化和執行的整個過程了。

7.Pluggable Storage Engine

存儲引擎的具體實現,這些存儲引擎都實現了MySQl定義好的存儲引擎API的部分或者全部。MySQL可以動態安裝或移除存儲引擎,可以有多種存儲引擎同時存在,可以爲每個Table設置不同的存儲引擎。存儲引擎負責在文件系統之上,管理表的數據、索引的實際內容,同時也會管理運行時的Cache、Buffer、事務、Log等數據和功能。

三、併發控制和鎖的概念

當數據庫中有多個操作需要修改同一數據時,不可避免的會產生數據的髒讀。這時就需要數據庫具有良好的併發控制能力,這一切在MySQL中都是由服務器和存儲引擎來實現的。

解決併發問題最有效的方案是引入了鎖的機制,鎖在功能上分爲共享鎖(shared lock)和排它鎖(exclusive lock)即通常說的讀鎖和寫鎖。當一個select語句在執行時可以施加讀鎖,這樣就可以允許其它的select操作進行,因爲在這個過程中數據信息是不會被改變的這樣就能夠提高數據庫的運行效率。當需要對數據更新時,就需要施加寫鎖了,不在允許其它的操作進行,以免產生數據的髒讀和幻讀。鎖同樣有粒度大小,有表級鎖(table lock)和行級鎖(row lock),分別在數據操作的過程中完成行的鎖定和表的鎖定。這些根據不同的存儲引擎所具有的特性也是不一樣的。

死鎖:兩個或多個事務在同一資源上相互佔用並請求鎖定對方佔用的資源,從而導致惡性循環的現象。
對於死鎖的處理:MySQL的部分存儲引擎能夠檢測到死鎖的循環依賴併產生相應的錯誤。InnoDB引擎解決的死鎖的方案是將持有最少寫鎖的事務進行回滾。
爲了提供回滾或者撤銷未提交的變化的能力,許多數據源採用日誌機制。例如:sql server使用一個預寫事務日誌,在將數據應用於(或提交到)實際數據頁面前,先寫在事務日誌上。但是,其他一些數據源不是關係型數據庫管理系統,他們管理未提交事務的方式完全不同。只要事務回滾時,數據源可以撤銷所有未提交的改變,那麼這種技術可用於事務管理。

MySQL大多數事務型的存儲引擎都不只是簡單的行級鎖,基於性能的考慮,他們一般在行級鎖基礎上實現了多版本併發控制(MVCC)。這一方案也被Oracle等主流的關係數據庫採用。它是通過保存數據中某個時間點的快照來實現的,這樣就保證了每個事務看到的數據都是一致的。詳細的實現原理可以參考《高性能MySQL》第三版。

四、事務

1.事務具有ACID的特性:
1)原子性:
事務中的所有操作要麼全部提交成功,要麼全部失敗回滾
比如你從取款機取錢,這個事務可以分成兩個步驟:1劃卡,2出錢.不可能劃了卡,而錢卻沒出來.這兩步必須同時完成.要麼就不完成. 
2)一致性:
數據庫總是從一個一致性的狀態轉換到另一個一致性的狀態
例如,完整性約束了a+b=10,一個事務改變了a,那麼b也應該隨之改變.不管數據怎麼改變。一定是符合約束
3)隔離性:
一個事務所做的修改在提交之前對其它事務是不可見的
兩個以上的事務不會出現交錯執行的狀態.因爲這樣可能會導致數據不一致.
4)持久性:
一旦事務提交,其所做的修改便會永久保存在數據庫中。

 

如果不考慮隔離性,就會引發一些 讀和寫 的問題,以讀爲例:

髒讀 :一個事務讀到另一個事務未提交的數據

不可重複讀 :一個事務讀到了另一個事務已經提交的update數據,導致多次查詢結果不一致

幻讀): 一個事務讀到了另一個事務已經提交的insert數據,導致多次查詢的結果不一樣

 

2.事務的隔離級別:
1)READ UNCOMMITTED(讀未提交):
事務中的修改即使未提交也是對其它事務可見,可能發生髒讀、不可重複讀、幻讀。
2)READ COMMITTED(讀提交):
事務提交後所做的修改纔會被另一個事務看見,可能產生一個事務中兩次查詢的結果不同。可能發生不可重複讀、幻讀
3)REPEATABLE READ(可重讀):
只有當前事務提交才能看見另一個事務的修改結果。解決了一個事務中兩次查詢的結果不同的問題。可能發生幻讀
4)SERIALIZABLE(串行化):
只有一個事務提交之後纔會執行另一個事務。髒讀、不可重複讀以及幻讀都可避免

五、MySQL存儲引擎及應用方案

MySQL採用插件式的存儲引擎的架構,可以根據不同的需求爲不同的表設置不同的存儲引擎

常用MySQL存儲引擎介紹:

InnoDB引擎:將數據存儲在表空間中,表空間由一系列的數據文件組成,由InnoDb管理。支持每個表的數據和索引存放在單獨文件中(innodb_file_per_table);支持事務,採用MVCC來控制併發,並實現標準的4個事務隔離級別,支持外鍵。索引基於聚簇索引建立,對主鍵查詢有較高性能。數據文件的平臺無關性,支持數據在不同的架構平臺移植。能夠通過一些工具支持真正的熱備,如XtraBackup等;內部進行自身優化如採取可預測性預讀,能夠自動在內存中創建bash索引等。

MyISAM引擎:MySQL5.1默認,不支持事務和行級鎖,提供大量的特性如全文索引、空間函數、壓縮、延遲更新等。數據庫故障後,安全恢復性,對於只讀數據可以忍受故障恢復,MyISAM依然非常適用 ,日誌服務器的場景也比較適用,只需插入和數據讀取操作,不支持單表一個文件,會將所有的數據和索引內容分別存放在兩個文件中,MyISAM對整張表加鎖而不是對行,所以不適用寫操作比較多的場景,支持索引緩存不支持數據緩存。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章