淺談MySQL中InnoDB的結(jié)構(gòu)(2)

上一期我們聊了InnoDB的內(nèi)存結(jié)構(gòu),那么我們這一期說一說磁盤結(jié)構(gòu)。


一、前期回顧


二、InnoDB的磁盤結(jié)構(gòu)

????InnoDB磁盤主要包含Tablespace(表空間),Data Dictionary數(shù)據(jù)字典,Doublewrite Buffer(雙寫緩沖區(qū))、redo log(重做日志) 和undo log(撤銷日志)

2.1 表空間

????用于存儲表結(jié)構(gòu)和數(shù)據(jù)。表空間又分為系統(tǒng)表空間、獨(dú)立表空間、 通用表空間、臨時(shí)表空間、Undo表空間等多種類型


????2.1.1系統(tǒng)表空間(The System Tablespace)


????系統(tǒng)表空間:系統(tǒng)表空間是存放change buffer的區(qū)域,Change Buffer是緩存那些不在buffer pool里的輔助索引的變化的特殊數(shù)據(jù)結(jié)構(gòu)。在磁盤上,Change Buffer是system tablespace(系統(tǒng)表空間)的一部分,當(dāng)數(shù)據(jù)庫宕機(jī)時(shí),索引的變更會被緩沖到磁盤的Change Buffer區(qū)域

    • 如果表是在系統(tǒng)表空間中創(chuàng)建的,而不是單表單文件表空間或常規(guī)表空間,則系統(tǒng)表空間中還會保存表和索引的數(shù)據(jù)。

    • 在早期的MySQL版本中,系統(tǒng)表空間包含InnoDB數(shù)據(jù)字典。在MySQL 8.0中,InnoDB數(shù)據(jù)存儲在MySQL數(shù)據(jù)字典中

    • 系統(tǒng)表空間可以有一個(gè)或多個(gè)數(shù)據(jù)文件,默認(rèn)情況下,有一個(gè)單獨(dú)的數(shù)據(jù)文件被創(chuàng)建在數(shù)據(jù)目錄下,名稱為:iddata1

    • MySQL8開始刪除了原來的frm文件,并采用 Serialized Dictionary Information (SDI), SDI是MySQL8.0重新設(shè)計(jì)數(shù)據(jù)詞典后引入的新產(chǎn)物,并開始已經(jīng)統(tǒng)一使用InnoDB存儲引擎來存儲表的元數(shù)據(jù)信息。SDI信息源記錄保存在ibd文件中


????2.1.2 獨(dú)立表空間(File-Per-Table Tablespaces)


????默認(rèn)開啟,獨(dú)立表空間是一個(gè)單表表空間,該表創(chuàng)建于自己的數(shù)據(jù)文件中,而非創(chuàng)建于 系統(tǒng)表空間中。當(dāng)innodb_file_per_table選項(xiàng)開啟時(shí),表將被創(chuàng)建于表空間中。否則, innodb將被創(chuàng)建于系統(tǒng)表空間中。每個(gè)表文件表空間由一個(gè).ibd數(shù)據(jù)文件代表,該文件 默認(rèn)被創(chuàng)建于數(shù)據(jù)庫目錄中。表空間的表文件支持動態(tài)(dynamic)和壓縮 (commpressed)行格式


????2.1.3通用表空間(General Tablespaces)


????是使用CREATE TABLESPACE語法創(chuàng)建的共享InnoDB表空間,和系統(tǒng)表空間類似,也是共享的表空間,一個(gè)文件能夠存儲多個(gè)表數(shù)據(jù)。

????通過CREATE TABLESPACE創(chuàng)建的共享表空間


????2.1.4 Undo表空間(Undo Tablespaces)


????撤銷日志又叫回滾表空間,用來保存回滾日志,即undo logs。記錄數(shù)據(jù)更改前的快照(感覺就是備份),在數(shù)據(jù)需要回滾就可以根據(jù)undo log恢復(fù)。

????那些undo log 記錄關(guān)于在global temporary tablespace 的用戶臨時(shí)表的回滾信息,不會在回滾中恢復(fù)。

????該表空間有rollback segments,rollback segments是用于存?undo log segments, 而undo log segments存的就是undo logs。

