MySQL InnoDB存儲引擎

呵呵噠。。。

?

MySQL體系結構和存儲引擎

首先要搞懂的是什么是數據庫,什么是數據庫實例。

數據庫:物理操作系統文件或其他形式文件類型的集合。

實例:MySQL數據庫由后臺線程以及一個共享內存區組成,實例才是真正對數據庫進行操作的。

譬如:數據庫就像蓋樓所需的石頭、砂和水泥等原材料,而正在使用這些原材料蓋樓的施工隊則是實例,哈哈。

?

MySQL實例啟動的方法有很多種,啟動時讀取配置文件,如果配置文件有多個,而且配置項又有很多相同的,那么會以最后讀到的配置項為準。

?

數據庫實例是一層數據庫管理軟件,用戶不能直接地操縱數據庫,只能通過實例提供的接口來訪問數據庫。

psearch

圖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體系架構

?

image

圖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)。

?

image

圖 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,必須找到一個平衡點。

?

image

?

對于數據的使用,從一開始就應該添加索引。

開發人員往往對于數據庫的使用停留在應用層面,比如編寫SQL語句、存儲過程之類的,甚至不知道索引的存在。

DBA往往不夠了解業務的數據流,而添加索引需要通過監控大量的SQL語句進而從中找到問題。這個步驟所需的時間肯定大于當初添加索引所需要的時間。索引也不是越多越好,索引越多導致磁盤占用很高。

?

這里對索引的內部機制了解,通過了解內部索引來了解哪里可以使用索引。

?

InnoDB存儲引擎索引的概述

?

InnoDB支持的索引類型有:B+樹索引、全文索引、哈希索引

?

InnoDB支持的哈希索引是自適應的,InnoDB存儲引擎會根據表的使用情況自動為表生成哈希索引,不能人為干預是否在一張表中生成哈希索引。

image

自適應哈希索引

?

InvertedIndex

?

圖 全文索引

?

image

?

?

B+樹索引是傳統意義上的索引, 也是目前關系型數據庫中使用最多和最有效的索引。B不是binary的意思,而是balance的意思,可有效減少磁盤IO。

注意:B+樹索引并不能夠找到一個給定鍵值的具體行。B+樹索引只能找到被查詢數據行所在的頁。然后通過將其讀入內存,再在內存中進行查找。

image

?

?

image

?

image

?

?

數據結構與算法

?

關于B+ tree的

二分查找法(binary search):二分查找應用廣泛,思想易于理解,但是直到1962年才有了第一個完全正確的二分查找法。

?

二叉查找樹和平衡二叉樹

?

B+樹和二叉樹、平衡二叉樹一樣都是經典的數據結構。

B+樹由B樹和索引順序訪問方法(ISAM)演化而來,但是現實中已經沒有使用B樹的情況了。

B+樹的定義很復雜,總而言之:B+樹是為磁盤或其他直接存取輔助設備設計的一種平衡查找樹。

?

image

圖 高度為2的B+樹

?

B+樹的插入操作

B+樹的插入必須保證插入以后葉子節點中的記錄依然排序,同時要考慮到插入到B+樹中的三種情況,每個情況都有不同的插入算法。

image

圖 B+樹插入數據的三種不同情況

?

不管怎么插入數據,B+樹總是會保持平衡,但是為了平衡性,對新插入的鍵值可能需要做大量的拆分頁(split)操作。

因為B+樹結構主要用于磁盤,頁的拆分意味著磁盤操作,所以應當盡量減少頁的拆分操作。

所以B+樹提供了類似于平衡二叉樹的旋轉(Rotation)功能。

?

旋轉發生在Leaf Page已滿,但是左右兄弟節點沒有滿的情況下,B+樹不會急于做拆分操作,而是將記錄轉移到所在頁的兄弟節點上。

通常會先對左兄弟檢查來做旋轉操作。采用旋轉操作使得B+樹減少了一次頁的拆分操作。

