InnoDB 內(nèi)存和磁盤結(jié)構(gòu)介紹

前言

??本來只是想了解下redo、undo log的機(jī)制盗胀,但發(fā)現(xiàn)好像牽扯挺多知識點(diǎn),就寫了這篇文章記錄下票灰。。米间。

InnoDB 架構(gòu)

本文分析的mysql版本為8.0

innodb-architecture.png

一 InnoDB 內(nèi)存結(jié)構(gòu)

1.1 Buffer pool

??Buffer pool(下文簡稱BP) 是在主內(nèi)存中的一塊區(qū)域膘侮,用于在訪問時緩存表和索引數(shù)據(jù)屈糊。它可以直接從內(nèi)存處理數(shù)據(jù),因此處理速度非城砹耍快。
??為了提高大容量讀取操作的效率雕薪,BP被分成可以容納多行的Page(默認(rèn)16K)。BP的底層數(shù)據(jù)結(jié)構(gòu)是鏈表所袁,以此管理Page。

innodb-buffer-pool-list.png
1.1.1 Buffer Pool LRU

??BP的LRU是一種變體燥爷。BP插入數(shù)據(jù)時懦窘,采用了中間策略(midpoint insertion strategy)稚配。中間策略將BP視為兩個子列表:

new sublist : 存放最近訪問的子列表
old sublist : 存放最近訪問較少的子列表 

LRU算法主要的操作如下:

  • 默認(rèn)將3/8的BP空間分配給old sublist
  • 規(guī)定midpointnew sublist的tail 與 old sublist的head交界處
  • InnoDB讀取Page到BP時畅涂,插入到midpoint(old sublist的頭部)道川。Page被讀取有兩種情況:
    • 用戶的sql查詢
    • InnoDB的預(yù)讀操作
  • 當(dāng)訪問old sublist的Page時,會將其移到new sublist的head,實(shí)際上幾乎所有的read Page操作都會將其移動到new sublist的head冒萄。除了預(yù)讀的Page的情況,預(yù)讀后如果一直沒其他的讀操作,該P(yáng)age最終會從tail剔除
  • 隨著數(shù)據(jù)庫的運(yùn)行,一直沒有被訪問的page會被移向tail尊流,最終被剔除
1.1.2 Making the Buffer Pool Scan Resistant

默認(rèn)情況下,會出現(xiàn)以下兩種case

  • 因表掃描奠旺,大量數(shù)據(jù)讀入BP施流,但這數(shù)據(jù)之后不再被使用
  • 由預(yù)讀加載然后僅訪問一次的Page移動到新列表的頭部

這兩種情況可以將經(jīng)常使用的page移向到舊子列表中,最終導(dǎo)致被剔除瞪醋。
因此InnoDB做了Making the Buffer Pool Scan Resistant這個優(yōu)化。簡單的說就是讀取Page插入到BP的時候不是插入到midpoint而是先插入到old sublist的tail 银受,第一次被讀取的時候,再移到midpoint宾巍。
另外的一些參數(shù)優(yōu)化可參考官方文檔:

Making the Buffer Pool Scan Resistant
Configuring InnoDB Buffer Pool Prefetching (Read-Ahead)

1.2 Change Buffer

??Change Buffer(以下簡稱CB) 存在于內(nèi)存,當(dāng)對輔助索引(secondary index) 進(jìn)行DML操作時顶霞,BP沒有其相應(yīng)的Page,會將這些變更緩存到CP中选浑。當(dāng)CB里的Page被read的時候,會被合并到BP中古徒。當(dāng)臟頁超過一定比例時,會將其flush磁盤中隧膘。 CB的內(nèi)存默認(rèn)占BP的25%寺惫。
??個人認(rèn)為刷新頁到磁盤時沒有將CB的數(shù)據(jù)刷到磁盤,因?yàn)镃B中的數(shù)據(jù)只有在被讀到的時候才會和BP合并肌蜻,因此數(shù)據(jù)庫對應(yīng)的舊數(shù)據(jù)也不會被讀,所以也不急著和flush到磁盤蒋搜。判莉。豆挽。券盅。

