1. <i id="s6b2k"><small id="s6b2k"></small></i>
    <b id="s6b2k"><bdo id="s6b2k"></bdo></b>
  2. <wbr id="s6b2k"></wbr>

    MySQL Innodb關鍵特性之插入緩沖(insert buffer)_Mysql

    來源:腳本之家  責任編輯:小易  

    什么是insert buffer?

       插入緩沖,也稱之為insert buffer,它是innodb存儲引擎的關鍵特性之一,我們經常會理解插入緩沖時緩沖池的一個部分,這樣的理解是片面的,insert buffer的信息一部分在內存中,另外一部分像數據頁一樣,存在于物理頁中。

        在innodb中,我們知道,如果一個表有自增主鍵,那么對于這個表的默認插入是非常快的,注意,這里的主鍵是自增的,如果不是自增的,那么這個插入將會變成隨機的,就可能帶來數據頁分裂的開銷,這樣,插入就不是順序的,就會變慢。還有一種情況,就是如果我們插入的id不是順序的,而是隨機的,那么即使有自增主鍵,那么插入的速度也不會特別快。

        如果我們定義了一個表,包含一個主鍵和一個非聚集索引,如下:

    create table t(
    
    a int auto_increment,
    
    b varchar(30),
    
    primary key(a),
    
    key (b)
    
    );
    

    當我們按照主鍵a進行插入的時候,對于非聚集索引,也就是常說的二級索引b,它的插入不是順序的,插入性能必然會下降。

      Innodb存儲引擎針對這種情況,設計了Insert Buffer,對于非聚集索引的插入或者更新操作,不是每一次插入到索引頁中,而是先判斷插入的非聚集索引頁是否在緩沖池中,如果在,則直接插入,如果不在,則先放入一個insert buffer中,告訴數據庫這個非聚集的索引已經插入到了葉子節點,實際上并沒有插入,只是存放在另外一個位置,然后再以一定的頻率和情況進行Insert buffer和輔助索引葉子節點合并操作。這種時候,經常能將多條記錄的插入合并到一個操作中,這樣就大大提高了非聚集索引離散插入的性能。

    insert buffer的觸發條件?

        insert buffer需要滿足兩個條件才能被使用,第一,索引是輔助索引,也就是二級索引,第二,索引不是唯一的。當滿足上述兩個條件的時候,就可以使用insert buffer,從而提高數據庫的插入操作性能。

        這里需要注意,如果在程序進行了大量操作的時候發生了MySQL數據庫的宕機,那么肯定有大量的insert buffer沒有合并到實際的非聚集索引中去,恢復可能會造成很長的時間。

    為什么不能是唯一索引?

        之所以不支持唯一索引,是因為如果輔助索引是唯一索引,那么在插入時需要校驗唯一性,校驗唯一性的時候就會發生離散讀取,從而又增加了開銷,那么insert buffer得不償失。

        我們可以通過show engine innodb status來查看insert buffer的使用情況,如下:

    mysql--root@localhost:dms_alimetadata 20:35:24>>show engine innodb status\G
    -------------------------------------
    INSERT BUFFER AND ADAPTIVE HASH INDEX
    -------------------------------------
    Ibuf: size 1, free list len 0, seg size 2, 0 merges
    merged operations:
     insert 0, delete mark 0, delete 0
    discarded operations:
     insert 0, delete mark 0, delete 0

      其中size代表了已經合并記錄頁的數量,free list len代表了空閑列表的長度,seg size顯示了當前insert buffer的大小為2*16KB

    引入Change Buffer的概念

        最新的MySQL5.7已經支持change buffer,事實上,它在innodb 1.0.x版本已經引入,這個change buffer 可以理解為insert buffer的升級,也就是對常見的DML語言都可以進行緩沖,包含insert delete以及update,對應的分別是insert buffer,delete buffer以及purge buffer。

       當然,change buffer的使用對象仍然是非唯一的輔助索引。

        這里我們以update操作為例,update的過程可以拆分為兩個部分:

    第一個部分是將記錄的delete_mask標記為刪除,如果你不了解delete_mask,可以在4月9號的文章中去看。第二個部分是真正的將記錄刪除。

    而delete buffer對應的是update的第一個過程,purge buffer對應的是第二個部分。

        在innodb中,我們可以通過參數innodb_change_buffering來開啟buffer的各種選項,該參數可選的值為inserts,deletes,purges,changes,all,none等,其中inserts,deletes和purges就是前面討論過的情況,changes表示開啟inserts和deletes,all表示開啟所有,默認的參數如下:

    mysql--root@localhost:dms_alimetadata 21:13:37>>show variables like '%buffering%';        
    +-------------------------+-------+
    | Variable_name           | Value |
    +-------------------------+-------+
    | innodb_change_buffering | all   |
    +-------------------------+-------+
    1 row in set (0.01 sec)

    我們還可以通過innodb_change_buffer_max_size來控制change_buffer的最大使用內存數量,該參數的默認值是25,也就是1/4,示例如下:

    mysql--root@localhost:dms_alimetadata 21:20:52>>show variables like '%innodb_change_buffer_max_size%';
    +-------------------------------+-------+
    | Variable_name                 | Value |
    +-------------------------------+-------+
    | innodb_change_buffer_max_size | 25    |
    +-------------------------------+-------+
    1 row in set (0.00 sec)

        在上面的show engine innodb status命令的輸出結果中,顯示了merged operation和discarded operation,其中insert 表示insert buffer的操作次數,delete mark表示delete buffer的操作次數,而delete表示purge buffer的操作次數,discarded operation表示當change buffer發生merge時,表已經被刪除,此時就無需進行合并。

    Insert Buffer的實現?

       insert buffer的數據結構是一棵B+樹,類似聚集索引一樣,全局只有一棵insert buffer B+樹,它負責對所有的表進行insert buffer,而這棵B+樹放在共享表空間中,也就是ibdata1文件中,因此,試圖通過ibd文件恢復表數據的時候可能會出現check table失敗,原因是表的輔助索引中的數據可能還在insert buffer中,所以通過ibd文件恢復文件之后,還需要進行repair table操作來重建表上的輔助索引。

       insert buffer既然是一棵樹,那么必定有葉子節點和非葉子節點,非葉子節點存放的是查詢的search key值,它的構造如下:

    +---------+------------+-------+
    | space   |   marker   | Value |
    +---------+------------+-------+

    這個結構一共占用9個字節,其中,space表示待插入的記錄所在的表的表空間id,這個id是每個表都要有的唯一的id,其中space占用4個字節,marker占用1個字節,用來兼容老版本的insert buffer,offset占用4個字節,表示頁所在的偏移量。

    輔助索引的插入過程?

        當一個輔助索引要插入到數據頁的時候,如果這個數據頁不在緩沖池中,那么innodb會根據規則構造一個search key,接下來將這個記錄插入到insert buffer的B+樹里面去,插入的過程中,需要對這個記錄進行一些構造,最終插入的結果是類似下面這樣的一條記錄:

    +---------+------------+-------+------------+------+-------+------+-------+
    | space   |   marker   | Value | metadata   |      |       |      |       |
    +---------+------------+-------+------------+------+-------+------+-------+

    可以發現,最后面多了一個metadata的字段和4個其他的字段,先來說說metadata的字段,它占用4個字節,它用來排序每個記錄進入insert buffer的順序,從第5列開始,就是實際插入記錄的各個字段的值了,因此和單純的數據記錄相比,insert buffer需要額外13個字節的開銷。

       為了保證每次merge insert buffer成功,需要設置一個特殊的數據頁來標記每個輔助索引頁的可用空間,這個數據頁的類型為insert buffer bitmap,這個頁可以追蹤很多輔助索引頁的可用空間。這里簡單了解一下,下面會解釋它的用法。

    Merged Insert Buffer的時機?

       我們前面已經知道,當插入記錄的輔助索引頁不在緩沖池中的時候,需要將輔助索引記錄插入到這棵B+樹中,后續會從insert buffer中往真正的輔助索引中進行合并,那么什么時候進行合并呢?

    1、輔助索引頁被讀取到緩沖池的時候

    2、insert buffer Bitmap追蹤到該輔助索引頁已經沒有足夠的可用空間時,一般的閾值是輔助索引頁空間的1/32

    3、master thread每秒執行一次merge insert buffer的操作

    以上就是MySQL Innodb關鍵特性之插入緩沖(insert buffer)的詳細內容,更多關于Innodb特性之插入緩沖的資料請關注真格學網其它相關文章!

    您可能感興趣的文章:淺談innodb的索引頁結構,插入緩沖,自適應哈希索引MySQL InnoDB 鎖的相關總結如何區分MySQL的innodb_flush_log_at_trx_commit和sync_binlogMysql InnoDB的鎖定機制實例詳解Mysql技術內幕之InnoDB鎖的深入講解修改MySQL數據庫引擎為InnoDB的操作mysql innodb的重要組件匯總Mysql InnoDB和MyISAM區別原理解析獲取 MySQL innodb B+tree 的高度的方法MySQL MyISAM 與InnoDB 的區別MySQL創建數據表時設定引擎MyISAM/InnoDB操作

  3. 本文相關:
  4. mysql中幾種數據統計查詢的基本使用教程
  5. mysql 5.7.17 免安裝版配置方法圖文教程(windows10)
  6. mysql數據庫insert、update、delete以及replace語句的用法詳解
  7. mysql雙master配置的方法詳解
  8. 干掉一堆mysql數據庫,僅需這樣一個shell腳本(推薦)
  9. windows下mysql8.0.11社區綠色版安裝步驟圖解
  10. 詳解如何通過mysql的二進制日志恢復數據庫數據
  11. mysql用戶權限管理實例分析
  12. centos 7 安裝mysql5.7.24二進制 版本的方法及解決辦法
  13. innodb表select查詢順序
  14. mysql中合并插入緩沖 是什么意思
  15. mysql使用innodb做緩存,感覺沒有什么效果,CPU一...
  16. 如何提高innodb insert into select的插入速度
  17. 如何優化MySQL insert性能
  18. 我修改 了mysql的配置文件,在my.ini后面加上innod...
  19. mysql innodb 怎么緩存數據的原理
  20. 下面哪個選項是mysql中innodb引擎的特點
  21. mysql innodb select 和insert會產生鎖嗎
  22. 關于MySQL Innodb參數的設置問題。
  23. Mysql中為什么使用InnoDB存儲引擎的時候建議關閉回...
  24. 網站首頁網頁制作腳本下載服務器操作系統網站運營平面設計媒體動畫電腦基礎硬件教程網絡安全mssqlmysqlmariadboracledb2mssql2008mssql2005sqlitepostgresqlmongodbredisaccess數據庫文摘數據庫其它首頁淺談innodb的索引頁結構,插入緩沖,自適應哈希索引mysql innodb 鎖的相關總結如何區分mysql的innodb_flush_log_at_trx_commit和sync_binlogmysql innodb的鎖定機制實例詳解mysql技術內幕之innodb鎖的深入講解修改mysql數據庫引擎為innodb的操作mysql innodb的重要組件匯總mysql innodb和myisam區別原理解析獲取 mysql innodb b+tree 的高度的方法mysql myisam 與innodb 的區別mysql創建數據表時設定引擎myisam/innodb操作mysql中幾種數據統計查詢的基本使用教程mysql 5.7.17 免安裝版配置方法圖文教程(windows10)mysql數據庫insert、update、delete以及replace語句的用法詳解mysql雙master配置的方法詳解干掉一堆mysql數據庫,僅需這樣一個shell腳本(推薦)詳解如何通過mysql的二進制日志恢復數據庫數據mysql用戶權限管理實例分析centos 7 安裝mysql5.7.24二進制 版本的方法及解決辦法innodb表select查詢順序mysql安裝圖解 mysql圖文安裝教程can""""t connect to mysql servwindows下mysql5.6版本安裝及配置mysql字符串截取函數substring的mysql創建用戶與授權方法mysql提示:the server quit withmysql——修改root密碼的4種方法mysql日期數據類型、時間類型使用mysql之timestamp(時間戳)用法mysql update語句的用法詳解mysql 查詢當天、本周,本月,上一個月的數查看mysql的錯誤日志的方法mysql分頁limit的優化過程實戰windows7下python3.4使用mysql數據庫mysql增加用戶、授權、修改密碼等語句5個常用的mysql數據庫管理工具詳細介紹簡述mysql與oracle的區別mysql數據庫中select用法小結win2003服務器安裝及設置教程 mysql安全設mysql存儲過程之創建(create procedure)
    免責聲明 - 關于我們 - 聯系我們 - 廣告聯系 - 友情鏈接 - 幫助中心 - 頻道導航
    Copyright © 2017 www.yu113.com All Rights Reserved
    战天txt全集下载