Documentation Home
MySQL 8.4 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 39.8Mb
PDF (A4) - 39.9Mb
Man Pages (TGZ) - 257.9Kb
Man Pages (Zip) - 364.9Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 8.4 Reference Manual  /  ...  /  InnoDB INFORMATION_SCHEMA Schema Object Tables

17.15.3 InnoDB INFORMATION_SCHEMA 对象表

您可以使用InnoDB INFORMATION_ SCHEMA 表来提取关于由InnoDB管理的架构对象的元数据。这类信息来自数据字典。传统上,您将使用第17.17节,“InnoDB 监控”中的技术,设置InnoDB监控,并解析SHOW ENGINE INNODB STATUS语句的输出。InnoDB INFORMATION_ SCHEMA 表接口允许您使用 SQL 查询这些数据。

InnoDB INFORMATION_ SCHEMA 架构对象表包括以下表格:

  • INNODB_ DATAFILES

  • INNODB_ TABLESTATS

  • INNODB_ FOREIGN

  • INNODB_ COLUMNS

  • INNODB_ INDEXES

  • INNODB_ FIELDS

  • INNODB_ TABLESPACES

  • INNODB_ TABLESPACES_ BRIEF

  • INNODB_ FOREIGN_ COLS

  • INNODB_ TABLES

表名表明了提供的数据类型:

InnoDB INFORMATION_SCHEMA schema 对象表可以通过字段如 TABLE_IDINDEX_IDSPACE 进行连接,从而允许您轻松地检索要研究或监控的对象所有可用数据。

请参阅 InnoDB INFORMATION_SCHEMA 文档,以获取每个表的列信息。

示例 17.2 InnoDB INFORMATION_ SCHEMA Schema 对象表