innodb-change-buffer.png
1.2.1 CB帶來的提升

??原本修改BP不存在的Page需要先從磁盤讀取(一次IO操作)到內(nèi)存锰镀,然后寫redo log。
??引入CB后泳炉,會先緩存在CB,然后寫redo log花鹅。
由于CB的存在,避免了從磁盤讀取輔助索引到緩沖池所需的大量隨機(jī)訪問I / O刨肃。

輔助索引不支持Change Buffer的情況:

  • 如輔助索引包含降序索引列
  • 主鍵包含降序索引

PS. 降序索引在8.0以上版本才支持。

1.3. Adaptive Hash Index

??Adaptive Hash Index對InnoDB在BP的查詢有很大的優(yōu)化真友。針對BP中熱點(diǎn)頁數(shù)據(jù),構(gòu)建索引(一般使用索引鍵的前綴構(gòu)建哈希索引)锻狗。因?yàn)镠ASH索引的等值查詢效率遠(yuǎn)高于B+ tree,所以當(dāng)查詢命中hash轻纪,就能很快返回結(jié)果,不用再去遍歷B+ tree刻帚。

1.4. Log Buffer

??Log Buffer是保存要寫入磁盤上日志文件的數(shù)據(jù)的內(nèi)存區(qū)域。默認(rèn)大小16MB崇众。相關(guān)參數(shù)設(shè)置如下

  • innodb_log_buffer_size : 設(shè)置大小
  • innodb_flush_log_at_trx_commit : 刷新行為航厚。默認(rèn)值:1锰蓬, 取值有0幔睬,1芹扭,2三種麻顶。
    • 0: 日志每秒刷新到磁盤舱卡。 未刷新日志的事務(wù)會在mysql崩潰中丟失
    • 1: 每次提交事務(wù)時,寫入并刷新日志到磁盤
    • 2: 每次提交事務(wù)后寫入日志轮锥,并每秒刷新一次磁盤。 未刷新日志的事務(wù)可能會在mysql崩潰中丟失舍杜。
  • innodb_flush_log_at_timeout:每幾秒刷新日志,取值范圍 [1,2700] (second)

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

2.1 Tablespaces

2.1.1 The System Tablespace

The System Tablespace 是Doublewrite Buffer和Change buffer的儲存區(qū)域既绩,也有用戶創(chuàng)建的表和索引數(shù)據(jù)。該空間的數(shù)據(jù)文件通過參數(shù)innodb_data_file_path控制熬词,默認(rèn)值是ibdata1:12M:autoextend(文件名為ibdata1吸重,大小略大于12MB,自動擴(kuò)展)嚎幸。

8.0之后InnoDB將元數(shù)據(jù)(以前的.frm文件,存表結(jié)構(gòu))存在該區(qū)域的數(shù)據(jù)字典中(data dictionary)嫉晶。

2.1.2 File-Per-Table Tablespaces

File-Per-Table Tablespaces 默認(rèn)開啟,為每個表都獨(dú)立建一個.ibd文件。 通過參數(shù)innodb_file_per_tabl 可以設(shè)置關(guān)閉替废,這樣的話所有表數(shù)據(jù)是都存在The System Tablespace的ibdata。

2.1.3 General Tablespaces

General Tablespaces 是通過CREATE TABLESPACE創(chuàng)建的共享表空間椎镣。

2.1.4 Undo Tablespaces

Undo Tablespaces保存的是undo log ,用于回滾事務(wù)状答。
該表空間有rollback segments,rollback segments是用于存 undo log segments, 而undo log segments存的就是undo logs刀崖。

mysql啟動的時候,默認(rèn)初始兩個undo tablespace亮钦。因?yàn)閟ql執(zhí)行前必須要有rollback segments。而兩個undo tablespace才支持automated truncation of undo蜂莉。

truncating undo tablespaces

