Mysql 讀書筆記 - 《高性能MySQL》
mysql 存儲引擎結構: 將查詢處理,及其餘系統任務和數據的存儲/提取相分離。mysql
mysql邏輯架構
mysql服務邏輯架構圖sql
鏈接/線程處理
- 每一個客戶端都會在服務器進程中擁有一個線程,該鏈接的查詢只會在這個單獨的線程中執行。
- 客戶端鏈接時須要對其進行認證
- 鏈接成功後會繼續驗證客戶端是否有執行特定查詢的權限
優化與執行
- mysql會解析查詢,建立內部數據結構--解析樹
併發控制
mysql 控制併發的兩個層面:服務器層與存儲引擎層數據庫
讀寫鎖
實現一個由兩種類型的鎖組成的鎖系統來解決問題
這兩種類型的鎖被稱爲共享鎖
和排他鎖
,也叫讀鎖
和寫鎖
安全
讀鎖是共享的,相互不干擾的。
寫鎖是排他的,即寫鎖會阻塞其餘的寫鎖和讀鎖服務器
讀寫鎖確保在給定時間內,只有一個用戶能執行寫入,而且防止其餘用戶讀取正在寫入的同一資源數據結構
鎖粒度
- 任何狀況下,在給定的資源上,鎖定的數據越少,系統的併發程度越高(前提是相互之間不發生衝突)
- 加鎖也須要消耗資源
綜合上述兩點,引出了鎖策略架構
鎖策略,即在鎖的開銷和數據的安全性之間尋求平衡併發
兩種重要的鎖策略:性能
- 表鎖
表鎖是mysql最基本的鎖策略,也是開銷最小的策略,他會鎖定整張表優化
- 行級鎖
行級鎖能夠最大程度的支持併發處理,也帶來了最大的鎖開銷。行級鎖只在存儲引擎層實現,在服務器層沒有實現
事物
什麼是事物,事物是一組原子性的SQL查詢,或者說一個獨立的工做單元。事物內的語句,要麼所有執行成功,要麼所有執行失敗
事物的ACID
事物的ACID表示原子性、一致性、隔離性、持久性
一個良好的事物處理系統,必須具有這些標準的特徵
- 原子性:一個事物必須被視爲一個不可分割的最小工做單元,整個事物中的全部操做要麼所有執行成功,要麼所有執行失敗
- 一致性:數據庫老是從一個一致性狀態轉換到另一個一致性的狀態
- 隔離性:一個事物所作的修改在最終提交以前,其餘事物是不可以看到的。
- 持久性:事物一旦提交,所作的修改就會保存到數據庫中
事物同鎖粒度同樣,一樣會增長系統的開銷。
隔離級別
在SQL標準中定義了四種隔離級別,每一種級別都規定了一個事物中所作的修改,哪些在事物內和事物間是可見的,哪些是不可見的
四種隔離級別:
- READ UNCOMMITTED (未提交讀) 事物中的修改,即便沒有提交,對其餘事物也是可見的。所以會產生
髒讀
,即事物讀取未提交的數據。這個級別會產生不少問題,但在性能上卻不比其餘級別好太多。 - READ COMMITTED (提交讀) 此級別爲大多數數據庫系統的默認隔離級別(MYSQL不是)。此級別下,一個事物從開始直到提交以前,所作的任何修改對其餘事物都是不可見的。此級別下,執行一樣的查詢,可能會獲得不同的結果。所以此級別有時也叫
不可重複讀
- REPEATABLE READ (可重複讀)
此級別是MYSQL默認的事物隔離級別。
此級別保證在同一個事物中屢次讀取一樣的記錄的結果是一致的。可是,此級別還有另一個沒法解決的問題,幻讀
。幻讀,指的是當某個事物在讀取某個範圍內的記錄時,其餘的事物在該範圍內插入了新的記錄,當事物在此讀取該範圍的記錄時,會產生幻行
.InnoDB 和 XtraDB存儲引擎經過多版本併發控制解決了幻讀的問題。 - SERIALZABLE (可串行化)
此級別時事物的最高級別。它經過強制事物串行執行,避免幻讀問題,可是會致使大量的超時和鎖爭用的問題。他的原理是在讀取的每一行數據上都加鎖。
死鎖
死鎖是指兩個或者多個事物在同一資源上相互佔用,並請求鎖定對方佔用的資源,從而致使的惡性循環的現象。當多個事物以不一樣的順序鎖定資源時,就可能會產生死鎖。
數據庫系統實現各類死鎖檢測和死鎖超時機制
InnoDB 處理死鎖的方法:將持有最少行級排他鎖的事物進行回滾。
事物日誌
目前大多數存儲引擎都採用預寫式日誌
。
預寫式日誌:存儲引擎在修改表的時候只須要修改其內存拷貝,再吧該修改行爲記錄到持久在硬盤上的事物日誌中,而不用每次都將修改的數據自己持久到磁盤。事物日誌持久後,內存中被修改的數據在後臺能夠慢慢地刷回到磁盤。
MySQL中的事物
MySQL提供的兩種事務型存儲引擎:InnoDB,NDB Cluster。
MySQL的自動提交機制
-
MySQL中默認採用自動提交模式,若是不是顯示地開始一個事物,每一個查詢都會被看成一個事物執行提交操做。
能夠經過設置AUTOCOMMIT
變量來改變自動提交模式 -
當
AUTOCOMMIT=0
時,全部的查詢都在一個事物中,直到顯示執行COMMIT
或ROLLBACK
時,事物結束,同事開啓新的事物。還有些命令會強制執行
COMMIT
提交當前活動的事物 ,例如DDL語句 -
能夠經過執行
SET TRANSACTION ISOLATION LEVEL XXX
來設置隔離級別,新的級別將會在下個事物開始生效。 -
設置當前回話的隔離級別
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED
在事物中混合使用存儲引擎
MySQL中服務層無論理事務,事務都是由下層存儲引擎實現的。
若是在事物中混合使用了事務型和非事務型表,在正常提交狀況下沒有任何問題,可是一旦事物須要回滾時,非事務型表上的操做就沒法撤銷,這樣就會形成數據庫不一致的問題
顯示和隱式鎖定
- 隱式鎖定 InnoDB 會根據隔離級別在須要的時候自動加鎖,在事物的執行過程當中,隨時均可以執行鎖定,可是隻有在執行
COMMIT
或ROLLBACK
時候進行鎖釋放。 - 顯示鎖定
SELECT ... LOCAK IN SHARE MODE
SELECT ... FOR UPDATE
多版本併發控制
多版本併發控制(MVCC)的實現,是經過保存數據在某個時間點的快照來實現的。根據事物的開始時間不一樣,每一個事物對同一張表,同一個時刻看到的數據可能不同,同一個事物無論須要執行多長時間,看到的數據都是一致的。
InnoDB 的 MVCC
經過在每行記錄後面保存兩個隱藏的列來實現。一個保存的是行的建立時間,一個保存的是行的過時時間。其中存儲的是系統版本號,每開始一個新的事物,系統版本號都會自動遞增,事物開始時的系統版本號做爲事物的版本號。
InnoDB MVCC具體操做:
- SELECT 時,查詢複合如下條件的數據:
- 建立時間版本早於或等於當前事物版本。 -- 這樣能夠確保查詢的數據在事物開始前就已經存在,或者由事物自己插入
- 刪除時間未定義或大於當前事物版本。 -- 這樣能夠確保查詢到的數據在事物開始以前未被刪除
- INSERT 時, 爲新插入的每一行保存當前事物版本號做爲建立時間
- DELETE 時, 爲刪除的每一行保存當前事物版本號做爲刪除時間
- UPDATE 時, 新插入一行記錄,保存當前事物版本號做爲建立時間,同事保存事物版本號做爲原來行的刪除時間
MVCC 只在 REPEATABLE READ 和 READ COMMITTED兩個隔離級別下工做