上一期我們聊了InnoDB的內(nèi)存結(jié)構(gòu),那么我們這一期說(shuō)一說(shuō)磁盤(pán)結(jié)構(gòu)。
一、前期回顧
二锦秒、InnoDB的磁盤(pán)結(jié)構(gòu)
????InnoDB磁盤(pán)主要包含Tablespace(表空間),Data Dictionary數(shù)據(jù)字典喉镰,Doublewrite Buffer(雙寫(xiě)緩沖區(qū))旅择、redo log(重做日志) 和undo log(撤銷(xiāo)日志)
2.1 表空間
????用于存儲(chǔ)表結(jié)構(gòu)和數(shù)據(jù)。表空間又分為系統(tǒng)表空間侣姆、獨(dú)立表空間生真、 通用表空間沉噩、臨時(shí)表空間、Undo表空間等多種類(lèi)型
????2.1.1系統(tǒng)表空間(The System Tablespace)
????系統(tǒng)表空間:系統(tǒng)表空間是存放change buffer的區(qū)域,Change Buffer是緩存那些不在buffer pool里的輔助索引的變化的特殊數(shù)據(jù)結(jié)構(gòu)柱蟀。在磁盤(pán)上川蒙,Change Buffer是system tablespace(系統(tǒng)表空間)的一部分,當(dāng)數(shù)據(jù)庫(kù)宕機(jī)時(shí)产弹,索引的變更會(huì)被緩沖到磁盤(pán)的Change Buffer區(qū)域
如果表是在系統(tǒng)表空間中創(chuàng)建的派歌,而不是單表單文件表空間或常規(guī)表空間弯囊,則系統(tǒng)表空間中還會(huì)保存表和索引的數(shù)據(jù)痰哨。
在早期的MySQL版本中,系統(tǒng)表空間包含InnoDB數(shù)據(jù)字典匾嘱。在MySQL 8.0中斤斧,InnoDB數(shù)據(jù)存儲(chǔ)在MySQL數(shù)據(jù)字典中
系統(tǒng)表空間可以有一個(gè)或多個(gè)數(shù)據(jù)文件,默認(rèn)情況下霎烙,有一個(gè)單獨(dú)的數(shù)據(jù)文件被創(chuàng)建在數(shù)據(jù)目錄下撬讽,名稱(chēng)為:iddata1
MySQL8開(kāi)始刪除了原來(lái)的frm文件,并采用 Serialized Dictionary Information (SDI), SDI是MySQL8.0重新設(shè)計(jì)數(shù)據(jù)詞典后引入的新產(chǎn)物,并開(kāi)始已經(jīng)統(tǒng)一使用InnoDB存儲(chǔ)引擎來(lái)存儲(chǔ)表的元數(shù)據(jù)信息悬垃。SDI信息源記錄保存在ibd文件中
????2.1.2 獨(dú)立表空間(File-Per-Table Tablespaces)
????默認(rèn)開(kāi)啟游昼,獨(dú)立表空間是一個(gè)單表表空間,該表創(chuàng)建于自己的數(shù)據(jù)文件中尝蠕,而非創(chuàng)建于 系統(tǒng)表空間中烘豌。當(dāng)innodb_file_per_table選項(xiàng)開(kāi)啟時(shí),表將被創(chuàng)建于表空間中看彼。否則廊佩, innodb將被創(chuàng)建于系統(tǒng)表空間中。每個(gè)表文件表空間由一個(gè).ibd數(shù)據(jù)文件代表靖榕,該文件 默認(rèn)被創(chuàng)建于數(shù)據(jù)庫(kù)目錄中标锄。表空間的表文件支持動(dòng)態(tài)(dynamic)和壓縮 (commpressed)行格式
????2.1.3通用表空間(General Tablespaces)
????是使用CREATE TABLESPACE語(yǔ)法創(chuàng)建的共享InnoDB表空間,和系統(tǒng)表空間類(lèi)似茁计,也是共享的表空間料皇,一個(gè)文件能夠存儲(chǔ)多個(gè)表數(shù)據(jù)。
????通過(guò)CREATE TABLESPACE創(chuàng)建的共享表空間
????2.1.4 Undo表空間(Undo Tablespaces)
????撤銷(xiāo)日志又叫回滾表空間星压,用來(lái)保存回滾日志践剂,即undo logs。記錄數(shù)據(jù)更改前的快照(感覺(jué)就是備份)租幕,在數(shù)據(jù)需要回滾就可以根據(jù)undo log恢復(fù)舷手。
????那些undo log 記錄關(guān)于在global temporary tablespace 的用戶(hù)臨時(shí)表的回滾信息,不會(huì)在回滾中恢復(fù)劲绪。
????該表空間有rollback segments,rollback segments是用于存?undo log segments, 而undo log segments存的就是undo logs男窟。
????mysql啟動(dòng)的時(shí)候盆赤,默認(rèn)初始兩個(gè)undo tablespace。因?yàn)閟ql執(zhí)行前必須要有rollback segments歉眷。而兩個(gè)undo tablespace才支持automated truncation of undo牺六。
truncating?undo?tablespaces
????2.1.5?臨時(shí)表空間(emporary Tablespaces)
????InnoDB把?Temporary Tablespaces分為兩種,session temporary tablespaces?和global temporary tablespace汗捡。
session temporary tablespaces存儲(chǔ)的是用戶(hù)創(chuàng)建的臨時(shí)表和內(nèi)部的臨時(shí)表淑际,一個(gè)session最多有兩個(gè)表空間(用戶(hù)臨時(shí)表和內(nèi)部臨時(shí)表)。
global temporary tablespace儲(chǔ)存用戶(hù)臨時(shí)表的回滾段(rollback segments )扇住。
????2.1.6 數(shù)據(jù)字典
????InnoDB數(shù)據(jù)字典由內(nèi)部系統(tǒng)表組成春缕,這些表包含用于查找表、索引和表字段等對(duì)象的元數(shù) 據(jù)艘蹋。元數(shù)據(jù)物理上位于InnoDB系統(tǒng)表空間中锄贼。由于歷史原因,數(shù)據(jù)字典元數(shù)據(jù)在一定程度上 與InnoDB表元數(shù)據(jù)文件(.frm文件)中存儲(chǔ)的信息重疊女阀。
2.2?雙寫(xiě)緩沖區(qū)(Doublewrite Buffer)
????
????雙寫(xiě)緩沖區(qū)是系統(tǒng)表空間中的一個(gè)存儲(chǔ)區(qū)域宅荤。InnoDB在將從緩沖池中刷新的頁(yè)面寫(xiě)入數(shù)據(jù)文件中的適當(dāng)位置之前,將它們寫(xiě)入其中浸策。只有在刷新頁(yè)面并將其寫(xiě)入doublewrite緩沖區(qū)之后冯键,InnoDB才會(huì)將頁(yè)面寫(xiě)入其正確的位置。如果在頁(yè)面寫(xiě)入過(guò)程中出現(xiàn)操作系統(tǒng)庸汗、存儲(chǔ)子系統(tǒng)或mysqld進(jìn)程崩潰惫确,InnoDB可以在崩潰恢復(fù)期間從doublewrite緩沖區(qū)中找到頁(yè)面的一個(gè)好副本。
????盡管數(shù)據(jù)總是寫(xiě)兩次夫晌,但doublewrite緩沖區(qū)不需要兩倍的I/O開(kāi)銷(xiāo)或兩倍的I/O操作雕薪。數(shù)據(jù)作為一個(gè)大的連續(xù)塊寫(xiě)入doublewrite緩沖區(qū),只需對(duì)操作系統(tǒng)進(jìn)行一次fsync()調(diào)用晓淀。
????在大多數(shù)情況下所袁,默認(rèn)情況下啟用雙寫(xiě)緩沖區(qū)。要禁用doublewrite緩沖區(qū)凶掰,請(qǐng)將 innodb_doublewrite設(shè)置為0燥爷。
????如果系統(tǒng)表空間文件(“ibdata文件”)位于支持原子寫(xiě)入的Fusion io設(shè)備上,則會(huì)自動(dòng)禁用doublewrite緩沖懦窘,并對(duì)所有數(shù)據(jù)文件使用Fusion-io原子寫(xiě)入前翎。由于doublewrite緩沖區(qū)設(shè)置是全局的,因此也會(huì)對(duì)駐留在non-Fusion-io 硬件上的數(shù)據(jù)文件禁用doublewrite緩沖畅涂。此功能僅在 Fusion-io硬件上受支持港华,并且僅在Linux上為Fusion-io NVMFS啟用。為了充分利用這一特性午衰,建議將innodb_flush_method設(shè)置為O_DIRECT立宜。
2.3?重做日志(Redo Log)
????重做日志是一種基于磁盤(pán)的數(shù)據(jù)結(jié)構(gòu)冒萄,用于在崩潰恢復(fù)期間更正不完整事務(wù)寫(xiě)入的數(shù)據(jù)。記錄的DML操作的日志橙数,可以用來(lái)宕機(jī)后的數(shù)據(jù)前滾尊流。(在log buffer的redo log日志會(huì)在宕機(jī)中丟失)
要更改重做日志文件的數(shù)量或大小,請(qǐng)執(zhí)行以下步驟:
停止MySQL服務(wù)器并確保它在沒(méi)有錯(cuò)誤的情況下關(guān)閉灯帮。
編輯my.cnf以更改日志文件配置崖技。要更改日志文件大小,請(qǐng)配置innodb_log_file_size钟哥。
要增加日志文件的數(shù)量迎献,請(qǐng)配置innodb_log_files_in_group。
重新啟動(dòng)MySQL服務(wù)器瞪醋。
如果InnoDB檢測(cè)到 innodb_log_file_size 與重做日志文件大小不同忿晕,它將寫(xiě)入日志檢查點(diǎn)装诡,關(guān)閉并刪除舊的日志文件银受,以請(qǐng)求的大小創(chuàng)建新的日志文件,并打開(kāi)新的日志文件鸦采。
????Group Commit for Redo Log Flushing
????與任何其他符合ACID的數(shù)據(jù)庫(kù)引擎一樣宾巍,InnoDB在提交事務(wù)之前刷新該事務(wù)的重做日志。InnoDB使用組提交功能將多個(gè)這樣的刷新請(qǐng)求分組在一起渔伯,以避免每次提交都有一個(gè)刷新顶霞。對(duì)于組提交,InnoDB向日志文件發(fā)出一次寫(xiě)操作锣吼,以對(duì)幾乎同時(shí)提交的多個(gè)用戶(hù)事務(wù)執(zhí)行提交操作选浑,從而顯著提高吞吐量。
????好了玄叠,以上就是InnoDB的底層結(jié)構(gòu)有關(guān)所有的了古徒。更細(xì)節(jié)的東西可能需要大家自己在查查資料,翻翻文檔去學(xué)習(xí)下了读恃。本篇關(guān)于InnoDB的結(jié)構(gòu)就說(shuō)到這里隧膘。
????下一篇,我們說(shuō)一說(shuō)MySQL的核心算法——LRU算法
(ps:可以說(shuō)是核心吧K卤埂疹吃!,感覺(jué)必問(wèn)的西雀。(* ̄︶ ̄)……)
…………………………………分割線……………………………
不積跬步萨驶,無(wú)以至千里;不積小流艇肴,無(wú)以成江海腔呜。
關(guān)注我判莉,每天分享一些小知識(shí)點(diǎn)。分享自己的小心得育谬,包含但不限于初券盅、中、高級(jí)面試題呦L盘础C潭啤!
我都墨跡這么半天了 咖刃,你不點(diǎn)關(guān)注泳炉,不點(diǎn)贊,不收藏嚎杨,還不轉(zhuǎn)發(fā)花鹅,你想干啥!7阏恪E偎唷!