2.1.5 Temporary Tablespaces

InnoDB把 Temporary Tablespaces分為兩種,session temporary tablespacesglobal temporary tablespace巡语。
session temporary tablespaces存儲的是用戶創(chuàng)建的臨時表和內(nèi)部的臨時表,一個session最多有兩個表空間(用戶臨時表和內(nèi)部臨時表)男公。
global temporary tablespace儲存用戶臨時表的回滾段(rollback segments )。

2.2 Doublewrite Buffer

Doublewrite Buffer位于The System Tablespace合陵。在BP的頁數(shù)據(jù)刷到磁盤真正的位置前,會先將數(shù)據(jù)存在doublewrite buffer拥知。 這步操作是直接將數(shù)據(jù)作為順序塊,調(diào)用OS的fsync()方法寫入到doublewrite buffer低剔。

雖然數(shù)據(jù)寫了兩次,但是性能還是比兩次IO低的襟齿。
此外fsync保證了BP中的數(shù)據(jù)寫到磁盤中,即使數(shù)據(jù)庫掛了猜欺,還可以從doublewrite buffer中還原數(shù)據(jù)。
還可以解決頁斷裂的問題

https://www.cnblogs.com/cchust/p/3961260.html

2.3 Redo log

redo log記錄的DML操作的日志开皿,可以用來宕機(jī)后的數(shù)據(jù)前滾。(在log buffer的redo log日志會在宕機(jī)中丟失)

2.4 undo log

undo log記錄數(shù)據(jù)更改前的快照(感覺就是備份)赋荆,在數(shù)據(jù)需要回滾就可以根據(jù)undo log恢復(fù)。

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

總結(jié)

個人記錄,并不一定都是對的信认,還是得好好看看官方文檔,不斷琢磨。嫁赏。。

https://dev.mysql.com/doc/refman/8.0/en/innodb-in-memory-structures.html
https://dev.mysql.com/doc/refman/8.0/en/innodb-on-disk-structures.html

博客

個人博客同步更新

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末款熬,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子贤牛,更是在濱河造成了極大的恐慌,老刑警劉巖殉簸,帶你破解...
    沈念sama閱讀 217,509評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件沽讹,死亡現(xiàn)場離奇詭異般卑,居然都是意外死亡爽雄,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評論 3 394
  • 文/潘曉璐 我一進(jìn)店門挚瘟,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人乘盖,你說我怎么就攤上這事〔嗬欤” “怎么了监氢?”我有些...
    開封第一講書人閱讀 163,875評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長浪腐。 經(jīng)常有香客問我,道長议街,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,441評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮骨杂,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘搓蚪。我一直安慰自己,他們只是感情好妒潭,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,488評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著雳灾,像睡著了一般。 火紅的嫁衣襯著肌膚如雪谎亩。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,365評論 1 302
  • 那天团驱,我揣著相機(jī)與錄音空凸,去河邊找鬼嚎花。 笑死呀洲,一個胖子當(dāng)著我的面吹牛紊选,可吹牛的內(nèi)容都是我干的道逗。 我是一名探鬼主播,決...
    沈念sama閱讀 40,190評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼滓窍,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了吏夯?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,062評論 0 276
  • 序言:老撾萬榮一對情侶失蹤噪生,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后跺嗽,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體页藻,經(jīng)...
    沈念sama閱讀 45,500評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡植兰,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,706評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了钉跷。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,834評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡爷辙,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出膝晾,到底是詐尸還是另有隱情,我是刑警寧澤血当,帶...
    沈念sama閱讀 35,559評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站臊旭,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏离熏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,167評論 3 328
  • 文/蒙蒙 一滋戳、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧奸鸯,春花似錦、人聲如沸娄涩。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至弯蚜,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間碎捺,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評論 1 269
  • 我被黑心中介騙來泰國打工收厨, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留晋柱,地道東北人诵叁。 一個月前我還...
    沈念sama閱讀 47,958評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像拧额,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子侥锦,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,779評論 2 354

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