日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > 数据库 >内容正文

数据库

MySQL探秘(三):InnoDB的内存结构和特性(可靠性和持久性)

發(fā)布時(shí)間:2024/4/18 数据库 73 豆豆
生活随笔 收集整理的這篇文章主要介紹了 MySQL探秘(三):InnoDB的内存结构和特性(可靠性和持久性) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

?MySQL區(qū)別于其他數(shù)據(jù)庫(kù)的最為重要的特點(diǎn)就是其插件式的表存儲(chǔ)引擎。而在眾多存儲(chǔ)引擎中,InnoDB是最為常用的存儲(chǔ)引擎。從MySQL5.5.8版本開(kāi)始,InnoDB存儲(chǔ)引擎是默認(rèn)的存儲(chǔ)引擎
?InnoDB存儲(chǔ)引擎支持事務(wù),其設(shè)計(jì)目標(biāo)主要面向在線事務(wù)處理(OLTP)的應(yīng)用。其特點(diǎn)是行鎖設(shè)計(jì)、支持外鍵,并支持非鎖定讀,即默認(rèn)讀操作不會(huì)產(chǎn)生鎖
?InnoDB通過(guò)使用多版本并發(fā)控制(MVCC)來(lái)獲取高并發(fā)性,并且實(shí)現(xiàn)了SQL標(biāo)準(zhǔn)的4中隔離級(jí)別,默認(rèn)為REPEATABLE級(jí)別。同時(shí),使用一種被稱(chēng)為next-key-locking的策略來(lái)避免幻讀現(xiàn)象的產(chǎn)生。除此之外,InnoDB存儲(chǔ)引擎還提供了插入緩沖(insert buffer)二次寫(xiě)(double write)自適應(yīng)哈希索引(adaptive hash index)預(yù)讀(read ahead)高性能和高可用的功能。

?上圖詳細(xì)顯示了InnoDB存儲(chǔ)引擎的體系架構(gòu),從圖中可見(jiàn),InnoDB存儲(chǔ)引擎由內(nèi)存池,后臺(tái)線程和磁盤(pán)文件三大部分組成。接下來(lái)我們就來(lái)簡(jiǎn)單了解一下內(nèi)存相關(guān)的概念和原理。

緩沖池

?InnoDB存儲(chǔ)引擎是基于磁盤(pán)存儲(chǔ)的,并將其中的記錄按照頁(yè)的方式進(jìn)行管理。但是由于CPU速度和磁盤(pán)速度之間的鴻溝,基于磁盤(pán)的數(shù)據(jù)庫(kù)系統(tǒng)通常使用緩沖池記錄來(lái)提高數(shù)據(jù)庫(kù)的的整體性能。

?在數(shù)據(jù)庫(kù)中進(jìn)行讀取操作,首先將從磁盤(pán)中讀到的頁(yè)放在緩沖池中,下次再讀相同的頁(yè)中時(shí),首先判斷該頁(yè)是否在緩沖池中。若在緩沖池中,稱(chēng)該頁(yè)在緩沖池中被命中,直接讀取該頁(yè)。否則,讀取磁盤(pán)上的頁(yè)。

?對(duì)于數(shù)據(jù)庫(kù)中頁(yè)的修改操作,則首先修改在緩沖池中的頁(yè),然后再以一定的頻率刷新到磁盤(pán)上。頁(yè)從緩沖池刷新回磁盤(pán)的操作并不是在每次頁(yè)發(fā)生更新時(shí)觸發(fā),而是通過(guò)一種稱(chēng)為CheckPoint的機(jī)制刷新回磁盤(pán)。

?所以,緩沖池的大小直接影響著數(shù)據(jù)庫(kù)的整體性能,可以通過(guò)配置參數(shù)innodb_buffer_pool_size來(lái)設(shè)置。

?具體來(lái)看,緩沖池中緩存的數(shù)據(jù)頁(yè)類(lèi)型有:索引頁(yè)、數(shù)據(jù)頁(yè)、undo頁(yè)、插入緩沖(insert buffer)、自適應(yīng)哈希索引(adaptive hash index)、InnoDB存儲(chǔ)的鎖信息(lock info)和數(shù)據(jù)字典信息(data dictionary)

?在架構(gòu)圖上可以看到,InnoDB存儲(chǔ)引擎的內(nèi)存區(qū)域除了有緩沖池之外,還有重做日志緩沖和額外內(nèi)存池。InnoDB存儲(chǔ)引擎首先將重做日志信息先放到這個(gè)緩沖區(qū)中,然后按照一定頻率將其刷新到重做日志文件中。重做日志緩沖一般不需要設(shè)置的很大,該值可由配置參數(shù)innodb_log_buffer_size控制。

數(shù)據(jù)頁(yè)和索引頁(yè)

