【書 : InnoDB 存儲引擎】第2章 InnoDB 內(nèi)核體系

2.1 InnoDB 概述

2.2 InnoDB 版本

2.3 InnoDB 體系架構(gòu)

后臺線程的主要作用是負(fù)責(zé)刷新內(nèi)存池中的數(shù)據(jù)熬甫, 保證緩沖池中的內(nèi)存緩存的是最近的數(shù)據(jù)假抄。 此外將已修改的數(shù)據(jù)文件刷新到磁盤文件, 同時保證在數(shù)據(jù)庫發(fā)生異常的情況下 InnoDB 能恢復(fù)到正常運行的狀態(tài)。

2.3.1 后臺線程

1 Master Thread

主線程主要負(fù)責(zé)將緩沖池中的數(shù)據(jù)異步刷新到磁盤, 保證數(shù)據(jù)的一致性, 包括臟頁的刷新翘簇、合并插入緩沖(Insert Buffer), Undo 頁的回收等儿倒。

2 IO Thread

IO 線程主要負(fù)責(zé) AIO(async IO)請求的回調(diào)(call back)處理版保。 從 InnoDB 1.0.x 開始, read thread 和 write thread 分別增到到了 4 個义桂, 用 innodb_read_io_threads 和 innodb_write_io_threads 參數(shù)進(jìn)行設(shè)置找筝。


上圖可以看到 IO Thread 0 為 insert buffer thread。 IO Thread 1 為 log thread 慷吊。 之后就是 innodb_read_io_threads 及 innodb_write_io_threads 來設(shè)置的讀寫線程袖裕, 且 讀線程的 ID 總是 小于寫線程。?

3 Purge Thread

事務(wù)被提交后溉瓶, 其所使用的 undo log 可能不再需要, 因此需要 purge thread 來回收已經(jīng)使用并分配的 undo 頁。 從 Innodb 1.2 版本開始辆影, Innodb 支持多個 purge thread , 這樣做的目的是為了進(jìn)一步加快 undo 頁的回收。 同時由于 purge thread 需要離散地讀取 undo 頁张足, 這樣也能更進(jìn)一步利用磁盤的隨機讀取性能。

4 Page Cleaner Thread

作用是將之前版本中臟頁的刷新操作都放入到單獨的線程中來完成坎藐。 目的是為了減輕原 master thread 的工作及對于用戶查詢線程的阻塞为牍, 進(jìn)一步提高 Innodb 引擎的性能。

2.3.2 內(nèi)存

1 緩沖池

Innodb 引擎是基于磁盤存儲的岩馍, 并將其中記錄按照頁的方式進(jìn)行管理碉咆。 因此可將其視為基于磁盤的數(shù)據(jù)庫系統(tǒng)。

需要注意蛀恩, 頁從緩沖池刷新回磁盤的操作并不是在每次頁發(fā)生更新時觸發(fā)疫铜, 而是通過一種稱為 checkpoint 的機制刷新回磁盤。 同樣是為了提高數(shù)據(jù)庫的整體性能双谆。

緩沖池的配置通過參數(shù) innodb_buffer_pool_size 來設(shè)置壳咕。

緩沖池中緩沖的數(shù)據(jù)頁類型有: 索引頁, 數(shù)據(jù)頁顽馋, undo 頁谓厘, 插入緩沖(insert buffer),自適應(yīng)哈希索引(adaptive hash index), innodb 存儲的鎖信息(lock info), 數(shù)據(jù)字典信息(data dictionary)等.

參數(shù) innodb_buffer_pool_instances 來配置允許有多少個緩沖池實例寸谜。

從 mysql 5.6 開始庞呕, 通過 information_schema 下的 innodb_buffer_pool_stats 來觀察緩沖狀態(tài)。

2 LRU List程帕, Free List 和 Flush List

通常來說, 數(shù)據(jù)庫中的緩沖池是通過 LRU (Latest Recent Used)算法來管理的地啰。