这个示例使用了一个简单的表(t1),带有一个单独的索引(i1),来演示InnoDB INFORMATION_SCHEMA schema 对象表中的元数据类型。

  1. 创建一个测试数据库和表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);
  2. 在创建表t1后,查询INNODB_TABLES以定位test/t1的元数据:

    mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_TABLES WHERE NAME='test/t1' \G
    *************************** 1. row ***************************
         TABLE_ID: 71
             NAME: test/t1
             FLAG: 1
           N_COLS: 6
            SPACE: 57
       ROW_FORMAT: Compact
    ZIP_PAGE_SIZE: 0
     INSTANT_COLS: 0

    t1具有一个TABLE_ ID为71。FLAG字段提供了关于表格式和存储特征的位级信息。有六个列,其中三个是由InnoDB创建的隐藏列(DB_ROW_IDDB_TRX_IDDB_ROLL_PTR)。表的SPACE ID为57(一个值为0将表示该表位于系统表空间)。ROW_FORMAT是紧凑格式。ZIP_PAGE_SIZE仅适用于具有压缩行格式的表。INSTANT_COLS显示了在使用ALTER TABLE ... ADD COLUMN语句添加第一个瞬时列时表中的列数,该语句中使用了ALGORITHM=INSTANT

  3. 使用INNODB_TABLES中的TABLE_ID信息,查询INNODB_COLUMNS表以获取关于表的列信息。

    mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_COLUMNS where TABLE_ID = 71\G
    *************************** 1. row ***************************
         TABLE_ID: 71
             NAME: col1
              POS: 0
            MTYPE: 6
           PRTYPE: 1027
              LEN: 4
      HAS_DEFAULT: 0
    DEFAULT_VALUE: NULL
    *************************** 2. row ***************************
         TABLE_ID: 71
             NAME: col2
              POS: 1
            MTYPE: 2
           PRTYPE: 524542
              LEN: 10
      HAS_DEFAULT: 0
    DEFAULT_VALUE: NULL
    *************************** 3. row ***************************
         TABLE_ID: 71
             NAME: col3
              POS: 2
            MTYPE: 1
           PRTYPE: 524303
              LEN: 10
      HAS_DEFAULT: 0
    DEFAULT_VALUE: NULL

    除了TABLE_ID和列NAMEINNODB_COLUMNS还提供每列的顺序位置(从0开始,顺序递增),列MTYPE或“主类型”(6=INT,2=CHAR,1=VARCHAR),列PRTYPE或“精确类型”(一个二进制值,其中包含MySQL数据类型、字符集代码和可空性),和列长度LEN。只有使用ALTER TABLE ... ADD COLUMN语句添加的列,才会应用于HAS_DEFAULTDEFAULT_VALUE列。

  4. 使用INNODB_TABLES中的TABLE_ ID信息再次查询INNODB_INDEXES,获取与表t1相关的索引信息。

    mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_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
    MERGE_THRESHOLD: 50
    *************************** 2. row ***************************
           INDEX_ID: 112
               NAME: i1
           TABLE_ID: 71
               TYPE: 0
           N_FIELDS: 1
            PAGE_NO: 4
              SPACE: 57
    MERGE_THRESHOLD: 50

    INNODB_INDEXES返回两个索引的数据。第一个索引是GEN_ CLUST_INDEX,这是InnoDB在表中没有用户定义的聚簇索引时创建的聚簇索引。第二个索引(i1)是用户定义的次要索引。

    索引标识符INDEX_ID在实例中唯一,表明该索引所属的表。索引类型TYPE值表示索引类型(1 = Clustered Index,0 = Secondary index)。N_FILEDS值是索引中的字段数量。PAGE_NO是索引B-树的根页号,SPACE是索引所在表空间的ID。非零值表示索引不在系统表空间中。MERGE_THRESHOLD定义了索引页面中的数据量百分比阈值。如果索引页面中的数据量低于该值(默认为50%)当删除或更新操作缩短行时,InnoDB将尝试合并索引页面与邻近索引页面。

  5. 使用INNODB_INDEXES中的INDEX_ID信息,查询INNODB_FIELDS以获取索引1的字段信息。

    mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_FIELDS where INDEX_ID = 112 \G
    *************************** 1. row ***************************
    INDEX_ID: 112
        NAME: col1
         POS: 0

    INNODB_FIELDS 提供了索引字段的NAME和在索引中 ordinal 位置。如果该索引(i1)已定义为多个字段,INNODB_FIELDS将为每个索引字段提供元数据。

  6. 使用INNODB_TABLES中的SPACE信息,查询INNODB_TABLESPACES表以获取关于表的表空间信息。

    mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_TABLESPACES WHERE SPACE = 57 \G
    *************************** 1. row ***************************
              SPACE: 57
              NAME: test/t1
              FLAG: 16417
        ROW_FORMAT: Dynamic
         PAGE_SIZE: 16384
     ZIP_PAGE_SIZE: 0
        SPACE_TYPE: Single
     FS_BLOCK_SIZE: 4096
         FILE_SIZE: 114688
    ALLOCATED_SIZE: 98304
    AUTOEXTEND_SIZE: 0
    SERVER_VERSION: 8.4.0
     SPACE_VERSION: 1
        ENCRYPTION: N
             STATE: normal

    除了表空间的SPACEID和关联表的NAMEINNODB_TABLESPACES还提供了表空间的FLAG数据,这些数据是关于表空间格式和存储特征的位级信息。另外,还提供了表空间的ROW_FORMATPAGE_SIZE和其他多个表空间元数据项。

  7. 使用INNODB_TABLES中的SPACE信息再次查询INNODB_DATAFILES以获取表空间数据文件的位置。

    mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_DATAFILES WHERE SPACE = 57 \G
    *************************** 1. row ***************************
    SPACE: 57
     PATH: ./test/t1.ibd

    数据文件位于MySQL的data目录下的test子目录。如果使用file-per-table表空间在 MySQL 数据目录外创建了一个文件夹,使用CREATE TABLE语句的DATA DIRECTORY子句,那么表空间的PATH将是一个完全合格的目录路径。

  8. 最后一步是向表t1TABLE_ID = 71)中插入一行数据,然后查看INNODB_TABLESTATS表中的数据。该表中的数据由 MySQL 优化器用于计算查询 InnoDB 表时使用哪个索引。这项信息来自内存数据结构。

    mysql> INSERT INTO t1 VALUES(5, 'abc', 'def');
    Query OK, 1 row affected (0.06 sec)
    
    mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_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_SIZEOTHER_INDEX__SIZE字段报告存储该表聚簇索引和次要索引的磁盘页面数量,分别。MODIFIED_COUNTER值显示由DML操作和外键级联操作修改的行数。AUTOINC值是下一个用于自增操作的数字。在表t1中没有定义自增列,所以该值为0。REF_ COUNT值是一个计数器。当计数器达到0时,表示表元数据可以从表缓存中删除。


