从 MySQL 5.6 开始,您可以提取有关InnoDB
使用
InnoDB
INFORMATION_SCHEMA
系统表管理的模式对象的元数据。这些信息来自
InnoDB
内部系统表(也称为InnoDB
数据字典),不能像普通InnoDB
表那样直接查询。传统上,您将使用第 14.17 节“InnoDB 监视器”中的技术获得此类信息,设置
InnoDB
监视器并解析
SHOW ENGINE INNODB
STATUS
语句的输出。表InnoDB
INFORMATION_SCHEMA
界面允许您使用 SQL 查询此数据。
除了
INNODB_SYS_TABLESTATS
没有对应的内部系统表的 之外,
InnoDB
INFORMATION_SCHEMA
系统表填充了直接从内部
InnoDB
系统表读取的数据,而不是从缓存在内存中的元数据中读取的数据。
InnoDB
INFORMATION_SCHEMA
系统表包括下面列出的表。
INNODB_SYS_DATAFILES
并
INNODB_SYS_TABLESPACES
在 MySQL 5.6.6 中添加,引入了对语句子句的支持,它允许在 MySQL 数据目录之外的位置创建
file-per-table 表
空间(文件)。DATA
DIRECTORY='
directory
'CREATE TABLE
InnoDB
.ibd
mysql> SHOW TABLES FROM INFORMATION_SCHEMA LIKE 'INNODB_SYS%';
+--------------------------------------------+
| Tables_in_information_schema (INNODB_SYS%) |
+--------------------------------------------+
| INNODB_SYS_DATAFILES |
| INNODB_SYS_TABLESTATS |
| INNODB_SYS_FOREIGN |
| INNODB_SYS_COLUMNS |
| INNODB_SYS_INDEXES |
| INNODB_SYS_FIELDS |
| INNODB_SYS_TABLESPACES |
| INNODB_SYS_FOREIGN_COLS |
| INNODB_SYS_TABLES |
+--------------------------------------------+
表名指示所提供数据的类型:
INNODB_SYS_TABLES
提供表的元数据InnoDB
,相当于数据字典SYS_TABLES
中表中的信息。InnoDB
INNODB_SYS_COLUMNS
提供InnoDB
表列的元数据,相当于 数据字典SYS_COLUMNS
中表中的 信息。InnoDB
INNODB_SYS_INDEXES
提供关于InnoDB
索引的元数据,相当于数据字典SYS_INDEXES
中表中的信息。InnoDB
INNODB_SYS_FIELDS
提供InnoDB
索引的关键列(字段)的元数据,相当于数据字典SYS_FIELDS
中表的 信息。InnoDB
INNODB_SYS_TABLESTATS
InnoDB
提供有关从内存数据结构派生的表的低级状态信息的视图 。没有对应的内部InnoDB
系统表。INNODB_SYS_DATAFILES
为file-per-table表空间提供数据文件路径信息InnoDB
,相当于 数据字典SYS_DATAFILES
中表中的 信息。InnoDB
INNODB_SYS_TABLESPACES
提供关于InnoDB
file-per-table 表空间的元数据,相当于 数据字典SYS_TABLESPACES
中表中的 信息。InnoDB
INNODB_SYS_FOREIGN
提供InnoDB
表上定义的外键的元数据,相当于数据字典SYS_FOREIGN
中表中的 信息。InnoDB
INNODB_SYS_FOREIGN_COLS
提供有关表上定义的外键列的元数据InnoDB
,相当于数据字典SYS_FOREIGN_COLS
中表中的信息。InnoDB
InnoDB
INFORMATION_SCHEMA
系统表可以通过 、 和 等字段连接在一起
TABLE_ID
,INDEX_ID
使
SPACE
您可以轻松检索要研究或监控的对象的所有可用数据。
有关每个表的列的信息,请参阅InnoDB
INFORMATION_SCHEMA
文档。
示例 14.2 InnoDB INFORMATION_SCHEMA 系统表
t1
此示例使用带有单个索引 ( )
的简单表 ( i1
) 来演示在InnoDB
INFORMATION_SCHEMA
系统表中找到的元数据类型。
创建一个测试数据库和表
t1
:mysql> CREATE DATABASE test; mysql> USE test; mysql> CREATE TABLE t1 ( col1 INT, col2 CHAR(10), col3 VARCHAR(10)) ENGINE = InnoDB; mysql> CREATE INDEX i1 ON t1(col1);
创建表后
t1
,查询INNODB_SYS_TABLES
以查找元数据test/t1
:mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME='test/t1' \G *************************** 1. row *************************** TABLE_ID: 71 NAME: test/t1 FLAG: 1 N_COLS: 6 SPACE: 57 FILE_FORMAT: Antelope ROW_FORMAT: Compact ZIP_PAGE_SIZE: 0 ...
表
t1
的 aTABLE_ID
为 71。该FLAG
字段提供有关表格式和存储特性的位级信息。有六列,其中三列是由InnoDB
(DB_ROW_ID
、DB_TRX_ID
和DB_ROLL_PTR
) 创建的隐藏列。表的 IDSPACE
为 57(值为 0 表示该表驻留在系统表空间中)。FILE_FORMAT
是 Antelope,而 是ROW_FORMAT
Compact。ZIP_PAGE_SIZE
仅适用于具有Compressed
行格式的表。使用
TABLE_ID
来自 的信息INNODB_SYS_TABLES
查询INNODB_SYS_COLUMNS
表以获取有关表列的信息。mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS where TABLE_ID = 71 \G *************************** 1. row *************************** TABLE_ID: 71 NAME: col1 POS: 0 MTYPE: 6 PRTYPE: 1027 LEN: 4 *************************** 2. row *************************** TABLE_ID: 71 NAME: col2 POS: 1 MTYPE: 2 PRTYPE: 524542 LEN: 10 *************************** 3. row *************************** TABLE_ID: 71 NAME: col3 POS: 2 MTYPE: 1 PRTYPE: 524303 LEN: 10
除了
TABLE_ID
和列 之外NAME
,INNODB_SYS_COLUMNS
还提供了每一列的序号位置(POS
从0开始依次递增),列MTYPE
或者“主要类型”(6=INT,2=CHAR,1=VARCHAR),PRTYPE
或者“精确type ”(一个二进制值,带有表示 MySQL 数据类型、字符集代码和可空性的位)和列长度 (LEN
)。再次 使用
TABLE_ID
来自的信息 ,查询与表关联的索引的信息 。INNODB_SYS_TABLES
INNODB_SYS_INDEXES
t1
mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_INDEXES WHERE TABLE_ID = 71 \G *************************** 1. row *************************** INDEX_ID: 111 NAME: GEN_CLUST_INDEX TABLE_ID: 71 TYPE: 1 N_FIELDS: 0 PAGE_NO: 3 SPACE: 57 *************************** 2. row *************************** INDEX_ID: 112 NAME: i1 TABLE_ID: 71 TYPE: 0 N_FIELDS: 1 PAGE_NO: 4 SPACE: 57
INNODB_SYS_INDEXES
返回两个索引的数据。第一个索引是 ,如果表没有用户定义的聚集索引GEN_CLUST_INDEX
,它是创建的聚集索引。InnoDB
第二个索引 (i1
) 是用户定义的二级索引。是索引的
INDEX_ID
标识符,在一个实例中的所有数据库中是唯一的。TABLE_ID
标识与索引关联的表。索引TYPE
值指示索引的类型(1 = 聚集索引,0 = 二级索引)。该N_FILEDS
值是组成索引的字段数。PAGE_NO
是索引B树的根页码,SPACE
是索引所在表空间的ID。非零值表示索引不驻留在系统表空间中。使用
INDEX_ID
来自的信息INNODB_SYS_INDEXES
,查询INNODB_SYS_FIELDS
有关索引字段的信息i1
。mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FIELDS where INDEX_ID = 112 \G *************************** 1. row *************************** INDEX_ID: 112 NAME: col1 POS: 0
INNODB_SYS_FIELDS
提供NAME
索引字段及其在索引中的序号位置。如果索引 (i1) 已在多个字段上定义,INNODB_SYS_FIELDS
将为每个索引字段提供元数据。使用
SPACE
来自 的信息INNODB_SYS_TABLES
,查询INNODB_SYS_TABLESPACES
表以获取有关表的表空间的信息。mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESPACES WHERE SPACE = 57 \G *************************** 1. row *************************** SPACE: 57 NAME: test/t1 FLAG: 0 FILE_FORMAT: Antelope ROW_FORMAT: Compact or Redundant PAGE_SIZE: 16384 ZIP_PAGE_SIZE: 0
除了表空间的
SPACE
ID 和NAME
关联表的 ID 外,INNODB_SYS_TABLESPACES
还提供表空间FLAG
数据,即有关表空间格式和存储特性的位级信息。还提供了 tablespaceFILE_FORMAT
、ROW_FORMAT
、PAGE_SIZE
和其他几个表空间元数据项。再次 使用
SPACE
来自的信息 ,查询表空间数据文件的位置。INNODB_SYS_TABLES
INNODB_SYS_DATAFILES
mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_DATAFILES WHERE SPACE = 57 \G *************************** 1. row *************************** SPACE: 57 PATH: ./test/t1.ibd
数据文件位于
test
MySQL 目录下的data
目录中。如果 使用该语句的子句 在 MySQL 数据目录之外的位置创建了file-per-table 表空间 ,则该表空间将是完全限定的目录路径。DATA DIRECTORY
CREATE TABLE
PATH
t1
最后一步,向表( ) 中插入一行TABLE_ID = 71
并查看INNODB_SYS_TABLESTATS
表中的数据。MySQL 优化器使用此表中的数据来计算查询InnoDB
表时使用哪个索引。此信息源自内存中的数据结构。没有对应的内部InnoDB
系统表。mysql> INSERT INTO t1 VALUES(5, 'abc', 'def'); Query OK, 1 row affected (0.06 sec) mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS where TABLE_ID = 71 \G *************************** 1. row *************************** TABLE_ID: 71 NAME: test/t1 STATS_INITIALIZED: Initialized NUM_ROWS: 1 CLUST_INDEX_SIZE: 1 OTHER_INDEX_SIZE: 0 MODIFIED_COUNTER: 1 AUTOINC: 0 REF_COUNT: 1
该
STATS_INITIALIZED
字段指示是否已为表收集统计信息。NUM_ROWS
是表中当前估计的行数。CLUST_INDEX_SIZE
和 字段分别报告磁盘上存储表的聚簇索引和二级索引的OTHER_INDEX_SIZE
页数。该MODIFIED_COUNTER
值显示由外键的 DML 操作和级联操作修改的行数。该AUTOINC
值是为任何基于自动增量的操作发出的下一个数字。table 上没有定义自动增量列t1
,因此值为 0。REF_COUNT
值是一个计数器。当计数器达到 0 时,表示表元数据可以从表缓存中逐出。
示例 14.3 外键 INFORMATION_SCHEMA 系统表
INNODB_SYS_FOREIGN
和
INNODB_SYS_FOREIGN_COLS
表提供有关外键关系的数据
。本示例使用具有外键关系的父表和子表来演示在
INNODB_SYS_FOREIGN
和
INNODB_SYS_FOREIGN_COLS
表中找到的数据。
使用父表和子表创建测试数据库:
mysql> CREATE DATABASE test; mysql> USE test; mysql> CREATE TABLE parent (id INT NOT NULL, PRIMARY KEY (id)) ENGINE=INNODB; mysql> CREATE TABLE child (id INT, parent_id INT, INDEX par_ind (parent_id), CONSTRAINT fk1 FOREIGN KEY (parent_id) REFERENCES parent(id) ON DELETE CASCADE) ENGINE=INNODB;
父子表创建完成后,查询
INNODB_SYS_FOREIGN
定位test/child
andtest/parent
外键关系的外键数据:mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN \G *************************** 1. row *************************** ID: test/fk1 FOR_NAME: test/child REF_NAME: test/parent N_COLS: 1 TYPE: 1
元数据包括外键
ID
(fk1
),它以CONSTRAINT
在子表上定义的 命名。FOR_NAME
是定义外键的子表的名称 。REF_NAME
是父表(“引用”表)的名称。N_COLS
是外键索引中的列数。TYPE
是一个数值,表示提供有关外键列的附加信息的位标志。在本例中,TYPE
值为 1,表示ON DELETE CASCADE
为外键指定了选项。有关值的更多信息,请参阅INNODB_SYS_FOREIGN
表定义TYPE
。使用外键
ID
查询INNODB_SYS_FOREIGN_COLS
查看外键列的数据。mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS WHERE ID = 'test/fk1' \G *************************** 1. row *************************** ID: test/fk1 FOR_COL_NAME: parent_id REF_COL_NAME: id POS: 0
FOR_COL_NAME
是子表中外键列REF_COL_NAME
的名称,是父表中引用列的名称。该POS
值是外键索引中键字段的序号位置,从零开始。
示例 14.4 加入 InnoDB INFORMATION_SCHEMA 系统表
此示例演示连接三个
InnoDB
INFORMATION_SCHEMA
系统表(INNODB_SYS_TABLES
、
INNODB_SYS_TABLESPACES
和
INNODB_SYS_TABLESTATS
)以收集有关员工示例数据库中的表的文件格式、行格式、页面大小和索引大小信息。
以下表名别名用于缩短查询字符串:
IF()
控制流函数用于解释压缩表
。如果表被压缩,索引大小是使用
ZIP_PAGE_SIZE
而不是
计算的PAGE_SIZE
。
CLUST_INDEX_SIZE
和
OTHER_INDEX_SIZE
以字节为单位报告,除以1024*1024
以提供以兆字节 (MB) 为单位的索引大小。ROUND()
使用该函数
将 MB 值四舍五入为零小数位。
mysql> SELECT a.NAME, a.FILE_FORMAT, a.ROW_FORMAT,
@page_size :=
IF(a.ROW_FORMAT='Compressed',
b.ZIP_PAGE_SIZE, b.PAGE_SIZE)
AS page_size,
ROUND((@page_size * c.CLUST_INDEX_SIZE)
/(1024*1024)) AS pk_mb,
ROUND((@page_size * c.OTHER_INDEX_SIZE)
/(1024*1024)) AS secidx_mb
FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES a
INNER JOIN INFORMATION_SCHEMA.INNODB_SYS_TABLESPACES b on a.NAME = b.NAME
INNER JOIN INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS c on b.NAME = c.NAME
WHERE a.NAME LIKE 'employees/%'
ORDER BY a.NAME DESC;
+------------------------+-------------+------------+-----------+-------+-----------+
| NAME | FILE_FORMAT | ROW_FORMAT | page_size | pk_mb | secidx_mb |
+------------------------+-------------+------------+-----------+-------+-----------+
| employees/titles | Antelope | Compact | 16384 | 20 | 11 |
| employees/salaries | Antelope | Compact | 16384 | 91 | 33 |
| employees/employees | Antelope | Compact | 16384 | 15 | 0 |
| employees/dept_manager | Antelope | Compact | 16384 | 0 | 0 |
| employees/dept_emp | Antelope | Compact | 16384 | 12 | 10 |
| employees/departments | Antelope | Compact | 16384 | 0 | 0 |
+------------------------+-------------+------------+-----------+-------+-----------+