在 innodb 存儲引擎中愁拭, 緩沖池頁的大小默認(rèn)為 16KB , 同樣用 LRU 算法對緩洪池進(jìn)行管理亏吝。

midpoint insertion strategy: ?新讀取到的頁岭埠, 雖然是最新訪問的頁, 但并不是直接放入到 LRU 列表的首部蔚鸥, 而是放入到 LRU 列表的 midpoint 位置惜论。 默認(rèn)配置下, 該位置在 LRU 列表長度的 5 / 8 出止喷。 midpoint 位置可由參數(shù) innodb_old_blocks_pct 控制馆类。 innodb_old_blocks_pct 默認(rèn)值為 37 , 表示新讀取的頁插入到 LRU 列表尾端的 37% 位置(差不多 3 / 8 處)弹谁。 在 Innodb 中乾巧, 把 midpoint 之后的列表稱為 old 列表句喜, 之前的列表 稱為 new 列表。 可以簡單理解為 new 列表的頁都是最為活躍的熱點數(shù)據(jù)沟于。?

參數(shù) innodb_old_blocks_time : 用于表示頁讀取到 mid 位置后需要等待多久才會被加入到 LRU 列表的熱端咳胃。

database pages 表示 LRU 列表中頁的數(shù)量。

pages made young 顯示了 LRU 列表中頁移動到前端的次數(shù)旷太, 若服務(wù)器運行階段沒有改變 innodb_old_blocks_time 的值展懈, 則 not young 為 0

modified db pages 顯示了臟頁的數(shù)量。

可通過表 innodb_buffer_page_lru 觀察每個 LRU 列表中每個頁的具體信息供璧。

在 LRU 列表中頁被修改后存崖, 該頁為臟頁(dirty page), 即緩沖池中的頁和磁盤上的頁的數(shù)據(jù)不一致嗜傅, 這時數(shù)據(jù)庫會通過 checkpoint 機制將臟頁刷新回磁盤金句, 而 flush 列表中的頁即為臟頁列表。 需要注意吕嘀, 臟頁既存在與 LRU 列表中违寞, 也存在于 Flush 列表中。 LRU 列表用來管理緩沖池中頁的可用性偶房, Flush 列表用來管理將頁刷新回磁盤趁曼。

3 重做日志緩沖

重做日志緩沖一般不需要設(shè)置得很大, 因為一般情況下每一秒會將重做日志緩沖刷新到日志文件棕洋, 因此用戶只需要保證每秒產(chǎn)生的事務(wù)量在扎個緩沖大小之內(nèi)即可挡闰。 該值可由 innodb_log_buffer_size 控制, 默認(rèn) 8MB掰盘。

重做日志在下列三種情況下會將重做日志緩沖中的內(nèi)容刷新到外部磁盤的重做日志文件中:

1 master thread 每一秒將重做日志緩沖刷新到重做日志文件摄悯;

2 每個事務(wù)提交時會將重做日志緩沖刷新到重做日志文件;

3 當(dāng)重做日志緩沖池剩余空間小于 1 / 2 時愧捕, 重做日志換成刷新到重做日志文件奢驯。

4 額外的內(nèi)存池



2.4 CheckPoint 技術(shù)

倘若每次一個頁發(fā)生變化, 就將新頁的版本刷新到磁盤次绘, 這個開銷就非常大了瘪阁, 當(dāng)前事務(wù)數(shù)據(jù)庫系統(tǒng)普遍都采用了 Write Ahead Log 策略, 即當(dāng)事務(wù)提交時邮偎, 先寫重做日志管跺,再修改頁。

checkpoint (檢查點)技術(shù)的目的是解決一下幾個問題:

1 縮短數(shù)據(jù)庫的恢復(fù)時間禾进;

2 緩沖池不夠用時豁跑, 將臟頁刷新到磁盤;

3 重做日志不可用是泻云, 刷新臟頁贩绕。

對 Innodb 引擎而言火的, 其是通過 LSN(Log Sequence Number) 來標(biāo)記版本的。

