高性能MySQL學習總結一----MySQL常見概念

1、MySQL邏輯架構

 

  第一層的服務不是MySQL獨有的,大多數是基於網絡的客戶端/服務端的工具,如鏈接處理、受權認證、安全等等。數據庫

  第二層就是MySQL的核心功能,包括查詢解析、分析、優化、緩存以及全部的內置函數,全部的跨存儲引擎的功能都在這一層實現:存儲過程、觸發器、視圖等。緩存

  第三層包含了存儲引擎,主要負責MySQL中數據的存儲和提取。安全

1.鏈接管理與安全

  每一個客戶端鏈接都會服務器進程中擁有一個線程,這個鏈接的查詢只會在這個單獨的線程中執行,該線程只能輪流在某個CPU核心或者CPU中運行,服務器會緩存線程,因此不須要對每一個鏈接新建或者銷燬一個線程(能夠複用緩存中的線程)。服務器

  當客戶端鏈接到MySQL時服務器須要對其進行認證,若是認證成功,服務器會繼續驗證該客戶是否有執行某個待定查詢的權限。網絡

2.優化與執行

  MySQL會解析查詢,而且建立內部數據結構(解析樹),而後對其進行各類優化,包括重寫查詢SQL、決定表的讀取順序,以及選擇合適的索引等。數據結構

  對於一個SELECT查詢語句來講:在解析查詢以前,服務器會先檢查查詢緩存,若是可以在其中找到對應的查詢,服務器會直接返回結果,不須要再執行查詢解析、優化和執行整個過程。架構

2、併發控制

1.讀寫鎖

  好比有一張表,多個線程對這張表進行操做,加入恰好有一個線程在對一條數據更改,另外一個線程也對其進行讀取操做,那麼進行讀操做的這個線程可能讀到的數據是不正確的,怎麼解決這個問題呢?這時就用到了併發控制,主要是經過兩種鎖來控制的:讀鎖(共享鎖)、寫鎖(排他鎖)
併發

  讀鎖是共享的,或者說是相互不阻塞的,即對個線程讀取同一個資源,互不干擾;寫鎖是排他的,也就是說只要有一個線程對其進行寫操做,那麼其餘的讀和寫線程將都會被阻塞。只有這樣才能保證才能保證在給定的時間內只有一個線程在寫操做,並防止其餘線程讀取正在寫入的數據。函數

2.鎖粒度

  最理想的狀況是:須要寫入哪一個對象就鎖定哪一個對象。儘可能只鎖定須要修改的部分數據,而不是全部的數據。在任什麼時候候,在給定的資源上,鎖定的數據越少,系統的併發程度越高。工具

  可是還有一個問題,加鎖也會消耗資源,鎖的各類操做:得到鎖、檢查鎖是否已經解除、釋放鎖等,都會增長系統的開銷,若是花費大量的時間來管理鎖,而不是存取數據,那麼系統的性能將會受到影響。

  所謂的鎖策略,就是在鎖的開銷和數據的徹底性之間尋求平衡。

  表鎖是MySQL中最基本的鎖策略,而且是開銷最小的策略(意味着併發程度低),可是表鎖的缺點是在執行插入、刪除、更改的操做時會使其餘的用戶線程阻塞。(注意:讀鎖之間是互不影響的)。另外寫鎖比讀鎖的優先級更高。寫鎖能夠插到讀鎖中,可是讀鎖卻不能插到寫鎖中。

  行級鎖:能夠最大程度的支持併發處理(可是同時也帶來了更大的鎖開銷)最典型的就是InnoDB存儲引擎,行級鎖只在存儲引擎層實現。

3、事務

  最重要的事務終於到啦,事務即ACID(原子性、一致性、隔離性、持久性),在開始講這四個特性以前咱們先舉一個最經典的例子:某帳戶存了1000元,如今用戶A要往裏面存200元、用戶B要往出來取200元。

  原子性:一個事務必須被視爲不可分割的最小工做單元,整個事務的全部操做要麼所有提交完成,要麼所有失敗回滾,對於一個事務來講不可能執行其中的一部分。那上面例子來講:A要從帳戶取200須要執行如下四步操做:

 

