MySQL中InnoDB存儲(chǔ)引擎是如何設(shè)計(jì)的

小編給大家分享一下MySQL中InnoDB存儲(chǔ)引擎是如何設(shè)計(jì)的,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

創(chuàng)新互聯(lián)是一家專注于網(wǎng)站制作、網(wǎng)站建設(shè)與策劃設(shè)計(jì),鼓樓網(wǎng)站建設(shè)哪家好?創(chuàng)新互聯(lián)做網(wǎng)站,專注于網(wǎng)站建設(shè)十載,網(wǎng)設(shè)計(jì)領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:鼓樓等地區(qū)。鼓樓做網(wǎng)站價(jià)格咨詢:18982081108

MySQL 中的兩個(gè)成員 binlog 和 redo log。然而,這只是 MySQL 家族里的兩個(gè)小嘍啰,Mysql 可以做到高性能高可靠,靠的絕對(duì)不只有他們倆。

MySQL 里還有什么其他成員呢?

這其中,最底下的存儲(chǔ)引擎層(Storage Engines),它決定了 MySQL 會(huì)怎樣存儲(chǔ)數(shù)據(jù),怎樣讀取和寫入數(shù)據(jù),也在很大程度上決定了 MySQL 的讀寫性能和數(shù)據(jù)可靠性。

對(duì)于這么重要的一層能力,MySQL 提供了極強(qiáng)的擴(kuò)展性,你可以定義自己要使用什么樣的存儲(chǔ)引擎:InnoDB、MyISAM、MEMORY、CSV,甚至可以自己開發(fā)一個(gè)存儲(chǔ)引擎然后使用它。

通常我們說 Mysql 高性能高可靠,都是指基于 InnoDB 存儲(chǔ)引擎的 Mysql,所以,這一講,先讓我們來看看,除了 redo log,InnoDB 里還有哪些成員,他們都有什么能力,承擔(dān)了什么樣的角色,他們之間又是怎么配合的?

InnoDB 內(nèi)存架構(gòu)

InnoDB 主要分為兩大塊:內(nèi)存和磁盤,讓我們先從內(nèi)存開始。

1、Buffer Pool

正如之前提到的,MySQL 不會(huì)直接去修改磁盤的數(shù)據(jù),因?yàn)檫@樣做太慢了,MySQL 會(huì)先改內(nèi)存,然后記錄 redo log,等有空了再刷磁盤,如果內(nèi)存里沒有數(shù)據(jù),就去磁盤 load。

而這些數(shù)據(jù)存放的地方,就是 Buffer Pool。

我們平時(shí)開發(fā)時(shí),會(huì)用 redis 來做緩存,緩解數(shù)據(jù)庫壓力,其實(shí) MySQL 自己也做了一層類似緩存的東西。

MySQL 是以「頁」(page)為單位從磁盤讀取數(shù)據(jù)的,Buffer Pool 里的數(shù)據(jù)也是如此,實(shí)際上,Buffer Pool 是a linked list of pages,一個(gè)以頁為元素的鏈表。

為什么是鏈表?因?yàn)楹途彺嬉粯?,它也需要一套淘汰算法來管理?shù)據(jù)。

Buffer Pool 采用基于 LRU(least recently used) 的算法來管理內(nèi)存。

2、Change Buffer

上面提到過,如果內(nèi)存里沒有對(duì)應(yīng)「頁」的數(shù)據(jù),MySQL 就會(huì)去把數(shù)據(jù)從磁盤里 load 出來,如果每次需要的「頁」都不同,或者不是相鄰的「頁」,那么每次 MySQL 都要去 load,這樣就很慢了。

于是如果 MySQL 發(fā)現(xiàn)你要修改的頁,不在內(nèi)存里,就把你要對(duì)頁的修改,先記到一個(gè)叫 Change Buffer 的地方,同時(shí)記錄 redo log,然后再慢慢把數(shù)據(jù) load 到內(nèi)存,load 過來后,再把 Change Buffer 里記錄的修改,應(yīng)用到內(nèi)存(Buffer Pool)中,這個(gè)動(dòng)作叫做 merge;而把內(nèi)存數(shù)據(jù)刷到磁盤的動(dòng)作,叫 purge:

merge:Change Buffer -> Buffer Pool

purge:Buffer Pool -> Disk

上面是 MySQL 官網(wǎng)對(duì) Change Buffer 的定義,仔細(xì)看的話,你會(huì)發(fā)現(xiàn)里面提到:Change Buffer 只在操作「二級(jí)索引」(secondary index)時(shí)才使用,原因是「聚簇索引」(clustered indexes)必須是「唯一」的,也就意味著每次插入、更新,都需要檢查是否已經(jīng)有相同的字段存在,也就沒有必要使用 Change Buffer 了;另外,「聚簇索引」操作的隨機(jī)性比較小,通常在相鄰的「頁」進(jìn)行操作,比如使用了自增主鍵的「聚簇索引」,那么 insert 時(shí)就是遞增、有序的,不像「二級(jí)索引」,訪問非常隨機(jī)。

