成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

不知道 Insert Buffer 的請舉手

運維 數據庫運維
在講插入緩沖這個振奮人心的 InnoDB 新特性之前,我們有必要先來回顧下 Buffer Pool(緩存池)的概念。

[[434991]]

Buffer Pool 緩沖池回顧

在講插入緩沖這個振奮人心的 InnoDB 新特性之前,我們有必要先來回顧下 Buffer Pool(緩存池)的概念。

前文說過,InnoDB 存儲引擎是基于磁盤存儲的,并將其中的記錄按照頁的方式進行管理。因此可將其視為基于磁盤的數據庫系統(Disk-base Database)。為了緩解 CPU 與磁盤速度之間的矛盾,基于磁盤的數據庫系統通常使用緩沖池技術來提高數據庫的整體性能。

緩沖池其實就是一塊內存區域,沒什么特別的。

  • 對于數據庫中頁的讀取操作,首先會將從磁盤讀到的頁存放在緩沖池中,這個過程也稱為將頁 FIX 在緩沖池中。這樣,下一次再讀相同的頁時,如果該頁是否在緩沖池中,則直接讀取該頁就行了,不用去磁盤上讀取。
  • 對于數據庫中頁的修改操作,則首先修改在緩沖池中的頁,然后再以一定的頻率刷新到磁盤上。

簡單來說,緩沖池就是通過內存的速度來彌補磁盤速度較慢對數據庫性能的影響。

當然了,緩沖池畢竟不是無限大的,不能把所有的數據都存在緩沖池上面,InnoDB 通過一種稱為 Checkpoint 的機制來決定哪些數據該從緩沖池移出去(移到磁盤上),這個在前面文章中我們也解釋過啦,遺忘的小伙伴可以翻看下前文。

Insert Buffer 插入緩沖

Insert Buffer 這個名字可能會讓小伙伴們認為它是 Buffer Pool 中的一個組成部分。其實不然,Insert Buffer 是物理頁的一個組成部分,是一顆 B+ 樹,頁是存在磁盤中的,而 Buffer Pool 它是一塊內存區域。

不過,需要注意的是,Buffer Pool 中會包含 Insert Buffer 的某些信息,來看下 InnoDB 存儲引擎的內存結構:

可以看到,Innodb Buffer Pool 包含的數據頁類型有:索引頁,數據頁,undo 頁,Insert Buffer,自適應哈希索引,鎖信息,數據字典信息等。

以問題為導向,對于 Insert Buffer,我們需要弄清楚的其實就 2 個問題:

  • Insert Buffer 能解決什么問題?
  • 什么情況下能夠使用 Insert Buffer?

通常,我們在建表的時候,都會給主鍵定一個自增長(AUTO_INCREMENT)的特性,也即主鍵按照遞增的順序進行插入。上篇文章講過,聚集索引一般建立在主鍵上面,也就是說,插入聚集索引一般是順序的,不需要經過磁盤的隨機讀取。

舉個例子:

  1. CREATE TABLE user
  2.  id INT(11) AUTO_INCREMENT,   
  3.     username VARCHAR(30),   
  4.     PRIMARY KEY(id) 
  5. ); 

id 是自增長的主鍵,我們在插入一個新的行記錄的時候,無須對 id 賦值或者說賦 NULL 值,存儲引擎會幫助我們將這個值自動增長。

同時頁中的行記錄是按照主鍵 id 的值進行順序存放的,所以,在我們插入新的行記錄的時候,一般來說磁盤是不需要去隨機讀取另一個頁中的記錄的,因此速度非常快。

當然了,并不是說所有的主鍵插入都是順序的。有些業務場景下可能需要用 UUID 這種作為主鍵,即使它被定義了自增長類型,如果每次插入的都是通過 UUID 生成的指定值,而不是 NULL,那么顯然它的插入就是隨機的了。

