国产成人精品18p,天天干成人网,无码专区狠狠躁天天躁,美女脱精光隐私扒开免费观看

InnoDB的外存數據結構介紹

發(fā)布時(shí)間:2021-09-14 18:07 來(lái)源:億速云 閱讀:0 作者:chen 欄目: Mysql 歡迎投稿:712375056

這篇文章主要講解了“InnoDB的外存數據結構介紹”,文中的講解內容簡(jiǎn)單清晰,易于學(xué)習與理解,下面請大家跟著(zhù)小編的思路慢慢深入,一起來(lái)研究和學(xué)習“InnoDB的外存數據結構介紹”吧!

PartⅠ 表和表空間

“Everything is a file…”這句至理名言告訴我們一切都得從文件說(shuō)起。那么對 InnoDB 外存數據結構的學(xué)習,我們也先從表和文件開(kāi)始。

一、表 ( Table )

當我們使用 CREATE TABLE 創(chuàng )建一個(gè)表時(shí), 會(huì )創(chuàng )建一個(gè) .frm 文件和一個(gè) .ibd 文件。.frm 文件是描述表結構定義的文件,而 .ibd 文件是 InnoDB 引擎層特有的,用于記錄InnoDB表的數據。舉個(gè)例子,在 db.CCCtest 下創(chuàng )建一個(gè)表”jersey_test”,建表語(yǔ)句如下:

CREATE TABLE `jersey_test` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `requestId` char(64) NOT NULL COMMENT 'request',
  `type` smallint(6) NOT NULL DEFAULT '0' COMMENT '類(lèi)型',
  `name` varchar(64) NOT NULL COMMENT 'name',
  PRIMARY KEY (`id`),
  KEY `request` (`requestId`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8

同時(shí),我們往表中插入一條記錄如下:

[ jersey_test 表中的數據 ]

我們進(jìn)入到 MySQL 的 /data 目錄下面,可以看到”jersey_test.frm”文件和”jersey_test.ibd”文件。

[ CCCtest 庫中的文件 ]

.frm 文件是二進(jìn)制格式的,我們通過(guò) hexdump 工具稍加分析,可以看到文件中除了一些編碼信息外,主要內容就是表結構信息。

[ .frm 文件內容 ]

這和我們使用 DESC TABLE 語(yǔ)法看到的表結構描述一致。

[ 表結構描述 ]

數據文件 .ibd 的分析與之類(lèi)似。

二、Row Formats

InnoDB 中的表都是分文件存儲的,表中的行數據也按照相應的格式記錄在文件中。這里我們簡(jiǎn)要歸納一下 InnoDB 所支持的文件存儲格式和行存儲格式。InnoDB 的文件格式由參數 innodb_file_format 指定,它支持 Antelope 和 Barracuda 兩種文件格式。Barracuda 是新的文件格式,它是包含 Antelope 格式在內的。Antelope 文件格式支持兩種行存儲格式,Compact 和 Redundant ,Barracuda 支持的新的行存儲格式為 Compressed 和 Dynamic。

[ InnoDB行存儲格式 ]

InnoDB 表的行存儲格式由參數 innodb_default_row_format 指定,在 5.7 版本中的默認值為 Dynamic 。行存儲格式?jīng)Q定了表中的記錄在文件中是如何進(jìn)行存儲的,不同的行存儲格式有其特殊的優(yōu)勢和劣勢,也會(huì )影響數據庫的行為。例如,使用 Compressed 這種格式可以使行記錄有更高的壓縮比,如果一個(gè)物理頁(yè)能存放的行記錄越多,它的索引或記錄查找會(huì )更快,內存消耗也會(huì )更小,但是壓縮數據本身也會(huì )帶回額外的系統開(kāi)銷(xiāo)。另外一個(gè)需要注意的地方是,在進(jìn)行數據庫表遷移時(shí),需要關(guān)注源實(shí)例和目標實(shí)例的 Row Format 是否匹配。比如你有一個(gè) MyISAM 的表要遷移到 InnoDB 上,并且 MyISAM 表的 Row Format 為默認值 Fixed ,此時(shí)需要改成 Dynamic ,因為這兩種格式對變長(cháng)字段如 varchar/blob/text 等的處理是不一致的。

三、表空間 ( TableSpace )

我們前面談到,InnoDB 每個(gè)表都有自己獨立的文件,其實(shí)是用到了它的默認行為,即使用獨立表空間,它由參數 innodb_file_per_table 控制。事實(shí)上 InnoDB 包含多種表空間類(lèi)型,包括系統表空間 ( System TableSpace ),獨立表空間 ( File-Per-Table TableSpace ) 和通用表空間 ( General TableSpace ) 等。

