呵呵噠。。。
?
MySQL體系結構和存儲引擎
首先要搞懂的是什么是數據庫,什么是數據庫實例。
數據庫:物理操作系統文件或其他形式文件類型的集合。
實例:MySQL數據庫由后臺線程以及一個共享內存區組成,實例才是真正對數據庫進行操作的。
譬如:數據庫就像蓋樓所需的石頭、砂和水泥等原材料,而正在使用這些原材料蓋樓的施工隊則是實例,哈哈。
?
MySQL實例啟動的方法有很多種,啟動時讀取配置文件,如果配置文件有多個,而且配置項又有很多相同的,那么會以最后讀到的配置項為準。
?
數據庫實例是一層數據庫管理軟件,用戶不能直接地操縱數據庫,只能通過實例提供的接口來訪問數據庫。
圖1 MySQL體系結構
從圖1中可以發現,MySQL又一下幾部分組成:
- 連接池組件:Connectors
- 管理服務和工具組件:Management Service & Utilities
- SQL接口組件:SQL Interface
- 查詢分析器組件:Parser
- 優化器組件:Optimizer
- 緩沖組件:Caches & Buffers
- 插件式存儲引擎:Pluggable Storage Engines
- 物理文件:Files & Logs
MySQL的這個架構模式在很多數據庫中都有體現,你可以學一下MySQL這個架構,好歹也是架構啊!
MySQL數據庫的特色就是插件式的表存儲引擎。
MySQL插件式存儲引擎架構提供了一系列標準的管理和服務支持。
存儲引擎是底層物理結構的實現,每個存儲引擎開發者可以按照自己的意愿進行開發。
??? 注意:
??????? 存儲引擎是基于表的,而不是數據庫的!
?
存儲引擎的好處是:
- 每個存儲引擎都有各自的特點,可以根據具體的應用不同選擇/建立不同的存儲引擎表。
- 對于上層應用的開發來說,存儲引擎是透明的。
- MySQL數據庫的核心在于存儲引擎。
- MySQL官方手冊給出了編寫自定義存儲引擎的過程(可以去看下咯)。
?
常見的存儲引擎有(不能詳寫了,木有時間了):
InnoDB、MyISAM、NDB、Memory、Archive、Federated、Maria;
其他的有:Merge、CSV、Sphinx、Infobright
至于存儲引擎之間的比較,讓他們見鬼去吧, 哦,我的上帝~
?
查看當前MySQL數據庫所支持的引擎:SHOW ENGINES\G;
MySQL自帶的示例數據庫和數據庫的文檔放在一起,下載地址:http://dev.mysql.com/doc/
?
連接MySQL
連接MySQL操作是一個連接進程和MySQL數據庫實例進行通信,本質上是進程通信(還好老子看了點,不然就懵逼了),常見的進程通信方式有:
管道、命名管道、命名名字、TCP/IP套接字、UNIX域套接字。
TCP/IP套接字:在任何平臺下都可以使用,也是使用最多的一種,通過TCP/IP連接MySQL實例時,MySQL會先檢查一張權限視圖,判斷請求客戶端IP是否允許連接到實例;
SELECT host, user, password FROM user;
命名管道和共享內存:
UNIX域套接字:在Linux和Unix下可以使用UNIX域套接字,這個并不是一個網絡協議,所以只能在客戶端和數據庫實例在同一臺機器的情況下使用。
制定套接字文件的路徑:—socket=/tmp/mysql.sock
SHOW VARIABLES LIKE 'socket';
?
好了,這章就看完了,遺留的就是對不同存儲引擎的介紹和比較咯。。。。。。
?
?
InnoDB存儲引擎
?
InnoDB是事物安全的MySQL存儲引擎,是OLTP應用中核心表的首選存儲引擎。
InnoDB是MySQL中第一個完整支持ACID事物的存儲引擎,其特點是:
行鎖設計
支持MVCC
支持外鍵
提供一致性非鎖定讀
有效利用CPU和內存
?
從MySQL5.1版本開始,允許存儲引擎以動態方式加載,這樣存儲引擎的更新可以不受MySQL數據庫版本的限制。
所以5.1中可以有靜態編譯的版本,也可以有動態加載的版本。
?
InnoDB體系架構
?
圖2 InnoDB存儲引擎體系架構
InnoDB存儲引擎有多個內存塊,可以認為這些內存塊組成了一個大的內存池,負責:
維護所有進程/線程需要訪問的多個內部數據結構
緩存磁盤上的數據
重做日志的緩沖(redo log)
?
后臺線程的主要作用是負責刷新內存池中的數據,保證緩沖池內的數據是最近的數據;同時將臟數據刷回磁盤;保證數據庫發生異常時InnoDB的恢復。
?
InnoDB是一個多線程模型,每個線程負責不同的任務。
1. Master Thread
2. IO Thread
3. Purge Thread
4. Page Cleaner Thread
?
內存
1. 緩沖池
2. LRU List、Free List和Flush List
3. 重做日志緩沖
4. 額外的內存池
?
CheckPoint技術
?
Master Thread工作方式
?
InnoDB的關鍵特性
插入緩沖(Insert Buffer)
兩次寫(Double Write)
自適應哈希索引(Adaptive Hash Index)
異步IO(Async IO)
刷新鄰接頁(Flush Neighbor Page)
?
啟動、關閉與恢復
?
小結:感覺這章的內容還是挺重要的,對于理解InnoDB引擎或者底層實現
?
文件
MySQL和InnoDB存儲引擎用到的文件有:
參數文件:
日志文件:
socket文件:
pid文件:
MySQL表結構文件:
存儲引擎文件:
?
?
?
表
?
InnoDB存儲引擎表的邏輯存儲和實現,重點分析表的物理存儲特征,即表中的數據是如何組織和存放的。
?
索引組織表
?
在InnoDB存儲引擎中,表都是根據主鍵順序存放的,這種存儲方式的表稱為索引組織表(index organized table)。
在InnoDB存儲引擎表中,每張表都有個主鍵(Primary Key),如果創建表時沒有顯式地定義主鍵,則InnoDB存儲引擎會按照如下方式選擇或者創建主鍵:
首先判斷表中是否有非空的唯一索引(Unique NOT NULL),如果有,則該列即為主鍵;
如果不符合上述條件,InnoDB存儲引擎將選擇建表時定義一個非空唯一索引主鍵。注意,主鍵的選擇是根據的是定義索引的順序,而不是建表時列的順序。
?
?
InnoDB邏輯存儲結構
?
在InnoDB中所有的數據都被邏輯地存放在一個空間中,稱之為表空間(tablespace)。表空間又由段(segment)、區(extent)、頁(page)組成。頁在一些文檔中也稱之為塊(block)。
?
圖 InnoDB邏輯存儲結構
表空間
?
?
段
?
區
?
頁
?
行
?
?
InnoDB行記錄格式
?
InnoDB存儲引擎和大多數的數據庫一樣,記錄是以行的形式存在的。即頁中保存著表中一行行的數據。
在InnoDB 1.0.x版之前,InnoDB引擎提供了Compact和Redundant兩種格式來存放行記錄數據,這也是目前用得最多的,Redundant是為了兼容之前的版本而保留的。
數據庫實例的作用之一就是讀取頁中存放的行記錄。如果用戶知道野種行記錄的組織規則,也可以自行編寫工具讀取記錄。
?
分表講了一下Compact行記錄格式和Redundant行記錄格式。
?
?
行溢出數據
?
?
Compressed和Dynamic行記錄格式
?
Char個行記錄格式
?
InnoDB數據頁結構
?
頁是InnoDB引擎管理數據庫的最小磁盤單位。頁類型為B-tree Node的頁存放的即是表中行的實際數據了。
?
?
Named File Formats機制
?
InnoDB存儲引擎通過Named File Formats解決不同版本下頁結構的兼容性問題。
?
?
約束
?
?
視圖
?
分區表:水平分區和垂直分區
?
?
索引與算法
索引太多,程序的性能受到影響;
索引太少,查詢的性能又會受到影響。So,必須找到一個平衡點。
?
?
對于數據的使用,從一開始就應該添加索引。
開發人員往往對于數據庫的使用停留在應用層面,比如編寫SQL語句、存儲過程之類的,甚至不知道索引的存在。
DBA往往不夠了解業務的數據流,而添加索引需要通過監控大量的SQL語句進而從中找到問題。這個步驟所需的時間肯定大于當初添加索引所需要的時間。索引也不是越多越好,索引越多導致磁盤占用很高。
?
這里對索引的內部機制了解,通過了解內部索引來了解哪里可以使用索引。
?
InnoDB存儲引擎索引的概述
?
InnoDB支持的索引類型有:B+樹索引、全文索引、哈希索引
?
InnoDB支持的哈希索引是自適應的,InnoDB存儲引擎會根據表的使用情況自動為表生成哈希索引,不能人為干預是否在一張表中生成哈希索引。
自適應哈希索引
?
?
圖 全文索引
?
?
?
B+樹索引是傳統意義上的索引, 也是目前關系型數據庫中使用最多和最有效的索引。B不是binary的意思,而是balance的意思,可有效減少磁盤IO。
注意:B+樹索引并不能夠找到一個給定鍵值的具體行。B+樹索引只能找到被查詢數據行所在的頁。然后通過將其讀入內存,再在內存中進行查找。
?
?
?
?
?
數據結構與算法
?
關于B+ tree的
二分查找法(binary search):二分查找應用廣泛,思想易于理解,但是直到1962年才有了第一個完全正確的二分查找法。
?
二叉查找樹和平衡二叉樹
?
B+樹和二叉樹、平衡二叉樹一樣都是經典的數據結構。
B+樹由B樹和索引順序訪問方法(ISAM)演化而來,但是現實中已經沒有使用B樹的情況了。
B+樹的定義很復雜,總而言之:B+樹是為磁盤或其他直接存取輔助設備設計的一種平衡查找樹。
?
圖 高度為2的B+樹
?
B+樹的插入操作
B+樹的插入必須保證插入以后葉子節點中的記錄依然排序,同時要考慮到插入到B+樹中的三種情況,每個情況都有不同的插入算法。
圖 B+樹插入數據的三種不同情況
?
不管怎么插入數據,B+樹總是會保持平衡,但是為了平衡性,對新插入的鍵值可能需要做大量的拆分頁(split)操作。
因為B+樹結構主要用于磁盤,頁的拆分意味著磁盤操作,所以應當盡量減少頁的拆分操作。
所以B+樹提供了類似于平衡二叉樹的旋轉(Rotation)功能。
?
旋轉發生在Leaf Page已滿,但是左右兄弟節點沒有滿的情況下,B+樹不會急于做拆分操作,而是將記錄轉移到所在頁的兄弟節點上。
通常會先對左兄弟檢查來做旋轉操作。采用旋轉操作使得B+樹減少了一次頁的拆分操作。
?
B+樹的刪除操作
B+樹使用填充因子(fill factor)來控制樹的刪除變化,50%是填充因子的最小值。B+樹的刪除操作同樣必須保證刪除后葉子節點中的記錄依然排序,刪除也要考慮三種情況:
如果刪除之后,Fill Factor小于50%,那么需要做合并操作。
?
B+樹索引
?
B+樹索引的本質就是B+樹在數據庫中的實現。但是B+樹在數據庫中的特點是高扇出性,什么鬼?就是葉節點多。
因此數據庫中,B+樹的高度一般都是在2~4層,也就是說查找某一鍵值最多需要2到4次IO。2~4次IO意味著查詢時間只要0.02~0.04秒。
?
?
?
?
數據庫中的B+樹索引可以分為聚集索引(clustered index)和輔助索引(secondary index)。
?
聚集索引
?
圖 聚集索引
?
圖 聚集索引
?
?
圖 聚集索引和非聚集索引的區別
?
InnoDB存儲引擎表是索引組織表,即表中的數據按照主鍵順序存放。
而聚集索引(clustered index)就是按照每張表的主鍵構造一顆B+樹,同時葉子節點中存放的即為整張表的行記錄數據,也將聚集索引的葉子節點稱為數據頁。
聚集索引的這個特性決定了索引組織表中數據也是索引的一部分。同B+樹數據結構一樣,每個數據頁都通過一個雙向鏈表來進行鏈接。
?
由于實際的數據頁只能按照一顆B+樹進行排序,因此每張表只能擁有一個聚集索引。在多數情況下,查詢優化器傾向于采用聚集索引,
因為聚集索引能夠在B+樹索引的葉子節點上直接找到數據。
此外由于定義了數據的邏輯順序,聚集索引能夠特別快地訪問針對范圍值的查詢。查詢優化器能夠快速地發現某一段范圍的數據頁需要掃描。
?
圖 聚集索引中的數據查找
?
圖 非聚集索引中的數據查找
注意,聚集索引如果按照特定的順序存放物理數據,那么維護成本會很高。所以聚集索引的存儲并不是物理上連續的,而是邏輯上連續的。
其中有兩點:一時前面說到的頁通過雙向鏈表鏈接,頁按照主鍵的順序排序;
另一點是每個頁中的記錄也是通過雙向鏈表進行維護的,物理存儲上可以同樣不按照主鍵存儲。
?
?
聚集索引的另一個好處是,它對于主鍵的排序查找和范圍查找的速度非常快,葉子節點的數據就是用戶所要查找的數據。
?
雖然有通過order by進行排序,但是實際過程中并不會進行所謂的filesort,這是聚集索引的特點之一。
?
另一個是范圍查找,即如果要查找主鍵某一范圍內的數據,通過葉子節點的上層中間節點就可以得到頁的范圍,之后直接讀取數據頁即可。
?
輔助索引
?
輔助索引(secondary index),也成為非聚集索引,葉子節點并不包含記錄的全部數據。葉子節點除了包含鍵值以外,每個葉子節點中還會包含了一個書簽(bookmark)。
該書簽用來告訴InnoDB存儲引擎哪里可以找到與索引對應的行數據。
由于InnoDB存儲引擎是索引組織表,因此InnoDB存儲引擎的輔助索引的書簽就是相應行數據的聚集索引鍵。
?
輔助索引的存在并不影響數據在聚集索引中的組織,因此每張表上可以有多個輔助索引。當通過輔助索引來尋找數據時,InnoDB存儲引擎會遍歷輔助索引并通過葉級別的指針
獲得指向主鍵索引的主鍵,然后再通過主鍵索引來找到一個完整的行記錄。
?
注意:輔助索引并不需要讀取數據頁,輔助索引中并不存放數據,全都是索引
?
圖 非聚集索引
?
?
圖 非聚集索引
?
?
圖 聚集索引與非聚集索引
上面這張圖表現的還不錯哦。
?
稱為堆表的表類型是將行數據按照插入的順序存放,堆表的特性決定了堆表上的索引都是非聚集索引,主鍵與非主鍵的區別只是是否唯一且非空(NOT NULL)。
此時書簽是一個行標識(Row Identifier, RID),可以用如"文件號:頁號:槽號"的格式來定位實際的數據行。
?
某些情況下堆表的確要比索引組織表更快,但也要考慮到數據是否需要更新,并且更新是否影響到物理地址的變更。
同時也不能忽視排序和查找。
非聚集索引的離散讀,但是一般的數據庫都通過實現預讀(read ahead)技術來避免多次的離散讀操作。
因此建立索引組織表還是堆表取決于具體應用。
?
圖 預讀
?
B+樹索引的分裂
?
之前講到的B+樹的分裂是最為簡單的一種情況,在數據庫中的B+樹分裂則有所不同。
因為之前的B+樹分裂并沒有涉及到并發,這是最難的一部分。
圖 B+樹的分裂
圖 B+樹的分裂
?
B+樹的分裂也并不總是從中間開始,這樣會導致頁空間的浪費。
?
?
InnoDB存儲引擎的Page Header中有以下幾個部分用來保存插入的順序信息:
PAGE_LAST_INSERT
PAGE_DIRECTION
PAGE_N_DIRECTION
通過這些信息,InnoDB存儲引擎可以決定是向左還是向右分裂,同時決定將分裂點記為哪一個。
?
?
B+樹索引的管理
?
索引的創建和刪除可以通過兩種方法,一種是ALTER TABLE,另一種是CREATE/DROP INDEX。
?
用戶可以設置對整個列的數據進行索引,也可以只索引一個列的開頭部分。
?
SHOW INDEX可以查看表中的索引信息。
?
Fast Index Creation
?
對于索引添加或者刪除這類DDL操作,MySQL數據庫的操作過程為:
首先創建一張新的臨時表,表結構為通過命令ALTER TABLE新定義的結構
然后把原表中數據導入到臨時表中
接著刪除原表
最后把臨時表重命名為原來的表名。
?
?
如果對一張很大的表進行索引的添加和刪除操作,那么將耗費較長時間,更關鍵的是,若有大量事物需要訪問正在被修改的表,這意味著數據庫不可用。
?
InnoDB從 1.0.x開始支持一種稱為FIC(快速索引創建)的索引創建方式。
?
對于輔助索引的創建,InnoDB存儲引擎會對創建索引的表上加一個S鎖。在創建的過程中不需要重建表。
?
刪除輔助索引則更為簡單了,InnoDB存儲引擎只需要更新內部視圖,并將輔助索引的空間標記為可用,同時刪除MySQL數據庫內部視圖上對該表的索引定義即可。
?
?
?
Online Schema Change
?
The openarkkit toolkit oak-online-alter-table
?
Online DDL
?
?
Cardinality值
?
?
什么是Cardinality
并不是在所有的查詢條件中出現的列都需要添加索引。
一般的經驗是,在訪問表中很少一部分時使用B+樹索引才有意義。
對于性別字段、地區字段、類型字段,它們的取值的范圍很小,稱為低選擇性。
?
?
相反,如果某個字段的取值范圍很廣,幾乎沒有重復,即屬于高選擇性,則此時使用B+樹索引是非常合適的。
?
?
如果查看索引是否是高選擇性的呢?
?
可以通過SHOW INDEX結果列中的Cardinality來觀察。
Cardinality值非常關鍵,表示索引中不重復記錄數量的預估值。
同時需要注意的是Cardinality是一個預估值,而不是準確值。
在實際應用中,Cardinality/n_rows_in_table應盡可能接近1,如果非常小,那么用戶需要考慮是否還有必要建立這個索引。
?
?
B+樹索引的使用
?
不同應用中使用B+樹索引
聯合索引
覆蓋索引
?
優化器選擇不使用索引的情況
?
?
索引提示
?
?
Multi-Range Read優化
?
?
ICP優化
?
?
哈希算法
?
InnoDB存儲引擎中的哈希算法
?
自適應哈希算法
?
全文檢索
?
?
鎖
?
?
開發多用戶的系統時,最大的難點在于:一方面要最大程度利用數據庫的并發訪問,另外一方面還要確保每個用戶能以一致的方式讀取和修改數據。
為此就需要鎖機制。
鎖也是數據庫區別于文件系統的一個關鍵特性。
?
這部分學習的是InnoDB如何對表中的數據進行鎖定,以及以怎樣的粒度鎖定數據。
?
?
什么是鎖?
?
?
鎖機制用于管理共享資源的并發訪問。InnoDB存儲引擎會在行級別上對表數據上鎖。
?
除了對數據表進行上鎖之外,InnoDB也會在內部對其他的很多資源使用鎖,從而允許對多種不同資源提供并發訪問。
例如操作緩沖池中的LRU列表,刪除、添加、移動LRU列表中的元素,為了保證一致性,必須有鎖的介入,從而提供完整性和一致性。
?
對于MyISAM引擎,其鎖是表鎖設計,并發情況下的讀沒有問題,但是并發插入時的性能就要差一些。
?
?
lock與latch
?
在數據庫中lock和latch都可以被稱為鎖,但是兩者的含義截然不同。
?
latch一般稱為閂鎖,因其要求鎖定的時間必須非常短,若持續的時間長,則應用性能會很差。在InnoDB存儲引擎中,latch有可以分為mutex(互斥量)和rolock(讀寫鎖)。其目的使用來保證并發線程操作臨界資源的正確性,并且通常沒有檢測死鎖的機制。
?
lock的對象是事務,用來鎖定的是數據庫中的對象,如表、頁、行。并且一般lock的對象僅在事務commit或者rollback后進行釋放(不同事務隔離級別釋放的時間可能不同)。lock是有死鎖機制的。
?
?
?
?
SHOW ENGINE INNODB MUTEX可以查看InnoDB存儲引擎中的latch,輸出結果的解釋如下:
以上的信息都是比較底層的,一般僅供開發人員參考,但是用戶還是可以使用這些參數進行調優。
?
?
InnoDB存儲引擎中的鎖
?
鎖的類型
?
InnoDB存儲引擎實現了如下兩種標準的行級鎖:
共享鎖(S Lock),允許事務讀一行數據。
排他鎖(X Lock),允許事務刪除或更新一行數據。
?
?
如果一個事務T1已經獲取行r的共享鎖,那么另外的事務T2可以立即獲取行r的共享鎖,因為讀取并沒有改變行r的數據,這種情況稱為鎖兼容(Lock Compatible)。
但若有其他的事務T3想獲取行r的排他鎖,則其必須等待事務T1、T2釋放行r上的共享鎖——稱之為鎖不兼容。
?
X鎖與任何鎖都不兼容,而S鎖僅與S鎖兼容。需要注意的是X和S都是行鎖,兼容是指對同一記錄(row)鎖的兼容情況。
?
此外InnoDB存儲引擎支持多粒度(granular)鎖定,這種鎖定允許事務在行級別上的鎖和表級上的鎖同時存在。
?
為了支持不同粒度上的鎖,InnoDB存儲引擎有一個額外的鎖方式,稱之為意向鎖(Intention Lock)。意向鎖是將鎖定的對象分為多個層次,意向鎖意味著事務希望在更細粒度(fine granularity)上進行加鎖。
?
如果把上鎖的對象看做一顆樹,那么對最下層的對象上鎖,也就是對最細粒度的對象上鎖,那么首先需要對粗粒度的對象上鎖。
?
如需對頁上的記錄r進行上X鎖,那么分別需要對數據庫A、表、頁上意向鎖IX,最后對記錄r上X鎖。
其中任何一部分導致等待,那么該操作需要等待粗粒度鎖的完成。
?
舉例就是,對記錄r加X鎖之前,已經有事務對表1進行了S表鎖,那么表1上已經存在了S鎖,之后事務需要對記錄r在表上加IX,由于不兼容,所以對該事務需要等待表鎖操作的完成。
?
InnoDB存儲引擎支持的意向鎖設計比價簡單,其意向鎖為表級別的鎖。設計目的主要是為了在一個事務中揭示下一行將被請求的鎖類型。
1. 意向共享鎖(IS Lock),事務想要獲得一張表中某幾行的共享鎖
2. 意向排他鎖(IX Lock),事務想要獲得一張表中某幾行的排他鎖
?
由于InnoDB存儲引擎支持的是行級別的鎖,因此意向鎖其實不會阻塞除全表掃描以外的任何請求。
?
?
用戶可以通過命令SHOW ENGINE INNODB STATUS命令來查看當前鎖請求的信息。
?
可以看到SQL語句select * from? where a<4 lock in share mode在等待,
RECORD LOCKS space id 30 page no 3 n bits 72 index 'PRIMARY' of table 'test'.'t' trx id 48B89DB lock_mode X locks rec but not gap表示鎖住的資源。
locks rec but not gap代表鎖住的是一個索引,不是一個范圍。
?
在InnoDB 1.0版本之前,用戶只能通過命令SHOW FULL PROCESSLIST,SHOW ENGINE INNODB STATUS等來查看當前數據庫中的鎖請求,然后再判斷事務鎖的情況。
從InnoDB1.0開始,INFORMATION_SCHEMA架構下添加了表INNODB_TRX、INNODB_LOCKS、INNODB_LOCK_WAITS。
通過這三張表,用戶可以更加單地監控當前事務并分析可能存在的問題。
?
?
?
?
一致性非鎖定讀(consistent nonlocking read)指的是InnoDB存儲引擎通過多行版本控制(multi versioning)的方式來讀取當前執行時間數據庫中行的數據。
?
如果讀取的行正在執行DELETE或者UPDATE操作,這時讀取操作不會因此去等待行上鎖的釋放,相反的,InnoDB存儲引擎會讀取行的一個快照數據。
?
?
?
之所以成為非鎖定讀,是因為不需要等待訪問的行上X鎖的釋放。
?
快照數據是指該行的之前版本的數據,該實現是通過undo段來完成。而undo用來在事務中回滾數據,因此快照數據本身是沒有額外的開銷。
此外快照數據的讀取是不需要上鎖的,因為沒有事務需要對歷史數據進行修改操作。
?
?
非鎖定讀機制極大提高了數據庫的并發性。
在InnoDB存儲引擎的默認設置下,這是默認的讀取方式,即讀取不會占用和等待表上的鎖。
?
但是在不同事務隔離級別下,讀取的方式不同,并不是在每個事務隔離級別下都是采用非鎖定的一致性讀。
此外即使使用非鎖定的一致性讀,但是對于快照數據的定義也各不相同。
?
快照數據就是當前行數據之前的歷史版本,每行記錄可能有多個版本。一行記錄可能有不止一個快照數據,一般稱這種技術為行多版本控制,由此帶來的并發控制,
稱為多版本并發控制(Multi Version Concurrency Control,MVCC)。
?
在事務隔離級別READ COMMITTED和REPEATABLE READ(InnoDB存儲引擎默認的隔離級別)下,InnoDB存儲引擎使用的是非鎖定的一致性讀。
然后對于快照數據的定義卻不一樣。
?
在READ COMMITTED事務隔離級別下,對于快照數據,非一致性讀總是讀取被鎖定行的最新一份快照數據(fresh snapshot)。
而在REPEATEABLE READ事務隔離級別下,對于快照數據,非一致性讀總是讀取事務開始時的行數據版本。
?
?
BEGIN;
COMMIT;
?
?
?
非一致性鎖定讀
?
在默認配置下,即事務隔離級別為REPEATABLE READ模式下,InnoDB存儲引擎的SELECT操作使用一致性非鎖定讀。
但是在某些情況下,用戶需要顯式地對數據庫操作進行加鎖以保證數據邏輯的一致性。
而這要求數據庫支持加鎖語句,即使對于SELECT的只讀操作。
InnoDB存儲引擎對于SELECT語句支持兩種一致性的鎖定讀(locking read)操作:
SELECT ..... FOR UPDATE
SELECT ..... LOCK IN SHARE MODE
?
SELECT ...... FOR UPDATE對讀取的行記錄加一個X鎖,其他事物不能對已鎖定的行加上任何鎖。
SELECT ...... LOCK IN SHARE MODE對讀取的行記錄加一個S鎖,其他事務可以向被鎖定的行加S鎖,但是如果加X鎖,則會被阻塞。
?
?
對于一致性非鎖定讀,即使讀取的行已被執行了SELECT ..... FOR UPDATE,也是可以進行讀取的。
此外,SELECT .... FOR UPDATE,SELECT ...... LOCK IN SHARE MODE必須在一個事務中,當事務提交了,鎖也就被釋放了。
?
因此在使用上面兩句SELECT的時候,務必加上begin,start transaction或者set autocommit=0。
?
?
自增長和鎖
?
外鍵和鎖
?
?
?
鎖的算法
?
行鎖的三種算法:
Record Lock:單行記錄的鎖
Gap Lock:間隙鎖,鎖定一個范圍,但不包含記錄本身
Next-key Lock:Gap Lock + Record Lock,鎖定一個范圍,并鎖定記錄本身
?
解決Phantom Problem
?
?
鎖問題
?
臟讀
?
臟讀就是指在不同的事務下,當前事務讀到了另外事務未提交的數據。
?
不可重復讀
?
丟失更新
?
?
阻塞
?
?
死鎖
?
死鎖的概念
?
?
死鎖概率
?
?
死鎖示例
?
鎖升級
?
事務
?
數據庫中事務的目的:事務會把數據庫從一種一致狀態轉為另一種一致狀態。
在數據庫提交工作時,要么確保所有修改都已經保存了,要么所有修改都不保存。
?
ACID
原子性(atomicity)
一致性(consistency)
隔離性(isolation)
持久性(durability)
?
認識事務
?
事務有著嚴格的定義,必須同時滿足四個特性,但是數據庫廠商出于各種目的,并沒有嚴格去滿足事務的ACID標準。
對于InnoDB存儲引擎而言,其默認的事務隔離級別READ REPEATABLE,完全遵循和滿足事務的ACID特性。
?
分別介紹事務的四個特性
?
事務的分類
?
扁平事務(Flat Transaction)
帶有保存點的扁平事務(Flat Transaction with Savepoints)
鏈事務(Chained Transactions)
嵌套事務(Nested Transactions)
分布式事務(Distributed Transactions)
?
?
?
事務的實現
?
?
事務控制語句
?
隱式提交的SQL語句
?
?
對事物操作的統計
?
每秒事務處理能力(Transaction Per Second)
?
事務的隔離級別
?
?
分布式事務
?
?
不好的事務習慣
?
?
長事務
?
?
備份與恢復
?
?
?