寫(xiě)在前面的話
你有沒(méi)有想過(guò)這樣一個(gè)問(wèn)題:我們的數(shù)據(jù)在MySQL中是如何存放的?它是以什么樣的組織方式存放在我們磁盤(pán)中的?
我們知道,數(shù)據(jù)是存放在表里面的,在表里面是一行一行存在的。那么這一行一行的數(shù)據(jù)怎么樣在磁盤(pán)中存放的呢?表又是如何在磁盤(pán)上存放的?讀完下面的文章,你就會(huì)對(duì)這個(gè)問(wèn)題整體的認(rèn)識(shí)。
InnoDB的存儲(chǔ)結(jié)構(gòu)
數(shù)據(jù)是放在表空間tablesapce中的,而表空間是段segment組成的,段又是由區(qū)extent組成的,區(qū)又是由頁(yè)page組成的。page里面放的就是一行一行的數(shù)據(jù)。這樣就組成了MySQL中innodb的存儲(chǔ)結(jié)構(gòu)。如下圖所示:
Tablespace
tablespace就是我們平時(shí)所說(shuō)的表空間。它是一個(gè)物理概念,對(duì)應(yīng)到磁盤(pán)上,就是一個(gè)個(gè)數(shù)據(jù)文件。例如在我的MySQL的安裝目錄下面有一個(gè)名稱為feng的數(shù)據(jù)庫(kù),該數(shù)據(jù)庫(kù)下的表空間如下所示:
root@test:/var/lib/mysql/feng# pwd
/var/lib/mysql/feng --------------------->這是我的數(shù)據(jù)庫(kù)目錄,數(shù)據(jù)名稱為:feng
root@test:/var/lib/mysql/feng# ls -lstr
total 1464
4 -rw-r----- 1 mysql mysql 67 Dec 6 14:24 db.opt
12 -rw-r----- 1 mysql mysql 8674 Dec 24 10:51 t_innodb.frm # 表結(jié)構(gòu)定義文件
96 -rw-r----- 1 mysql mysql 98304 Dec 24 10:54 t_innodb.ibd # 表空間文件,里面存放數(shù)據(jù)和索引
12 -rw-r----- 1 mysql mysql 8674 Dec 24 10:51 t_myisam.frm # 表結(jié)構(gòu)定義文件
4 -rw-r----- 1 mysql mysql 2048 Dec 24 10:54 t_myisam.MYI # 表索引文件
4 -rw-r----- 1 mysql mysql 168 Dec 24 10:54 t_myisam.MYD # 表空間文件,里面存數(shù)據(jù)
root@test:/var/lib/mysql/feng#
從上面我們可以看出innodb存儲(chǔ)引擎的表空間和myisam存儲(chǔ)引擎的表空間,有一點(diǎn)不一樣:innodb存儲(chǔ)引擎的表空間對(duì)應(yīng)的數(shù)據(jù)文件和索引是放在一個(gè)文件中的,而myisam存儲(chǔ)引擎的表對(duì)應(yīng)的數(shù)據(jù)文件和索引文件是兩個(gè)分開(kāi)的數(shù)據(jù)文件,這也是innodb表又稱為IOT,索引組織表的一個(gè)原因,它的數(shù)據(jù)和索引是存放在一個(gè)數(shù)據(jù)文件中的。
這里對(duì)應(yīng)的一個(gè)個(gè)數(shù)據(jù)文件.ibd和.MYD結(jié)尾的文件就是一個(gè)個(gè)表空間。我們可以看出這里面是一個(gè)表對(duì)應(yīng)一個(gè)表空間。不同的表他們的表空間是分開(kāi)的。并不像Oracle那樣多個(gè)表共享一個(gè)表空間數(shù)據(jù)文件。其實(shí)在MySQL中也有和Oracle類(lèi)似的存儲(chǔ)方式,多個(gè)表共享一個(gè)表空間文件。這個(gè)是通參數(shù)innodb_file_per_table來(lái)控制的。
如下是查看MySQL中當(dāng)前表空間文件是否獨(dú)立的方式,這個(gè)參數(shù)是從MySQL5.6之后的版本才支持的,在5.6之前的版本中,是不支持獨(dú)立表空間設(shè)置的,和Oracle一樣多個(gè)表共享一個(gè)表空間數(shù)據(jù)文件。
mysql> show variables like 'innodb_file_per_table'; /* 當(dāng)該參數(shù)為ON時(shí),表示每一個(gè)表單獨(dú)一個(gè)表空間文件;如果為OFF,表示多個(gè)表共享一個(gè)表空間文件。 */
+-----------------------+-------+
| Variable_name | Value |
+-----------------------+-------+
| innodb_file_per_table | ON |
+-----------------------+-------+
1 row in set (0.07 sec)
mysql>
常見(jiàn)的表空間
我們經(jīng)常遇到的表空間可以參考MySQLInnodb存儲(chǔ)引擎的存儲(chǔ)架構(gòu)圖:
innodb-architecture.png
從圖中我們可以看到我們經(jīng)常遇到的表空間有如下幾類(lèi):
- System Tablespace:系統(tǒng)表空間,對(duì)應(yīng)到磁盤(pán)上面的數(shù)據(jù)文件就是/var/lib/mysql/ibdata1,如下:
root@test:/var/lib/mysql# ls -lstr ibdata*
77824 -rw-r----- 1 mysql mysql 79691776 Dec 28 14:32 ibdata1
root@test:/var/lib/mysql#
- Undo Tablespace:回滾表空間,默認(rèn)這個(gè)空間是和系統(tǒng)表空間共用一個(gè)表空間的,它不會(huì)單獨(dú)存在,和ibdata1系統(tǒng)表空間文件存在一起。但是在MySQL5.6版本以后,支持單獨(dú)配置回滾表空間了。可以為其單獨(dú)配置,使用參數(shù)innodb_undo_tablespaces來(lái)配置使用幾個(gè)回滾表空間。如果安裝MySQL的時(shí)候沒(méi)有配置回滾表空間,那么查詢的結(jié)果如下:
mysql> show variables like '%undo%';
+--------------------------+------------+
| Variable_name | Value |
+--------------------------+------------+
| innodb_max_undo_log_size | 1073741824 |
| innodb_undo_directory | ./ |
| innodb_undo_log_truncate | OFF |
| innodb_undo_logs | 128 |
| innodb_undo_tablespaces | 0 |
+--------------------------+------------+
5 rows in set (0.02 sec)
從提升MySQL性能的角度上來(lái)看,為了減少磁盤(pán)I/O的競(jìng)爭(zhēng),所以建議把回滾表空間和系統(tǒng)表空間分開(kāi)存放,不讓回滾表空間和系統(tǒng)表空間共用同一個(gè)數(shù)據(jù)表空間文件:ibdata1,可以使用參數(shù)innodb_undo_tablespaces參數(shù)配置回滾表空間的數(shù)據(jù)文件的數(shù)目。配置參數(shù)在/etc/mysql/my.cnf配置文件中如下:[mysqld] # 回滾表空間的配置 innodb_max_undo_log_size = 100M innodb_undo_log_truncate = ON innodb_undo_logs = 128 innodb_undo_tablespaces = 4 配置后的結(jié)果在MySQL的命令行中查看如下:mysql> show variables like '%undo%'; +--------------------------+-----------+ | Variable_name | Value | +--------------------------+-----------+ | innodb_max_undo_log_size | 104857600 | | innodb_undo_directory | ./ | | innodb_undo_log_truncate | ON | | innodb_undo_logs | 128 | | innodb_undo_tablespaces | 4 | +--------------------------+-----------+ 5 rows in set (0.01 sec) 配置后可以查看到對(duì)應(yīng)的回滾表空間的數(shù)據(jù)文件已經(jīng)存在/var/lib/mysql/undo*,如下所示:root@test:/var/lib/mysql# ls -lstr undo* 10240 -rw-r----- 1 mysql mysql 10485760 Dec 28 15:45 undo002 10240 -rw-r----- 1 mysql mysql 10485760 Dec 28 15:45 undo001 10240 -rw-r----- 1 mysql mysql 10485760 Dec 28 15:45 undo004 10240 -rw-r----- 1 mysql mysql 10485760 Dec 28 15:45 undo003 root@test:/var/lib/mysql# 更多關(guān)于回滾表空間的問(wèn)題參考:https://dev.mysql.com/doc/refman/5.7/en/innodb-undo-tablespaces.html
-
- 從提升MySQL性能的角度上來(lái)看,為了減少磁盤(pán)I/O的競(jìng)爭(zhēng),所以建議把回滾表空間和系統(tǒng)表空間分開(kāi)存放,不讓回滾表空間和系統(tǒng)表空間共用同一個(gè)數(shù)據(jù)表空間文件:ibdata1,可以使用參數(shù)innodb_undo_tablespaces參數(shù)配置回滾表空間的數(shù)據(jù)文件的數(shù)目。配置參數(shù)在/etc/mysql/my.cnf配置文件中如下:
[mysqld]
# 回滾表空間的配置
innodb_max_undo_log_size = 100M
innodb_undo_log_truncate = ON
innodb_undo_logs = 128
innodb_undo_tablespaces = 4
-
- 配置后的結(jié)果在MySQL的命令行中查看如下:
mysql> show variables like '%undo%';
+--------------------------+-----------+
| Variable_name | Value |
+--------------------------+-----------+
| innodb_max_undo_log_size | 104857600 |
| innodb_undo_directory | ./ |
| innodb_undo_log_truncate | ON |
| innodb_undo_logs | 128 |
| innodb_undo_tablespaces | 4 |
+--------------------------+-----------+
5 rows in set (0.01 sec)
-
- 配置后可以查看到對(duì)應(yīng)的回滾表空間的數(shù)據(jù)文件已經(jīng)存在/var/lib/mysql/undo*,如下所示:
root@test:/var/lib/mysql# ls -lstr undo*
10240 -rw-r----- 1 mysql mysql 10485760 Dec 28 15:45 undo002
10240 -rw-r----- 1 mysql mysql 10485760 Dec 28 15:45 undo001
10240 -rw-r----- 1 mysql mysql 10485760 Dec 28 15:45 undo004
10240 -rw-r----- 1 mysql mysql 10485760 Dec 28 15:45 undo003
root@test:/var/lib/mysql#
-
- 更多關(guān)于回滾表空間的問(wèn)題參考:https://dev.mysql.com/doc/refman/5.7/en/innodb-undo-tablespaces.html
- Redo Log Tablespace:日志表空間,對(duì)應(yīng)到磁盤(pán)上面的數(shù)據(jù)文件就是/var/lib/mysql/ib_logfile*,如下:
root@test:/var/lib/mysql# ls -lstr ib_logfile*
49152 -rw-r----- 1 mysql mysql 50331648 Dec 6 14:15 ib_logfile1
49152 -rw-r----- 1 mysql mysql 50331648 Dec 28 14:32 ib_logfile0
root@test:/var/lib/mysql#
- Temporary Tablespace:臨時(shí)表空間,對(duì)應(yīng)到磁盤(pán)上面的數(shù)據(jù)文件就是/var/lib/mysql/ibtmp1,如下:
root@test:/var/lib/mysql# ls -lstr ibtmp*
12288 -rw-r----- 1 mysql mysql 12582912 Dec 28 14:32 ibtmp1
root@test:/var/lib/mysql#
- General Tablespace:一般表空間,就是平時(shí)我們用于存儲(chǔ)自己業(yè)務(wù)表中的數(shù)據(jù)用的表空間文件。這里需要注意的是目前很少使用這種以便的表空間了,因?yàn)樗嵌鄰埍砉灿靡粋€(gè)數(shù)據(jù)表空間文件,如果數(shù)據(jù)量比較大的情況下經(jīng)導(dǎo)致這個(gè)表空間數(shù)據(jù)文件會(huì)很大,導(dǎo)致備份、遷移、恢復(fù)等動(dòng)作都很困難。尤其是當(dāng)其中某一個(gè)表的數(shù)據(jù)損壞而引起所有的表數(shù)據(jù)都不可訪問(wèn)的情況。所以,推薦使用下面的獨(dú)立表空間文件。
- File-Pre-Table Tablespace:它和上的General Tablespace的功能一樣,就是用來(lái)存儲(chǔ)我們的業(yè)務(wù)數(shù)據(jù)的表空間。但是它和上面的General Tablespace有一點(diǎn)不同,顧名思義,它是每一個(gè)表對(duì)應(yīng)一個(gè)數(shù)據(jù)表空間文件,這樣可以提高數(shù)據(jù)文件并發(fā)時(shí)的磁盤(pán)I/O,同時(shí)可以避免因?yàn)閿?shù)據(jù)表被損壞導(dǎo)致的所有數(shù)據(jù)表都不可用的情況。在恢復(fù)的時(shí)候,備份的時(shí)候,都很方便。該功能開(kāi)啟的參數(shù)為:innodb_file_per_table=on。這也是目前MySQL5.7版本中默認(rèn)的參數(shù)值。
Segment
段(Segment)由一個(gè)或多個(gè)區(qū)組成,區(qū)在文件系統(tǒng)是一個(gè)連續(xù)分配的空間(在 InnoDB 中是連續(xù)的 64 個(gè)頁(yè)),不過(guò)在段中不要求區(qū)與區(qū)之間是相鄰的。段是數(shù)據(jù)庫(kù)中的分配單位,不同類(lèi)型的數(shù)據(jù)庫(kù)對(duì)象以不同的段形式存在。
Table表和Segment段之間的關(guān)系如下:
- 表是邏輯概念,段是物理存儲(chǔ)概念。
- 一張普通的表,對(duì)應(yīng)一個(gè)段。
- 一張表也可以有多個(gè)段,比如分區(qū)表,一個(gè)分區(qū)一個(gè)段。
- 多張表也可以共享一個(gè)段,比如簇表,多個(gè)簇表共享一個(gè)段。
- 通常情況下,創(chuàng)建一個(gè)表會(huì)創(chuàng)建一個(gè)段,但是:表的創(chuàng)建,并不意味著一定會(huì)創(chuàng)建一個(gè)段,比如臨時(shí)表的創(chuàng)建就不會(huì)創(chuàng)建段。
- 建立其他的數(shù)據(jù)庫(kù)對(duì)象也會(huì)創(chuàng)建段,比如:視圖、索引對(duì)應(yīng)著視圖段、索引段。
Extent
在 InnoDB 存儲(chǔ)引擎中,一個(gè)區(qū)塊分配 64 個(gè)連續(xù)的頁(yè)。因?yàn)?InnoDB 中的頁(yè)大小默認(rèn)是 16KB,所以一個(gè)區(qū)的大小是 64*16KB=1MB。在任何情況下每個(gè)區(qū)大小都為1MB,為了保證頁(yè)的連續(xù)性,InnoDB存儲(chǔ)引擎每次從磁盤(pán)一次申請(qǐng)4-5個(gè)區(qū)。默認(rèn)情況下,InnoDB存儲(chǔ)引擎的頁(yè)大小為16KB,即一個(gè)區(qū)中有64個(gè)連續(xù)的頁(yè)。
Page
Page頁(yè)是InnoDB存儲(chǔ)引擎磁盤(pán)管理的最小單位,每個(gè)頁(yè)默認(rèn)16KB:16384Byte = 16KB,可以使用如下命令在MySQL中進(jìn)行查看。
mysql> show variables like 'innodb_page_size';
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| innodb_page_size | 16384 |
+------------------+-------+
1 row in set (0.02 sec)
在MySQL5.6之前的版本,這個(gè)參數(shù)是不支持動(dòng)態(tài)修改的,如果想要修改,只能自己修改源碼編輯才可以。
而在5.6版本之后,參數(shù)innodb_page_size已經(jīng)支持動(dòng)態(tài)的配置,支持4KB、8KB、16KB(默認(rèn)值)、32KB、64KB。但是這個(gè)配置也僅僅是在數(shù)據(jù)庫(kù)安裝好之后初始化之前自行配置,當(dāng)有數(shù)據(jù)已經(jīng)存在之后,這個(gè)參數(shù)是不能修改的。除非把數(shù)據(jù)通過(guò)mysqldump導(dǎo)出來(lái),重新初始化一個(gè)新的數(shù)據(jù)庫(kù)環(huán)境,然后修改參數(shù)之后,把導(dǎo)出來(lái)的數(shù)據(jù)再次再導(dǎo)入進(jìn)去。
page頁(yè)再細(xì)粒度的劃分,可以分為如下幾種結(jié)構(gòu):
mysql innodb page structure.jpg
下面分別介紹一下page頁(yè)中各個(gè)組成部分的含義。
- File Header:文件頭信息,比較重要的信息有FIL_PAGE_PREV記錄上一個(gè)page頁(yè)和FIL_PAGE_NEXT下一個(gè)page頁(yè)的位置信息,通過(guò)這兩個(gè)信息,可以讓所有的page頁(yè)面組成一個(gè)雙向鏈表:
page雙向鏈表.png
關(guān)于文件頭File Header更為詳細(xì)的內(nèi)容參考如下圖:
- Page Header:記錄本頁(yè)存儲(chǔ)記錄的狀態(tài)信息,比如本頁(yè)記錄數(shù)量,槽數(shù)量,詳細(xì)的信息參考下圖:
- Infimun + Supermum Records:最小行與最大行記錄,是虛擬記錄,標(biāo)記該page頁(yè)中,存儲(chǔ)的id最大的行和id最小的行記錄。具體可以參考如下圖的結(jié)構(gòu):
page infimum and supremum.jpg
- User Records:用戶真正的數(shù)據(jù)存儲(chǔ)區(qū)域,這里真正存放用戶的行數(shù)據(jù),它占據(jù)了整個(gè)page頁(yè)的大部分空間。以單鏈表的形式存儲(chǔ)一條條行記錄。如下圖所示,他們?cè)谖锢砩喜灰欢ㄊ怯行虻模赡軇傞_(kāi)始是有序的,但是隨著增刪改的操作可能就無(wú)序了,但是在邏輯上是有序的:
page內(nèi)數(shù)據(jù)行存儲(chǔ)的方式.png
-
- 一個(gè)page頁(yè)中的多行記錄,再結(jié)合多個(gè)page頁(yè),就形成如下的存儲(chǔ)結(jié)構(gòu):頁(yè)與頁(yè)直接是雙向鏈表,頁(yè)內(nèi)的行記錄直接是單向鏈表。如下所示:page頁(yè)中的每一個(gè)箭頭可以理解為一行數(shù)據(jù)。
page頁(yè)和頁(yè)之間的關(guān)系.png
-
- 基于上面的圖,當(dāng)我們要查詢某一行記錄的時(shí)候,是通過(guò)下面的過(guò)程來(lái)查找的。
- 通過(guò)根節(jié)點(diǎn)開(kāi)始遍歷一個(gè)索引的B+樹(shù),通過(guò)各層非葉子節(jié)點(diǎn)達(dá)到底層的葉子節(jié)點(diǎn)的數(shù)據(jù)頁(yè)(Page),這個(gè)Page內(nèi)部存放的都是葉子節(jié)點(diǎn)
- 在Page內(nèi)部從“Infimum”節(jié)點(diǎn)開(kāi)始遍歷單鏈表(遍歷一般會(huì)被優(yōu)化),如果找到鍵則返回。
- 如果遍歷到了“Supremum”,說(shuō)明當(dāng)前Page里沒(méi)有合適的鍵,這時(shí)借助Page頁(yè)內(nèi)部的next page指針,跳轉(zhuǎn)到下一個(gè)page繼續(xù)從“Infmum”開(kāi)始逐個(gè)查找。
- 基于上面的圖,當(dāng)我們要查詢某一行記錄的時(shí)候,是通過(guò)下面的過(guò)程來(lái)查找的。
- Free Space:存數(shù)據(jù)空間中尚未使用的區(qū)域,該頁(yè)中剩余的空間,用于存放后續(xù)插入的數(shù)據(jù)。
- Page Directory:頁(yè)目錄,頁(yè)中某些記錄的相對(duì)位置,用于提升查詢效率。我們要在一個(gè)頁(yè)中查找指定的一條記錄。除了從頭遍歷還有更高效率的方法么?Page Directory提供了解決方案。
- InnoDB會(huì)將一個(gè)頁(yè)中的所有記錄劃分成若干個(gè)組,每組4-8個(gè)記錄。將每個(gè)組最后一個(gè)記錄相對(duì)于第一個(gè)記錄的地址偏移量(可以定位到真實(shí)數(shù)據(jù)記錄)提取出來(lái)存放在頁(yè)中一個(gè)叫做Page Directory的數(shù)組中,數(shù)組中的元素就是這些地址偏移量,也稱為槽(slot)。所以Page Directory就是由槽組成的。
- 所以在一個(gè)頁(yè)中根據(jù)主鍵查找記錄是很快的,步驟為:二分法確定該記錄所在的槽,并找到該槽所在分組中主鍵值最小的那條記錄。通過(guò)next_record屬性遍歷單鏈表找到記錄
- 注意:二分法,適用于數(shù)組。鏈表是順序存取,不是隨機(jī)存取,用二分查找并不能提高查找效率,因?yàn)槟忝看芜€得從第一個(gè)結(jié)點(diǎn)出發(fā),找到指針LOW,HIGH,MIDDLE所指的元素,所以一般不在鏈表內(nèi)使用二分查找。
- File Trailer:文件尾,刷盤(pán)時(shí)校驗(yàn)頁(yè)是否完整。詳細(xì)內(nèi)參考下圖:
什么是off-page
MySQL的表中存儲(chǔ)數(shù)據(jù)的時(shí)候,數(shù)據(jù)是一行一行的存儲(chǔ)的。這個(gè)行要落在innodb的最小存儲(chǔ)單位:page頁(yè)中。好比我們的書(shū)本中的一行一行的文字是在頁(yè)中,一個(gè)頁(yè)里面有很多行。MySQL中的page頁(yè),就是用來(lái)存儲(chǔ)多個(gè)行的基本單位。
但是如果一個(gè)行特別的大,大于了16KB的大小,那么此時(shí)一個(gè)page頁(yè),就容納不下這個(gè)行了,此時(shí)就要在用2個(gè)甚至更多的page頁(yè)來(lái)存儲(chǔ)這個(gè)行的數(shù)據(jù),這種現(xiàn)象就是off-page,即行溢出,off-page是指一個(gè)表的單行的大小超過(guò)了MySQL默認(rèn)的一個(gè)page頁(yè)的大小。一個(gè)行,要占用多個(gè)頁(yè)來(lái)存儲(chǔ)對(duì)于這種現(xiàn)象,在不同的行存儲(chǔ)格式下面會(huì)有不同的處理方式,下面會(huì)有詳細(xì)的介紹。默認(rèn)的方式是將多余的數(shù)據(jù)需要在overflow-page溢出頁(yè)中存儲(chǔ)。
InnoDB的文件存儲(chǔ)格式
InnoDB存儲(chǔ)引擎有兩種文件存儲(chǔ)格式:Antelope和Barracuda,而這兩種文件存儲(chǔ)格式下,有分別支持兩種行存儲(chǔ)格式。
- Antelope(羚羊):Compact(緊湊的)與Redundant(冗余的)兩種行記錄格式
- compact:在存儲(chǔ)大的數(shù)據(jù)字段的時(shí)候,比如blob、text類(lèi)型的字段,涉及到行溢出的問(wèn)題。它在存儲(chǔ)text大字段的時(shí)候,會(huì)在一個(gè)page頁(yè)中存儲(chǔ)前768個(gè)字節(jié),后面的字節(jié)會(huì)存儲(chǔ)在溢出頁(yè)``overflow page`中。
- redundant:是最早的一種存儲(chǔ)格式,相比compact要占用更多的存儲(chǔ)空間。現(xiàn)在級(jí)別已經(jīng)廢棄。
- Barracuda(梭魚(yú)):Dynamic(動(dòng)態(tài)的)和Compress(壓縮的)還支持compact、redundant兩種。
- dynamic:這種行存儲(chǔ)方式是目前MySQL5.7版本后默認(rèn)的行存儲(chǔ)格式。它在存儲(chǔ)大字段的時(shí)候,只會(huì)在page頁(yè)中存儲(chǔ)一個(gè)指向溢出頁(yè)的一個(gè)20個(gè)字節(jié)的物理指針,而不會(huì)真正的去存放大字段的內(nèi)容。真正的字段內(nèi)容存儲(chǔ)在溢出頁(yè)overflow page中。這種方式,針對(duì)溢出列所在的新頁(yè)利用率更高,查詢的效率會(huì)減少磁盤(pán)的I/O交互次數(shù),提高查效率。
- compress:相比dynamic,除了基本功能和dynamic一樣之外,它是把字段內(nèi)容以壓縮的方式存儲(chǔ)在page頁(yè)中,但是這種壓縮只是在物理存儲(chǔ)上的壓縮。在需要查詢對(duì)應(yīng)的字段內(nèi)容的時(shí)候,需要從物理的page頁(yè)面中,讀取到內(nèi)存中的數(shù)據(jù)需要進(jìn)行相應(yīng)的解壓縮的操作,這樣就需要大量的CPU的支持,降低的數(shù)據(jù)庫(kù)的TPS,影響數(shù)據(jù)庫(kù)的響應(yīng)時(shí)間,這是一種以時(shí)間來(lái)?yè)Q取空間的思想。而在當(dāng)前磁盤(pán)存儲(chǔ)空間不是瓶頸的前提下,這種方式一般不被大家所認(rèn)可了。因?yàn)榇疟P(pán)價(jià)格也不貴,花費(fèi)時(shí)間在CPU解壓數(shù)據(jù)上而換取節(jié)省磁盤(pán)空間的成本。這是一種得不償失的做法。
注意:在Barracuda文件存儲(chǔ)格式下,也是支持compact和redundant這兩種行存儲(chǔ)格式的,這個(gè)是為了將文件存儲(chǔ)格式從Antelope向Barracuda慢慢過(guò)度才支持的。
查看MySQL數(shù)據(jù)庫(kù)innodb存儲(chǔ)引擎使用的文件格式和行存儲(chǔ)格式的命令如下:
mysql> show variables like 'innodb_file%';
+--------------------------+-----------+
| Variable_name | Value |
+--------------------------+-----------+
| innodb_file_format | Barracuda |
| innodb_file_format_check | ON |
| innodb_file_format_max | Barracuda |
| innodb_file_per_table | ON |
+--------------------------+-----------+
4 rows in set (0.01 sec)
mysql> show variables like 'innodb_default_row_format';
+---------------------------+---------+
| Variable_name | Value |
+---------------------------+---------+
| innodb_default_row_format | dynamic |
+---------------------------+---------+
1 row in set (0.01 sec)






