在使用命令列連線 MySQL 的時候,我們在執行 SHOW DATABASES
命令時,會發現除了自己擁有許可權的資料庫之外,還有另外一個名為 INFORMATION_SCHEMA 的表,這個表示用來做什麼用的呢?
在 MySQL 中, INFORMATION_SCHEMA 是用來訪問資料庫的後設資料(比如資料庫,表的名稱,列的資料型別或者訪問許可權等)的,在每個 MySQL 的例項中,INFORMATION_SCHEMA 儲存了它維護的所有資料庫的資訊,這個庫中包含了很多隻讀的表(它們實際上是一些檢視,因此並沒有與之關聯的檔案,你可以無法為他們建立觸發器),用於滿足對 MySQL 服務本身的不同查詢需求。
你可以通過
USE
語句選擇使用 INFORMATION_SCHEMA 作為預設的資料庫,但是隻能對其執行讀取操作,無法執行INSERT
,UPDATE
和DELETE
操作。
比如,下面的的 SQL 可以查詢出資料庫 wizard 中所有的表以及資料型別,儲存引擎。
mysql> SELECT table_name, table_type, engine
-> FROM information_schema.tables
-> WHERE table_schema = 'wizard'
-> ORDER BY table_name;
+----------------------+------------+---------+
| table_name | table_type | engine |
+----------------------+------------+---------+
| migrations | BASE TABLE | InnoDB |
| notifications | BASE TABLE | InnoDB |
| wz_attachments | BASE TABLE | InnoDB |
| wz_categories | BASE TABLE | InnoDB |
| wz_comments | BASE TABLE | InnoDB |
| wz_groups | BASE TABLE | InnoDB |
| wz_operation_logs | BASE TABLE | ARCHIVE |
| wz_pages | BASE TABLE | InnoDB |
| wz_page_histories | BASE TABLE | InnoDB |
| wz_page_share | BASE TABLE | InnoDB |
| wz_page_tag | BASE TABLE | InnoDB |
| wz_password_resets | BASE TABLE | InnoDB |
| wz_projects | BASE TABLE | InnoDB |
| wz_project_catalogs | BASE TABLE | InnoDB |
| wz_project_group_ref | BASE TABLE | InnoDB |
| wz_project_stars | BASE TABLE | InnoDB |
| wz_tags | BASE TABLE | InnoDB |
| wz_templates | BASE TABLE | InnoDB |
| wz_users | BASE TABLE | InnoDB |
| wz_user_group_ref | BASE TABLE | InnoDB |
+----------------------+------------+---------+
20 rows in set (0.00 sec)
在 MySQL 中,每個使用者都有對 INFORMATION_SCHEMA 的訪問許可權,但是隻能看到表中他們有許可權的物件的資訊,也有點些場景下使用者如果沒有許可權,看到的是 NULL。對於 InnoDB 表來說,必須擁有 PROCESS 許可權才能檢視。
由於使用 INFORMATION_SCHEMA 查詢可能會從多個資料庫檢索資訊,所以查詢可能會比較耗時,對效能產生一定的影響。在執行之前,可以使用 EXPLAIN
命令檢查一下查詢的效率,關於如何優化 INFORMATION_SCHEMA 查詢效率,參考 Optimizing INFORMATION_SCHEMA Queries。
不同表的用途
在不同版本的 MySQL/MariaDB 中, INFORMATION_SCHEMA 中的表並不完全一樣,但是大部分都是一致的,下面是 MariaDB 10.3 中包含的表,我對它們一一做了註釋
表名 | 用途 |
---|---|
ALL_PLUGINS | 伺服器所有外掛的資訊,無論是否已經安裝 |
PLUGINS | 伺服器安裝的外掛資訊 |
APPLICABLE_ROLES | 當前使用者可以使用的角色資訊 |
CHARACTER_SETS | 可用的字符集資訊 |
CHECK_CONSTRAINTS | 表上定義的 CHECK 約束資訊 |
COLLATIONS | 字符集排序規則資訊 |
COLLATION_CHARACTER_SET_APPLICABILITY | 字符集和排序規則的對應關係 |
COLUMNS | 表中的列資訊 |
COLUMN_PRIVILEGES | 列的許可權資訊,資料來源於 mysql.columns_priv 系統表 |
ENABLED_ROLES | 當前會話的角色資訊 |
ENGINES | 儲存引擎的資訊,可以用於檢查引擎是否支援 |
EVENTS | 關於事件管理器的事件資訊 |
FILES | 表空間資料儲存檔案的資訊 |
GLOBAL_STATUS | 所有的狀態變數值,對應命令 SHOW GLOBAL STATUS |
GLOBAL_VARIABLES | 所有的系統變數值,對應命令 SHOW GLOBAL VARIABLES |
SESSION_STATUS | 所有的會話的狀態變數值,對應命令 SHOW SESSION STATUS |
SESSION_VARIABLES | 所有的會話變數,對應命令 SHOW SESSION VARIABLES |
KEY_CACHES | 關於 Segmented Key Cache 的統計資訊 |
KEY_COLUMN_USAGE | 描述了索引列有哪些約束 |
PARAMETERS | 儲存過程引數,返回值資訊 |
PARTITIONS | 表分割槽資訊,沒一行對應了一個獨立的分割槽或者分割槽表的子分割槽 |
PROCESSLIST | 提供了哪些執行緒正在執行的資訊 |
PROFILING | 提供了語句剖析資訊,它的內容對應了 SHOW PROFILE 和 SHOW PROFILES 語句的資訊 |
REFERENTIAL_CONSTRAINTS | 外來鍵資訊 |
ROUTINES | 儲存過程資訊 |
SCHEMATA | 資料庫的資訊 |
SCHEMA_PRIVILEGES | 資料庫許可權資訊,資料來源於 mysql.db 系統表 |
STATISTICS | 表索引資訊 |
SYSTEM_VARIABLES | 所有系統變數當前的值和各種後設資料 |
TABLES | 表的資訊 |
TABLESPACES | MySQL 叢集的表空間資訊 |
TABLE_CONSTRAINTS | 描述了哪個表有約束 |
TABLE_PRIVILEGES | 表許可權資訊,資料來源於 mysql.table_priv 系統表 |
TRIGGERS | 關於觸發器的資訊,必須有表的 TRIGGER 許可權才能檢視 |
USER_PRIVILEGES | 全域性許可權資訊,資料來源於 mysql.user 系統表 |
VIEWS | 資料庫檢視資訊 |
GEOMETRY_COLUMNS | 表中儲存空間資料的列的資訊 |
SPATIAL_REF_SYS | 儲存了資料庫中使用的每個空間參考系統的資訊 |
CLIENT_STATISTICS | 客戶端連線的統計資訊,作為 使用者統計 特性的一部分,預設不開啟 |
USER_STATISTICS | 使用者活動的統計資訊,作為 使用者統計 特性的一部分,預設不開啟 |
INDEX_STATISTICS | 索引使用統計,用於定位未使用的索引以及生成刪除命令,作為 使用者統計 特性的一部分,預設不開啟 |
TABLE_STATISTICS | 表使用的統計資訊,作為 使用者統計 特性的一部分,預設不開啟 |
在所有的儲存引擎中,我們最常用的就是 InnoDB 儲存引擎了,下面是 InnoDB 相關的表
表名 | 用途 |
---|---|
INNODB_SYS_DATAFILES | 資料檔案儲存路徑資訊 |
INNODB_SYS_TABLESTATS | 狀態資訊,可以用於開發效能相關的擴充套件或者高階的效能監控 |
INNODB_SYS_FIELDS | 索引的欄位資訊 |
INNODB_SYS_COLUMNS | 欄位資訊 |
INNODB_SYS_FOREIGN_COLS | 外來鍵列的資訊 |
INNODB_SYS_FOREIGN | 外來鍵資訊 |
INNODB_SYS_TABLES | 表資訊 |
INNODB_SYS_TABLESPACES | 表空間資訊 |
INNODB_SYS_INDEXES | 索引資訊 |
INNODB_SYS_VIRTUAL | 虛擬列的元資訊 |
INNODB_SYS_SEMAPHORE_WAITS | 當前的訊號量等待資訊 |
INNODB_TABLESPACES_SCRUBBING | 關於 資料清理 的資訊 |
INNODB_CMPMEM | 緩衝池中壓縮頁的資訊,可用於度量表壓縮效率 |
INNODB_CMPMEM_RESET | 同 INNODB_CMPEM ,但是每次查詢這個表會清空 RELOCATION_TIME 欄位的值 |
INNODB_CMP_PER_INDEX | 包含了以獨立的索引分組的與壓縮操作相關的狀態資訊 |
INNODB_CMP_PER_INDEX_RESET | 同 INNODB_CMP_PER_INDEX , 但是每次查詢之後都會清空資料 |
INNODB_CMP | 包含了與壓縮操作相關的狀態資訊 |
INNODB_CMP_RESET | 同 INNODB_CMP ,但是每次查詢之後會清空資料 |
INNODB_LOCK_WAITS | 阻塞的事務資訊 |
INNODB_TABLESPACES_ENCRYPTION | 加密的表空間資訊 |
INNODB_BUFFER_PAGE_LRU | 有關緩衝池中頁的資訊,以及出於清除目的如何對頁進行排序 |
INNODB_BUFFER_PAGE | 緩衝池中頁的資訊 |
INNODB_BUFFER_POOL_STATS | 緩衝池中頁的資訊,與 SHOW ENGINE INNODB STATUS 語句返回的內容類似 |
INNODB_FT_INDEX_TABLE | 全文索引資訊 |
INNODB_FT_DELETED | 包含了從全文索引中已經刪除的行,這些資訊用於過濾查詢請求的結果,解決每次刪除一行時昂貴的重新組織索引操作 |
INNODB_FT_INDEX_CACHE | 最近插入到全文索引的行資訊,為了避免每次改變都去重新組織索引,新的變更只在 OPTIMIZE TABLE 命令執行之後才會合併到全文索引 |
INNODB_FT_BEING_DELETED | 當 OPTIMIZE TABLE 正在執行中,此時發生了與 INNODB_FT_DELETED 有關的文件 |
INNODB_FT_DEFAULT_STOPWORD | 包含了用於建立全文索引的停止詞列表 |
INNODB_FT_CONFIG | 全文索引的後設資料 |
INNODB_TRX | 所有當前正在執行的事務的資訊 |
INNODB_LOCKS | 包含了事務請求但是未獲得的鎖或者阻塞其它事務的鎖的資訊 |
INNODB_METRICS | 一些有用的效能指標 |
INNODB_MUTEXES | 監控互斥鎖和讀寫鎖 |
總結
本文只是對 INFORMATION_SCHEMA 資料庫是什麼,都有哪些表以及它們的用途做了個簡要的概述,在瞭解這個資料庫的基礎之後,我們在下篇文章中將會詳細介紹 事務,鎖相關表以及如何排查死鎖問題,敬請關注。
本文將會持續修正和更新,最新內容請參考我的 GITHUB 上的 程式猿成長計劃 專案,歡迎 Star,更多精彩內容請 follow me。