這樣分析下來似乎我們的插入性能會比較好,但是,不可能一張數據庫表上只有一個聚集索引吧,還有其他的輔助索引呢。事實上,輔助索引也確實是影響插入性能的關鍵。

舉個例子,我們定義一個非聚集的且不是唯一的索引 username:

  1. CREATE TABLE user
  2.  id INT(11) AUTO_INCREMENT,   
  3.     username VARCHAR(30),   
  4.     PRIMARY KEY(id), 
  5.     key(username) 
  6. ); 

在進行插入操作時,數據頁的存放確實還是按自增長的主鍵 id 來進行順序存放的,這沒錯。

但是,索引的本質是什么?是 B+ 樹,是一個存在磁盤上的物理文件。那我們在構建輔助索引 username 的這棵 B+ 樹的時候,非聚集索引葉子節點的插入不再是順序的了,也就是說要去離散地訪問磁盤頁了。

正是由于隨機讀取的存在導致了插入操作性能下降。

和 “不是所有的主鍵插入都是順序的” 類似,在某些情況下,輔助索引的插入可能也是順序的,或者說是比較有順序的。

比如用戶表中有一個時間字段,用來表示用戶買下某個物品的時間。在通常情況下,用戶購買時間是一個輔助索引,用來根據時間條件進行查詢。但是在插入時卻是根據時間的遞增而插入的,因此插入也是比較有順序的。

至此,講了半天好像還沒有看見 Insert Buffer 的影子?

別急,這就來。

InnoDB 存儲引擎開創性地設計了 Insert Buffer。對于輔助索引的插入或更新操作,并不是每一次直接插入到索引頁(磁盤頁)中,而是先判斷插入的輔助索引頁是否在 Buffer Pool 中:

  • 若在,則直接插入;
  • 若不在,則先將其放入到一個 Insert Buffer 對象中,就好像騙了數據庫一波:告訴數據庫這個輔助索引的葉子節點了已經插入成功了(磁盤上),但是實際上并沒有,只是存放在內存里的 Insert Buffer 中。

當然,不能將這個葉子節點一直存在 Insert Buffer 中,對吧,這個輔助索引的 B+ 樹終歸還是得建立起來的。具體來說,InnoDB 會以一定的頻率和情況進行 Insert Buffer 和輔助索引頁子節點的 Merge(合并)操作,這時,就相當于將多個葉子節點插入操作合并到一個操作中(因為在一個索引頁中),這就大大提高了對于輔助索引插入性能

簡單概括下:Insert Buffer 就是一棵 B+ 樹,若需要實現插入記錄的輔助索引頁不在 Buffer Pool 中,那么需要將輔助索引記錄首先插入到這棵 B+ 樹中,然后在適當的情況下將其合并(Merge)到真正的輔助索引中。

舉個現實生活中的例子來說:

我們去圖書館還書,對于圖書館管理員來說,他需要做的就是 insert 操作,管理員在 1 小時內接受了 100 本書,這時候他有 2 種做法把還回來的書歸位到書架上:

  • 每還回來一本書,就把這本書送回架上
  • 暫時不做歸位操作,等到空閑下來了,再把這些書一次性送回書架上

用方法 1,管理員需要進出圖書管 100 次,不停的登高爬低完成圖書歸位操作,累死累活,效率很差。

用方法 2,管理員只需要對要歸位的書進行一個分類,進出圖書管 1 次,對同一個位置的書,不管多少,都只要爬一次樓梯,大大減輕了管理員的工作量。

那么,什么條件下可以使用 Insert Buffer 以此來提高插入操作的性能呢?

  • 索引是輔助索引
  • 索引不是唯一索引

為什么 Insert Buffer 不適用于唯一的輔助索引呢?

一個很簡單的套娃問題(滑稽):

如果輔助索引是唯一的,那么當把要插入的對象存到 Insert Buffer 時,數據庫就需要去磁盤上查找索引頁來判斷插入記錄的唯一性,顯然,如果去查找就會有離散讀取的情況發生,從而導致 Insert Buffer 失去了意義。

