1、簡介
MySQL 8.0 將資料庫元資訊都存放於InnoDB儲存引擎表中,在之前版本的MySQL中,資料字典不僅僅存放於特定的儲存引擎表中,還存放於後設資料檔案、非事務性儲存引擎表中。本文將會介紹MySQL 8.0對資料字典的改進,以及改進帶來的好處、影響以及侷限性。
2、資料字典
2.1、新版本之前的資料字典
資料字典是資料庫重要的組成部分之一,那麼什麼是資料字典?資料字典包含哪些內容呢?資料字典是對資料庫中的資料、庫物件、表物件等的元資訊的集合。在MySQL中,資料字典資訊內容就包括表結構、資料庫名或表名、欄位的資料型別、檢視、索引、表欄位資訊、儲存過程、觸發器等內容。MySQL INFORMATION_SCHEMA庫提供了對資料局後設資料、統計資訊、以及有關MySQL server的訪問資訊(例如:資料庫名或表名,欄位的資料型別和訪問許可權等)。該庫中儲存的資訊也可以稱為MySQL的資料字典。
在MySQL8.0之前,MySQL的資料字典資訊,並沒有全部存放在系統資料庫表中,部分資料庫資料字典資訊存放於檔案中,其餘的資料字典資訊存放於資料字典庫中(INFORMATION_SCHEMA,mysql,sys)。例如表結構資訊存放在.frm
檔案中,資料庫表欄位資訊存放於INFORMATION_SCHEMA下的COLUMNS表中。早期,5.6版本之前,MyISAM是MySQL的預設儲存引擎,而作為MyISAM儲存引擎,它是沒有資料字典的。只有表結構資訊記錄在.frm
檔案中。MySQL5.6版本之後,將InnoDB儲存引擎作為預設的儲存引擎。在InnoDB儲存引擎中,新增了一些資料字典檔案用於存放資料字典元資訊,例如:.opt
檔案,記錄了每個庫的一些基本資訊,包括庫的字符集等資訊,.TRN
,.TRG
檔案用於存放觸發器的資訊內容。
2.2、新版本資料字典的改進
最新的MySQL 8.0 釋出之後,對資料庫資料字典方面做了較大的改進。
- 首先是,將所有原先存放於資料字典檔案中的資訊,全部存放到資料庫系統表中,即將之前版本的
.frm
,.opt
,.par
,.TRN
,.TRG
,.isl
檔案都移除了,不再通過檔案的方式儲存資料字典資訊。 - 其次是對INFORMATION_SCHEM,mysql,sys系統庫中的儲存引擎做了改進,原先使用MyISAM儲存引擎的資料字典表都改為使用InnoDB儲存引擎存放。從不支援事務的MyISAM儲存引擎轉變到支援事務的InnoDB儲存引擎,為原子DDL的實現,提供了可能性。
3、新資料字典帶來的影響
3.1、INFORMATION_SCHEMA效能提升
8.0中對資料字典進行改進之後,很大程度上提高了對INFORMATIONS_SCHEMA的查詢效能,通過可以通過查錶快速的獲得想要查詢的資料,原因是:
- 資料庫在查詢INFORMATION_SCHEMA的表時,不再一定需要建立一張臨時表,可以直接查詢資料字典表。
- 在之前版本中,資料字典資訊不一定是存放於表中,所以在獲取資料字典資訊時候,不僅僅是查表操作。例如讀取資料庫表結構資訊,底層其實是讀取.frm檔案來獲得,是一個檔案開啟讀取的操作。而在新版本中,資料字典資訊都可以通過直接查表的方式獲取,替代那些獲取資訊慢的方式。
- 對儲存引擎的改進之後,在查詢INFORMATIONS_SCHEMA表時,如果表上有索引,優化器會合理的利用索引。
- 對於INFORMATION_SCHEMA下的STATISTICS表和TABLES表中的資訊,8.0中通過快取的方式,以提高查詢的效能。可以通過設定information_schema_stats_expiry引數設定快取資料的過期時間,預設是86400秒。查詢這兩張表的資料的時候,首先是到快取中進行查詢,快取中沒有快取資料,或者快取資料過期了,查詢會從儲存引擎中獲取最新的資料。如果需要獲取最新的資料,可以通過設定information_schema_stats_expiry引數為0或者ANALYZE TABLE操作。
3.2、原子DDL
MySQL8.0開始支援原子DDL操作,一個原子DDL操作,具體的操作內容包括:資料字典更新,儲存引擎層的操作,在binlog中記錄DDL操作。並且這些操作都是原子性的,表示中間過程出現錯誤的時候,是可以完整回退的。這在之前版本的DDL操作中是不支援的。之前資料庫版本中一直沒有支援原子DDL的特性,是有原因的,因為在早期的資料庫版本中,資料庫元資訊存放於元資訊檔案中、非事務性表中以及特定儲存引擎的資料字典中。這些都無法保證DDL操作內容在一個事務當中,無法保證原子性。 具體的原子DDL,後續會有專門的文章。
3.3、innodb_read_only對所有儲存引擎生效
在8.0之前版本中,innodb_read_only引數可以阻止對InnoDB儲存引擎表的create和drop等更新操作。但是在MySQL8.0中,開啟innodb_read_only引數阻止了所有儲存引擎的這些操作。create或者drop表的操作都需要更新資料字典表,8.0中這個資料字典表都改為了InnoDB儲存引擎,所以對於資料字典表的更新會失敗,從而導致各儲存引擎create和drop表失敗。同樣的像ANALYZE TABLE
和ALTER TABLE tbl_name ENGINE=engine_name
這種操作也會失敗,因為這些操作都要去更新資料字典表。
3.4、mysqldump mysqlpump匯出的內容影響
MySQL8.0之後,在使用mysqldump和mysqlpump匯出資料時候,與之前有了一些不同,主要是以下幾點:
- 之前版本的mysqldump和mysqlpump可以匯出mysql系統庫中的所有表的內容,8.0之後,只能匯出mysql系統庫中的非data dictionary table。(data dictionary table內容可以參照:dev.mysql.com/doc/refman/…
- 之前版本當使用--all-databases引數匯出資料的時候,不加--routines和--events選項也可以匯出觸發器、儲存過程等資訊,因為這些資訊都存放於proc和event表中,匯出所有表即可匯出這些資訊。但是在8.0中,proc表和event表都不再使用,並且定義觸發器、儲存過程的資料字典表不會被匯出,所以在8.0中使用mysqldump、mysqlpump匯出資料的時候,如果需要匯出觸發器、儲存過程等內容,一定需要加上--routines和--events選項。
- 之前版本中--routines選項匯出的時候,備份賬戶需要有proc表的SELECT許可權,在8.0中需要對所有表的SELECT許可權
- 之前版本中,匯出觸發器、儲存過程可以同時匯出觸發器、儲存過程的建立和修改的時間戳,8.0中不再支援。
3.5、新資料字典的侷限性
MySQL8.0資料字典的改進有很多方便的特性,例如帶來了原子DDL,提升了INFORMATION_SCHEMA的查詢效能等,但是它並不是完美的,新版資料字典還是存在一些侷限性:
- 通過手動mkdir的方式在資料目錄下建立庫目錄,這種方式是不會被資料庫所識別到。
- DDL操作會花費更長的時間,因為之前的DDL操作是直接對.frm檔案進行更改操作,只要寫一個檔案,現在是需要更新資料字典表,代表著需要將資料寫到儲存引擎、read log、undo log中。
4、總結
目前已經正式GA的MySQL 8.0是令人很期待的一個版本,從資料字典方面的改進,到原子DDL,到資料庫self tuning等等新特性,都讓人為8.0感到激動。8.0中有許多新特性等待去嘗試,去發現。
部落格地址:win-man.github.io/
公眾號:歡迎關注