?

B+樹的刪除操作

B+樹使用填充因子(fill factor)來控制樹的刪除變化,50%是填充因子的最小值。B+樹的刪除操作同樣必須保證刪除后葉子節點中的記錄依然排序,刪除也要考慮三種情況:

image

如果刪除之后,Fill Factor小于50%,那么需要做合并操作。

?

B+樹索引

?

B+樹索引的本質就是B+樹在數據庫中的實現。但是B+樹在數據庫中的特點是高扇出性,什么鬼?就是葉節點多。

因此數據庫中,B+樹的高度一般都是在2~4層,也就是說查找某一鍵值最多需要2到4次IO。2~4次IO意味著查詢時間只要0.02~0.04秒。

?

image

?

?

?

數據庫中的B+樹索引可以分為聚集索引(clustered index)和輔助索引(secondary index)。

?

聚集索引

?

image

圖 聚集索引

?

Clustered-Indexes

圖 聚集索引

?

?

clustereddiagram

圖 聚集索引和非聚集索引的區別

?

InnoDB存儲引擎表是索引組織表,即表中的數據按照主鍵順序存放。

而聚集索引(clustered index)就是按照每張表的主鍵構造一顆B+樹,同時葉子節點中存放的即為整張表的行記錄數據,也將聚集索引的葉子節點稱為數據頁。

聚集索引的這個特性決定了索引組織表中數據也是索引的一部分。同B+樹數據結構一樣,每個數據頁都通過一個雙向鏈表來進行鏈接。

?

由于實際的數據頁只能按照一顆B+樹進行排序,因此每張表只能擁有一個聚集索引。在多數情況下,查詢優化器傾向于采用聚集索引,

因為聚集索引能夠在B+樹索引的葉子節點上直接找到數據。

此外由于定義了數據的邏輯順序,聚集索引能夠特別快地訪問針對范圍值的查詢。查詢優化器能夠快速地發現某一段范圍的數據頁需要掃描。

?

ZnJvbT1jbmJsb2dzJnVybD1IQmxTdUVUTWpsR1V2UTNib1JYWnVCM2NoOVNidk4yWHpkMmJzSm1iajlTYnZObUx6ZDJic0ptYmo1eWNsZFdZdGwyTHZvRGMwUkhh

圖 聚集索引中的數據查找

?

ZnJvbT1jbmJsb2dzJnVybD1IQmxTdUFUTWpsR1V2UTNib1JYWnVCM2NoOVNidk4yWHpkMmJzSm1iajlTYnZObUx6ZDJic0ptYmo1eWNsZFdZdGwyTHZvRGMwUkhh

圖 非聚集索引中的數據查找

注意,聚集索引如果按照特定的順序存放物理數據,那么維護成本會很高。所以聚集索引的存儲并不是物理上連續的,而是邏輯上連續的。

其中有兩點:一時前面說到的頁通過雙向鏈表鏈接,頁按照主鍵的順序排序;

另一點是每個頁中的記錄也是通過雙向鏈表進行維護的,物理存儲上可以同樣不按照主鍵存儲。

?

?

聚集索引的另一個好處是,它對于主鍵的排序查找和范圍查找的速度非常快,葉子節點的數據就是用戶所要查找的數據。

?

雖然有通過order by進行排序,但是實際過程中并不會進行所謂的filesort,這是聚集索引的特點之一。

?

另一個是范圍查找,即如果要查找主鍵某一范圍內的數據,通過葉子節點的上層中間節點就可以得到頁的范圍,之后直接讀取數據頁即可。

?

輔助索引

?

輔助索引(secondary index),也成為非聚集索引,葉子節點并不包含記錄的全部數據。葉子節點除了包含鍵值以外,每個葉子節點中還會包含了一個書簽(bookmark)。

該書簽用來告訴InnoDB存儲引擎哪里可以找到與索引對應的行數據。