?Page是Innodb存儲(chǔ)的最基本結(jié)構(gòu),也是Innodb磁盤(pán)管理的最小單位,與數(shù)據(jù)庫(kù)相關(guān)的所有內(nèi)容都存儲(chǔ)在Page結(jié)構(gòu)里。Page分為幾種類(lèi)型,數(shù)據(jù)頁(yè)和索引頁(yè)就是其中最為重要的兩種類(lèi)型。

插入緩沖(Insert Buffer)

?我們都知道,在InnoDB引擎上進(jìn)行插入操作時(shí),一般需要按照主鍵順序進(jìn)行插入,這樣才能獲得較高的插入性能。當(dāng)一張表中存在非聚簇的且不唯一的索引時(shí),在插入時(shí),數(shù)據(jù)頁(yè)的存放還是按照主鍵進(jìn)行順序存放,但是對(duì)于非聚簇索引葉節(jié)點(diǎn)的插入不再是順序的了,這時(shí)就需要離散的訪問(wèn)非聚簇索引頁(yè),由于隨機(jī)讀取的存在導(dǎo)致插入操作性能下降。

?InnoDB為此設(shè)計(jì)了Insert Buffer來(lái)進(jìn)行插入優(yōu)化。對(duì)于非聚簇索引的插入或者更新操作,不是每一次都直接插入到索引頁(yè)中,而是先判斷插入的非聚集索引是否在緩沖池中,若在,則直接插入;若不在,則先放入到一個(gè)Insert Buffer中。看似數(shù)據(jù)庫(kù)這個(gè)非聚集的索引已經(jīng)查到葉節(jié)點(diǎn),而實(shí)際沒(méi)有,這時(shí)存放在另外一個(gè)位置。然后再以一定的頻率和情況進(jìn)行Insert Buffer和非聚簇索引頁(yè)子節(jié)點(diǎn)的合并操作。這時(shí)通常能夠將多個(gè)插入合并到一個(gè)操作中,這樣就大大提高了對(duì)于非聚簇索引的插入性能。

兩次寫(xiě)(Double Write)

?如果說(shuō)Insert Buffer給InnoDB存儲(chǔ)引擎帶來(lái)了性能上的提升,那么Double Write帶給InnoDB存儲(chǔ)引擎的是數(shù)據(jù)頁(yè)的可靠性

?如上圖所示,Double Write由兩部分組成,一部分是內(nèi)存中的double write buffer,大小為2MB,另一部分是物理磁盤(pán)上共享表空間連續(xù)的128個(gè)頁(yè),大小也為2MB。在對(duì)緩沖池的臟頁(yè)進(jìn)行刷新時(shí),并不直接寫(xiě)磁盤(pán),而是 1. 通過(guò)memcpy函數(shù)將臟頁(yè)先復(fù)制到內(nèi)存中的該區(qū)域(doublewrite buffer)1.1?之后通過(guò)doublewrite buffer再分兩次,每次1MB順序地寫(xiě)入共享表空間的物理磁盤(pán)上(doublewrite),然后馬上調(diào)用fsync函數(shù),同步磁盤(pán),避免操作系統(tǒng)緩沖寫(xiě)帶來(lái)的問(wèn)題(map技術(shù)的過(guò)程)2. 在完成doublewrite頁(yè)的寫(xiě)入后,再講doublewirite buffer中的頁(yè)寫(xiě)入各個(gè)表空間文件中。

?如果操作系統(tǒng)在將頁(yè)寫(xiě)入磁盤(pán)的過(guò)程中發(fā)生了崩潰(發(fā)生在第2步),在恢復(fù)過(guò)程中,InnoDB存儲(chǔ)引擎可以從共享表空間中的doublewrite中找到該頁(yè)的一個(gè)副本,將其復(fù)制到表空間文件中,再應(yīng)用重做日志。

重做日志(Redo Log Buffer)

?當(dāng)緩沖池中的頁(yè)的版本比磁盤(pán)要新時(shí),數(shù)據(jù)庫(kù)需要將新版本的頁(yè)從緩沖池刷新到磁盤(pán)。但是如果每次一個(gè)頁(yè)發(fā)送變化,就進(jìn)行刷新,那么性能開(kāi)銷(xiāo)是非常大的,于是InnoDB采用了Write Ahead Log策略,即當(dāng)事務(wù)提交時(shí),先寫(xiě)重做日志,然后再擇時(shí)將臟頁(yè)寫(xiě)入磁盤(pán)如果發(fā)生宕機(jī)導(dǎo)致數(shù)據(jù)丟失,就通過(guò)重做日志進(jìn)行數(shù)據(jù)恢復(fù)

?InnoDB存儲(chǔ)引擎會(huì)首先將重做日志信息先放入重做日志緩沖中,然后再按照一定頻率將其刷新到重做日志文件。重做日志緩沖一般不需要設(shè)置得很大,因?yàn)橐话闱闆r每一秒鐘都會(huì)將重做日志緩沖刷新到日志文件中。可通過(guò)配置參數(shù)innodb_log_buffer_size控制,默認(rèn)為8MB

