<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
我們都知道 MySQL 資料庫有很多個儲存引擎,其中另我們印象深刻的應該是 InnoDB
儲存引擎,它從 MySQL 5.5 之後就是預設的儲存引擎,它有支援事務、行級鎖、MVCC 以及外來鍵等優點。
那麼你知道InnoDB
儲存引擎的底層邏輯架構嗎?下面我們就來聊一下InnoDB
儲存引擎。
InnoDB
儲存引擎主要由兩個部分組成,分別是記憶體架構和磁碟架構,這兩個部分都有自己不可或缺的功能。下面我們就通過一張圖來詳細瞭解一下這兩個部分。
記憶體架構(英文名稱:In-Memory Structures
),在InnoDB
儲存引擎中主要包括四個部分,分別是自適應雜湊索引、Buffer pool
、Change buffer
和Log Buffer
四個部分。
首先我們來聊聊自適應雜湊索引,自適應雜湊索引的英文名稱:Adaptive Hash Index
。它的設計目的是想讓 MySQL 資料庫像記憶體資料庫一樣高效,同時不會丟掉事務、行鎖以及外來鍵等特性。
它並不是我們人為去建立的,而是InnoDB
儲存引擎通過索引監控機制去自動建立的,也就是說如果InnoDB
儲存引擎監控到自適應雜湊索引可以提高查詢速度,隨即InnoDB
儲存引擎會自動為本次查詢建立自適應雜湊索引。命中了自適應雜湊索引的查詢就不會觸發全表掃描,而是直接通過索引拿需要的資料,這樣就可以提高資料庫的查詢速度。
但是自適應雜湊索引並不是任何情況下都可以使用,例如:link '%xxx'
,這是因為 link 前置百分號查詢本身就需要全表掃描,所以用與不用索引的結果都是一樣的,用索引反而會多此一舉,因此這種情況下不需要建立自適應雜湊索引。
Buffer pool(中文名稱:緩衝池),是 MySQL 資料庫中最重要的一個部分。在資料庫啟動之時,首先會初始化這塊記憶體區域,它佔用了 MySQL 資料庫總記憶體空間的80%
以上。詳細情況可以通過show engine innodb statusG
來檢視:
mysql> show engine innodb statusG ---------------------- BUFFER POOL AND MEMORY ---------------------- Total large memory allocated 137428992 Dictionary memory allocated 301572 Buffer pool size 8191 Free buffers 6916 Database pages 1252 Old database pages 442 Modified db pages 0 Pending reads 0 Pending writes: LRU 0, flush list 0, single page 0 Pages made young 258, not young 1 0.00 youngs/s, 0.00 non-youngs/s Pages read 320, created 938, written 3279 0.00 reads/s, 0.00 creates/s, 0.00 writes/s No buffer pool page gets since the last printout Pages read ahead 0.00/s, evicted without access 0.00/s, Random read ahead 0.00/s LRU len: 1252, unzip_LRU len: 0 I/O sum[0]:cur[0], unzip sum[0]:cur[0]
它的主要作用是提高資料庫查詢的效率,其中主要使用了LRU
演演算法,下面我們一起來詳細瞭解一下LRU
演演算法。
在MySQL
資料庫中,LRU
演演算法的底層主要是一個連結串列。不過該連結串列被分為了兩個區域,分別是新子連結串列和舊子連結串列,而且新子連結串列佔用總空間的5/8
,舊子連結串列佔用總空間的3/8
。其主要實現的步驟如下:
資料2
,這個時候恰好資料2
在新子連結串列中,這個時候,會將資料2
調換至新子連結串列的開頭。buffer pool
中沒有的資料時,MySQL
資料庫將在磁碟中讀取出該條資料資料X
,並且插入新子連結串列後面,同時會淘汰舊子連結串列中的資料N
。說到這裡,可能就會有朋友問了,既然新資料移到連結串列的最前方,排列在最後面的資料直接淘汰,那麼為什麼還需要一個新子連結串列和舊子連結串列呢?
這個時候我們設想一下,假設我們查詢一個比較大的資料,可能會佔滿所有的Buffer pool
記憶體空間,按照我們理解的淘汰策略,這個時候會一下子將所有的資料全部淘汰。而這個時候正在高速運轉的資料庫會將所有的查詢全部作用於磁碟,那將會導致系統磁碟 IO 急劇升高且資料庫反應緩慢,最終會導致使用者體驗下降。
這個時候我們再看,如果把所有新查詢的資料全部存放於新子連結串列中,查詢的資料最多把新子連結串列中的空間全部佔滿而舊子連結串列中仍然保留著之前的資料,對於高速運轉的資料庫來講,就不會導致系統磁碟 IO 急劇升高和資料庫反應緩慢了。這也正是新舊子連結串列設計的初衷。
在Buffer Pool
儲存塊中還保留有一個小記憶體塊,即Change buffer
。下面我們就來聊聊這塊記憶體是用來做什麼的。
Change Buffer
的另一個名字叫“寫快取”。見名知意,Change Buffer
主要的功能是記錄資料庫的資料修改操作的結果的。主要目的是提高資料庫的寫效能。
下面我們就來詳細分析一下,資料修改操作的步驟。
第一步:修改一條資料時,首先判斷該條資料是否存在於Buffer Pool
之中。
Buffer Pool
中的相關資料。Change Buffer
之中,而後在Change Buffer
中修改該資料,同時寫入Redo Log
之中(為了防止資料丟失),等下一次查詢該條資料時,合併至Buffer Pool
中。第二步:Change Buffer
中資料修改之後,什麼時候合併資料呢?
Buffer Pool
。Master Thread
合併(週期預設:10s)。Redo Log
合併到磁碟中。Change Buffer
之所以這樣設計,是因為對於高速運轉的 MySQL 資料庫來講,如果每一次修改都修改磁碟同時又修改Buffer Pool
中的內容的話,對於 MySQL 資料庫來講代價太大了,磁碟的 IO 也會非常高,最終會導致 MySQL 資料庫執行緩慢。那麼,修改資料時使用Change Buffer
就相當於在記憶體中修改資料,並且儲存在記憶體中,當資料庫空閒時才會寫入磁碟,這樣既能夠達到修改資料的目的,又能夠降低資料庫對於系統的效能要求,進而提高資料庫的效能。
上面我們提到,Change Buffer
修改完成之後,會修改redo log
中的資料,那麼接下來我們就來了解一下Log Buffer
。
我們設想一下,如果在Change Buffer
修改完資料之後,僅僅儲存在記憶體中,那麼如果這個時候資料庫宕機,也就意味著我們剛剛修改的資料也隨即丟失,而這一點是不能被允許的。
怎麼解決這個問題呢?MySQL 給我們提供了一種寫紀錄檔的方案,也就是說,修改完的資料會儲存到一個叫Redo Log
(具體請參考下方的Redo Log
部分)的紀錄檔中。它是一個物理紀錄檔,當資料宕機時,它會將資料直接儲存在磁碟之上;當資料庫開啟時,自動寫入到資料庫的磁碟中,以至於資料不會丟失。
上方我們提到了,Redo Log
是一個物理紀錄檔,如果把大量的資料直接寫進磁碟,還是會導致資料庫效能低下,我們用一個Log Buffer
來儲存需要寫入Redo log
的資料,這樣有利於提高資料庫的效能。
這個時候你可能會問:那Change Buffer
為什麼不直接寫入磁碟呢?
具體情況是這樣的,MySQL 資料庫在系統磁碟上儲存的資料是有序的(典型就是按照主鍵 ID),如果每一次修改資料直接操作磁碟的話,會導致很多資料的位置發生更改(也就是我們常說的:隨機 IO),但是Redo log
中儲存的資料是無序的,隨意不會產生隨機 IO,所以使用Redo log
暫時儲存資料是確保資料不丟失時的最好辦法。
聊完InnoDB
儲存引擎的記憶體架構之後,接下來我們再來了解一下InnoDB
儲存引擎的磁碟架構。
對於InnoDB
儲存引擎來說,磁碟架構最重要的就是表空間了。InnoDB
儲存引擎的表空間主要分為:系統表空間、獨立表空間、普通表空間、Undo表空間以及臨時表空間。
下面我們一起來詳細聊聊InnoDB
儲存引擎的磁碟架構中的各個表空間。
系統表空間是InnoDB
儲存引擎中最重要的表空間之一,它的主要作用是儲存InnoDB
資料字典、雙寫緩衝、更改快取以及復原紀錄檔。
系統表空間一般存放於 MySQL 資料庫目錄中,名稱為:ibdata1
。系統表空間一般不一定只有一個,也可能有多個,系統表空間的大小和數量由innodb_data_file_path
控制。具體如下:
mysql> SHOW VARIABLES LIKE 'innodb_data_file_path'; +-----------------------+------------------------+ | Variable_name | Value | +-----------------------+------------------------+ | innodb_data_file_path | ibdata1:12M:autoextend | +-----------------------+------------------------+ 1 row in set (0.00 sec)
在這裡特別需要說明的是,InnoDB 資料字典在 MySQL 8.0 版本以後合併至 MySQL 資料字典中了,不再儲存在系統表空間中了。
這個時候你可能會問,MySQL 資料表中的資料存放於哪裡呢?下面我們就來聊一聊這個問題。
對於innodb
儲存引擎來說,我們通常建立資料表的時候,會在 MySQL 資料目錄中建立兩個檔案,分別是.ibd
和.frm
兩個檔案。.ibd
檔案主要用來儲存表資料,而.frm
檔案主要用來儲存索引。
這種做法可以將所有的資料表分開管理,也能夠實現快速資料遷移,當資料出現故障之時也可以提高資料恢復的成功率。不過這樣的做法又會增加磁碟的碎片,對系統處理表檔案的效能有一定的影響。
普通表空間的本質其實就是一個共用的表空間。其具體檔案在 MySQL 資料庫的資料目錄中是以.ibd
結尾的檔案。跟系統表空間類似,它支援所有 MySQL 資料庫中的資料表的結構,它是將資料庫的一些後設資料儲存在記憶體之中,進而能夠減少獨立表空間對於記憶體的消耗。
Undo 表空間主要是用來儲存復原紀錄檔(即:Undo Log
)的空間。它預設情況下儲存在 MySQL 資料庫的根目錄。我們可以通過以下方式來檢視:
mysql> SHOW VARIABLES LIKE 'innodb_undo_directory'; +--------------------------+-------+ | Variable_name | Value | +--------------------------+-------+ | innodb_undo_directory | ./ | +--------------------------+-------+ 4 rows in set (0.00 sec)
在MySQL 8.0
版本之後,undo 表空間會在 MySQL 資料庫的資料根目錄生成 undo_001
和 undo002
共兩個檔案。
臨時表空間主要是用來儲存資料庫對談中的臨時資料的。在 MySQL 資料庫的資料根目錄中儲存以ibtmp1
命名的檔案。最主要的是我們在使用 join 連表查詢的時候,會在臨時表空間內建立臨時資料表用來輔助查詢。我們可以通過以下方式來檢視臨時表空間的設定:
mysql> SELECT @@innodb_temp_data_file_path; +------------------------------+ | @@innodb_temp_data_file_path | +------------------------------+ | ibtmp1:12M:autoextend | +------------------------------+ 1 row in set (0.00 sec)
InnoDB
儲存引擎是 MySQL 資料庫中最重要的一個儲存引擎之一。今天我們一起通過它的記憶體架構和磁碟架構深入地瞭解了它的底層架構。
在記憶體架構中,自適應雜湊索引有利於提高查詢速度;Buffer pool
主要提供了一個記憶體池,將經常查詢的資料存放於記憶體中,這樣做有利於提高資料庫的查詢效能和降低系統的磁碟 IO;Change buffer
主要是將修改好的資料存放於記憶體之中,下一次查詢的時候合併到Buffer pool
之中,這樣做的好處是可以降低修改資料時的磁碟 IO,進而提高資料庫的效能;Log Buffer
是將所有修改的資料存放在其中,之後寫入到Redo Log
之中,防止資料丟失。
在磁碟架構中,系統表空間是用來修改和復原紀錄檔的地方,之前的資料庫版本中還存放InnoDB
資料字典以及雙寫緩衝;獨立表空間主要是用來儲存表資料和索引的地方;普通表空間是一個共用的表空間,能夠減少獨立表空間對於記憶體的消耗;Undo 表空間主要作用於事務回滾的,在使用未提交之前,用來儲存原來的資料,一旦事務回滾則用 Undo 表空間中的內容替換修改過後的資料,進而達到回滾的目的;臨時表空間主要是一個過渡的表空間,通常的一些操作需要有這種過渡來輔助操作,例如連表查詢。
從記憶體架構到磁碟架構,InnoDB
儲存引擎為我們提供了一個高效能、高安全的資料庫儲存引擎。通常在實際應用過程中,InnoDB
儲存引擎是我們的首選儲存引擎,但是在使用過程中一定要把Buffer pool
的空間設定得足夠大,這樣有利於提高資料的查詢效能。
以上就是MySQL InnoDB 儲存引擎的底層邏輯架構的詳細內容,更多關於MySQL InnoDB 底層邏輯的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45