InnoDB儲存引擎檔案
MySql中每個表儲存引擎都有自己獨有的檔案,InnoDB儲存引擎相關的檔案主要包括:重做日誌檔案,表空間檔案。
1、表空間檔案
InnoDB採用將儲存的資料按表空間(tablespace)進行存放的設計。在預設配置下會有一個初始大小為10MB,名為ibdata1的檔案。該檔案就是預設的表空間檔案(tablespace file),使用者可以通過引數innodb_data_file_path對其進行設定.
mysql> show variables like 'innodb_data_file_path';
+-----------------------+------------------------+
| Variable_name | Value |
+-----------------------+------------------------+
| innodb_data_file_path | ibdata1:10M:autoextend |
+-----------------------+------------------------+
1 row in set (0.00 sec)
使用者可以通過多個檔案組成一個表空間,同時制定檔案的屬性。
innodb_data_file_path=/db/ibdata1:200M;/dr2/db/ibdata2:2000M:autoextend
這裡/db/ibdata1和/dr2/db/ibdata2兩個檔案用來組成表空間。若這兩個檔案位於不同的磁碟上,磁碟的負載可能被平均,因此可以提高資料庫的整體效能。同時,兩個檔案的檔名後都跟了屬性,表示檔案ibdata1大小為200M, ibdata2大小為20000M,如果用完了這2000M,該檔案可以自動增長(autoextend)。
設定innodb_data_file_path引數後,所有基於InnoDB儲存引擎的表的資料都會記錄到該共享表空間中。若設定了擦拭農戶innodb_file_per_table,則使用者可以將每個基於InnoDB儲存引擎的表產生一個獨立表空間。
獨立表空間的命名規則為:表名.ibd。通過這樣的方式,使用者不用將所有資料都存放於預設的表空間中。
這些單獨的表空間僅僅儲存該表的資料、索引和插入緩衝BITMAP等資訊,其餘資訊還是存放在預設的表空間中。
預設該引數是關閉的。
mysql> show variables like 'innodb_file_per_table';
+-----------------------+-------+
| Variable_name | Value |
+-----------------------+-------+
| innodb_file_per_table | OFF |
+-----------------------+-------+
1 row in set (0.00 sec)
下圖顯示了InnoDB儲存引擎對於檔案的儲存方式:
2、重做日誌檔案
在預設情況下,在InnoDB儲存引擎的資料目錄下會有兩個名為ib_logfile0和ib_logfile1的檔案。在MySql官方手冊中將其稱為InnoDB儲存引擎的日誌檔案,不過更準確的定義應該是重做日誌檔案(redo log file)。
重做日誌檔案對於InnoDB儲存引擎很重要,它們記錄了對於InnoDB儲存引擎的事務日誌。
當例項或介質(media failure)時,重做日誌檔案就派上用場了。例如,資料庫由於所在主機掉電導致例項失敗,InnoDB儲存引擎會使用重做日誌恢復到掉電前的時刻,以此來保證資料的完整性。
每個InnoDB儲存引擎至少有1個重做日誌檔案組,每個檔案組下至少有2個重做日誌檔案,如預設的ib_logfile0和ib_logfile1。
root@TryHard:~# find / -name ib_logfile*;
/var/lib/mysql/ib_logfile1
/var/lib/mysql/ib_logfile0
為了得到更高的可靠性,使用者可以設定多個映象日誌組,將不同的檔案組放在不同的磁碟上,以此提高日誌的高可用性。在日誌組中每個重做日誌檔案的大小一致,並以迴圈寫入的方式執行。InnoDB儲存引擎先寫重做日誌檔案1,當達到檔案的最後時,會切換至重做日誌檔案2,再當重做日誌檔案2也被寫滿時,會再切換到重做日誌檔案1中。下圖顯示了一個擁有3個重做日誌檔案的重做日誌檔案組。
下面引數影響著重做日誌檔案的屬性:
(1)innodb_log_file_size
(2)innodb_log_files_in_group
(3)innodb_mirrored_log_groups
(4)innodb_log_group_home_dir
引數innodb_log_file_size指定每個重做日誌檔案的大小。在InnoDB1.2.x版本之前,重做日誌檔案總的大小不得大於等於4GB,而1.2.x版本將該顯示擴大為512GB。
引數innodb_log_files_in_group指定了日誌檔案組中重做日誌檔案的數量,預設為2.
引數innodb_mirrored_log_groups指定了日誌映象檔案組的數量,預設為1,表示只有一個日誌檔案組,沒有映象。如果磁碟本身已經做了高可用的方案,如磁碟陣列,那麼可以不開啟重做日誌映象的功能。
引數innodb_log_goup_home_dir指定了日誌檔案組所在路徑,預設為./,表示在MySql資料庫的資料目錄下。
mysql> show variables like 'innodb%log%';
+--------------------------------+---------+
| Variable_name | Value |
+--------------------------------+---------+
| innodb_flush_log_at_trx_commit | 1 |
| innodb_locks_unsafe_for_binlog | OFF |
| innodb_log_buffer_size | 8388608 |
| innodb_log_file_size | 5242880 |
| innodb_log_files_in_group | 2 |
| innodb_log_group_home_dir | ./ |
| innodb_mirrored_log_groups | 1 |
+--------------------------------+---------+
7 rows in set (0.00 sec)
重做日誌檔案的大小設定對於InnoDB儲存引擎的效能有著非常大的影響。一方面重做日誌不能設定的太大。如果設定的很大,在恢復時可能需要很長的時間;另一方面又不能設定的太小了,否則可能導致一個事務的日誌需要多次切換重做日誌檔案。此外,重做日誌檔案太小會導致頻繁地發生async checkpoint,導致效能的抖動。
因為重做日誌有一個capacity變數,該值代表了最後的檢查點不能超過這個閥值,如果超過則必須將緩衝池中髒頁列表中的部分髒資料頁寫回磁碟,這時會導致使用者執行緒的阻塞。
重做日誌也是記錄事務日誌,那麼它和二進位制日誌有什麼區別?
首先,二進位制日誌會記錄所有與MySql資料庫有關的日誌記錄,包括InnoDB,MyISAM,Heap等其它儲存引擎的日誌。而InnoDB儲存引擎的重做日誌只記錄有關該儲存引擎本身的事務日誌。
其次,記錄的內容不同。無論使用者將二進位制日誌檔案記錄的格式設定為STATEMENT還是ROW,又或者是MIXED,其記錄的都是關於一個事務的具體操作內容,即該日誌是邏輯日誌。而InnoDB儲存引擎的重做日誌檔案記錄的是關於每個頁的更改的物理情況。
最後,寫入的時間也不同,二進位制日誌檔案僅在事務提交前進行提交,即只寫磁碟一次,不論這時該事務多大。而在事務進行的過程中,卻不斷有重做日誌條目被寫入重做日誌檔案中。
在InnoDB儲存引擎中,對於各種不同的操作有著不同的重做日誌格式。到InnoDB1.2.x版本為止,總共定義了51種重做日誌型別。雖然各種重做日誌的型別不同,但是他們有著基本的格式,下表顯示了重做日誌條目的結構:
重做日誌條目由4個部分組成:
redo_log_type佔用1個位元組,表示重做日誌的型別。
space表示表空間的ID,但採用壓縮的方式,因此佔用的空間可能小於4位元組。
page_no表示頁的偏移量,同樣採用壓縮的方式
redo_log_body表示每個重做日誌的資料部分,恢復時需要呼叫相應的函式進行解析。
寫入重做日誌檔案的操作不是直接寫,而是先寫入一個重做日誌緩衝(redo log buffer)中,然後按照一定的條件順序地寫入日誌檔案。下圖顯示了重做日誌的寫入過程。
從重做日誌緩衝往磁碟寫入時,是按512位元組,也就是一個扇區的大小進行寫入。因為扇區是寫入的最小單位,因此可以保證寫入必定是成功的。因此在重做日誌的寫入過程中不需要有doublewrite。
前面說,從日誌緩衝寫入磁碟上的重做日誌檔案是按一定條件進行的,那麼這些條件有哪些呢?
主執行緒每秒會將重做日誌緩衝寫入磁碟的重做日誌檔案中,不論事務是否已經提交。
另一個觸發寫磁碟的過程是由引數innodb_flush_log_at_trx_commit控制,表示在提交操作時,處理重做日誌的方式。
mysql> show variables like 'innodb_flush_log_at_trx_commit';
+--------------------------------+-------+
| Variable_name | Value |
+--------------------------------+-------+
| innodb_flush_log_at_trx_commit | 1 |
+--------------------------------+-------+
1 row in set (0.00 sec)
引數innodb_flush_log_at_trx_commit的有效值有0,1,2。
0代表當前提交事務時,並不將事務的重做日誌寫入磁碟上的日誌檔案,而是等待主執行緒每秒的重新整理。
1和2不同的地方在於:1表示在執行commit時將重做日誌緩衝同步寫到磁碟,即伴有fsync的呼叫。2表示將重做日誌非同步寫到磁碟,即寫到檔案系統的快取中。因此不能完全保證在執行commit時肯定會寫入重做日誌檔案,只是有這個動作發生。
因此為了保證事務的ACID中的永續性,必須將innodb_flush_log_at_trx_commit設定為1,也就是每當有事務提交時,就必須確保事務都已經寫入重做日誌檔案。那麼當資料庫因為意外發生當機時,可以通過重做日誌檔案恢復,並保證可以恢復已經提交的事務。而設定為0或2,都有可能發生恢復時部分事務的丟失。不同之處在於,設定為2時,當MySql資料庫發生當機而作業系統及伺服器並沒有發生當機時,由於此時未寫入磁碟的事務日誌儲存在檔案系統快取中,當恢復時同樣能保證資料不丟失。
總結
InnoDB儲存引擎相關的檔案,包括表空間檔案和重做日誌檔案。表空間檔案是用來管理InnoDB儲存引擎的儲存,分為共享表空間和獨立表空間。
重做日誌非常的重要,用來記錄InnoDB儲存引擎的事務日誌,也因為重做日誌的存在,才使得InnoDB儲存引擎可以提供可靠的事務。
相關文章
- MyISAM 儲存引擎,Innodb 儲存引擎儲存引擎
- Innodb儲存引擎儲存引擎
- InnoDB儲存引擎——表儲存引擎
- MySQL InnoDB儲存引擎MySql儲存引擎
- InnoDB儲存引擎簡介儲存引擎
- Mysql技術內幕InnoDB儲存引擎讀書筆記--《二》InnoDB儲存引擎MySql儲存引擎筆記
- MySQL InnoDB 儲存引擎探祕MySql儲存引擎
- InnoDB儲存引擎——兩次寫儲存引擎
- InnoDB儲存引擎——記憶體儲存引擎記憶體
- InnoDB儲存引擎——Checkpoint技術儲存引擎
- InnoDB儲存引擎——插入緩衝儲存引擎
- InnoDB儲存引擎——非同步IO儲存引擎非同步
- Mysql技術內幕InnoDB儲存引擎讀書筆記--《三》檔案MySql儲存引擎筆記
- 你真的瞭解Innodb儲存引擎?儲存引擎
- InnoDB儲存引擎MVCC實現原理儲存引擎MVC
- 14.1 InnoDB 儲存引擎介紹儲存引擎
- innodb儲存引擎備份工具--Xtrabackup儲存引擎
- 第二章 InnoDB儲存引擎儲存引擎
- [Mysql技術內幕]Innodb儲存引擎MySql儲存引擎
- InnoDB儲存引擎鎖機制(一、案例)儲存引擎
- innodb儲存引擎鎖的實現(一)儲存引擎
- MySQL InnoDB儲存引擎體系結構MySql儲存引擎
- 《MySQL 效能優化》之 InnoDB 儲存引擎MySql優化儲存引擎
- InnoDB儲存引擎——後臺執行緒儲存引擎執行緒
- MySQL儲存引擎--MyISAM與InnoDB區別MySql儲存引擎
- MySQL技術內幕:InnoDB儲存引擎MySql儲存引擎
- Myisam 儲存引擎-MYI索引檔案-1儲存引擎索引
- MySQLInnoDB儲存引擎(一):精談innodb的儲存結構MySql儲存引擎
- MyISAM與innoDB儲存引擎有何差別儲存引擎
- MySQL儲存引擎:MyISAM和InnoDB的區別MySql儲存引擎
- InnoDB儲存引擎——Master Thread工作方式儲存引擎ASTthread
- InnoDB儲存引擎——自適應雜湊索引儲存引擎索引
- MySQL儲存引擎MyISAM與InnoDB的優劣MySql儲存引擎
- Mysql核心:INNODB儲存引擎--《十一》Insert BufferMySql儲存引擎
- MySQL核心InnoDB儲存引擎(卷1)筆記MySql儲存引擎筆記
- Mysql innodb儲存引擎的效能最佳化MySql儲存引擎
- Myisam-儲存引擎-MYI索引檔案-2儲存引擎索引
- 總結MySQL儲存引擎MyISAM與InnoDB區別MySql儲存引擎