《InnoDB存儲引擎》筆記

来源:https://www.cnblogs.com/fhwup/archive/2018/03/17/8587840.html
-Advertisement-
Play Games

第1章 Mysql體繫結構和存儲引擎 1.1 定義資料庫和實例 資料庫:database,物理的操作系統文件或其他形式文件類型的集合。當使用NDB存儲引擎時,資料庫文件可能是存放在記憶體中而不是磁碟之上。 實例:instance,Mysql資料庫實例由後臺線程和一個共用記憶體區組成。實例才是真正用於操作 ...


第1章 Mysql體繫結構和存儲引擎 1.1 定義資料庫和實例 資料庫:database,物理的操作系統文件或其他形式文件類型的集合。當使用NDB存儲引擎時,資料庫文件可能是存放在記憶體中而不是磁碟之上。 實例:instance,Mysql資料庫實例由後臺線程和一個共用記憶體區組成。實例才是真正用於操作資料庫文件的。   1.2 Mysql體繫結構 mysql由以下幾部分組成:連接池組件、管理服務和工具組件、SQL介面組件、查詢分析器組件、優化器組件、緩衝組件、插件式存儲引擎、物理文件。 mysql體繫結構圖: mysql架構圖:   1.3 Mysql存儲引擎 OLTP是線上事務處理,讀少寫多;OLAP是線上分析處理,讀多寫少。 (1)InnoDB存儲引擎 從mysql 5.5.8開始,InnoDB是預設存儲引擎,主要面向OLTP。 特點:支持事務、行鎖設計、支持外鍵、支持非鎖定讀(預設讀取不會產生鎖)。 InnoDB將數據存放在一個邏輯表空間里,每張表單獨存放到一個獨立的ibd文件。使用MVCC(多版本併發控制)來獲得高併發性,預設隔離級別為可重覆讀。另外還提供了插入緩衝(Insert buffer)、二次寫(double write)、自適應哈希索引(adaptive hash index)、預讀(read ahead)等高性能和高可用的功能。 表中數據存儲採用聚集(cluster)方式,每張表的存儲都是按主鍵順序。當表沒有顯示指定主鍵時,會生成一個6位元組的ROWID做為主鍵。   (2)MyISAM存儲引擎 mysql 5.5.8之前是預設存儲引擎,主要面向OLAP。 特點:不支持事務、表鎖設計、支持全文檢索、緩衝池只緩衝索引文件不緩衝數據文件。 表由MYD數據文件和MYI索引文件組成。其中數據文件可以壓縮。   (3)NDB存儲引擎 是一個高可用、高性能的集群存儲文件,類似oracle的RAC集群。 特點:數據全部放在記憶體、主鍵查找速度極快、通過添加集群節點來線性提高資料庫性能、類似Join的複雜操作在Mysql上層完成而開銷大速度慢。   (4)Memory存儲引擎 數據存放在記憶體中、適合存儲臨時數據的臨時表,預設採用哈希索引,而不是B+樹索引。 特點:數據存放在記憶體崩潰會丟失、只支持表鎖、併發性能差、不支持TEXT和BLOB列類型。 mysql查詢中間結果集的臨時表會放在Memory存儲引擎。   (5)Archive存儲引擎 設計目標主要提供高速插入和壓縮,適合存儲歸檔數據。 特點:只支持Insert和Select操作、數據行壓縮。   (6)Maria存儲引擎 新開發的用來取代MyISAM,從而成為預設存儲引擎。 特點:支持緩存數據和索引文件、行鎖設計、提供MVCC、支持事務和非事務選項、更好的BLOB字元類型處理性能。     第2章 InnoDB存儲引擎 2.1 InnoDB存儲引擎概述 是Innobase Oy公司開發,其創始人和linus是芬蘭赫爾辛基大學校友。   2.2 InnoDB體繫結構 (1)後臺線程 ①Master Thread 負責將緩衝池中的數據非同步刷新到磁碟,保證數據的一致性,包括臟頁的刷新、合併插入緩衝、undo日誌回收等。 ②IO Thread 負責大量AIO非同步寫的回調處理,4種IO線程:write、read、insert buffer、log。 ③Purge Thread 當事務提交後,用多線程負責回收不需要的undo日誌。減輕Master線程工作。 ④Page Cleaner Thread 負責臟頁的刷新操作,減輕Master線程工作。   (2)記憶體 ①緩衝池 由於CPU速度和磁碟速度之間的鴻溝,基於磁碟的資料庫系統都使用緩衝池技術來提高DBMS整體性能。緩衝池(buffer pool)是一塊很大的記憶體區域,大小直接影響DBMS整體性能,強烈建議安裝在64位操作系統,以突破32位最大3G的記憶體上限。 A、讀記錄操作 將從磁碟讀到的頁FIX到緩衝池,下一次再讀相同頁時,先去緩衝池查看是否命中,否則讀磁碟。 B、寫記錄操作 先修改緩衝池中的頁,然後再以一定的頻率刷新回磁碟。通過Checkpoint機制觸發刷新,而不是每次修改都觸發。 允許有多個緩衝池實例,頁通過哈希分配。好處:減少資源競爭,增加併發處理能力。 緩衝池通過LRU(Latest Recent Used,最近最少使用)演算法進行管理。隊頭為熱端,隊尾為冷端,新頁插入到midpoint,每頁預設16KB。頁可以壓縮。   ②LRU List、Free List 和 Flush List Free List:資料庫剛啟動時,頁都存放到Free列表中,此時LRU列表為空。 LRU List:管理已經讀取的頁。當讀頁時,先查找Free列表,存在則將頁移動到LRU列表;不存在則從LRU讀取,否則從磁碟取新頁並淘汰LRU隊尾頁。頁被修改後,則稱為臟頁(dirty page)。 Flush List:臟頁列表,資料庫通過checkpoint機制將臟頁刷新回磁碟。 臟頁同時存在於LRU和Flush List中。其中LRU列表用來管理緩衝池中頁的可用性;Flush列表用來管理將頁刷新回磁碟。   ③重做日誌緩衝 redo log buffer:先將重做日誌放入到這個緩衝區,然後預設每1秒將其刷新到重做日誌文件。預設8MB。 將重做日誌刷新到磁碟有如下三種情況:Master Thread每一秒、事務提交時、重做日誌緩衝剩餘空間小於1/2時。   ④額外的記憶體池 存儲每個緩衝池的控制對象,以及其他如LRU管理、鎖、等待等信息。   2.3 Checkpoint技術 Write Ahead Log策略:當臟頁刷新回磁碟發生宕機,為避免數據丟失。當事務提交時,先寫重做日誌,再修改頁。 Checkpoint:檢查點技術,職責:將緩衝池中的臟頁刷新回磁碟。解決三個問題:縮短資料庫恢復時間、緩衝池不夠用時將臟頁刷新到磁碟、重做日誌不可用時刷新臟頁。 Checkpoint分為如下兩類: ①Sharp Checkpoint:資料庫關閉時將所有臟頁都刷新回磁碟。預設工作方式。 ②Fuzzy Checkpoint:只選擇一部分臟頁刷新回磁碟,而非全部。 Fuzzy的四種場景:Master Thread每1秒和10秒從臟頁列表Flush List非同步刷新、LRU列表空閑頁不足100個強制刷新、迴圈使用的重做日誌文件不可用時強制刷新、臟頁總數量太多且占比超過75%時強制刷新。   2.3 插入緩衝 主鍵聚集索引:數據頁記錄按主鍵順序存放,插入速度極快。 輔助索引:插入需要隨機讀取,來離散訪問非聚集索引頁,性能不高。 Insert Buffer:是緩衝池中的一塊記憶體,數據結構為B+樹,用途:非唯一輔助索引的插入操作。全局只有一棵Insert Buffer B+樹,負責對所有表的非唯一輔助索引進行插入緩衝,存放在共用表空間。 Change Buffer:InnoDB 1.0版本引入,是插入緩衝的升級,可以對INSERT、DELETE、UPDATE等DML操作都進行緩衝,分別是Insert | Delete | Purge Buffer。 Insert Buffer原理:對於非聚集索引的插入和更新操作,不是每一次都直接插入到索引頁中,而是先判斷插入的非聚集索引頁是否在緩衝池中,若在,則直接插入;若不在,則先放入到一個Insert Buffer對象中來告訴資料庫,非聚集索引頁以及插入到葉子節點成功,實際並沒有。然後以一定的頻率和情況進行Insert Buffer和輔助索引葉子節點的合併操作。 Insert Buffer優點:通過將同一個索引頁中的多個插入合併到一個操作中,大大提高了非聚集索引插入性能。 Merge Insert Buffer(合併插入緩衝)發生場景如下: ①輔助索引頁被讀取到緩衝池時。 ②Insert Buffer Bitmap頁追蹤到該輔助索引頁已無可用空間時。 ③Master Thread。   2.4 兩次寫 部分寫失效:當臟頁刷新到磁碟時,如果碰到宕機,只將該頁16K的一部分如4K寫入磁碟,則出現數據丟失。 重做日誌文件:記錄的是對頁的物理操作,比如:偏移量200寫入記錄A。恢復時還需有一份該頁的副本才行,而兩次寫通過在共用表空間保存宕機時刻的頁副本,來提高可靠性。 兩次寫由兩部分組成:一部分是記憶體中的doublewrite buffer,大小2MB;另一部分是磁碟上共用表空間中連續的2個區,共128頁,總大小也是2MB。 兩次寫過程如下: ①對緩衝池臟頁刷新時,不直接寫磁碟,而是先將臟頁用memcpy函數複製到記憶體中的doublewrite buffer。 ②分成兩次,每次將1MB數據寫入磁碟共用表空間中的一個區,並立即調用fsycn函數強制同步磁碟,避免磁碟緩衝。因兩個區地址是連續的,所以為順序寫入,速度很快。 ③最後將記憶體中的doublewrite buffer寫入到磁碟各個表空間文件中,為離散隨機寫入。   兩次寫崩潰恢復過程:從共用表空間兩個區找到該頁的一個副本,然後複製到表空間文件,再應用重做日誌。   2.5 自適應哈希索引 Adaptive Hash Index:AHI是資料庫內部自動優化,預設開啟。查詢定位只用一次操作,而B+樹高度一般3~4層,需要3~4次操作。AHI通過緩衝池中的B+樹頁構造而來,建立速度很快,不需要對整張表構建哈希索引。 存儲引擎會自動根據訪問頻率和模式來自動的為某些熱點頁建立哈希索引。 一般要滿足如下三個條件才會建立: ①對該頁的訪問模式必須是連續且一樣的,不能交替訪問。 ②以該訪問模式訪問了100次或頁中記錄*1/16次。   2.6 非同步IO AIO:Async IO,優點:可以通過避免同步等待、合併IO操作來提高IOPS。需要操作系統Native AIO支持。 在InnoDB中,預讀、臟頁刷新到磁碟等都是通過AIO完成。   2.7 刷新鄰接頁 當刷新一個臟頁時,會檢測該頁所在區(extent)的所有頁,如果是臟頁,則一起刷新。好處是通過AIO將多個頁IO操作合併為一個IO操作,提升性能。     第3章 文件 mysql和InnoDB文件包括:參數文件、日誌文件(錯誤日誌、慢查詢日誌、查詢日誌、二進位日誌)、套接字文件、pid文件、表結構定義文件、存儲引擎文件(表空間文件、重做日誌文件)等。 3.1 二進位日誌 binary log:記錄了對mysql資料庫執行更改的所有操作。屬於mysql服務層,而不是存儲引擎層。預設不啟動。 二進位日誌的作用:point-in-time恢復、主從複製、安全審計。 當存儲引擎支持事務時,所有事務未提交的二進位日誌會被記錄到一個會話級別的緩存中去,當事務提交時,直接將緩存中的二進位日誌寫入二進位日誌文件中。 文件內容格式有三種:STATEMENT(邏輯SQL語句)、ROW(行記錄更改情況)、MIXED(預設採用Statement,有時採用Row)。ROW格式的優點是複製和恢復可靠性高,但缺點是文件較大。   3.2 其他文件 .sock尾碼為套接字文件,在Unix系統下本地連接Mysql可以採用Unix域套接字方式。 .pid尾碼為pid文件,mysql實例啟動時,會將自己的進程ID寫入該文件。 .frm尾碼為表結構定義文件。還用來存放視圖定義。   3.3 表空間文件 .ibd尾碼為表空間文件,分為兩類: 共用表空間文件:也叫預設表空間文件。 獨立表空間文件:當設置innodb_file_per_table參數時,每個表都會有一個獨立表空間。否則數據保存到共用表空間。   3.4 重做日誌文件 redo log file:InnoDB存儲引擎級別的事務日誌文件。以迴圈寫入方式運行。InnoDB有51種重做日誌類型。 重做日誌文件與二進位日誌文件都是記錄事務日誌,但區別如下: ①級別和範圍不同。binlog屬於Mysql服務層,會記錄所有與Mysql資料庫有關的日誌,包括所有存儲引擎;而redolog屬於InnoDB存儲引擎層,只會記錄該引擎的事務日誌。 ②記錄內容不同。binlog記錄的是事務邏輯日誌;而redolog記錄的是關於每個頁的更改物理情況。 ③寫入時間不同。binlog僅在事務提交時寫一次磁碟;而redolog卻在事務進行中不斷寫入。     第4章 表 4.1 索引組織表 HOT:堆組織表,索引和表數據是分離的,索引記錄了數據所在位置的的rowid。數據插入時存儲位置是隨機的,主要由資料庫內部塊的空閑情況決定,獲取數據是安裝命中率計算,全表掃描時不見得先插入的數據先查到。 IOT:索引組織表,索引和數據是在一起的,行數據以索引形式存放。 兩者區別:查詢速度索引組織表更高,插入速度堆組織表更高。Oracle支持堆表,也支持索引組織表。Innodb只支持索引組織表。   InnoDB存儲引擎中,表都是按照主鍵順序組織存放的,如果沒有顯式定義主鍵,則先判斷表是否有非空唯一索引,有則當主鍵;若沒有則自動創建一個6位元組大小的指針,即“_rowid”。   4.2 InnoDB邏輯存儲結構 所有數據都被邏輯的存放在表空間(tablespace)中,表空間又由段(segment)、區(extent)、頁(page)組成。 (1)表空間 共用表空間:存放undo日誌、插入緩衝索引頁、redo日誌、二次寫緩衝等。 各表的獨立表空間:數據、索引、插入緩衝bitmap頁。 (2)段 表空間由各個段組成,常見段有:數據段、索引段、回滾段等。 (3)區 區由連續頁組成的空間,任何情況下每個區大小都是1MB。一個區有64個連續的頁,每個頁大小是16KB。 (4)頁 頁是InnoDB磁碟管理的最小單位。常見頁類型有:數據頁、undo頁、系統頁、事務數據頁、插入緩衝點陣圖頁等。   4.3 InnoDB行記錄格式 行記錄格式分為Compact和Redundant兩種。Compact是最新版,Redundant是為了相容老版本。 Compact格式下,NULL值不占用任何存儲空間。每行數據有額外的2~3個隱藏列:事務ID列、回滾指針列、可能的_rowid列。   行溢出數據:將一條記錄中的某些數據存儲在真正的數據頁面之外,當發生行溢出時,該行數據可能保存在2~N個頁。BLOB、LOB、varchar等大對象有可能在頁內或頁外。varchar定義時可設置最大65535位元組,但實際因別的開銷最大隻能存儲65532位元組。 對於多位元組編碼的Char類型,InnoDB內部將其視為變長字元類型,char(N),N是字元個數。   4.4 約束 InnoDB有5種約束:Primary Key、Unique Key、Foreign Key、Default、Not Null。 約束和索引區別:約束是邏輯概念,用來保證數據完整性。而索引是一個數據結構,既有邏輯概念,又有物理存儲方式。 觸發器的作用:在執行INSERT、DELETE和UPDATE之前或之後自動調用SQL命令或存儲過程。   4.5 視圖 視圖是基於基表的一個虛擬表,對視圖的操作就是基於視圖的定義操作基礎表。 物化視圖:該視圖不是基於基表的虛擬表,而是根據基表實際存在的實表。物化視圖可用於預先計算並保存多表的鏈接或聚集等耗時角度的SQL操作結果。   4.5 分區表 分區功能是在mysql服務層完成,而不是在存儲引擎層完成,但並不是所有的存儲引擎都支持分區。 局部分區索引:mysql資料庫的分區是局部分區索引,一個分區中即存放了數據又存放了索引。 全局分區:數據存放在各個分區中,但是所有數據的索引放在一個對象中。目前mysql還不支持全局分區。   mysql資料庫支持如下4種分區類型: ①RANGE分區:行數據基於連續區間的列值被放入分區。 ②LIST分區:面向離散的值。 ③HASH分區:根據用戶自定義的表達式的返回值來進行分區,不能為負數。 ④KEY分區:根據mysql資料庫提供的哈希函數來進行分區。   不論採用何種分區,如果表中存在主鍵或唯一索引時,分區列必須是唯一索引的一個組成部分。否則可以指定任何一個列為分區列。允許對NULL值做分區,與排序一樣總是視NULL值為最小值。   子分區:也叫複合分區,是在分區的基礎上再進行分區。Mysql資料庫允許在RANGE和LIST的分區上再進行HASH或KEY的子分區。     第5章 索引與演算法 5.1 InnoDB索引概述 InnoDB存儲引擎支持三種索引:B+樹索引、全文索引、哈希索引。其中B代表平衡,哈希索引不能人工干預。   5.2 數據結構與演算法 二分查找法:也稱折半查找法,用來查找一組有序記錄數組中的某一記錄。 二叉查找樹:根節點鍵值總是大於左子樹的鍵值,且小於右子樹的鍵值。中序遍歷。極端情況退化為順序查找。 平衡二叉樹:AVL樹,定義是:首先符合二叉查找樹的定義,其次必須滿足任何節點的兩個子樹的高度最大差為1。通過左旋和右旋來平衡。多用於記憶體結構對象。 B+樹:由平衡二叉樹和B樹演化而來,是為磁碟或其他存儲設備設計的一種平衡查找樹。在B+樹中,所有記錄節點都是按鍵值的大小順序存放在同一層的葉子節點上,由各葉子節點指針進行連接。B+樹插入和刪除節點時,會通過旋轉或拆分來重新平衡。   5.3 B+樹索引 B+樹索引分為聚集索引和輔助索引,兩者內部都是2~4層高度平衡的B+樹,區別是葉子節點存放的是否是一整行的信息。 (1)聚集索引 clustered index:也叫主鍵索引,按照每張表的主鍵構造一棵B+樹,同時葉子節點存放的即為整張表的行記錄數據,葉子節點也叫數據頁,中間節點叫索引頁。每個數據頁都通過一個雙向鏈表連接。因為InnoDB是索引組織表,表中數據按照主鍵順序存放。所以每張表只能有一個聚集索引。數據邏輯上連續,但物理上不連續。主鍵排序速度極快。 (2)輔助索引 secondary index:也叫二級索引、非聚集索引。葉子節點存放的是主鍵,而不是整行記錄。每張表可以有多個輔助索引。 當通過輔助索引找數據時,分成兩步:先通過輔助索引找葉子節點的主鍵,如果索引不能覆蓋,再通過主鍵索引找到行記錄。一般通過預讀來避免輔助索引的多次離散讀。 (3)B+樹索引的分裂 B+樹索引的分裂並不總是從頁的中間記錄開始,這樣可能會導致頁空間的浪費。 (4)B+樹索引的管理 索引的創建和刪除有兩種方法:一種是alter table;另一種是create/drop index。 聚集索引的創建和刪除過程:(缺點:對大表耗時較長,導致不可用) ①首先創建一張新的臨時表,表結構為通過alter table命令新定義的表結構。 ②然後把原表中數據導入到臨時表。 ③接著刪除原表。 ④最後把臨時表重命名為新表。   輔助索引的創建和刪除採用FIC(Fast Index Creation),過程如下:(缺點:寫操作仍然不可用) 創建時:InnoDB對創建索引的表加一個S鎖。不需要重建表,速度較快。 刪除時:只需刪除內部視圖上對該表的索引定義即可。 FIC只能用於輔助索引,聚集索引仍然要重建表。   5.4 Cardinality值 低選擇性列:如性別、地區、類型等欄位,可取值範圍很小,不需要建B+樹索引。 高選擇性:某個欄位可取值範圍很廣,幾乎沒有重覆,則很適合B+樹索引。 Cardinality值:表示索引中不重覆記錄數量的預估值。通過抽樣獲取,不是準確值。Cardinality與表中行記錄總數的比值應儘可能接近1。   5.5 聯合索引 聯合索引是指對錶上的多個列進行索引。也是一棵B+樹,並且已經對第二個鍵值進行了排序。   5.6 覆蓋索引 covering index:也稱索引覆蓋,即從輔助索引中就可以得到查詢的記錄,而不需要查詢聚集索引中的記錄。 覆蓋索引的好處:輔助索引不包含整行記錄的所有信息,故其大小要遠遠小於聚集索引,因此可以減少大量的IO操作。 當輔助索引不能覆蓋時,且查詢返回大量行,就算查詢條件匹配了輔助索引,但這時優化器卻會選擇走聚集索引,用順序讀來替換隨機讀的查找。   5.7 MRR優化 MMR:Multi-Range Read優化,即多範圍讀優化。查詢性能提高10倍。目的:減少磁碟的隨機訪問,並轉化為較為順序的訪問。 MRR工作方式如下: ①將查詢得到的輔助索引鍵值存放於一個緩存中,這時緩存中的數據是根據輔助索引順序排序的。 ②將緩存中的鍵值根據RowID進行排序。 ③根據RowID的排序順序來訪問實際的數據文件。   5.7 ICP優化 ICP:Index Condition Pushdown優化,即索引條件下沉。通過將where的部分過濾操作放在了存儲引擎層,即在取出索引的同時,判斷是否可以進行where條件的過濾。目的:減少上層SQL層對記錄的索取。   5.8 全文檢索 Full-Text Search:從InnoDB 1.2版本開始支持全文檢索。全文檢索使用倒排索引來實現。 Inverted index:倒排索引,也是一種索引結構,通過在輔助表中存儲了單詞與單詞自身在一個或多個文檔中所在位置的映射。利用關聯數組實現,擁有兩種表現形式: ①inverted file index,表現形式為 { 單詞,單詞所在文檔ID } 。 ②full inverted index,表現形式為 { 單詞,(單詞所在文檔ID,在具體文檔中的位置)} 。InnoDB採用此種方式。   Auxiliary Table:輔助表,是用來保存單詞並持久化到磁碟的表。為提高並行性能,總共有6張表,每張表根據單詞的Latin編碼分區。 FTS Index Cache:全文檢索索引緩存,是一個紅黑樹結構。 全文檢索使用限制: ①每張表只能有一個全文檢索的索引。 ②由多列組合而成的全文檢索的索引列必須使用相同的字元集與排序規則。 ③不支持沒有單詞界定符的語言,如中文,日文,韓語。     第6章 鎖 6.1 什麼是鎖 鎖機制用於管理對共用資源的併發訪問,來提供數據的完整性和一致性。latch和lock都可以稱為鎖。 latch:閂鎖,輕量級鎖,要求鎖定時間非常短。InnoDB中,latch有mutex(互斥量)和rwlock(讀寫鎖)。目的是用來保證併發線程操作臨界資源的正確性。沒有死鎖檢測機制。 lock:鎖的對象是事務,用來鎖定資料庫中的對象,如:表、頁、行。鎖住的對象僅在事務提交或回滾時釋放。有死鎖檢測機制。   6.2 InnoDB存儲引擎中的鎖 (1)鎖的類型 InnoDB實現了兩種標準的行級鎖: ①共用鎖(S Lock):允許事務讀一行數據。 ②排他鎖(X Lock):允許事務刪除或更新一行數據。 鎖相容:共用鎖和排他鎖都是行鎖,相容是對同一行記錄鎖的相容性情況。   意向鎖:Intention Lock,將鎖定的對象分為多個層次,InnoDB支持的多粒度鎖定允許事務在行級上的鎖和表級上的鎖同時存在。若將上鎖的對象看成一棵樹,如果對細粒度的對象上鎖,那麼首先需要對其上層粗粒度的對象上意向鎖。如對頁中row上X或S行鎖,那麼需要對錶、頁等對象上意向鎖。 InnoDB只有表級別意向鎖,設計目的是為了在一個事務中揭示下一行將被請求的鎖類型。支持兩種意向鎖: ①意向共用鎖(IS Lock):事務想要獲得一張表中某幾行的共用鎖。 ②意向排他鎖(IX Lock):事務想要獲得一張表中某幾行的排他鎖。 鎖相容性如下:   (2)一致性非鎖定讀 一致性非鎖定讀:指InnoDB通過行多版本控制的方式來讀取當前執行時間資料庫中行的數據。如果讀取的行上有X鎖,則不需要等待X鎖釋放,會讀取行的一個快照數據。快照數據是該行之前版本的數據,通過事務undo段實現,沒有額外開銷,且讀取快照不需要加鎖。 非鎖定讀是預設的讀取方式,極大提高資料庫的併發性。 MVCC:多版本併發控制。一個行記錄可能有不止一個快照數據(事務undo段),一般稱這種技術為行多版本技術,由此帶來的併發控制,稱為MVCC。 快照數據的定義在事務不同隔離級別下不一樣: ①讀已提交隔離級別下,非鎖定讀總是讀取被鎖定行的最新一份快照數據。 ②可重覆讀隔離級別下,非鎖定讀總是讀取事務開始時的行數據版本。   (3)一致性鎖定讀 InnoDB對select語句支持兩種一致性鎖定讀,都必須在一個事務里: ①select .... for update,對讀取的行記錄加一個X鎖。 ②select .... lock in share mode,對讀取的行記錄加一個S鎖。   (4)自增長與鎖 InnoDB存儲引擎提供了一種輕量級互斥量的自增長實現機制,大大提高了自增長值插入的性能。 InnoDB中,自增長的列必須時是索引,且為索引的第一個列。   (5)外鍵和鎖 外鍵主要用於引用完整性的約束檢查,在InnoDB中,對於一個外鍵列,如果沒有顯式對這列加索引,InnoDB會自動對其加一個索引,來避免表鎖。 對於外鍵值的插入或更新,首先需要查詢父表中的記錄,但對父表的查詢操作,不能使用一致性非鎖定讀,因為會發生數據不一致。因此使用select .... lock in share mode方式,對父表加S鎖讀取。   6.3 行鎖的三種演算法 InnoDB存儲引擎有三種行鎖演算法: ①Record Lock:單個行記錄上的鎖。 ②Gap Lock:間隙鎖,鎖定一個範圍,但不包含記錄本身。 ③Next-Key Lock:記錄鎖+間隙鎖,鎖定一個範圍,並且鎖定記錄本身。   Next-Key Locking技術的鎖定區間為從負無窮到正無窮的多個開閉區間範圍。設計目的是為瞭解決幻讀。當查詢的索引含有唯一屬性時,Next-Key Lock會降級為Record Lock,即僅鎖住索引本身,而不是範圍。 幻讀:指在同一事務下,連續執行兩次同樣的SQL語句可能導致不同的結果,第二次的SQL語句可能會返回之前不存在的行。   6.4 死鎖 死鎖:兩個或兩個以上的事務在執行過程中,因爭奪鎖資源而造成的一種互相等待的現象。 解決死鎖最簡單的方式是超時,即當兩個事務互相等待時,當一個等待時間超過閾值時,其中一個事務回滾,另一個事務就能繼續進行。缺點:當超時回滾事務較大,占用較多undo日誌,則回滾代價較高。 等待圖:wait-for graph,一種主動的死鎖檢測方式,判斷圖中是否存在迴路來發現死鎖,並選擇回滾undo量最小的事務。InnoDB採用等待圖來死鎖檢測。等待圖要求資料庫保存兩種信息:鎖的信息鏈表和事務等待鏈表。   6.5 鎖升級 鎖升級是指將當前鎖的粒度降低。好處是鎖是一種稀有資源,通過鎖升級降低鎖的數量,減少系統記憶體等鎖開銷,在一定程度上提高了效率。缺點是導致併發性能的降低。 InnoDB存儲引擎不需要鎖升級,因為其不是根據每個記錄來產生行鎖的,相反,它根據每個事務訪問的每個頁對鎖進行管理的,採用的是點陣圖的方式。因此不管一個事務鎖住頁中一條記錄還是多條記錄,其開銷通常都是一樣的。     第7章 事務 7.1 認識事務 事務分為5種類型:(InnoDB不支持嵌套事務,但支持其他4種事務) ①扁平事務:所有操作處於同一層次,不能提交或回滾事務的某一部分。 ②帶有保存點的扁平事務:可以回滾到同一事務中較早的一個狀態。但崩潰時保存點都會消失。 ③鏈事務:提交事務時釋放不需要對象,將必要的處理上下文隱式傳遞給下一個要開始的事務。 ④嵌套事務:頂層事務控制各個層次的子事務,子事務控制每一個局部變換,子事務可以提交或回滾,但不會馬上失效,任何子事務都在頂層事務提交後才真正提交。樹狀結構的任何節點回滾,都會引起其全部子節點事務的回滾。 ⑤分散式事務:通常是一個分散式環境下的扁平事務。   7.2 事務的實現 redo log稱為重做日誌,用來保證事務的原子性和持久性。undo log用來保證事務的一致性。 兩者不是彼此的逆過程,都可以視為一種恢復操作。redo log恢復提交事務所修改的頁操作。undo log回滾行記錄到某個特定版本。兩者記錄內容不同,redo通常是物理日誌,記錄的是頁的物理修改操作。undo是邏輯日誌,根據每行記錄進行記錄。 redo log用來保證事務的持久性,undo log用來保證事務回滾和MVCC的功能。 redo log基本都是順序寫,資料庫運行時不需要讀取操作;而undo log需要進行隨機讀寫。   7.3 redo Log 重做日誌由兩部分組成:記憶體中的redo log buffer和磁碟中的redo log file。InnoDB通過Force Log at Commit機制實現持久化。即當事務提交時,必須先將事務的所有redo日誌寫入到redo log file進行持久化,待事務提交操作完成後才算完成。為了確保每次日誌都寫入重做日誌文件,在每次將重做日誌緩衝寫入重做日誌文件後,都需要調用一次fsync操作,因此磁碟性能決定了事務提交性能。 Mysql二進位日誌只在事務提交完成後進行一次寫入。而InnoDB重做日誌在事務進行中不斷的被寫入。   redo log block:重做日誌塊,每塊大小512位元組,重做日誌buffer和file都是以block的方式存儲。因為塊大小和磁碟扇區大小一樣,所以重做日誌文件寫入可以保證原子性,不需要doublewrite技術。 LSN:Log Sequence Number,日誌序列號。8位元組,單調遞增。LSN代表三個含義:重做日誌寫入的總量、checkpoint的位置、頁的版本。 重做日誌的恢復:由於checkpoint表示刷新到磁碟頁上的LSN,因此在恢復過程中僅需恢復checkpoint開始的日誌部分。存儲引擎每次啟動都會嘗試恢復操作。因為redo是物理日誌,恢復速度比binlog等邏輯日誌快。 Insert操作在二進位日誌中不是冪等的,而在重做日誌中是冪等的。因為redo記錄的是頁的物理修改操作。   7.4 undo Log undo segment:undo存放在資料庫共用表空間的undo段中,undo是邏輯日誌,將資料庫邏輯的恢復到原來的樣子。 undo的兩個作用:回滾操作和MVCC。 MVCC:當用戶讀取一行記錄時,若該事務已經被其他事務占用,當前事務可以通過undo讀取之前的行版本信息,以此實現非鎖定讀。 只讀事務:在整個事務中的數據在事務開始時就決定,即使有其他會話在事務周期內修改並提交數據,也不會影響事務。 資料庫只讀事務也是利用undo段快照來實現的。 事務在undo log segment分配頁並寫入undo log的這個過程同樣需要寫入重做日誌。事務提交後,並不能馬上刪除undo log 及undo log所在的頁,這是因為可能還有其他事務需要通過undo log來得到行記錄之前的版本。故事務提交後,將undo放入一個鏈表中,由purge線程來判斷和最終刪除。 一個undo頁存放不同事務的undo log。   7.5 group commit InnoDB在事務提交時會進行兩個階段操作: ①修改記憶體中事務對應的信息,並且將日誌寫入重做日誌緩衝。 ②調用fsync將確保日誌都從重做日誌緩衝寫入磁碟。對於該步驟,可以將多個事務的重做日誌通過一次fsync刷新到磁碟,以提高性能,這就是group commit。   當開啟二進位日誌後,為了保證存儲引擎層中的事務和二進位日誌的一致性,採用二階段事務,其步驟如下: 一旦Server通過fsync完成二進位日誌寫入,就表示事務成功提交完成,即使在執行後面的步驟時發生宕機。   BLGC:Binary Log Group Commit,是一種實現機制,支持mysql資料庫上層的二進位日誌寫入是group commit的,而且存儲引擎層的redo log也是group commit的。 在Mysql資料庫上層進行提交時首先按順序將其放入一個隊列中,隊列中的第一個事務稱為Leader,其他事務稱為Follower,Leader控制著Follower的行為。BLGC步驟分為三個階段: ①Flush階段,將每個事務的二進位日誌寫入記憶體中。 ②Sync階段,將記憶體中多個事務的二進位日誌用一次fsync操作刷新到磁碟,這就是Group Commit。 ③Commit階段,Leader根據順序調用存儲引擎層事務的提交。利用InnoDB本身的Group Commit。   7.6 分散式事務 InnoDB支持XA事務,當使用分散式事務時,InnoDB事務隔離級別必須設置為Serializable。 XA事務由一個應用程式,一個事務管理器,多個資源管理器組成。Mysql有外部XA事務和內部XA事務,分別如下: ①外部XA事務,資源管理器是Mysql資料庫本身。 ②內部XA事務,指存儲引擎與存儲引擎之間。 最常見的內部XA事務是binlog和innodb存儲引擎之間的。當事務提交時,InnoDB存儲引擎會先收到服務層發來的Prepare請求,此時會將事務的xid寫入;接著服務層進行二進位日誌寫入,如果在InnoDB執行最後一步Commit操作時,資料庫宕機了,那麼在Mysql資料庫重啟後會先檢查Prepare的事務xid是否已經提交,若沒有,則存儲引擎再進行一次提交操作。   7.7 不好的事務習慣 不好的事務習慣有:長事務、在迴圈中提交、使用自動提交、使用自動回滾等。     第8章 備份與恢復 8.1 備份 按備份方法不同,將備份分為: ①熱備:資料庫運行中直接備份。 ②冷備:資料庫停止後再備份。 ③溫備:資料庫運行中進行,會對資料庫操作有一定影響,如加一個全局讀鎖以保證備份數據的一致性。   按照備份後文件的內容,備份又分為: ①邏輯備份:一條條SQL語句的可讀文本文件,恢復慢。 ②裸文件備份:複製資料庫的物理文件。運行中複製工具有ibbackup和xtrabackup。恢復快。   按照備份資料庫的內容,備份又可分為: ①完全備份:對資料庫進行一個完整的備份。 ②增量備份:在上次完整備份的基礎上,對更改數據進行備份。 ③日誌備份:對二進位日誌進行備份。通過binlog重放來完成point-in-time的
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 下載安裝包 到官網下載MariaDB 10.2系列穩定版的源碼包 選擇源碼包 點擊鏈接後頁面會跳到下載頁面,頁面中有個信息表格可以填寫,這裡我們就直接跳過,點擊 No thanks, just take me to the download,保存源碼包 把源碼包保存到: 解壓: 編譯前準備工作 安裝 ...
  • 本文中使用的例子均在下麵的資料庫表tt2下執行: 一、concat()函數 1、功能:將多個字元串連接成一個字元串。 2、語法:concat(str1, str2,...) 返回結果為連接參數產生的字元串,如果有任何一個參數為null,則返回值為null。 3、舉例: 例1:select conca ...
  • 海明校驗碼是在n個數據位之外增設k個校驗位,從而形成一個k+n位的新的碼字,使新的碼字的碼距比較均勻地拉大。n與k的關係是(1)。 (1)A.2k-1>=n+k B.2k-1<=n+k C.n=k D.n-1<=k 【答案】A 【解析】本題考查校驗碼方面的基礎知識。 海明碼是一種多重(複式)奇偶檢錯 ...
  • MySQL官方將prepare、execute、deallocate統稱為PREPARE STATEMENT,習慣稱其為【預處理語句】,下麵是對其詳細的介紹。 示例代碼 PREPARE stmt_name FROM preparable_stmt EXECUTE stmt_name [USING @ ...
  • 轉載於https://www.cnblogs.com/aiyr/p/6830593.html mysql CONCAT()函數用於將多個字元串連接成一個字元串,是最重要的mysql函數之一,下麵就將為您詳細介紹mysql CONCAT()函數,供您參考 mysql CONCAT(str1,str2, ...
  • 前言 筆者在分類中的Hbase欄目之前已經分享了hbase的安裝以及一些常用的shell命令的使用,這裡不僅僅重新複習一下shell命令,還會介紹hbase的DDL以及DML的相關操作。 一、hbase的shell操作 1.1啟動hbase shell 在hbase的安裝目錄的bin目錄下麵啟動我們 ...
  • 我並不期望成為一個專家級的 DBA,但是,在我優化 MySQL 時,我推崇 80/20 原則,明確說就是通過簡單的調整一些配置,你可以壓榨出高達 80% 的性能提升。尤其是在伺服器資源越來越便宜的當下。 警告 沒有兩個資料庫或者應用程式是完全相同的。這裡假設我們要調整的資料庫是為一個“典型”的 We ...
  • mysql用戶授權、資料庫許可權管理、sql語法詳解 —— NiceCui ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...