還以圖書管那個例子來說:

如果圖書館中所有的書只允許存在一本,那我們還一本書到圖書館的時候,管理員就必須爬到圖書管的指定位置去確認判斷一下這本書是不是唯一的,這個過程就相當于產生了一次 IO 操作了。

另外,Insert Buffer 有利有弊,考慮一種極端情況:

如果數據庫中涌入了大量的插入操作,并且這些都涉及了不唯一的非聚集索引,也就是使用了 Insert Buffer。若此時數據庫崩潰了,這時勢必有大量的 Insert Buffer 沒有被合并到實際的輔助索引中去,那么這時候的恢復就可能需要很長的時間。

Change Buffer

InnoDB 從 1.0.x 版本開始引入了 Change Buffer,現在有些博客上說的也是 Change Buffer,容易讓小白懵逼,其實就是 Insert Buffer 的升級版。

從這個版本開始,InnoDB 存儲引擎可以對 DML 操作 — INSERT、DELETE、UPDATE 都進行緩沖,他們分別對應的是:Insert Buffer、Delete Buffer、Purge buffer

同樣的,和之前 Insert Buffer 一樣,Change Buffer 適用的對象依然是非唯一的輔助索引。

對一條記錄進行 UPDATE 操作可能分為兩個過程:

 

  • 將記錄標記為已刪除:對應 Delete Buffer
  • 真正將記錄刪除:對應 Purge Buffer

 

責任編輯:武曉燕 來源: 飛天小牛肉
相關推薦

2021-03-14 22:32:45

SQL數據庫XML

2020-06-12 09:20:33

前端Blob字符串

2020-07-28 08:26:34

WebSocket瀏覽器

2021-07-14 11:25:12

CSSPosition定位

2010-08-23 09:56:09

Java性能監控

2011-09-15 17:10:41

2021-02-01 23:23:39

FiddlerCharlesWeb

2022-10-13 11:48:37

Web共享機制操作系統

2009-12-10 09:37:43

2018-06-20 00:30:06

2021-10-17 13:10:56

函數TypeScript泛型

2020-08-11 11:20:49

Linux命令使用技巧

2012-11-23 10:57:44

Shell

2021-12-29 11:38:59

JS前端沙箱

2021-12-22 09:08:39

JSON.stringJavaScript字符串

2015-06-19 13:54:49

2020-09-15 08:35:57

TypeScript JavaScript類型

2022-11-04 08:19:18

gRPC框架項目

2020-12-21 09:00:04

MySQL緩存SQL

2018-12-06 09:12:58

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产精品一区二区福利视频 | 国产欧美一区二区三区在线看 | av网站免费 | 视频一区二区三区四区五区 | 99久久精品国产一区二区三区 | 免费av直接看 | 91av在线视频观看 | 精品久久久久久18免费网站 | 日本精品一区二区 | 国产区第一页 | 日本电影一区二区 | 国产最新精品视频 | 成人h视频在线 | 久久久久久久久久久国产 | 国产精品精品久久久 | 国产清纯白嫩初高生视频在线观看 | 久久精品欧美一区二区三区不卡 | 午夜国产一级 | 久久久久久久久久久久一区二区 | 天天操天天干天天曰 | 国产一区中文字幕 | 久久久www| 免费一级黄 | 91社区在线观看高清 | 精品不卡| 成人午夜免费视频 | 亚洲国产精品日韩av不卡在线 | 欧美中文字幕在线 | 欧美在线一区视频 | 久久久精品视频一区二区三区 | 国产精品毛片一区二区三区 | 久久国产精品一区 | 久久中文视频 | 欧美国产日韩一区二区三区 | 中文字幕一二三区 | 亚欧洲精品在线视频免费观看 | 精品国产一区二区三区久久 | 嫩草影院网址 | 国产羞羞视频在线观看 | 中文字幕一区二区三区乱码图片 | 亚洲精选久久 |