由于InnoDB存儲引擎是索引組織表,因此InnoDB存儲引擎的輔助索引的書簽就是相應行數據的聚集索引鍵。

?

輔助索引的存在并不影響數據在聚集索引中的組織,因此每張表上可以有多個輔助索引。當通過輔助索引來尋找數據時,InnoDB存儲引擎會遍歷輔助索引并通過葉級別的指針

獲得指向主鍵索引的主鍵,然后再通過主鍵索引來找到一個完整的行記錄。

?

注意:輔助索引并不需要讀取數據頁,輔助索引中并不存放數據,全都是索引

?

5_4_architecture_of_non_clustered_index1

圖 非聚集索引

?

?

Clustered-Indexes

圖 非聚集索引

?

?

nci2

圖 聚集索引與非聚集索引

上面這張圖表現的還不錯哦。

?

稱為堆表的表類型是將行數據按照插入的順序存放,堆表的特性決定了堆表上的索引都是非聚集索引,主鍵與非主鍵的區別只是是否唯一且非空(NOT NULL)。

此時書簽是一個行標識(Row Identifier, RID),可以用如"文件號:頁號:槽號"的格式來定位實際的數據行。

?

某些情況下堆表的確要比索引組織表更快,但也要考慮到數據是否需要更新,并且更新是否影響到物理地址的變更。

同時也不能忽視排序和查找。

非聚集索引的離散讀,但是一般的數據庫都通過實現預讀(read ahead)技術來避免多次的離散讀操作。

因此建立索引組織表還是堆表取決于具體應用。

?

unix-ch03032-21-638

圖 預讀

?

B+樹索引的分裂

?

之前講到的B+樹的分裂是最為簡單的一種情況,在數據庫中的B+樹分裂則有所不同。

因為之前的B+樹分裂并沒有涉及到并發,這是最難的一部分。

872539-20161107145043936-753882676

圖 B+樹的分裂

image

圖 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是有死鎖機制的。

?

image

?

?

?

SHOW ENGINE INNODB MUTEX可以查看InnoDB存儲引擎中的latch,輸出結果的解釋如下:

image

以上的信息都是比較底層的,一般僅供開發人員參考,但是用戶還是可以使用這些參數進行調優。

?

?

InnoDB存儲引擎中的鎖

?

鎖的類型

?

InnoDB存儲引擎實現了如下兩種標準的行級鎖:

共享鎖(S Lock),允許事務讀一行數據。

排他鎖(X Lock),允許事務刪除或更新一行數據。

?

?

如果一個事務T1已經獲取行r的共享鎖,那么另外的事務T2可以立即獲取行r的共享鎖,因為讀取并沒有改變行r的數據,這種情況稱為鎖兼容(Lock Compatible)。

但若有其他的事務T3想獲取行r的排他鎖,則其必須等待事務T1、T2釋放行r上的共享鎖——稱之為鎖不兼容。

image

?

X鎖與任何鎖都不兼容,而S鎖僅與S鎖兼容。需要注意的是X和S都是行鎖,兼容是指對同一記錄(row)鎖的兼容情況。

?

此外InnoDB存儲引擎支持多粒度(granular)鎖定,這種鎖定允許事務在行級別上的鎖和表級上的鎖同時存在。

?

為了支持不同粒度上的鎖,InnoDB存儲引擎有一個額外的鎖方式,稱之為意向鎖(Intention Lock)。意向鎖是將鎖定的對象分為多個層次,意向鎖意味著事務希望在更細粒度(fine granularity)上進行加鎖。

?

如果把上鎖的對象看做一顆樹,那么對最下層的對象上鎖,也就是對最細粒度的對象上鎖,那么首先需要對粗粒度的對象上鎖。

?

image

如需對頁上的記錄r進行上X鎖,那么分別需要對數據庫A、表、頁上意向鎖IX,最后對記錄r上X鎖。

