個人簡介:Java領(lǐng)域新星創(chuàng)作者;阿里云技術(shù)博主、星級博主、專家博主;正在Java學(xué)習(xí)的路上摸爬滾打,記錄學(xué)習(xí)的過程~
個人主頁:.29.的博客
學(xué)習(xí)社區(qū):進去逛一逛~
⑩⑧【MySQL】詳解InnoDB存儲引擎
1. InnoDB邏輯存儲結(jié)構(gòu)
InnoDB邏輯存儲結(jié)構(gòu)
:
-
??
表空間(idb文件)
:一個MySQL實例可以對應(yīng)多個表空間,用于存儲記錄、索引等數(shù)據(jù)。 -
??
段
:分為數(shù)據(jù)段(Leaf node segment) 、索引段(Non-leaf node segment) 、回滾段(Rollback segment) ,InnoDB是索引組織表,數(shù)據(jù)段就是B+樹的葉子節(jié)點,索引段即為B+樹的非葉子節(jié)點。段用來管理多個Extent(區(qū)) 。 -
??
區(qū)
:表空間的單元結(jié)構(gòu),每個區(qū)的大小為1M。默認(rèn)情況下,InnoDB存儲引擎頁大小為16K,即一個區(qū)中一共有64個連續(xù)的頁。 -
??
頁
:是InnoDB存儲引擎磁盤管理的最小單元,每個頁的大小默認(rèn)為16KB。為了保證頁的連續(xù)性,InnoDB存儲引擎每次從磁盤申請4-5個區(qū)。 -
??
行
:InnoDB存儲引擎數(shù)據(jù)是按行進行存放的。 -
- ?
Trx_id
:每次對某條記錄進行改動時,都會把對應(yīng)的事務(wù)id賦值給Trx_id隱藏列。 - ?
Roll pointer
:每次對某條引記錄進行改動時,都會把舊的版本寫入到undo日志中,然后這個隱藏列就相當(dāng)于一個指針,可以通過它來找到該記錄修改前的信息。
- ?
2. InnoDB架構(gòu)
架構(gòu)
:
MySQL5.5版本開始,默認(rèn)使用InnoDB存儲引擎,它擅長事務(wù)處理,具有崩潰恢復(fù)特性,在日常開發(fā)中使用非常廣泛。下面是InnoDB架構(gòu)圖,左側(cè)為內(nèi)存結(jié)構(gòu),右側(cè)為磁盤結(jié)構(gòu)。
文章來源:http://www.zghlxwxcb.cn/news/detail-759492.html
??內(nèi)存架構(gòu)
內(nèi)存結(jié)構(gòu) - In-Memory Structures
:
- ??
Buffer Poll
:緩沖池 是主內(nèi)存中的一個區(qū)域,里面可以緩存磁盤上經(jīng)常操作的真實數(shù)據(jù),在執(zhí)行增刪改查操作時,先操作緩沖池中的數(shù)據(jù)(若緩沖池沒有數(shù)據(jù),則從磁盤加載并緩存),然后再以一定頻率刷新到磁盤,從而減少磁盤IO,加快處理速度。 -
- 緩沖池以Page頁 為單位,底層采用鏈表數(shù)據(jù)結(jié)構(gòu)管理Page 。根據(jù)狀態(tài),將Page分為三種類型:
-
- ?
free page
—— 空閑page,未被使用。 - ?
clean page
—— 被使用page,數(shù)據(jù)沒有被修改過。 - ?
dirty page
—— 臟頁,被使用page,數(shù)據(jù)被修改過,頁中數(shù)據(jù)與磁盤的數(shù)據(jù)產(chǎn)生了不一致。
- ?
- ??
Change Buffer
:更改緩沖區(qū)(針對于非唯一二級索引頁) ,在執(zhí)行DML語句時,如果這些數(shù)據(jù)Page
沒有在Buffer Pool中,不會直接操作磁盤,而會將數(shù)據(jù)變更存放在更改緩沖區(qū)Change Buffer中,在未
來數(shù)據(jù)被讀取時,再將數(shù)據(jù)合并恢復(fù)到Buffer Pool中,再將合并后的數(shù)據(jù)刷新到磁盤中。 - 更改緩沖區(qū)Change Buffer的意義是什么?
-
- 與聚集索引不同,二級索引通常是非唯一的,并且以相對隨機的順序插入二級索引。同樣,刪除和更新可能會影響索引樹中不相鄰的二級索引頁,如果每一次都操作磁盤,會造成大量的磁盤IO。有了ChangeBuffer之后,我們可以在緩沖池中進行合并處理,減少磁盤IO。
-
??
Adaptive Hash Index
:自適應(yīng)hash索引 ,用于優(yōu)化對Buffer Pool數(shù)據(jù)的查詢。InnoDB存儲引擎會監(jiān)控對表上各索引頁的查詢,如果觀察到hash索引可以提升速度,則建立hash索引,稱之為自適應(yīng)hash索引。自適應(yīng)哈希索引,無需人工干預(yù),是系統(tǒng)根據(jù)情況自動完成。
-
-
-- innodb中,自適應(yīng)hash索引的參數(shù):innodb_adaptive_hash_index -- 查看是否開啟了 自適應(yīng)hash SHOW VARIABLES LIKE 'innodb_adaptive_hash_index';
-
-
??
Log Buffer
:日志緩沖區(qū),用來保存要寫入到磁盤中的log日志數(shù)據(jù)(redo log、undo log),默認(rèn)大小為16MB ,日志緩沖區(qū)的日志會定期刷新到磁盤中。如果需要更新、插入或刪除許多行的事務(wù),增加日志緩沖區(qū)的大小可以節(jié)省磁盤I/O。 -
-
#參數(shù) -- 緩沖區(qū)大?。篿nnodb_log_buffer_size -- 日志刷新到磁盤時機:innodb_flush_log_at_trx_commit -- 查看: SHOW VARIABLES LIKE 'innodb_log_buffer_size'; SHOW VARIABLES LIKE 'innodb_flush_log_at_trx_commit'; #或 SELECT @@innodb_log_buffer_size; SELECT @@innodb_flush_log_at_trx_commit;
-
日志刷新到磁盤時機:innodb_flush_log_at_trx_commit(值:0/1/2)
-
??磁盤架構(gòu)
磁盤結(jié)構(gòu) On-Disk Structures
:
-
??
System Tablespace
:系統(tǒng)表空間 是更改緩沖區(qū)的存儲區(qū)域。如果表是在系統(tǒng)表空間創(chuàng)建,而不是每個表文件或通用表空間中創(chuàng)建的,它也可能包含表和索引數(shù)據(jù)。(在MySQL5.x版本中還包含InnoDB數(shù)據(jù)字典、undologs等)。 -
-
#參數(shù) : innodb_data_file_path -- 查看相關(guān)信息 SHOW VARIABLES LIKE '%data_file_path%';
-
-
??
File-Per-Table Tablespaces
:每個表的文件表空間 包含單個InnoDB表的數(shù)據(jù)和索引,并存儲在文件系統(tǒng)上的單個數(shù)據(jù)文件中。 -
-
#參數(shù) : innodb_file_per_table SHOW VARIABLES LIKE '%file_per_table%';
-
-
??
General Tablespaces
:通用表空間 ,需要通過CREATE TABLESPACE語法
創(chuàng)建通用表空間,在創(chuàng)建表時,可以指定通用表空間。 -
-
-- 創(chuàng)建通用表空間 CREATE TABLESPACE 通用表空間名稱 ADD DATAFILE '表空間文件名' ENGINE = 存儲引擎名; -- 創(chuàng)建表時指定關(guān)聯(lián)的通用表空間 CREATE TABLE 表名( 字段1 字段1類型 [COMMENT 字段1注釋], 字段2 字段2類型 [COMMENT 字段2注釋], 字段3 字段3類型 [COMMENT 字段3注釋], ... 字段n 字段n類型 [COMMENT 字段n注釋] )[COMMENT 表注釋] TABLESPACE 通用表空間名稱;
-
- ??
Undo Tablespaces
:撤銷表空間,MySQL實例在初始化時會自動創(chuàng)建兩個默認(rèn)的undo表空間(初始大小16M),用于存儲undo log日志。
- ??
Temporary Tablespaces
:InnoDB使用會話臨時表空間 和全局臨時表空間 。存儲用戶創(chuàng)建的臨時表等數(shù)據(jù)。
- ??
Doublewrite Buffer Files
:雙寫緩沖區(qū) ,innoDB引擎將數(shù)據(jù)頁從Buffer Pool
刷新到磁盤前,先將數(shù)據(jù)頁寫入雙寫緩沖區(qū)文件中,便于系統(tǒng)異常時恢復(fù)數(shù)據(jù)。 (雙寫緩沖區(qū)文件:xxx.dblwr文件
)
- ??
Redo Log
:重做日志 ,是用來實現(xiàn)事務(wù)的持久性。該日志文件由兩部分組成:重做日志緩沖(redo log buffer) 以及 重做日志文件(redo log file) ,前者是在內(nèi)存中,后者在磁盤中。當(dāng)事務(wù)提交之后會把所有修改信息都會存到該日志中,用于在刷新臟頁到磁盤時,發(fā)生錯誤時,進行數(shù)據(jù)恢復(fù)使用。
??后臺線程
后臺線程
:
- ??
Master Thread
: -
- 核心后臺線程,負(fù)責(zé)調(diào)度其他線程,還負(fù)責(zé)將緩沖池中的數(shù)據(jù)異步刷新到磁盤中,保持?jǐn)?shù)據(jù)的一致性,還包括臟頁的刷新、合并插入緩存、undo頁的回收。
- ??
IO Thread
: -
- 在InnoDB存儲引擎中大量使用了AIO(異步非阻塞IO)來處理IO請求,這樣可以極大地提高數(shù)據(jù)庫的性能,而IO Thread主要負(fù)責(zé)這些IO請求的回調(diào)。
- ??
Purge Thread
: -
- 主要用于回收事務(wù)已經(jīng)提交了的undo log,在事務(wù)提交之后,undo log可能不用了,就用它來回收。
-
??
Page Cleaner Thread
: -
- 協(xié)助Master Thread刷新臟頁到磁盤的線程,它可以減輕Master Thread的工作壓力,減少阻塞。
3. 事務(wù)的原理
事務(wù)
:
事務(wù)是一組操作的集合,它是一個不可分割的工作單位,事務(wù)會把所有的操作作為一個整體一起向系統(tǒng)提交或撤銷操作請求,即這些操作要么同時成功,要么同時失敗。
事務(wù)四大特性
:
- 原子性(Atomicity) 事務(wù)是不可分割的最小操作單元,要么全部成功,要么全部失敗。
- 一致性(Consistency) 事務(wù)完成時,必須使所有的數(shù)據(jù)都保持一致狀態(tài)。
- 隔離性(Isolation) 數(shù)據(jù)庫系統(tǒng)提供的隔離機制,保證事務(wù)在不受外部并發(fā)操作影響的獨立環(huán)境下運行。
- 持久性(Durability) 事務(wù)一旦提交或回滾,它對數(shù)據(jù)庫數(shù)據(jù)的改變就是永久的。
?redo log
重做日志 - redo log
:
重做日志 ,記錄的是事務(wù)提交時數(shù)據(jù)頁的物理修改,是用來實現(xiàn)事務(wù)的持久性 。該日志文件由兩部分組成:重做日志緩沖(redo log buffer) 以及 重做日志文件(redo log file) ,前者是在內(nèi)存中,后者在磁盤中。當(dāng)事務(wù)提交之后會把所有修改信息都會存到該日志中,用于在刷新臟頁到磁盤時,發(fā)生錯誤時,進行數(shù)據(jù)恢復(fù)使用。
?undo log
回滾日志 - undo log
:
回滾日志 ,用于記錄數(shù)據(jù)被修改前的信息,作用包含兩個:提供回滾 和 MVCC(多版本并發(fā)控制) 。
undo log 和redo log 記錄物理日志不一樣,undo log 是邏輯日志。可以認(rèn)為當(dāng)delete一條記錄時,undo log中會記錄一條對應(yīng)的insert記錄,反之亦然,當(dāng)update 一條記錄時,它記錄一條對應(yīng)相反的update記錄。當(dāng)執(zhí)行rollback時,就可以從undo log中的邏輯記錄讀取到相應(yīng)的內(nèi)容并進行回滾。
-
Undo log銷毀
: -
- undo log在事務(wù)執(zhí)行時產(chǎn)生,事務(wù)提交時,并不會立即刪除undo log,因為這些日志可能還用于MVCC。
-
Undo log存儲
: -
- undo log采用段的方式進行管理和記錄,存放在前面介紹的rollback segment回滾段中,內(nèi)部包含1024個undo log segment。
4. MVCC
??MVCC基本概念
當(dāng)前讀
:
讀取的是記錄的最新版本,讀取時還要保證其他并發(fā)事務(wù)不能修改當(dāng)前記錄,會對讀取的記錄進行加鎖。對于我們日常的操作 ,如:select..lock in share mode(共享鎖)
,select\update\insert\delete..for update(排他鎖)
都是一種當(dāng)前讀 。
快照讀
:
簡單的select(不加鎖)就是快照讀,快照讀,讀取的是記錄數(shù)據(jù)的可見版本,有可能是歷史數(shù)據(jù),不加鎖,是非阻塞讀。
- 事務(wù)隔離級別:
-
- Read Committed :每次select,都生成一個快照讀。
- Repeatable Read :開啟事務(wù)后第一個select語句才是快照讀的地方。
- Serializable :快照讀會退化為當(dāng)前讀。
多版本并發(fā)控制 - MVCC
:
全稱Multi--Version Concurrency Control
,多版本并發(fā)控制 。指維護一個數(shù)據(jù)的多個版本,使得讀寫操作沒有沖突 ,快照讀為MySQL實現(xiàn)MVCC提供了一個非阻塞讀功能。MVCC的具體實現(xiàn),還需要依賴于數(shù)據(jù)庫記錄中的:三個隱式字段
、undo log日志
、readView
。
??MVCC實現(xiàn)原理
表的隱藏字段
:
undo log - 回滾日志
:
- 回滾日志 ,在insert、update、delete的時候產(chǎn)生的便于數(shù)據(jù)回滾的日志 。
- 當(dāng)insert的時候,產(chǎn)生的undo log日志只在回滾時需要,在事務(wù)提交后,可被立即刪除 。
- 而update、delete的時候,產(chǎn)生的undo log日志不僅在回滾時需要,在快照讀時也需要,不會立即被刪除 。
-
undo log 版本鏈
: -
- 不同事務(wù)或相同事務(wù)對同一條記錄進行修改,會導(dǎo)致該記錄的undolog生成一條記錄版本鏈表,鏈表的頭部是最新的舊記錄,鏈表尾部是最早的舊記錄。
readView - 讀視圖
:
ReadView(讀視圖)是快照讀SQL執(zhí)行時MVCC提取數(shù)據(jù)的依據(jù),記錄并維護系統(tǒng)當(dāng)前活躍的事務(wù)(未提交的)id。
不同的隔離級別,生成ReadViewl的時機不同:
READ COMMITTED:在事務(wù)中每一次執(zhí)行快照讀時生成ReadView。
REPEATABLE READ:僅在事務(wù)中第一次執(zhí)行快照讀時生成ReadView,后續(xù)復(fù)用該ReadView。
- ReadView的4個核心字段:
-
文章來源地址http://www.zghlxwxcb.cn/news/detail-759492.html
到了這里,關(guān)于⑩⑧【MySQL】InnoDB架構(gòu)、事務(wù)原理、MVCC多版本并發(fā)控制的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!