在 Innodb 引擎內(nèi)淑倾, 有兩種 checkpoint , 分別為:

1 Sharp Checpoint?

2 Fuzzy Checkpoint

Sharp Checkpoint 發(fā)生在數(shù)據(jù)庫關(guān)閉時將所有的臟頁都刷新回磁盤馏鹤, 這是默認(rèn)工作方式。

Fuzzy Checkpoint 使用 Fuzzy Checkpoint 進(jìn)行頁刷新娇哆, 即只刷新一部分臟頁湃累, 而不是刷新所有的臟頁回磁盤。

innodb_lru_scan_depth 控制 LRU 列表中可用頁的數(shù)量碍讨, 默認(rèn)為 1024.


2.5 Master Thread 工作方式

http://www.cnblogs.com/xuanzhi201111/p/4040681.html

主線程邏輯:


2.6 InnoDB 關(guān)鍵特性

2.6.1 插入緩沖 (Insert Buffer)

1 Insert Buffer

Insert Buffer 的使用需要同時滿足以下兩個條件:

1 索引是輔助索引(secondary index)治力;

2 索引不是唯一的(unique)。

2 Change Buffer

參數(shù) innodb_change_buffering, 用來開啟各種 buffer 的選項勃黍。 參數(shù)可選值: inserts宵统, deletes, purges, changes, all, none.

從 Innodb 1.2.x 開始, 通過 innodb_change_buffer_max_size 來控制 change buffer 最大使用內(nèi)存的數(shù)量覆获。 默認(rèn)值為 25 马澈, 表示 最多使用 1 / 4 ?的緩沖池內(nèi)存空間。需要注意弄息, 該參數(shù)的最大有效值為 50.?

3 Insert Buffer 的內(nèi)部實現(xiàn)

Insert Buffer 的數(shù)據(jù)結(jié)構(gòu)是一顆 B+ 數(shù)痊班, 在現(xiàn)在的版本中, 全局只有一棵 Insert Buffer ?B + 樹摹量, 負(fù)責(zé)對所有表的輔助索引進(jìn)行 Insert Buffer涤伐。 其 非葉子節(jié)點存放的是查詢的 search key (鍵值)


4 Merge Insert Buffer

Merge Insert Buffer 的操作可能發(fā)生在一下幾種情況下:

1 輔助索引頁被讀取到緩沖池時;

2 Insert Buffer Bitmap 頁追蹤到該輔助索引頁已無可用空間時缨称;

3 Master Thread

2.6.2 兩次寫 (Double Write)

double write 由兩部分組成凝果, 一部分是內(nèi)存中的 double write buffer, 大小為 2MB睦尽; 另一部分是物理磁盤上共享表空間中連續(xù)的 128 個頁豆村, 即 2 個區(qū), 大小同樣是 2MB骂删。

2.6.3 自適應(yīng)哈希索引 (Adaptive Hash Index)

Innodb 存儲引擎會自動根據(jù)訪問的頻率和模式來自動地為某些熱點頁建立哈希索引。

訪問模式一樣指的是查詢的條件一樣四啰, 若交替進(jìn)行上述查詢宁玫, 那么 Innodb 引擎不會對該頁構(gòu)造 AHI。

哈希索引 只能用來搜索等值的查詢柑晒, 如 select *from table where index_col='xxx'. 而對于其他查找類型欧瘪, 如范圍查找, 是不能使用哈希索引的匙赞, 因此出現(xiàn)了 non-hash searches / s 的情況佛掖。 通過 hash searches:non-hash searches 可以大概了解使用哈希索引后的效率妖碉。?

2.6.4 異步 IO (Async IO)


2.6.5 刷新臨接頁 (Flush Neighbor Page)

參數(shù) innodb_flush_neighbors, 用來控制該特性。 對于傳統(tǒng)機械硬盤建議啟用該特性芥被, 對于固態(tài)硬盤有著超高 IOPS 性能的磁盤欧宜, 則建議將該參數(shù)設(shè)置為 0, 即關(guān)閉次特性拴魄。