1 START TRANSACTION;
2 SELECT  '金額'  FROM  '帳戶表'  WHERE   user_id = 1221221;
3 UPDATE  '帳戶表'  SET  '金額'  =  '金額'  - 200  WHERE user_id = 1221221;
4 COMMIT;

 

  解釋:1.開啓事務 ,2.查詢帳戶有沒有200元 ,3.扣除金額  , 4.提交事務。

  原子性就是指這四步完整執行不可再分。

  一致性:數據庫從一個一致性的狀態轉換爲另外一個一致性的狀態。就上面那個例子:若是在第三步執行完系統崩潰,帳戶中的金額仍是1000元,由於一個事務沒有執行完,在最終提交前是不會保存到數據庫中的。

  隔離性:一般來說一個事務在最終提交前,對其餘事務是不可見的。就以前例子來講,第三步執行完,在沒提交以前B帳戶來看到的金額仍然是1000元。是不可見的。

  持久性:事務一旦提交其所作的修改就會永遠的被保存到數據庫中,即便系統崩潰也不會丟失。

  一個實現了事務的數據庫相比於沒有實現事務的數據庫它須要更強的CPU處理能力、更大的內存、更多的磁盤空間。對於有些不須要事務的查詢類應用選擇一個非事務型的存儲引擎能夠得到更高的性能。

1.隔離級別

一共有四種隔離級別先簡單作個介紹:

A.READ  UNCOMMIT(讀未提交)

  在這個隔離級別中,事務的修改,即便沒有提交,對其餘的事務也是可見的。事務能夠讀到未提交的數據,這些數據也被稱爲髒讀。

B.READ  COMMIT(讀已提交)(不可重複讀)

  大多數數據庫系統的默認隔離級別都是讀已提交,可是MySQL不是,MySQL的默認隔離級別是可重複讀。簡單說就是一個事務開始時只能 「看見」 已經提交的事務所作的修改,換句話說,一個事務從開始到提交這個過程當中所作的全部修改對其餘事務是不可見的。這個級別對於兩次執行相同狀況的查詢,可能會獲得不一樣的結果。

C.REPEATABLE  READ(可重複讀)

  該級別保證了在同一個事務中屢次讀取一樣的記錄結果是一致的,可是它沒法解決幻讀的問題。

D.SERIALIZABLE(可串行化)

  是最高的隔離級別。它經過強制事務串行化執行,避免了全部問題,他會在讀取的每一行記錄上面都加鎖,因此可能致使大量的超時與鎖等待的問題,併發低。

講幾個概念:

1.髒讀:A用戶把錢取出沒有提交,B用戶讀取到修改了的金額爲800,過一會A由於異常事務回滾,B再次讀取發現值變爲1000,兩次不同,第一次讀到的是髒數據。

2.不能夠重複讀:B讀到數據爲1000後,A修改數據爲800而且提交,B再次讀取爲800,兩次數據不一致。

3.幻讀:與不可重複讀相似:B讀到一個表裏有10條記錄,A插了一條並提交,B再次讀爲11條,感受發生幻覺同樣。

不一樣隔離級別引起的問題:

 2.死鎖

多個事務在同一資源上相互佔有,而且請求鎖定對方佔用的資源,從而致使惡性循環的現象。

數據庫系統實現了各類死鎖檢測和死鎖超時機制。InnoDB目前處理死鎖的方法是:將持有最少行排它鎖的事務進行回滾。

3.事務日誌

事務日誌能夠提升事務的效率,使用事務日誌時:存儲引擎在修改表數據時只須要修改其內存拷貝,再把該修改行爲記錄到持久在硬盤上的事務日誌中,不用每次將修改的數據自己持久到硬盤。事務日誌採用追加的方式,寫日誌的操做是磁盤上的一小塊區域內的順序I/O.事務日誌持久後,內存中被修改的數據將在後臺慢慢刷回到磁盤。因此一共須要兩次磁盤I/O:一次寫日誌磁盤I/O,一次刷回磁盤I/O.

4.MySQL中的事務

1.自動提交:MySQL默認採用自動提交的方式。好比每一個查詢就是一個事務執行完自動提交。

2.非事務型存儲引擎如:MyISAM無回滾功能。

4、多版本併發控制MVCC

  能夠認爲MVCC是行級鎖的一個變種,它在不少狀況下避免了加鎖,MVCC的實現是經過保存數據在某個時間的快照來實現的。

  InnoDB的MVCC,是經過在每行記錄後面保存兩個隱藏的列來實現的,這兩個列一個保存了行的建立時間,一個保存了行的刪除時間,存儲的不是真正時間而是系統的版本號。每一個新事物開始系統版本號自動遞增。事物開始時刻的版本號做爲事物的版本號,用來和查詢到的每行記錄版本號進行比較。

  MVCC只在可重複讀和讀已提交兩個隔離級別下工做,其餘兩個級別都和MVCC不兼容。由於讀未提交老是讀取最新的數據行,不符合當前事物版本的數據行。可串行化會對全部行加鎖。

  個人理解其實MVCC就跟CAS是一個原理,就是一個比較並交換的過程。

相關文章
相關標籤/搜索