系統表空間存儲了 InnoDB 的數據字典(元數據信息),系統表,雙寫(xiě)緩沖區 ( doublewrite buffer ),Change Buffer 等。如果將參數 innodb_file_per_table 置為 OFF ,即所有的表數據都存儲在系統表空間中。但是在使用 InnoDB 時(shí),更推薦的方法是將 innodb_file_per_table 置為 ON,即使用獨立表空間,它有如下幾個(gè)好處:

  1. 當使用 Truncate Table 和 Drop Table 命令刪除表時(shí),系統會(huì )直接刪除表的數據文件,即回收物理空間。而使用系統表空間則無(wú)法回收這些物理空間;

  2. 和上面類(lèi)似,當使用重建表的語(yǔ)法時(shí),如 OPTIMIZE TABLE 或者 ALTER TABLE ENGINE = InnoDB 時(shí),系統也能夠回收物理空間;

  3. 可以單獨將某個(gè)表指定到對應的存儲位置,這個(gè)存儲位置可以不在 MySQL 的數據目錄下。比如你想使用 RAID 或者 SSD 來(lái)存儲某個(gè)表,當你使用獨立表空間時(shí),就可以通過(guò) CREATE TABLE … DATA DIRECTORY 這個(gè)語(yǔ)法來(lái)實(shí)現。

使用獨立表空間也有一些潛在的問(wèn)題。例如,每個(gè)表都有自己的單獨的文件,容易造成物理空間的浪費,如果數據庫有很多小表的話(huà),這種空間浪費也會(huì )比較明顯。通用表空間 ( General TableSpace ) 可以緩解這個(gè)問(wèn)題。通用表空間可以認為是 all-in-one (系統表空間) 和 file-per-table 的一個(gè)折中,它允許你使用 CREATE TABLESPACE 語(yǔ)法創(chuàng )建一個(gè)大的空間,然后你可以向這個(gè)空間中添加一些表的數據文件進(jìn)行存儲,這些表的數據文件是共享存儲空間的。

Part Ⅱ 索引

索引可以說(shuō)是 InnoDB 最重要的數據結構,介紹數據庫索引的資料也很多,談點(diǎn)題外話(huà),什么是索引呢?索引其實(shí)就是幫助我們快速查找到數據( data ) 的輔助結構,可以說(shuō)有數據的地方就需要索引。比如在文件系統里,數據的索引保存在元數據 inode 信息中,它記錄著(zhù)這個(gè)文件所有的數據頁(yè)( data pages ) 具體在哪個(gè)位置,比如文件有10個(gè)頁(yè),它就對應記錄10個(gè)頁(yè)框的物理地址。文件系統的索引當然也會(huì )有直接索引和間接索引,因為如果直接索引裝不下,就會(huì )用二級索引來(lái)裝,其結構如下圖所示,

[ 文件系統 inode 結構 ]

操作系統中最常見(jiàn)(也可能是最快)的索引大概是虛擬地址到物理地址的映射表。之所以快,首先在于它是連續的,當你進(jìn)行跨頁(yè)訪(fǎng)問(wèn)的時(shí)候不需要去計算下一個(gè)頁(yè)的地址,另外地址的轉換是由專(zhuān)門(mén)的硬件MMU來(lái)做的,硬件肯定更快??梢栽O想一下,如果文件存儲或者數據庫存儲的索引也采用虛擬地址映射表加上硬件加速的話(huà),肯定會(huì )比現有的方式更快。虛擬地址直接映射到進(jìn)程地址空間還可以減少進(jìn)入內核態(tài)的開(kāi)銷(xiāo)。

說(shuō)回 InnoDB 的索引結構,InnoDB 的索引采用 B+ 樹(shù)這種數據結構,InnoDB 表中的行數據都是由聚簇索引 ( clustered index ) 組織的,它也被稱(chēng)作主鍵索引 ( primar key ),即主鍵索引這棵 B+ 樹(shù)的葉子節點(diǎn)存儲的是主鍵對應的整行數據。為 InnoDB 的每個(gè)表都建立自增的主鍵索引非常重要,之所以需要自增,是因為在插入新記錄時(shí)可以做到連續,追加插入,這樣可以減少索引查找和索引頁(yè)分裂所帶來(lái)的額外開(kāi)銷(xiāo)。InnoDB 其他的索引稱(chēng)為二級索引 ( secondary index ),二級索引的葉子節點(diǎn)存儲的是主鍵索引的值,因此,絕大多數使用二級索引查詢(xún)記錄時(shí),都會(huì )先通過(guò)二級索引找到主鍵索引的值,再通過(guò)主鍵索引找到行記錄。

