innodb存儲引擎

數據庫和實例

 
數據庫(database):物理操做系統文件或其餘形式文件類型的集合
實例(instance):mysql數據庫由後臺線程以及一個共享內存區組成。
 
一般狀況下,二者是一對一關係;可是,在集羣狀況下可能存在一個數據庫被多個數據實例使用的狀況。
 
mysql實例在系統上的表現就是一個進程;
 
InnoDB存儲架構
 
 

 

innodb 在內存中的緩存池 buffer pool ;
 
 
innodb相關的磁盤文件

 

 

innodb系統表空間文件:
ibdata1存放:
  • 回滾段
  • 全部innodb表元數據信息(這就是爲何innodb沒法像myisam表同樣,直接將表定義文件  表名.frm 和表數據文件 表名.ibd 拷貝到 另外一個庫中,由於還有部分元數據信息在ibdata1文件中)
  • double write,insert buffer dump 等等
自動擴展機制
 
 
基本參數

 
查看innodb的配置參數
mysql> show global variables like "%innodb%" ;
基本參數:
innodb_data_home_dir:               系統表空間文件ibdata1存放在哪一個目錄下
innodb_log_group_home_dir:  日誌文件ib_logfile0/1存放在哪一個目錄
innodb_data_file_path:              定義系統表空間文件ibdata1的屬性;
innodb_autoextend_increment:   系統表空間文件每次擴展的大小
innodb_log_file_size:                  ib_logfile文件大小(寫操做多時能夠增大)
innodb_log_files_in_group:         有幾個ib_logfile文件(寫操做多時能夠增大 )
innodb_file_per_table:  
關鍵;開啓後,會產生表定義文件 表名.frm,和表數據文件  表名.idb,
這樣每一個表的數據都會存在本身的.idb文件中;若是 關閉,那麼全部的
數據都會 存在系統表空間文件 ibdata1文件中,這會ibdata1 很是繁忙
而且臃腫 龐大,並且ibdata1沒法 收縮的,好比線上將一個 大的表 drop掉,
此時ibdata1是沒法自動縮小的(須要使用 optimiza table 來優化);而若是開啓,數據存在 .idb文件中,則能夠隨時縮小;
 
innodb數據文件存儲結構

 

 

特色:
  • 根據主鍵尋址速度很快
  • 主鍵值遞增的insert插入效率較好
  • 主鍵值隨機insert插入操做效率差
  • 所以,innodb表必須指定主鍵,建議使用自增數字;
若是不使用主鍵,系統會自動加上一個6字符字符串的主鍵;
 
innodb數據塊緩存池

  • 數據的讀寫須要通過緩存(緩存在buffer pool 即在內存中)
  • 數據以整頁(16K)位單位讀取到緩存中
  • 緩存中的數據以LRU策略換出(最少使用策略)
  • IO效率高,性能好
 

 

innodb_buffer_pool_size:

 

爲了IO效率,數據庫修改的文件都在內存緩存中完成的;那麼咱們知道一旦斷電,內存中的數據將消失,而數據庫是如何保證數據的完整性的呢?那就是數據持久化與事務日誌;
 
innodb 數據持久化與事務日誌

  • 事務日誌實時持久化
  • 內存變化數據(髒數據)增量異步刷出到磁盤
  • 實例故障靠重放日誌恢復
  • 性能好,可靠,恢復快;

 

若是宕機了則:應用已經持久化好了的日誌文件,讀取日誌文件中沒有被持久化到數據文件裏面的記錄;將這些記錄從新持久化到咱們的數據文件中.
 
優缺點:若是實時的刷新到 磁盤中,要找到x隨機存放的位置,IO消耗大;而若是將修改刷新到日誌文件中,由於它是順序讀寫的,速度會快不少。
 
innodb日誌持久化相關參數
innodb_flush_log_at_trx_commit 
 
innodb 行級鎖
  • 寫不阻塞讀
  • 不一樣行間的寫相互不阻塞
  • 併發性能好
 
innodb與事務ACID
事務ACID特性完整支持
  • 回滾段失敗回滾                     A
  • 支持主外鍵約束                     C
  • 事務版本+回滾段=MVCC       I
  • 事務日誌持久化                     D
 
默承認重複讀隔離級別,能夠調整
 
innodb關鍵特性

 
  • 插入緩衝(insert buffer)
  • 兩次寫(Double write)
  • 自適應哈希索引(adaptive hash index)
  • 異步io(Async IO)
  • 刷新領接頁(Flush Neighbor  Page)
帶來了更好的性能以及更高的可靠性。
 
 
1.插入緩衝
 
使用場景,即非惟一輔助索引的插入操做,由於不是順序的,因此將這些插入操做,
存到插入緩衝中去,而後一段時間統一插入到真的索引中去,此時頗有可能有幾條 插入合併操做,
由於他們是對同一索引頁進行的操做,這樣就大大提升了效率。
關鍵就是將一些 離散的操做,緩存起來,而後找到一些對同一個索引頁 進行 操做的 操做項 進行合併,這樣提升了 效率。
 
 
2.兩次寫 
提升了 數據頁的可靠性。
 
在應用(apply)重作日誌前,用戶須要一個頁的副本,當寫入失效發生時,先經過頁的副原本還原該頁,再進行重作,這就是duble write 。
 
 
dublewrite組成
  • 內存中的dublewrite buffer,大小2M,
  • 物理磁盤上共享表空間中連續的128個頁,即2個區(extend),大小一樣爲2M。
