MySQL中的ibdata1用法解讀
MySQL的ibdata1用法
系統(tǒng)表空間是InnoDB數(shù)據(jù)字典、雙寫緩沖區(qū)、更改緩沖區(qū)和撤消日志的存儲區(qū)域 。
如果表是在系統(tǒng)表空間中創(chuàng)建的,而不是在每個表文件或通用表空間中創(chuàng)建,則它還可能包含表和索引數(shù)據(jù)。
系統(tǒng)表空間可以有一個或多個數(shù)據(jù)文件。默認情況下,ibdata1會在數(shù)據(jù)目錄中創(chuàng)建一個名為 的系統(tǒng)表空間數(shù)據(jù)文件 。系統(tǒng)表空間數(shù)據(jù)文件的大小和數(shù)量由innodb_data_file_path啟動選項定義。

ibdata1即Innodb data1的縮寫,是innodb引擎的表空間,用于存放以下內(nèi)容:
- 數(shù)據(jù)字典Data dictionary:只讀的表,存儲對象的相關信息,如占用空間,列的缺省值,約束信息,用戶名,權限,審計信息等;
- 雙寫緩沖區(qū) Double write buffer:Innodb寫入數(shù)據(jù)默認是16k/pages為一個單位寫入,而磁盤是4k/page一個單位,為了防止寫入一半,斷電無法恢復數(shù)據(jù)的情況發(fā)生,引入了double writer buffer機制;double write buffer是一段連續(xù)空間,大小2M(128 page),數(shù)據(jù)寫入的時候先寫到doublewrite空間,然后再寫入到磁盤,如果發(fā)生寫入了一個page一半的時候斷電,恢復后會自動從doublewrite中恢復;
- 插入緩沖區(qū)INSERT BUFFER:針對輔助索引(非unique),插入數(shù)據(jù)的時候,先將插入的數(shù)據(jù)在buffer中根據(jù)輔助索引葉子節(jié)點的Page_no排序,而后按照Page_no分批次插入,提高性能;
- 回滾日志rollback segment: 用于存儲未提交事物,便于用戶rollback,當commit后,數(shù)據(jù)即被標記無效;
- undo空間 用于存放undo 日志的;用于記錄事物變更前的狀態(tài),如果未commit,其他session可以查看到變更前狀態(tài)
- 如果innodb_file_per_table=0,則Innodb的數(shù)據(jù)和索引也存儲在ibdata中; (如果為1,則存儲在表名相同的ibd和frm文件中); 如果表數(shù)據(jù)存儲在ibdata中的話,那么刪除表是不會釋放空間;
mysql 默認配置使用 innodb 引擎 innodb_file_per_table 默認是關閉的 , 因此表空間默認建立在 ibdata1 上

1 、默認情況下 ibdata 存放 InnoDB 表( InnoDB 數(shù)據(jù)字典)元數(shù)據(jù)、 undo logs 、 the change buffer, and the doublewrite buffer
2 、如果 innodb_file_per_table=0( 默認 =1) ,則 ibdata 也存放 InnoDB 表的實際數(shù)據(jù),也就是 InnoDB 表建立后,不會再有單獨的 tablename.ibd 文件 , 如果是 innodb_file_per_table=1, 存放 在新的表的 ibd 文件當中
3 、 雖 然 InnoDB 表 元 數(shù) 據(jù) 通 過 information_schema.tables 來 讀 取 , 但 是 實 際 上 information_schema 是一個虛擬數(shù)據(jù)庫,并不物理存在,這些數(shù)據(jù)真正存放的地方就是 ibdata redo 是寫在 ib_logfile 中的 , 不寫在 ibdata 中。
導致ibdata1 增長很快的原因
數(shù)據(jù)庫中運行有長事務,記錄了大量的UNDO信息,從而導致了ibdata1持續(xù)增長。
可以通過show engine innodb status ;命令來查看。

mysql中并未提供如何查看ibdata1中的存儲內(nèi)容信息??梢允褂霉ぞ?innochecksum 來看。
ibdata1是什么?
MySQL使用InnoDB引擎的時候,ibdata1這個文件會隨著時間的增長,會變得越來越大,占據(jù)大量的磁盤空間。
那么,ibdata1里保存了哪些東西,為什么會變得越來越大呢,讓我們開看看ibdata1的構(gòu)造。
ibdata1是InnoDB的共有表空間,默認情況下會把表空間存放在一個文件ibdata1中,會造成這個文件越來越大。
發(fā)現(xiàn)問題所在之后,解決方法就是,使用獨享表空間,將表空間分別單獨存放。MySQL開啟獨享表空間的參數(shù)是Innodb_file_per_table,會為每個Innodb表創(chuàng)建一個.ibd的文件。
操作步驟
下面講一下具體的操作。
1) 導出數(shù)據(jù)庫中所有數(shù)據(jù)
# mysqldump -u root -p --all-database > /tmp/all-database.dump
2) 刪除數(shù)據(jù)庫中數(shù)據(jù)
# mysql -u root -p mysql> drop database dbname;
3) 停止MySQL
# /etc/init.d/mysqld stop
4) 刪除ibdata1文件(移動到/tmp下)
# mv /var/lib/mysql/ibdata1 /tmp # mv /var/lib/mysql/ib_logfile0 /tmp # mv /var/lib/mysql/ib_logfile1 /tmp
5) my.cnf設定
# vi /etc/my.cnf 開啟獨享表空間,并指定ibdata1大小為1G,ibdata2大小200M,自動擴張。 innodb_data_home_dir = /var/lib/mysql innodb_data_file_path = ibdata1:1G;ibdata2:200M:autoextend innodb_file_per_table
6) 啟動MySQL
# /etc/init.d/mysqld start
7) 導入數(shù)據(jù)
# mysql -u root -p < /tmp/all-database.dump
8) 確認
后記
開啟獨享表空間后,并不是說就不需要ibdata1了,因為在ibdata1中還保存著下面這些數(shù)據(jù)。
- InnoDB表的元數(shù)據(jù)
- Buffer
- UNDO日志
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
mysql中find_in_set()函數(shù)的使用及in()用法詳解
這篇文章主要介紹了mysql中find_in_set()函數(shù)的使用以及in()用法詳解,需要的朋友可以參考下2018-07-07
MySQL錯誤:You can‘t specify target table&n
在編寫MySQL的UPDATE或DELETE語句時,如果子查詢中直接引用了要操作的目標表,可能會遇到一個常見的錯誤:You can’t specify target table ‘xxx’ for update in FROM clause,這個錯誤讓許多開發(fā)者感到困惑,本文將深入分析其原因,并提供多種解決方案,2025-02-02
Mysql中Insert into xxx on duplicate key update問題
在看代碼的過程中碰到了這一用法,不太理解,google了一下。它的意義其實是如果在insert語句末尾制定了on duplicate key update語句的話,則當插入行會導致一個unique索引或者primary key中出現(xiàn)重復值,則執(zhí)行update中的語句,否則才插入新行2012-08-08
Navicat Premium遠程連接MySQL數(shù)據(jù)庫的方法
這篇文章主要介紹了Navicat Premium遠程連接MySQL數(shù)據(jù)庫的方法,本文分步驟通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-12-12

