今天我要跟你分享的話題是:“大家常說的表空間到底是什么?究竟什么又是數據表?”
這其實是一個概念性的知識點,當作拓展知識。涉及到的概念大家了解一下就好,涉及的參數,留個印象就好。
一、什么是表?
但凡是用過MySQL都知道,直觀上看,MySQL的數據都存在數據表中。
比如一條Update SQL:
update user set username = '白日夢' where id = 999;
它將user這張數據表中id為1的記錄的username列修改成了‘白日夢’
這里的user其實就是數據表。當然這不是重點,重點是我想表達:數據表其實是邏輯上的概念。而下面要說的表空間是物理層面的概念。
二、什么是表空間?
不知道你有沒有看到過這句話:“在innodb存儲引擎中數據是按照表空間來組織存儲的”。其實有個潛台詞是:表空間是表空間文件是實際存在的物理文件。
大家不用糾結為啥它叫表空間、為啥表空間會對應着磁盤上的物理文件,因為MySQL就是這樣設計、設定的。直接接受這個概念就好了。
MySQL有很多種表空間,下面一起來了解一下。
三、sys表空間
你可以像下面這樣查看你的MySQL的系統表空間

Value部分的的組成是:name:size:attributes
默認情況下,MySQL會初始化一個大小為12MB,名為ibdata1文件,並且隨着數據的增多,它會自動擴容。
這個ibdata1文件是系統表空間,也是默認的表空間,也是默認的表空間物理文件,也是傳說中的共享表空間。
關於這個共享表空間,直觀上看,如果這個表空間能為multiple tables.存儲數據,那么它就可以被稱為共享表空間,所以你可以認為系統表空間是共享表空間。
四、配置sys表空間
系統表空間的數量和大小可以通過啟動參數:innodb_data_file_path
# my.cnf
[mysqld]
innodb_data_file_path=/dir1/ibdata1:2000M;/dir2/ibdata2:2000M:autoextend
ibdata1表空間為固定大小2000M,而ibdata2的2000M使用完后會自動增長。
假設你的服務器有兩塊存儲A、B。並且A、B上分別掛載着dir1目錄和dir2目錄。那你再看上面的配置,它其實是在使用兩個不同磁盤上的文件共同構建表空間。由於這兩個文件位於不同的磁盤上,磁盤的負載就會被均分,數據庫整體的性能也有所提升。
五、file per table 表空間
如果你想讓每一個數據庫表都有一個單獨的表空間文件的話,可以通過參數innodb_file_per_table設置。
這個參數只有在MySQL5.6或者是更高的版本中才可以使用。
可以通過配置文件
[mysqld]
innodb_file_per_table=ON
也可以通過命令
mysql> SET GLOBAL innodb_file_per_table=ON;

讓你將其設置為ON,那之后InnoDB存儲引擎產生的表都會自己獨立的表空間文件。
獨立的表空間文件命名規則:表名.ibd
注意:
獨立表空間文件中僅存放該表對應數據、索引、insert buffer bitmap。
其余的諸如:undo信息、insert buffer 索引頁、double write buffer 等信息依然放在默認表空間,也就是共享表空間中。
這里的undo、insert buffer、double write buffer 如果你不了解他們是啥也沒關系。按照大綱排期,我會在第 41、42 篇文中跟大家分享。在這里只需要先了解即使你設置了
innodb_file_per_table=ON共享表空間的體量依然會不斷的增長,並且你即使你不斷的使用undo進行rollback,共享表空間大小也不會縮減就好了。
查看我的表空間文件:

最后再簡述一下這種file per table的優缺點:
優點:
- 提升容錯率,表A的表空間損壞后,其他表空間不會收到影響。s
- 使用MySQL Enterprise Backup快速備份或還原在每表文件表空間中創建的表,不會中斷其他
InnoDB表的使用
缺點:
- 對fsync系統調用來說不友好,如果使用一個表空間文件的話單次系統調用可以完成數據的落盤,但是如果你將表空間文件拆分成多個。原來的一次fsync可能會就變成針對涉及到的所有表空間文件分別執行一次fsync,增加fsync的次數。
fsync我計划會在第 18 篇文章中跟大家分享。歡迎關注!持續更新中~
六、臨時表空間
臨時表空間用於存放用戶創建的臨時表和磁盤內部臨時表。
參數innodb_temp_data_file_path定義了臨時表空間的一些名稱、大小、規格屬性如下圖:

查看臨時表空間文件存放的目錄

七、undo表空間
相信你肯定聽過說undolog,常見的當你的程序想要將事物rollback時,底層MySQL其實就是通過這些undo信息幫你回滾的。
在MySQL的設定中,有一個表空間可以專門用來存放undolog的日志文件。
然而,在MySQL的設定中,默認的會將undolog放置到系統表空間中。
如果你的MySQL是新安裝的,那你可以通過下面的命令看看你的MySQL undo表空間的使用情況:

大家可以看到,我的MySQL的undo log 表空間有兩個。
也就是我的undo從默認的系統表空間中轉移到了undo log專屬表空間中了。

那undo log到底是該使用默認的配置放在系統表空間呢?還是該放在undo表空間呢?
這其實取決服務器使用的存儲卷的類型。
如果是SSD存儲,那推薦將undo info存放在 undo表空間中。
白日夢計划在第19篇文章中跟大家分享 undolog 相關的知識點。歡迎關注
參考:
https://dev.mysql.com/doc/refman/5.7/en/innodb-tablespace.html
https://dev.mysql.com/doc/refman/5.7/en/innodb-system-tablespace.html
https://dev.mysql.com/doc/refman/5.7/en/innodb-file-per-table-tablespaces.html
https://dev.mysql.com/doc/refman/5.7/en/general-tablespaces.html
https://dev.mysql.com/doc/refman/5.7/en/innodb-undo-tablespaces.html
https://dev.mysql.com/doc/refman/5.7/en/innodb-init-startup-configuration.html
推薦閱讀

- 大家常說的基數是什么?(已發布)
- 講講什么是慢查!如何監控?如何排查?(已發布)
- 對NotNull字段插入Null值有啥現象?(已發布)
- 能談談 date、datetime、time、timestamp、year的區別嗎?(已發布)
- 了解數據庫的查詢緩存和BufferPool嗎?談談看!(已發布)
- 你知道數據庫緩沖池中的LRU-List嗎?(已發布)
- 談談數據庫緩沖池中的Free-List?(已發布)
- 談談數據庫緩沖池中的Flush-List?(已發布)
- 了解臟頁刷回磁盤的時機嗎?(已發布)
- 用十一張圖講清楚,當你CRUD時BufferPool中發生了什么!以及BufferPool的優化!(已發布)
- 聽說過表空間沒?什么是表空間?什么是數據表?(已發布)
- 談談MySQL的:數據區、數據段、數據頁、數據頁究竟長什么樣?了解數據頁分裂嗎?談談看!(已發布)
- 談談MySQL的行記錄是什么?長啥樣?(已發布)
- 了解MySQL的行溢出機制嗎?(已發布)
- 說說fsync這個系統調用吧! (已發布)
- 簡述undo log、truncate、以及undo log如何幫你回滾事物! (已發布)
- 我勸!這位年輕人不講MVCC,耗子尾汁! (已發布)
- MySQL的崩潰恢復到底是怎么回事? (已發布)
- MySQL的binlog有啥用?誰寫的?在哪里?怎么配置 (已發布)
- MySQL的bin log的寫入機制 (已發布)
面試官都關注了!你還在猶豫什么呢?