2.7 啟動冗茸、關(guān)閉與恢復(fù)

參數(shù) innodb_fast_shutdown 影響著表的存儲引擎 Innodb 的行為。 參數(shù)可取值為 0匹中, 1, 2 夏漱, 默認(rèn)為 1.

為 0 時, ?表示數(shù)據(jù)庫關(guān)閉時顶捷, innodb 需要完成 所有的 full purge 和 merge insert buffer, 并且將所欲的臟頁刷新回磁盤挂绰。 如果在進(jìn)行 Innodb 升級時, 必須將這個參數(shù)調(diào)為 0服赎, 然后再關(guān)閉數(shù)據(jù)庫葵蒂。

為 1 時, ?默認(rèn)值专肪, 表示不需要完成 full purge 和 merge insert buffer 操作刹勃, 單是在緩沖池中的一些數(shù)據(jù)臟頁還是會刷新回磁盤。

為 2 時嚎尤, 不完成 full purge 和 merge insert buffer 操作荔仁, 也不將緩沖池中的數(shù)據(jù)臟頁寫會磁盤, 而是將日志都寫入日志文件芽死。這樣不會有任何事物丟失乏梁, 單下次 Mysql 啟動時, 會進(jìn)行恢復(fù)操作关贵。

需要注意的是遇骑, 在設(shè)置了參數(shù) innodb_force_recovery 大于 0 后, 用戶可以對表進(jìn)行 select , create 和 drop 操作揖曾, 但 Insert 落萎,update 和delete 這類 DML 操作是不允許的。?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末炭剪,一起剝皮案震驚了整個濱河市练链,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌奴拦,老刑警劉巖媒鼓,帶你破解...
    沈念sama閱讀 216,544評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡绿鸣,警方通過查閱死者的電腦和手機疚沐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來潮模,“玉大人亮蛔,你說我怎么就攤上這事≡俚牵” “怎么了尔邓?”我有些...
    開封第一講書人閱讀 162,764評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長锉矢。 經(jīng)常有香客問我梯嗽,道長,這世上最難降的妖魔是什么沽损? 我笑而不...
    開封第一講書人閱讀 58,193評論 1 292
  • 正文 為了忘掉前任灯节,我火速辦了婚禮,結(jié)果婚禮上绵估,老公的妹妹穿的比我還像新娘炎疆。我一直安慰自己,他們只是感情好国裳,可當(dāng)我...
    茶點故事閱讀 67,216評論 6 388
  • 文/花漫 我一把揭開白布形入。 她就那樣靜靜地躺著,像睡著了一般缝左。 火紅的嫁衣襯著肌膚如雪亿遂。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,182評論 1 299
  • 那天渺杉,我揣著相機與錄音蛇数,去河邊找鬼。 笑死是越,一個胖子當(dāng)著我的面吹牛耳舅,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播倚评,決...
    沈念sama閱讀 40,063評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼浦徊,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了天梧?” 一聲冷哼從身側(cè)響起盔性,我...
    開封第一講書人閱讀 38,917評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎腿倚,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,329評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡敷燎,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,543評論 2 332
  • 正文 我和宋清朗相戀三年暂筝,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片硬贯。...
    茶點故事閱讀 39,722評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡焕襟,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出饭豹,到底是詐尸還是另有隱情鸵赖,我是刑警寧澤,帶...
    沈念sama閱讀 35,425評論 5 343
  • 正文 年R本政府宣布拄衰,位于F島的核電站它褪,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏翘悉。R本人自食惡果不足惜茫打,卻給世界環(huán)境...
    茶點故事閱讀 41,019評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望妖混。 院中可真熱鬧老赤,春花似錦、人聲如沸制市。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽祥楣。三九已至开财,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間荣堰,已是汗流浹背床未。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留振坚,地道東北人薇搁。 一個月前我還...
    沈念sama閱讀 47,729評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像渡八,于是被迫代替她去往敵國和親啃洋。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,614評論 2 353

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