?除了每秒刷新機(jī)制之外,每次事務(wù)提交時(shí)重做日志緩沖也會(huì)刷新到日志中。InnoDB是事務(wù)的存儲(chǔ)引擎,其通過(guò)Force Log at Commit機(jī)制實(shí)現(xiàn)事務(wù)的持久性,即當(dāng)事務(wù)提交時(shí),必須先將該事務(wù)的所有日志寫(xiě)入到重做日志文件進(jìn)行持久化,然后事務(wù)的提交操作完成才算完成。InnoDB的寫(xiě)入機(jī)制大致如下圖所示。

?為了確保每次日志都寫(xiě)入到重做日志文件,在每次將重做日志緩沖寫(xiě)入重做日志后,必須調(diào)用一次fsync操作,將緩沖文件從文件系統(tǒng)緩存中真正寫(xiě)入磁盤(pán)。

?可以通過(guò)innodb_flush_log_at_trx_commit來(lái)控制重做日志刷新到磁盤(pán)的策略。該參數(shù)默認(rèn)值為1,表示事務(wù)提交必須進(jìn)行一次fsync操作,還可以設(shè)置為0和2。0表示事務(wù)提交時(shí)不進(jìn)行寫(xiě)入重做日志操作,該操作只在主線程中完成,2表示提交時(shí)寫(xiě)入重做日志,但是只寫(xiě)入文件系統(tǒng)緩存,不進(jìn)行fsync操作。由此可見(jiàn),設(shè)置為0時(shí),性能最高,但是喪失了事務(wù)的一致性。

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

?InnoDB會(huì)根據(jù)訪問(wèn)的頻率和模式,為熱點(diǎn)頁(yè)建立哈希索引,來(lái)提高查詢效率。InnoDB存儲(chǔ)引擎會(huì)監(jiān)控對(duì)表上各個(gè)索引頁(yè)的查詢,如果觀察到建立哈希索引可以帶來(lái)速度上的提升,則建立哈希索引,所以叫做自適應(yīng)哈希索引。

?自適應(yīng)哈希索引是通過(guò)緩沖池的B+樹(shù)頁(yè)構(gòu)建而來(lái),因此建立速度很快,而且不需要對(duì)整張數(shù)據(jù)表建立哈希索引。其有一個(gè)要求,即對(duì)這個(gè)頁(yè)的連續(xù)訪問(wèn)模式必須是一樣的,也就是說(shuō)其查詢的條件(WHERE)必須完全一樣,而且必須是連續(xù)的。

鎖信息(lock info)

?我們都知道,InnoDB存儲(chǔ)引擎會(huì)在行級(jí)別上對(duì)表數(shù)據(jù)進(jìn)行上鎖。不過(guò)InnoDB也會(huì)在數(shù)據(jù)庫(kù)內(nèi)部其他很多地方使用鎖,從而允許對(duì)多種不同資源提供并發(fā)訪問(wèn)。數(shù)據(jù)庫(kù)系統(tǒng)使用鎖是為了支持對(duì)共享資源進(jìn)行并發(fā)訪問(wèn),提供數(shù)據(jù)的完整性和一致性。關(guān)于鎖的具體知識(shí)我們之后再進(jìn)行詳細(xì)學(xué)習(xí)。

數(shù)據(jù)字典信息(Data Dictionary)

?InnoDB有自己的表緩存,可以稱(chēng)為表定義緩存或者數(shù)據(jù)字典。當(dāng)InnoDB打開(kāi)一張表,就增加一個(gè)對(duì)應(yīng)的對(duì)象到數(shù)據(jù)字典。

?數(shù)據(jù)字典是對(duì)數(shù)據(jù)庫(kù)中的數(shù)據(jù)、庫(kù)對(duì)象、表對(duì)象等的元信息的集合。在MySQL中,數(shù)據(jù)字典信息內(nèi)容就包括表結(jié)構(gòu)、數(shù)據(jù)庫(kù)名或表名、字段的數(shù)據(jù)類(lèi)型、視圖、索引、表字段信息、存儲(chǔ)過(guò)程、觸發(fā)器等內(nèi)容。MySQL INFORMATION_SCHEMA庫(kù)提供了對(duì)數(shù)據(jù)局元數(shù)據(jù)、統(tǒng)計(jì)信息、以及有關(guān)MySQL server的訪問(wèn)信息(例如:數(shù)據(jù)庫(kù)名或表名,字段的數(shù)據(jù)類(lèi)型和訪問(wèn)權(quán)限等)。該庫(kù)中保存的信息也可以稱(chēng)為MySQL的數(shù)據(jù)字典。

參考

  • 1.《MySQL技術(shù)內(nèi)幕InnoDB存儲(chǔ)引擎》

  • 2.《高性能MySQL》

  • 3. 姜承曉老師的InnoDB架構(gòu)圖

總結(jié)

以上是生活随笔為你收集整理的MySQL探秘(三):InnoDB的内存结构和特性(可靠性和持久性)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。