3、Adaptive Hash Index

MySQL 索引,不管是在磁盤里,還是被 load 到內(nèi)存后,都是 B+ 樹,B+ 樹的查找次數(shù)取決于樹的深度。你看,數(shù)據(jù)都已經(jīng)放到內(nèi)存了,還不能“一下子”就找到它,還要“幾下子”,這空間犧牲的是不是不太值得?

尤其是那些頻繁被訪問的數(shù)據(jù),每次過來都要走 B+ 樹來查詢,這時(shí)就會(huì)想到,我用一個(gè)指針把數(shù)據(jù)的位置記錄下來不就好了?

這就是「自適應(yīng)哈希索引」(Adaptive Hash Index)。自適應(yīng),顧名思義,MySQL 會(huì)自動(dòng)評(píng)估使用自適應(yīng)索引是否值得,如果觀察到建立哈希索引可以提升速度,則建立。

4、Log Buffer

Log Buffer 里的 redo log,會(huì)被刷到磁盤里。

Operating System Cache

在內(nèi)存和磁盤之間,你看到 MySQL 畫了一層叫做 Operating System Cache 的東西,其實(shí)這個(gè)不屬于 InnoDB 的能力,而是操作系統(tǒng)為了提升性能,在磁盤前面加的一層高速緩存,這里不展開細(xì)講,感興趣的同學(xué)可以參考下維基百科:Page Cache

InnoDB 磁盤架構(gòu)

磁盤里有什么呢?除了表結(jié)構(gòu)定義和索引,還有一些為了高性能和高可靠而設(shè)計(jì)的角色,比如 redo log、undo log、Change Buffer,以及 Doublewrite Buffer 等等。

1、表空間(Tablespaces)

可以看到,Tablespaces 分為五種:The System Tablespace;File-Per-Table Tablespaces;General Tablespace;Undo Tablespaces;Temporary Tablespaces。

其中,我們平時(shí)創(chuàng)建的表的數(shù)據(jù),可以存放到 The System Tablespace 、File-Per-Table Tablespaces、General Tablespace 三者中的任意一個(gè)地方,具體取決于你的配置和創(chuàng)建表時(shí)的 sql 語句。

2、Doublewrite Buffer

如果說 Change Buffer 是提升性能,那么 Doublewrite Buffer 就是保證數(shù)據(jù)頁的可靠性。

前面提到過,MySQL 以「頁」為讀取和寫入單位,一個(gè)「頁」里面有多行數(shù)據(jù),寫入數(shù)據(jù)時(shí),MySQL 會(huì)先寫內(nèi)存中的頁,然后再刷新到磁盤中的頁。

這時(shí)問題來了,假設(shè)在某一次從內(nèi)存刷新到磁盤的過程中,一個(gè)「頁」刷了一半,突然操作系統(tǒng)或者 MySQL 進(jìn)程奔潰了,這時(shí)候,內(nèi)存里的頁數(shù)據(jù)被清除了,而磁盤里的頁數(shù)據(jù),刷了一半,處于一個(gè)中間狀態(tài),不尷不尬,可以說是一個(gè)「不完整」,甚至是「壞掉的」的頁。

有同學(xué)說,不是有 Redo Log 么?其實(shí)這個(gè)時(shí)候 Redo Log 也已經(jīng)無力回天,Redo Log 是要在磁盤中的頁數(shù)據(jù)是正常的、沒有損壞的情況下,才能把磁盤里頁數(shù)據(jù) load 到內(nèi)存,然后應(yīng)用 Redo Log。而如果磁盤中的頁數(shù)據(jù)已經(jīng)損壞,是無法應(yīng)用 Redo Log 的。

所以,MySQL 在刷數(shù)據(jù)到磁盤之前,要先把數(shù)據(jù)寫到另外一個(gè)地方,也就是 Doublewrite Buffer,寫完后,再開始寫磁盤。Doublewrite Buffer 可以理解為是一個(gè)備份(recovery),萬一真的發(fā)生 crash,就可以利用 Doublewrite Buffer 來修復(fù)磁盤里的數(shù)據(jù)。

以上是“MySQL中InnoDB存儲(chǔ)引擎是如何設(shè)計(jì)的”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!

文章名稱:MySQL中InnoDB存儲(chǔ)引擎是如何設(shè)計(jì)的
網(wǎng)頁網(wǎng)址:http://bm7419.com/article34/jdispe.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站排名、網(wǎng)站制作、標(biāo)簽優(yōu)化、做網(wǎng)站、App開發(fā)、服務(wù)器托管

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

成都定制網(wǎng)站建設(shè)