????mysql啟動的時(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存儲的是用戶創(chuàng)建的臨時(shí)表和內(nèi)部的臨時(shí)表,一個(gè)session最多有兩個(gè)表空間(用戶臨時(shí)表和內(nèi)部臨時(shí)表)。

    • global temporary tablespace儲存用戶臨時(shí)表的回滾段(rollback segments )。


????2.1.6 數(shù)據(jù)字典

????InnoDB數(shù)據(jù)字典由內(nèi)部系統(tǒng)表組成,這些表包含用于查找表、索引和表字段等對象的元數(shù) 據(jù)。元數(shù)據(jù)物理上位于InnoDB系統(tǒng)表空間中。由于歷史原因,數(shù)據(jù)字典元數(shù)據(jù)在一定程度上 與InnoDB表元數(shù)據(jù)文件(.frm文件)中存儲的信息重疊。


2.2?雙寫緩沖區(qū)(Doublewrite Buffer)

????

????雙寫緩沖區(qū)是系統(tǒng)表空間中的一個(gè)存儲區(qū)域。InnoDB在將從緩沖池中刷新的頁面寫入數(shù)據(jù)文件中的適當(dāng)位置之前,將它們寫入其中。只有在刷新頁面并將其寫入doublewrite緩沖區(qū)之后,InnoDB才會將頁面寫入其正確的位置。如果在頁面寫入過程中出現(xiàn)操作系統(tǒng)、存儲子系統(tǒng)或mysqld進(jìn)程崩潰,InnoDB可以在崩潰恢復(fù)期間從doublewrite緩沖區(qū)中找到頁面的一個(gè)好副本。


????盡管數(shù)據(jù)總是寫兩次,但doublewrite緩沖區(qū)不需要兩倍的I/O開銷或兩倍的I/O操作。數(shù)據(jù)作為一個(gè)大的連續(xù)塊寫入doublewrite緩沖區(qū),只需對操作系統(tǒng)進(jìn)行一次fsync()調(diào)用。


????在大多數(shù)情況下,默認(rèn)情況下啟用雙寫緩沖區(qū)。要禁用doublewrite緩沖區(qū),請將 innodb_doublewrite設(shè)置為0。


????如果系統(tǒng)表空間文件(“ibdata文件”)位于支持原子寫入的Fusion io設(shè)備上,則會自動禁用doublewrite緩沖,并對所有數(shù)據(jù)文件使用Fusion-io原子寫入。由于doublewrite緩沖區(qū)設(shè)置是全局的,因此也會對駐留在non-Fusion-io 硬件上的數(shù)據(jù)文件禁用doublewrite緩沖。此功能僅在 Fusion-io硬件上受支持,并且僅在Linux上為Fusion-io NVMFS啟用。為了充分利用這一特性,建議將innodb_flush_method設(shè)置為O_DIRECT。


2.3?重做日志(Redo Log)


????重做日志是一種基于磁盤的數(shù)據(jù)結(jié)構(gòu),用于在崩潰恢復(fù)期間更正不完整事務(wù)寫入的數(shù)據(jù)。記錄的DML操作的日志,可以用來宕機(jī)后的數(shù)據(jù)前滾。(在log buffer的redo log日志會在宕機(jī)中丟失)


要更改重做日志文件的數(shù)量或大小,請執(zhí)行以下步驟:

    • 停止MySQL服務(wù)器并確保它在沒有錯(cuò)誤的情況下關(guān)閉。

    • 編輯my.cnf以更改日志文件配置。要更改日志文件大小,請配置innodb_log_file_size。

    • 要增加日志文件的數(shù)量,請配置innodb_log_files_in_group。

    • 重新啟動MySQL服務(wù)器。

如果InnoDB檢測到 innodb_log_file_size 與重做日志文件大小不同,它將寫入日志檢查點(diǎn),關(guān)閉并刪除舊的日志文件,以請求的大小創(chuàng)建新的日志文件,并打開新的日志文件。


????Group Commit for Redo Log Flushing


????與任何其他符合ACID的數(shù)據(jù)庫引擎一樣,InnoDB在提交事務(wù)之前刷新該事務(wù)的重做日志。InnoDB使用組提交功能將多個(gè)這樣的刷新請求分組在一起,以避免每次提交都有一個(gè)刷新。對于組提交,InnoDB向日志文件發(fā)出一次寫操作,以對幾乎同時(shí)提交的多個(gè)用戶事務(wù)執(zhí)行提交操作,從而顯著提高吞吐量。


????好了,以上就是InnoDB的底層結(jié)構(gòu)有關(guān)所有的了。更細(xì)節(jié)的東西可能需要大家自己在查查資料,翻翻文檔去學(xué)習(xí)下了。本篇關(guān)于InnoDB的結(jié)構(gòu)就說到這里。

????下一篇,我們說一說MySQL的核心算法——LRU算法

(ps:可以說是核心吧!!,感覺必問的。(* ̄︶ ̄)……)



…………………………………分割線……………………………

不積跬步,無以至千里;不積小流,無以成江海。

關(guān)注我,每天分享一些小知識點(diǎn)。分享自己的小心得,包含但不限于初、中、高級面試題呦!!!


我都墨跡這么半天了 ,你不點(diǎn)關(guān)注,不點(diǎn)贊,不收藏,還不轉(zhuǎn)發(fā),你想干啥!!!!



?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容