示例17.3 外键INFORMATION_SCHEMA对象表

INNODB_FOREIGNINNODB_FOREIGN_COLS提供关于外键关系的数据。该示例使用父表和子表之间的外键关系来演示INNODB_FOREIGNINNODB_FOREIGN_COLS表中的数据。

  1. 创建测试数据库,包括父表和子表:

    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;
  2. 在创建父表和子表后,查询INNODB_FOREIGN,找到test/childtest/parent外键关系的外键数据:

    mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_FOREIGN \G
    *************************** 1. row ***************************
          ID: test/fk1
    FOR_NAME: test/child
    REF_NAME: test/parent
      N_COLS: 1
        TYPE: 1

    元数据包括外键IDfk1),该名称来自于子表上定义的约束。FOR_NAME是子表名称,其中定义了外键。REF_NAME是父表名称(被引用表)。N_COLS是外键索引中的列数。TYPE是一个数字值,表示位标志,提供关于外键列的额外信息。在这个例子中,TYPE值为1,表示指定了外键的“ON DELETE CASCADE”选项。请查看INNODB_FOREIGN表定义,以获取更多关于TYPE值的信息。

  3. 使用外键ID,查询INNODB_FOREIGN_COLS以查看外键列的数据。

    mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_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 值是键字段在外键索引中的顺序,从零开始。


示例17.4 InnoDB INFORMATION_SCHEMA Schema Object Tables Joining

这个示例演示了将三个InnoDB INFORMATION_SCHEMA schema object tables (INNODB_TABLESPACES, INNODB_TABLESTATS)连接起来,以获取employees示例数据库中的表的文件格式、行格式、页面大小和索引大小信息。

以下是用于简化查询字符串的表别名:

使用IF()控制流函数来处理压缩表。如果一个表是压缩的,索引大小将使用ZIP_PAGE_SIZE而不是PAGE_SIZE进行计算。CLUST_INDEX_SIZEOTHER_INDEX_SIZE,以字节为单位报告的值,将被除以1024*1024以提供索引大小(MB)。MB值使用ROUND()函数进行四舍五入到小数点后零位。

mysql> SELECT a.NAME, 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_TABLES a
       INNER JOIN INFORMATION_SCHEMA.INNODB_TABLESPACES b on a.NAME = b.NAME
       INNER JOIN INFORMATION_SCHEMA.INNODB_TABLESTATS c on b.NAME = c.NAME
       WHERE a.NAME LIKE 'employees/%'
       ORDER BY a.NAME DESC;
+------------------------+------------+-----------+-------+-----------+
| NAME                   | ROW_FORMAT | page_size | pk_mb | secidx_mb |
+------------------------+------------+-----------+-------+-----------+
| employees/titles       | Dynamic    |     16384 |    20 |        11 |
| employees/salaries     | Dynamic    |     16384 |    93 |        34 |
| employees/employees    | Dynamic    |     16384 |    15 |         0 |
| employees/dept_manager | Dynamic    |     16384 |     0 |         0 |
| employees/dept_emp     | Dynamic    |     16384 |    12 |        10 |
| employees/departments  | Dynamic    |     16384 |     0 |         0 |
+------------------------+------------+-----------+-------+-----------+