Part Ⅲ 恢復日志

一、重做日志和回滾日志 ( Redo Log & Undo Log )

在 InnoDB 中,數據一致性由 Redo Log 來(lái)保證,它使用的是 WAL(Write-Ahead Logging) 機制,即先寫(xiě)日志再寫(xiě)數據。InnoDB 使用這種方式在進(jìn)行故障恢復時(shí),會(huì )將 Redo Log 中的日志重做一遍,也就是將系統中未提交的事務(wù)重新執行。默認情況下,Redo Log 記錄在磁盤(pán)的 ib_logfile0 和 ib_logfile1 這兩個(gè)文件里,MySQL 循環(huán)的寫(xiě)這兩個(gè)文件,因此,Redo Log 會(huì )有寫(xiě)滿(mǎn)的情況,這里就需要介紹日志中的 checkpoint 機制。checkpoint 記錄了整個(gè)系統當前日志已經(jīng)同步到的位置,也就是說(shuō),在 checkpoint 之前的事務(wù)都是已經(jīng)提交的事務(wù),數據不會(huì )存在不一致的情況。而當 MySQL 寫(xiě)入 Redo Log 記錄追上 checkpoint 時(shí),Redo Log 就寫(xiě)滿(mǎn)了,此時(shí)需要等待 Redo Log 同步數據并釋放空間。

另一方面,在數據庫這種存儲系統中,更新操作失敗并回滾的情況是很常見(jiàn)的,所以需要特別關(guān)注這種情況,Undo Log 就是用來(lái)解決這個(gè)問(wèn)題。Undo Log 記錄的是當一個(gè)更新操作失敗需要回滾時(shí),應該進(jìn)行哪些反向操作。即當你 insert 一條記錄時(shí),Undo log中會(huì )記錄一條對應的 delete 記錄,反之亦然。

二、Binlog

Redo Log 解決了本地數據(這里是指單點(diǎn)實(shí)例)一致性的問(wèn)題。但是數據庫要做到高可用,還需要考慮多副本或跨區跨地域容災。MySQL Binlog 就提供了這種能力,Binlog 支持 Statement,Row 和 Mixed 三種模式。其中, Row 模式會(huì )記錄每行數據的修改操作,相比 Statement 模式,它能保證主從復制的正確性。

前面已經(jīng)提到,Redo Log 和 Binlog 必須同時(shí)使用才能做到數據一致且高可用。接下來(lái)簡(jiǎn)要分析一下數據庫進(jìn)行插入或更新操作時(shí)是如何做到這一點(diǎn)的。MySQL 使用 WAL 機制進(jìn)行更新操作,即先寫(xiě) Redo Log 和 Binlog,然后再寫(xiě)數據。寫(xiě) Redo Log 和 Binlog 必須保證原子性,要么都更新成功,要么都更新失敗,否則會(huì )造成本地數據和其他副本數據不一致的情況。更新 Redo Log 和 Binlog 的過(guò)程稱(chēng)為兩階段提交,其步驟為:

  1. 先將更新的操作寫(xiě)到 Redo Log,此時(shí)流程標記為 prepare 狀態(tài);

  2. 更新 Binlog,此時(shí)需將 BinLog 刷回磁盤(pán)才能視為成功;

  3. 提交事務(wù)(此時(shí)還會(huì )清除該事務(wù) Undo 日志),流程標記為 commit 狀態(tài)。

兩階段提交可以保證數據的一致性,它在任何一個(gè)階段異常失敗都可以進(jìn)行恢復。比如,如果事務(wù)已經(jīng)是 commit 狀態(tài),此時(shí)Redo Log 和 Binlog 都已更新成功;如果是在 prepare 狀態(tài),此時(shí)就需要判斷 BinLog 中是否有完整的信息,如果有,則會(huì )進(jìn)行 commit,如果沒(méi)有完整信息,則整個(gè)事務(wù)回滾。

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng )、來(lái)自本網(wǎng)站內容采集于網(wǎng)絡(luò )互聯(lián)網(wǎng)轉載等其它媒體和分享為主,內容觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如侵犯了原作者的版權,請告知一經(jīng)查實(shí),將立刻刪除涉嫌侵權內容,聯(lián)系我們QQ:712375056,同時(shí)歡迎投稿傳遞力量。

色天天躁夜夜躁天干天干| 国产亚洲AV手机在线观看| 在线观看免费人成视频色9| 爱啪啪AV网| 亚洲AV永久纯肉无码精品动漫| 日韩激情无码AV一区二区|