buffer pool
,若是mysql不使用內存緩衝池,每次讀取數據時,都須要訪問磁盤,會大大的增長磁盤的IO請求,致使效率低下;在Innodb引擎在讀取數據的時候,把相應的數據和索引載入到內存的緩衝池(buffer pool)中,必定程度的提升了數據的讀寫速度mysql
佔用大量內存,用來存放各類數據的緩存包括:索引頁,數據頁,undo頁,插入緩衝,自適應哈希索引,innodb存儲的鎖信息,數據字典等。工做方式是將數據庫文件按照頁(每頁16k)讀取到緩衝池,而後按照最近最少使用算法(LRU
)來保留緩衝池中的緩衝數據。若是數據庫文件須要修改,老是首先修改在緩衝池中的頁(發生修改後即成爲髒頁
),而後在按照必定的頻率將緩衝池中的髒頁刷新到文件算法
表空間能夠看做是InnoDB存儲引擎邏輯結構的最高層。表空間文件:InnoDB默認的表空間文件爲ibdata1
sql
頁:每頁數據爲16kb,且不能進行修改。常見的頁類型有:數據頁,Undo頁,系統頁,事務數據頁,插入緩衝位圖頁,插入緩衝空閒列表頁,未壓縮的二進制大對象頁,壓縮的二進制大對象頁數據庫
區:由64個連續的頁組成,每一個頁大小爲16kb,即每一個區的大小爲1024kb即1MB緩存
段:表空間由各個段組成,常見的段有數據段,索引段,回滾段(undo log段)等併發
mysql中的原則是日誌先行。爲了知足事務的持久性,防止buffer pool
數據丟失,innodb引入了redo log
。爲了知足事務的原子性,innodb引入了undo log
性能
redo log就是保存執行的SQL語句到一個指定的log文件,當mysql進行數據恢復的時候,從新執行redo log記錄的SQL操做便可。引入buffer pool會致使更新的數據不會實時地將數據持久化到硬盤,當系統崩潰時,雖然buffer pool中的數據丟失,數據沒有持久化。可是系統能夠根據redo log的內容,將全部數據恢復到最新的狀態。redo log在磁盤上做爲一個獨立的文件存在,默認狀況下會有兩個文件,名稱分別爲ib_logfile0
和ib_logfile1
設計
innodb_additional_mem_pool_size = 100M innodb_buffer_pool_size = 128M innodb_data_home_dir = /home/mysql/local/mysql/var innodb_data_file_path = ibdata1:1G:autoextend innodb_file_io_threads = 4 innodb_thread_concurrency = 16 innodb_flush_log_at_trx_commit = 1 innodb_log_buffer_size = 8M innodb_log_file_size = 128M innodb_log_file_in_group = 2 innodb_log_group_home_dir = /home/mysql/local/mysql/var
undo log和redo log自己是分開的。Innodb的undo log是記錄在數據文件(ibd)中的,並且innodb將undo log的內容看作是數據,所以對undo log自己的操做(如向undo log插入一條undo log記錄等),都會記錄redo log。undo log能夠沒必要當即持久化到磁盤上。即使丟失了,也能夠經過redo log將其恢復。所以當插入一條記錄時:指針
向undo log插入一條undo log記錄日誌
向redo log中插入一條「插入undo log記錄」的redo log記錄
插入數據
向redo log插入一條「insert」的redo log記錄
在一個事務中插入數據的時候:
假設對兩個字段A,B分別進行更新,初始值分別爲1,3 begin 在undo log中記錄A爲1 更新A爲2 記錄A=2到redo log 在undo log中記錄B爲3 更新B爲4 記錄B=4到redo log 將redo log寫入到磁盤 commit
爲了保證redo log可以有很好的io性能,innodb的redo log的設計有如下幾個特色:
儘可能保持redo log存儲在一段連續的空間上。所以在系統第一次啓動時就會將日誌文件的空間徹底分配。以順序追加的方式記錄redo log
批量寫入日誌。日誌並非直接寫入到文件,而是先寫入redo log buffer,而後每秒鐘將buffer中數據一併寫入磁盤
併發的事務共享redo log的存儲空間,他們的redo log按語句的執行順序,依次交替的記錄在一塊兒,以減小日誌佔用的空間
redo log上只進行順序追加的操做,當一個事務須要回滾時,它的redo log記錄也不會從redo log中刪除
爲了知足事務的原子性,在操做任何數據以前,首先將數據備份到undo log,而後進行數據的修改。若是出現了錯誤或者用戶手動執行了rollback
,系統能夠利用undo log中的備份將數據恢復到事務開始以前的狀態。與redo log不一樣的是,磁盤上不存在單獨的undo log 文件,他存放在數據庫內部的特殊段(segment)中,這稱之爲undo段(undo segment),undo段位於共享表空間內
Innodb爲每行undo log記錄都實現了三個隱藏字段:
6字節的事務ID(DB_TRX_ID)
7字節的回滾指針(DB_ROLL_PTR)
隱藏的ID
數據持久化
pool中維護一個按髒頁修改前後順序排列的鏈表,叫flush_list
。根據flush_list中頁的順序刷數據到持久化存儲。按頁面最先一次被修改的順序排列。正常狀況下,dirty page刷新數據的時機爲:
當redo空間佔滿時,將會將部分dirty page flush到disk上,而後釋放部分redo log內容
當須要buffer pool分配一個page,可是已經滿了,這時候必須flush dirty pages to disk。
檢測到系統空閒的時候
數據恢復隨着時間積累,redo log會變得很大。若是每次都從第一條記錄開始恢復,恢復過程會十分緩慢,從而沒法被容忍。爲了減小恢復的時間,就引入了checkpoint機制:假設在某個時間點,全部的髒頁都被刷新到了磁盤上。這個時間點以前的全部redo log就不須要重作了。系統記錄下這個時間點時redo log的結尾位置做爲checkoutpoint。在進行恢復時,從這個checkpoint的位置開始便可。checkpoint點以前的日誌就再也不須要了,能夠被刪除掉