IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    MySQL 8 新特性体验之InnoDB数据字典

    朝阳发表于 2016-09-10 10:27:07
    love 0

    MySQL 8作为目前正在开发的最新版本,目前已经发布了DMR版本,这篇文章主要介绍 MySQL 8 的新特性之一:InnoDB数据字典。 MySQL的核心架构采用统一Server层+不同的底层引擎插件的架构模式,在Server层为每个表创建了frm文件,以保存与表定义相关的元数据信息。但有些引擎(例如InnoDB)本身也会存储元数据,这样不仅产生了元数据冗余,并且Server层和引擎层分别各自管理,在DDL之类的操作时,无法做到crash-safe,更别说让DDL具备事务性了。 MySQL 8 为了解决这些问题(尤其是DDL无法做到atomic),尝试取消了FRM文件及其他server层的元数据文件(frm, par, trn, trg, isl,db.opt),所有的元数据都用InnoDB引擎进行存储, 另外一些诸如权限表之类的系统表也改用InnoDB引擎。 下面就针对MySQL 8 的这个特性做一些基本的测试,一探究竟。 先创建个新库,并在库下创建两个表来开启我们的测试

    mysql> CREATE DATABASE mysql8test;
    Query OK, 1 row affected (0.00 sec)
    
    mysql> USE mysql8test
    Database changed
    mysql> CREATE TABLE t1 (a int primary key);
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> CREATE TABLE t2 (a int primary key, b int);
    Query OK, 0 rows affected (0.00 sec)
    
    $ls -lh /data/mysqldata/mydata/mysql8test/
    total 256K
    -rw-r----- 1 Sky users 128K Oct  5 19:44 t1.ibd
    -rw-r----- 1 Sky users 128K Oct  5 19:44 t2.ibd
    
    $cat /data/mysqldata/mydata/mysql8test_9.SDI
    {
        "sdi_version": 1,
        "dd_version": 1,
        "dd_object_type": "Schema",
        "dd_object": {
            "name": "mysqltest",
            "default_collation_id": 33,
            "created": 0,
            "last_altered": 0
        }
    }
    
    现在库目录下只有ibd文件,并没有frm文件,而在数据目录下,相应的生成了一个SDI文件,来描述这个sbtest库的信息。

    我们再来看看创建一个MYISAM引擎的表:

    mysql> create database mysql8myisam;
    Query OK, 1 row affected (0.00 sec)
    
    mysql> use mysql8myisam
    Database changed
    mysql> create table t1 (a int, b varchar(320)) engine=myisam;
    Query OK, 0 rows affected (0.00 sec)
    
    $ls /data/mysqldata/mydata/mysql8myisam/
    t1_435.SDI  t1.MYD  t1.MYI
    
    
    $cat /data/mysqldata/mydata/mysql8myisam/t1_435.SDI
    {
        "sdi_version": 1,
        "dd_version": 1,
        "dd_object_type": "Table",
        "dd_object": {
            "name": "t1",
            "mysql_version_id": 80000,
            "created": 20161005201935,
            "last_altered": 20161005201935,
            "options": "avg_row_length=0;key_block_size=0;keys_disabled=0;pack_record=1;stats_auto_recalc=0;stats_sample_pages=0;",
            "columns": [
                {
                    "name": "a",
                    "type": 4,
                    "is_nullable": true,
                    "is_zerofill": false,
                    "is_unsigned": false,
                    "is_auto_increment": false,
                    "is_virtual": false,
                    "hidden": false,
                    "ordinal_position": 1,
                    "char_length": 11,
                    "numeric_precision": 10,
                    "numeric_scale": 0,
                    "datetime_precision": 0,
                    "has_no_default": false,
                    "default_value_null": true,
                    "default_value": "",
                    "default_option": "",
                    "update_option": "",
                    "comment": "",
                    "generation_expression": "",
                    "generation_expression_utf8": "",
                    "options": "interval_count=0;",
                    "se_private_data": "",
                    "column_key": 1,
                    "column_type_utf8": "int(11)",
                    "elements": [],
                    "collation_id": 33
                },
                {
                    "name": "b",
                    "type": 16,
                    "is_nullable": true,
                    "is_zerofill": false,
                    "is_unsigned": false,
                    "is_auto_increment": false,
                    "is_virtual": false,
                    "hidden": false,
                    "ordinal_position": 2,
                    "char_length": 960,
                    "numeric_precision": 0,
                    "numeric_scale": 0,
                    "datetime_precision": 0,
                    "has_no_default": false,
                    "default_value_null": true,
                    "default_value": "",
                    "default_option": "",
                    "update_option": "",
                    "comment": "",
                    "generation_expression": "",
                    "generation_expression_utf8": "",
                    "options": "interval_count=0;",
                    "se_private_data": "",
                    "column_key": 1,
                    "column_type_utf8": "varchar(320)",
                    "elements": [],
                    "collation_id": 33
                }
            ],
            "schema_ref": "mysql8myisam",
            "hidden": false,
            "se_private_id": 18446744073709551615,
            "engine": "MyISAM",
            "comment": "",
            "se_private_data": "",
            "row_format": 2,
            "partition_type": 0,
            "partition_expression": "",
            "default_partitioning": 0,
            "subpartition_type": 0,
            "subpartition_expression": "",
            "default_subpartitioning": 0,
            "indexes": [],
            "foreign_keys": [],
            "partitions": [],
            "collation_id": 33
        }
    }
    
    

     

    新的Information Schema定义

    一些新IS表使用View进行了重新设计,主要包括这些表:

    CHARACTER_SETS
    COLLATIONS
    COLLATION_CHARACTER_SET_APPLICABILITY
    COLUMNS
    KEY_COLUMN_USAGE
    SCHEMATA
    STATISTICS
    TABLES
    TABLE_CONSTRAINTS
    VIEWS
    
    #例如SCHEMATA
    
    mysql> show create table information_schema.schemata\G
    *************************** 1. row ***************************
                    View: SCHEMATA
             Create View: CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `information_schema`.`SCHEMATA` AS select `cat`.`name` AS `CATALOG_NAME`,`sch`.`name` AS `SCHEMA_NAME`,`cs`.`name` AS `DEFAULT_CHARACTER_SET_NAME`,`col`.`name` AS `DEFAULT_COLLATION_NAME`,NULL AS `SQL_PATH` from (((`mysql`.`schemata` `sch` join `mysql`.`catalogs` `cat` on((`cat`.`id` = `sch`.`catalog_id`))) join `mysql`.`collations` `col` on((`sch`.`default_collation_id` = `col`.`id`))) join `mysql`.`character_sets` `cs` on((`col`.`character_set_id` = `cs`.`id`))) where can_access_database(`sch`.`name`)
    character_set_client: utf8
    collation_connection: utf8_general_ci
    1 row in set (0.01 sec)
    

    也就是说,虽然DD系统表被隐藏不可见了,但你依然可以通过视图获得大部分信息。这种方式实际上大大加快了IS表的查询速度,转换成物理表的查询后,将无需为每个IS表的查询创建临时表(临时表的操作包含了server层创建frm, 引擎层获取数据or需要锁保护的全局数据)。另外优化器也能为IS表的查询选择更好的执行计划(例如使用系统表上的索引进行查询)。

     

    新选项: information_schema_stats: CACHED | LATEST

    目前表的元数据信息缓存在statistics及tables表中以加速对IS表的查询性能。你可以通过参数information_schema_stats来直接读取已经缓存到内存的数据(cached),还是从存储引擎中获取最新的数据(latest). 很显然后者要慢一点。
    
    而从is库下,可以看到对应两种表:TABLES及TABLES_DYNAMIC, 以及STATISTICS及STATISTICS_DYNAMIC。当被设置为LATEST时,就会去从**_DYNAMIC表中去读取数据。
    
    该选项也会影响到SHOW TABLES等语句的行为。
    

    Data Dictionary Cache

    数据词典的结构发生巨大的变化后,相应的对于内存数据词典Cache也做改动,

    mysql> show variables like '%defin%';
    +---------------------------------+-------+
    | Variable_name                   | Value |
    +---------------------------------+-------+
    | schema_definition_cache         | 256   |
    | stored_program_definition_cache | 256   |
    | table_definition_cache          | 1400  |
    | tablespace_definition_cache     | 256   |
    +---------------------------------+-------+
    4 rows in set (0.00 sec)
    

    tablespace_definition_cache: tablespace cache的大小,存储了tablespace的定义. 一个tablespace中可能包含多个table。 table_definition_cache: stored_program_definition_cache: 存储过程&&function的定义cache. schema_definition_cache: 存储schema定义的cache hardcode的字符集cache:

    character set definition cache partition: Stores character set definition objects and has a hardcoded object limit of 256.
    collation definition cache partition: Stores collation definition objects and has a hardcoded object limit of 256.
    

    系统表变化

    • 和权限相关的表转换成InnoDB引擎
      • 包括:user, db, tables_priv, columns_priv, procs_priv, proxies_priv
    • func表转换成InnoDB事务表
      • 基于此变化,对function的操作(例如CREATE FUNCTION或者DROP FUNCTION, 或者用户定义的UDF)可能会导致一次隐式提交
    • mysql库下的routine表及event表不再使用,这些信息被存储到新的DD table中,并且在mysql库下是不可见的。
    • 外键系统表
      • 使用两个不可见的系统表foreign_keys和foreign_key_column_usage来存储外键信息 // 由于这两个系统表不可见,你需要通过IS库下的REFERENTIAL_CONSTRAINTS和KEY_COLUMN_USAGE表来获得外键信息 // 引入的不兼容:foreign key的名字不可以超过64个字符(之前版本是允许的)


沪ICP备19023445号-2号
友情链接