大家好,我是anyux。本文介紹MySQL存儲引擎的物理結構與表空間。
InnoDB物理結構
在5.6版本中,ibdata1包含存儲系統元信息,undo表空間數據和臨時表空間
在5.7版本中,文件結構與作用如下
表空間
在5.7版本中下面兩個參數長的很像,名字叫起來也相似,但完全不一樣,需要重點牢記
ibdata1:整個庫的統計信息和undo信息
ibd:數據行和索引信息
關於ibdata1是如何出現的,又是如何沒落了。
雖然ibdata1和ibd是兩個文件,但是在MySQL系統中將它們兩個稱為表空間(Tablespace)
現在我們使用磁碟,都是將一塊300G的磁碟,格式化並且掛載到/data目錄下,給MySQL服務使用。半年後,磁碟幾乎被佔滿。此時又添加一塊新的600G磁碟,格式化並且掛載到/data目錄下,給MySQL服務使用。又半年後,又需要重新掛載磁碟,並且每次都需要停止資料庫服務,那麼有沒有可能不重啟也能實現數據在磁碟間的轉移呢?
此時就使用到了表空間,表空間這個名詞是來自於Oracle資料庫。Oracle就是將資料庫中的數據存儲到表空間(Tablespace),而在表空間內存,會分配數據存儲到sdb1,sdc1等磁碟分區位置上,也就是說磁碟空間的增加對於資料庫服務而言是透明的,是不可感知的
而對於MySQL到了5.5這個版本,已經被Oracle收購了。就將表空間的概念引入到MySQL中,MySQL也具備了表空間的管理模式。不足的是MySQL訪問數據是基於文件系統去訪問,表空間被迫改成了共享表空間,分別存儲到各個磁碟下。
最初始時只要是個innodb引擎的表,都需要將數據行,索引,元信息和undo信息都存入到共享表空間,共享表空間再以不可見的形式存入到各大磁碟下,全都存入了ibdata1中。這樣做的好處是可以實現類似Oracle的表空間管理模式,做一些擴容。問題是所有數據全部寫入到幾個有限的文件中,一旦數據多了,處理效率就會出現嚴重下降
所以到了5.6版本就改成了獨立表空間模式,獨立表空間解決了共享表空間數據"扎堆"的問題,解決方式是獨立存儲每一張表,每張表都自己的ibd,frm,見下圖
需要知道現在共離表空間還在,只不在存儲每張表的數據了,而是存儲庫的元信息和undo信息。而獨立表空間存儲數據行和索引信息
對於mariaDB和PerconaDB和5.5版本,需要更新,否則一旦數據量增長到一定量級,會導致性能下降
對於共享表空間(ibdata1~N),自5.5版本以來,其負責的職責就被不同的程度的剝離
5.6版本以後,共享表空間得以保留,只用來存儲:數字字典信息,undo信息,臨時表
5.7版本以後,臨時表被剝離
8.0版本以後,undo信息被剝離
查看共享表空間路徑
select @@innodb_data_file_path;
下圖表示,第一次啟動時創建共享表空間ibdata1,初始大小為12M,空間不夠時,會自動增長64M的空間
使用du -sh 命令查看文件大小
du -sh /data/mysql/data/ibdata1;
查看共享表空間默認每次自動增長值
show variables like 'innodb_data_file_path'; show variables like '%extend%'
共享表空間參數的配置需要要創建資料庫服務時配置,否則無法修改
獨立表空間
從MySQL5.6版本開始,默認表空間已經變成了獨立表空間,而不再是共享表空間
獨立表空間主要用於存儲用戶數據
每一個表都有一個ibd文件,用於存儲數據及索引信息
基本表結構元數據存儲在frm文件
mysql數據表是由元數據,數據,索引構成
mysql資料庫是由ibdata1~N和frm(元數據),ibd文件(段區頁)
一張InnoDB表由frm,ibd,ibdata1構成
查看獨立表空間變量
select @@innodb_file_per_table;
如果將innodb_file_per_table設置為0,那麼以後創建的數據表,就沒有了獨立表空間了
修改獨立表空間變量
set global innodb_file_per_table=0;
不建議修改此變量,原因是改為0後,所以表將存儲到共享表空間中,數據量增長後,容易導致資料庫性能瓶頸
MySQL的存儲引擎日誌
Redo Log: ib_logfile0 ib_logfile1 重做日誌
Undo Log: ibdata1 ibdata2(存儲在共享表空間中),回滾日誌
臨時表:ibtmp1,在做join union操作產生臨時數據,用完就自動清理
表空間遷移
建立與原表一樣的空表discard空表的ibd文件複製原表的ibd文件,修改權限,import原表的ibd文件查詢驗證 alter table city dicard tablespace; alter table city import tablespace;