其中任何一部分導致等待,那么該操作需要等待粗粒度鎖的完成。

?

舉例就是,對記錄r加X鎖之前,已經有事務對表1進行了S表鎖,那么表1上已經存在了S鎖,之后事務需要對記錄r在表上加IX,由于不兼容,所以對該事務需要等待表鎖操作的完成。

?

InnoDB存儲引擎支持的意向鎖設計比價簡單,其意向鎖為表級別的鎖。設計目的主要是為了在一個事務中揭示下一行將被請求的鎖類型。

1. 意向共享鎖(IS Lock),事務想要獲得一張表中某幾行的共享鎖

2. 意向排他鎖(IX Lock),事務想要獲得一張表中某幾行的排他鎖

?

由于InnoDB存儲引擎支持的是行級別的鎖,因此意向鎖其實不會阻塞除全表掃描以外的任何請求。

?

image

?

用戶可以通過命令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。

通過這三張表,用戶可以更加單地監控當前事務并分析可能存在的問題。

?

image

image

?

image

?

?

一致性非鎖定讀(consistent nonlocking read)指的是InnoDB存儲引擎通過多行版本控制(multi versioning)的方式來讀取當前執行時間數據庫中行的數據。

?

如果讀取的行正在執行DELETE或者UPDATE操作,這時讀取操作不會因此去等待行上鎖的釋放,相反的,InnoDB存儲引擎會讀取行的一個快照數據。

?

image

?

?

之所以成為非鎖定讀,是因為不需要等待訪問的行上X鎖的釋放。

?

快照數據是指該行的之前版本的數據,該實現是通過undo段來完成。而undo用來在事務中回滾數據,因此快照數據本身是沒有額外的開銷。

此外快照數據的讀取是不需要上鎖的,因為沒有事務需要對歷史數據進行修改操作。

?

?

非鎖定讀機制極大提高了數據庫的并發性。

在InnoDB存儲引擎的默認設置下,這是默認的讀取方式,即讀取不會占用和等待表上的鎖。

?

但是在不同事務隔離級別下,讀取的方式不同,并不是在每個事務隔離級別下都是采用非鎖定的一致性讀。

此外即使使用非鎖定的一致性讀,但是對于快照數據的定義也各不相同。

?

快照數據就是當前行數據之前的歷史版本,每行記錄可能有多個版本。一行記錄可能有不止一個快照數據,一般稱這種技術為行多版本控制,由此帶來的并發控制,

稱為多版本并發控制(Multi Version Concurrency Control,MVCC)。

?

在事務隔離級別READ COMMITTED和REPEATABLE READ(InnoDB存儲引擎默認的隔離級別)下,InnoDB存儲引擎使用的是非鎖定的一致性讀。

然后對于快照數據的定義卻不一樣。

?

在READ COMMITTED事務隔離級別下,對于快照數據,非一致性讀總是讀取被鎖定行的最新一份快照數據(fresh snapshot)。

而在REPEATEABLE READ事務隔離級別下,對于快照數據,非一致性讀總是讀取事務開始時的行數據版本。

?

?

BEGIN;

COMMIT;

?

image

?

?

非一致性鎖定讀

?

在默認配置下,即事務隔離級別為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)

?

事務的隔離級別

?

?

分布式事務

?

?

不好的事務習慣

?

?

長事務

?

?

備份與恢復

?

?

?

性能調優

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/280676.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/280676.shtml
英文地址,請注明出處:http://en.pswp.cn/news/280676.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Blazor學習之旅 (8) MudBlazor組件庫介紹

【Blazor】| 總結/Edison Zhou大家好&#xff0c;我是Edison。為了實現一個Web應用系統&#xff0c;需要有個看起來不丑的UI&#xff0c;而對于.NET程序員來說要做全棧開發還是有點難&#xff0c;而本篇介紹的這個UI組件庫正好可以幫助我們解決這個問題&#xff01;MudBlaozr是…