對緩衝池的髒頁進行刷新時,不是直接寫磁盤,而是會經過memcpy()函數將髒頁先複製到內存中的doublewrite buffer,
以後經過doublewrite 再分兩次,每次1M順序地寫入共享表空間的物理磁盤上,在這個過程當中,由於doublewrite頁是連續的,
所以這個過程是順序寫的,開銷並非很大。在完成doublewrite頁的寫入後,再將doublewrite buffer 中的頁寫入各個 表空間文件中,
此時的寫入則是離散的。若是操做系統在將頁寫入磁盤的過程當中發生了崩潰,在恢復過程當中,innodb能夠從共享表空間中的doublewrite
中找到該頁的一個副本,將其複製到表空間文件,再應用重作日誌。
 
 
3.自適應哈希索引
哈希(hash)是一種很是快的查找方法,在通常狀況下這種查找的時間複雜度爲O(1),即通常僅須要一次查找就能定位數據。
而B+樹的查找次數,取決於B+樹的高度,在生成環境中,B+樹的高度通常3-4層,故須要3-4次的查詢。
 
innodb會監控對錶上個索引頁的查詢。若是觀察到創建哈希索引能夠帶來速度提高,則創建哈希索引,稱之爲自適應哈希索引(Adaptive Hash Index,AHI)。
 
AHI有一個要求,就是對這個頁的連續訪問 模式必須是同樣的。
例如對於(a,b)訪問模式狀況:
where a = xxx
where a = xxx and b = xxx
 
訪問模式同樣指的是查詢的條件同樣,若交替進行上述兩種查詢,那麼innodb不會對該頁構造AHI,此外AHI還有以下的要求:
  • 以該模式訪問了100次
  • 頁經過該模式訪問了N次,其中N=頁中記錄*1/16;
 
AHI啓動後,讀寫速度提升了2倍,輔助索引的鏈接操做性能能夠提升5倍。
AHI,是數據庫自動優化的,DBA只須要指導開發人員去儘可能使用符合AHI條件的查詢, 以提升效率
 
 
4.異步IO
 
sync  IO :同步IO 即每進行一次IO操做,這次操做結束才能繼續接下來的操做。
可是若是用戶發須要等待出一條索引掃描的查詢,那麼這條SQL查詢語句可能須要掃描多個索引頁,
也就是須要進行屢次的IO操做。在每掃描一個頁並等待期完成再進行下一次的掃描是沒有必要的。
 
異步IO: 
用戶能夠在發出一個IO請求後當即再發出另外一個IO請求,當所有IO請求發送完畢後,等待全部IO操做的完成,這就是AIO。
 
AIO另外一個優點能夠將多個IO,合併爲1個IO,以提升IO效率。例如:
用戶須要訪問3頁內容,但這3頁時連續的。同步IO須要進行3次IO,而AIO只須要一次 就能夠了。
 
使用AIO的恢復速度 提升了75%
 
5.刷新領接頁
工做原理:
當刷新一個髒頁時,innodb會檢測該頁所在區(extent)的全部頁,若是是髒頁,那麼一塊兒進行刷新。
這樣作,經過AIO將多個IO寫入操做合併爲一個IO操做。在傳統機械磁盤下有着顯著優點。
innodb_flush_neighbors 參數來控制是否開啓。
 
 
 總結

  •  數據庫與實例
  •  innodb相關磁盤文件:
    •  ibdata1:
      • 回滾段
      • 表元數據
      • double write
      • insert buffer dump等
    •  ib_logfile0/1
    •  .frm:表定義文件
    •  .ibd:數據文件,innodb_file_per_table=1
  •  性能相關參數:
    • innodb_log_file_size
    • innodb_log_files_in_group
    • 緣由:當redo log 採用輪尋範式ib_logfile0寫完,寫ib_logfile1完,清楚ib_logfile0並繼續寫入ib_logfile0;當ib_logfile1寫完,ib_logfile0中還有數據沒有持久化到磁盤,又來了新的寫入,此時會阻塞新寫入,強制刷新ib_logfile0到磁盤,再將新寫,寫入ib_logfile0;這樣就是說,logfile越大其寫入越不容易阻塞,寫入性能也就越好。
  •  數據節點每頁16K
  •  innodb數據塊緩存池
    • 數據讀寫通過緩存池
    • 數據以整頁爲單位讀取
    • LRU策略(最少使用)換出,
  •  innodb數據持久化:經過事務日誌
  •  innodb_flush_log_at_trx_commit
    • 0:每秒寫入並持久化一次(不安全,性能高,不管mysql或服務器宕機,都會丟數據)
    • 1:每次commit都持久化(安全,性能低,IO負擔重)
    • 2:每次commit都寫入內存的redo log緩存,每秒再刷新到磁盤(安全,性能折中,mysql宕機數據不會丟失,服務器宕機數據會丟失)
  •  innodb關鍵特性
    • 插入緩衝(insert buffer)
    • 兩次寫(Double write)
    • 自適應哈希索引(adaptive hash index)
    • 異步io(Async IO)
    • 刷新領接頁(Flush Neighbor  Page)
相關文章
相關標籤/搜索