MySql - InnoDB 存儲引擎

InnoDB存儲引擎是MySql第一個完整支持事務的存儲引擎,最早由第三方公司開發,並不是MySql的官方引擎,在MySql 5.6後被作爲默認引擎推出。

特點

InnoDB設計是爲OLTP(在線事務處理類型)應用設計,支持事務是最大的特點,此外還有如下特點:

  • 事務:完整的ACID及4級事務隔離級別支持;
  • 基於行鎖設計:支持行鎖、表鎖,可通過擴展sql主動S和X鎖,不能主動加表鎖;
  • 支持外鍵:可以設定外鍵及外鍵的完整性約束;
  • 支持MVVC:多版本併發控制技術,實現了多個版本數據的讀寫;
  • 一致性非鎖定讀:類似Oracle,提高併發,不是所有的讀都會加鎖,大部分讀不加鎖;

InnoDB的版本

InnoDB的跨界版本是1.0.x,建議使用最新版本獲取更好的性能;

體系結構

InnoDB能很好的利用內存和CPU,它的大部分操作都是利用異步IO技術,屏蔽磁盤和內存的速度差,從而獲得更高的性能;

  • 多個後臺線程:通過多個後臺線程,每個線程完成自己的任務,後臺線程的主要作用是刷新內存池中的數據,保持磁盤和內存數據一致;
  • 內存池:使用內存緩衝技術,建立多種緩衝池來緩衝數據、索引,內存管理採用基於頁的管理方式,讓讀寫效率更高;

InnoDB的核心線程

  • Master Thread:核心線程,將數據異步刷新到磁盤,分爲多種狀態,每秒、每10秒的處理邏輯都不同;
  • IO Thread : 採用AIO異步刷新數據到磁盤;
  • Purge Thread:清理線程,實際執行update、insert、delete操作,回收undo頁;
  • Page Cleander Thread:刷新髒頁數據到磁盤,保持數據同步;

內存池

InnoDB通過內存池技術來解決磁盤讀寫速度問題,其內存池管理結構如下:

InnoDB內存管理結果

可以看到,InnoDB是通過頁的方式來管理數據,類似操作系統的內存管理方式,熱點頁常駐內存,採用LRU等算法進行頁的管理,InnoDB通過多種參數和配置可以影響內存池大小和數據頁的換入換出。

InnoDB每個page的大小是16k

內存池參數

在mysql中可以通過如下參數影響InnoDB內存池的大小及行爲:

觀察InnoDB狀態:Show engine innodb status \G

內存池大小:innodb_buffer_pool_size;
page被hit多少次後加入LRU列表的熱點區:innodb_old_blocks_time

InnoDB狀態參數的含義:

Buffer Pool Hit Rate : 緩存命中策略 不應該小於 95%

Free Buffers + Buffer Pool Size  != DataBase Size

重做日誌

爲了實現數據庫事務,基本上所有的數據庫引擎都需要重做日誌,重做日誌包括:redo log 和undo log,統稱重做日誌,重做日誌保證了事務的原子性、一致性、持久性,但是重做日誌本身會帶來開銷。

Checkpoint技術

檢查點技術被很多需要保證系統高可用的程序採用,InnoDB爲了解決磁盤的速度問題,採用內存緩衝方式,也就是很多最新的數據都是在內存中的,但是內存不是持久的,一旦內存斷電,這些修改和操作沒有更新到物理文件中,那麼就會造成數據的丟失和不一致性。InnoDB使用一些技術來保證不會發生這些情況。

InnoDB採用兩種方式將數據異步刷新到磁盤,保證高可用和數據一致性:
- 通過多線程,尤其是核心Master Thread使用一些策略來將數據、日誌、操作刷新到磁盤;
- 檢測點技術,在一些關鍵的點上觸發磁盤操作,將數據、日誌、操作刷新到磁盤;

InnoDB的檢查點技術主要目的:

  • 縮短數據庫恢復時間:減少恢復數據量;
  • 緩衝池不夠的時候,將髒頁刷新到磁盤,釋放緩衝或者防止數據不一致;
  • 重做日誌不可用時,刷新到磁盤,防止重做日誌丟失;

Checkpoint的核心技術是通過LSN(log sequence number)來標記版本號,很多增量備份工具也是使用這個特性。

Checkpoint的觸發時機:

  • 數據庫關閉時,觸發Sharp Checkpoint;
  • Master Thread 每十幾秒觸發一次 Fuzzy Checkpoint;
  • 頁空間不足的時候時觸發Fuzzy Checkpoint;
  • 重做日誌不足,這時磁盤空間不夠了,日誌達到了指定大小,覆蓋日誌失敗了,都觸發Fuzzy Checkpoint;
  • 內存池中髒頁太多觸發Fuzzy Checkpoint。

InnoDB的一些關鍵技術

關鍵技術和特性不一樣,關鍵技術是實現過程中的一些做法,這些做法帶來了特性。下面是InnoDB採用的一些關鍵技術,有些是獨創的,極大的提高了InnoDB的性能。

  • 插入緩衝:insert buffer,解決輔助索引的插入性能問題;
  • 兩次寫:double write,提高數據的可靠性,保證數據一致;
  • 自適應哈希索引:adaptive hash index,提升索引效率;
  • 異步IO:Async IO,使用異步IO不進行同步等待,可以一次發出多個IO指令,底層還會合並多個IO到一次IO;
  • 刷新鄰接表:提升髒頁刷新效率。

Insert Buffer

對於非聚集類索引,也叫輔助索引,如果索引不是唯一的,不需要做唯一性校驗,InnoDB會先將索引放入到緩衝區不會每次都調整索引的B+樹,大致思路:

  • 每次insert的時候,如果輔助索引字段不是唯一的,不需要做唯一性校驗;
  • InnoDB 先不去實際insert index,不刷新磁盤,也不會產生B+樹的旋轉,也就不會引起隨機的IO,等到一定時機,將多個索引的insert merge爲一個insert,提高索引的插入效率。

merge insert buffer的時機:

  • 輔助索引頁被讀取到緩衝池中;
  • Insert Buffer Bitmap追蹤到輔助索引頁無可用空間;
  • Master Thread觸發;

Double Write

提高數據可靠性,尤其是將髒頁刷新到磁盤的時候,防止如果部分寫入失敗了,那麼將產生數據不一致情況;

自適應Hash索引

InnoDB通過監控B+ Tree的索引,如果適用Hash索引,則建立Hash索引。在實際生產環節中,B+ Tree的高度一般爲3 - 4,需要 3 - 4的邏輯IO,遠沒有Hash索引快。

Hash索引僅適用於等值索引,不適合範圍索引,也就是如果頻繁的用where id > ‘100’ 這類操作不會建立自適應Hash索引。

AIO

異步IO,連續發出多個IO,進行IO Merge,提升磁盤的IOPS。

刷新鄰接表

刷新dirty的page時會檢查這個page所在的區域的所有page,如果這些page也是dirty,則一起刷新,通過AIO的merge操作,提升性能。機械硬盤有很大用途;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章