棉花糖多少錢_如何在6.0棉花糖及更高版本中訪問Android的正在運行的應用程序列表...

棉花糖多少錢In Android 5.x and below, accessing your list of running apps was simple—you’d jump into Settings > Apps > Running. Easy! In Android 6.0, however, Google moved this setting. It’s still not super difficult to find, but it’s a little tr…

IE不能直接顯示PDF的原因分析和解決方法

>>>>>問題<<<<<因為有系統用iframe顯示PDF&#xff0c;但PDF有時卻并不能順利地在流覽器中顯示&#xff0c;而是跳出下載對話框&#xff0c;要求下載&#xff0c;給user帶來很多困擾&#xff0c;也給我們系統維護人員帶來了麻煩&#xff0c;用了…

C# 程序圖標設置/winform 圖標

一、目的、實際情況 1.編寫一個winform 程序&#xff0c;發現有一個圖標非常有意義。區分其他程序&#xff0c;以及感覺在做產品而不是寫代碼。 2.添加圖標圖片發現&#xff0c;需要用ico格式。在線轉換&#xff08;某度搜索&#xff09;還是不靠譜。要微信登陸&#xff0c;登…

數字化轉型,究竟在“轉”什么?

這是頭哥侃碼的第265篇原創「頭哥嘮B嘮」這個欄目已經持續了幾個月了&#xff0c;沒想到還在繼續進行&#xff0c;并收獲了很多朋友們的喜愛。非常感謝大家的支持&#xff01;在上次的直播中&#xff0c;我找來了我的老熟人們。一個是右軍老師&#xff0c;之前 APISIX 的很多內…

C++ Primer 第Ⅲ部分筆記——類設計者的工具

1.對象移動 1.1右值引用 右值引用區別于普通引用&#xff0c;用兩個&表示 返回左值引用的函數&#xff0c;連同賦值、下標、解引用和前置遞增遞減運算符返回左值 返回非引用的函數&#xff0c;連同算術、關系、位以及后置遞增遞減運算符都生成右值 我們不能將左值引用綁定到…

Crash 的文明世界

題目描述 給一棵樹&#xff0c;求以每個點為根時下列式子的值。 題解 當k1時這就是一個經典的換根dp問題。 所以這道題還是要用換根dp解決。 部分分做法&#xff1a; 考慮轉移時是這樣的一個形式(圖是抄的)。 用二項式定理展開就可以nk2做了。 觀察到結果是一個xk的形式。 然后…

wampServer配置WWW根目錄遇到的坑

直接在官網下載之后開始安裝&#xff0c;一切正常 打開使用&#xff0c;一切正常 設置WWW目錄。坑了一波 按照的都是百度上的教程&#xff0c;設置httpd.conf 這里配置之后網頁訪問127.0.0.1 還是localhost都還是原始的www目錄 后來 我發現了這里 是配置虛擬URL的地方。以上是正…

windows安裝程序創建_如何在Windows上創建已安裝程序的列表

windows安裝程序創建Reinstalling Windows is a good way to fix serious problems with your computer, or just to get a fresh slate. But before you reinstall Windows, you should make a list of programs you currently have installed on your PC so you know what yo…

實現一個更新所有 dotnet tool 的 dotnet tool

實現一個更新所有 dotnet tool 的 dotnet toolIntrodotnet tool 是從 .NET Core 2.1 開始支持的命令行工具&#xff0c;在使用 dotnet tool 比較多了的時候&#xff0c;想要更新所有的 dotnet tool 就比較麻煩&#xff0c;而目前 .NET SDK 還不支持&#xff0c;也有一些人希望能…

C# 普通權限運行程序\非管理員運行\降低權限運行

一、目的與實際 1.VS設置管理員權限運行程序后&#xff0c;發現調用powershell命令或程序需要普通權限即可&#xff0c;Administrator權限反而錯。 2.網上搜索關鍵字&#xff0c;大部分都是怎么使用管理員權限運行。 3.bing搜索意外發現有相關資料&#xff0c;記錄分享。 二…

am335x PDK3.0 設置為單網口配置記錄

原來的配置是雙網口的&#xff0c;現在要配置為單網口。一直以為這個配置是在 make menuconfig 里面&#xff0c; 沒想到是在設備樹里面。修改設備樹// vim arch/arm/boot/dts/am335x-sbc7109.dts722 &mac {723 pinctrl-names "default", "sleep"…

[AHOI2009]飛行棋 BZOJ1800

題目描述 給出圓周上的若干個點&#xff0c;已知點與點之間的弧長&#xff0c;其值均為正整數&#xff0c;并依圓周順序排列。 請找出這些點中有沒有可以圍成矩形的&#xff0c;并希望在最短時間內找出所有不重復矩形。 輸入輸出格式 輸入格式&#xff1a;第一行為正整數N&…

webapi+Quartz.NET解決若干定時程序同時運行的問題

項目現狀&#xff1a; 有若干定時程序需要自啟動運行&#xff0c;為了簡便程序部署等問題&#xff0c;采取這種辦法把定時程序集中管理到webapi中跟隨api發布 代碼架構介紹&#xff1a; 新建一個類庫&#xff0c;類庫引用Quartz&#xff08;Quartz.2.3.2&#xff09;&#xff0…

mac恢復iphone_免費下載:舊Mac和iPhone壁紙的令人震驚的完整檔案

mac恢復iphoneLove or hate Apple, you’ve got to admit: their background images are consistently stunning. Now you can download all of them. 愛或恨蘋果&#xff0c;您必須承認&#xff1a;它們的背景圖像始終令人贊嘆。 現在&#xff0c;您可以下載所有這些文件。 A …

Django01-1: request 方法

#POST request.method #返回全大寫字符穿&#xff0c;<class str> POST/GETrequest.POST #用戶提交數據&#xff0c;不包含文件 #<QueryDict>request.POST.get(hobby) #拿列表最后一個 request.POST.getList(hobby) #拿多個&#xff0c;列表全部#GET 獲取url &a…

Magicodes.IE 2.7.1發布

2.7.12022.12.01Magicodes.IE.EPPlus默認添加SkiaSharp.NativeAssets.Linux.NoDependencies包&#xff0c;以便于在Linux環境下使用導入驗證支持將錯誤數據通過Stream的方式返回&#xff0c;感謝sampsonye &#xff08;見pr#466&#xff09;2.7.02022.11.07添加SkiaSharp移除Si…

Oracle監聽的靜態注冊和動態注冊

靜態注冊&#xff1a;通過解析listene.ora文件 動態注冊&#xff1a;由PMON進程動態注冊至監聽中 在沒有listener.ora配置文件的情況下&#xff0c;如果啟動監聽&#xff0c;則監聽為動態注冊。用圖形化netca創建的監聽&#xff0c;默認也為動態注冊 1.靜態注冊 listener.ora文…

AKOJ-1695-找素數

題意&#xff1a; 給定區間L&#xff0c;R。 計算區間中素數個數。 2 < L,R < 2147483647, R-L < 1000000。 思路&#xff1a; 素數區間篩 先篩(2-sqrt(r))。 再用(2-sqrt(r))中的素數篩(l-r)。 代碼: 1.自己寫的區間篩&#xff0c;將篩2-sqrt&#xff08;r) 分開了。…

Spring 環境與profile(一)——超簡用例

什么是profile,為什么需要profile? 在開發時&#xff0c;不同環境&#xff08;開發、聯調、預發、正式等&#xff09;所需的配置不同導致&#xff0c;如果每改變一個環境就更改配置不但麻煩&#xff08;修改代碼、重新構建&#xff09;而且容易出錯。Spring提供了解決方案。 方…