数据库内核月报 - 2015 / 08-MySQL · 功能分析 · MySQL表定义缓存

本文涉及的产品
RDS AI 助手,专业版
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
RDS MySQL DuckDB 分析主实例,基础系列 4核8GB
简介:

表定义

MySQL的表包含表名,表空间、索引、列、约束等信息,这些表的元数据我们暂且称为表定义信息。
对于InnoDB来说,MySQL在server层和engine层都有表定义信息。server层的表定义记录在frm文件中,而InnoDB层的表定义信息存储在InnoDB系统表中。例如:

 InnoDB_SYS_DATAFILES   
 InnoDB_SYS_TABLESTATS  
 InnoDB_SYS_INDEXES     
 InnoDB_SYS_FIELDS      
 InnoDB_SYS_TABLESPACES 
 InnoDB_SYS_FOREIGN_COLS
 InnoDB_SYS_FOREIGN     
 InnoDB_SYS_TABLES      
 InnoDB_SYS_COLUMNS     

注:以上都是memory表,它们内容是从实际系统表中获取的。实际上InnoDB系统表engine也是InnoDB类型的,数据也是以B树组织的。

在数据库每次执行sql都会访问表定义信息,如果每次都从frm文件或系统表中获取,效率会较低。因此MySQL在server层和InnoDB层都有表定义的缓存。以MySQL 5.6为例,参数table_definition_cache控制了表定义缓存中表的个数,server层和InnoDB层的表定义缓存共用此参数。

server层表定义缓存

server层表定义为TABLE_SHARE对象,TABLE_SHARE对象有引用计数和版本信息,每次使用flush操作会递增版本信息。
server层表定义缓存由hash表和old_unused_share链表组成,通过hash表table_def_cache以表名为key缓存TABLE_SHARE对象,同时未使用的TABLE_SHARE对象通过old_unused_share链表链接。

  • 获取TABLE_SHARE(get_table_share)
    先从HASH查找,找不到再读取frm文件加载表定义信息。同时递增引用计数。

  • 释放TABLE_SHARE(release_table_share)
    递减引用计数。当引用计数为0时,如果版本发生变化,直接删除此TABLE_SHARE。

old_unused_share链表调整:

  • 获取TABLE_SHARE时(get_table_share)
    未使用的TABLE_SHARE对象被启用,须从LRU链表取出;
    如果缓存总数超出table_definition_cache大小,须依次从old_unused_share链表尾部去除。

  • 释放TABLE_SHARE时(release_table_share)
    当引用计数为0时,如果版本没有发生变化,将TABLE_SHARE对象加入old_unused_share链表尾部。如果缓存总数超出table_definition_cache大小,须依次从old_unused_share链表尾部去除。
    真正free TABLE_SHARE对象时,如果此对象还在old_unused_share链表中,须从其中去除。

InnoDB层表定义缓存

InnoDB表定义为dict_table_t, 缓存为dict_sys_t,结构如下

struct dict_sys_t{
    ...
    hash_table_t*    table_hash;    /*!< hash table of the tables, based
                    on name */
    hash_table_t*    table_id_hash;    /*!< hash table of the tables, based
                    on id */
    ulint        size;        /*!< varying space in bytes occupied
                    by the data dictionary table and
                    index objects */
    dict_table_t*    sys_tables;    /*!< SYS_TABLES table */
    dict_table_t*    sys_columns;    /*!< SYS_COLUMNS table */
    dict_table_t*    sys_indexes;    /*!< SYS_INDEXES table */
    dict_table_t*    sys_fields;    /*!< SYS_FIELDS table */

    UT_LIST_BASE_NODE_T(dict_table_t)
            table_LRU;    /*!< List of tables that can be evicted
                    from the cache */
    UT_LIST_BASE_NODE_T(dict_table_t)
            table_non_LRU;    /*!< List of tables that can't be
                    evicted from the cache */
};

主要由hash表和LRU链表组成。

  • 两个hash表,分别按name和id,便于按name和id进行查找。

  • table_non_LRU:
    存放不放入到LRU链表的表,这些表不会从缓存中淘汰出去。那么哪些表会放入table_non_LRU链表呢?
    1. 系统表,如sys_tables sys_columns sys_fields SYS_INDEXES等;
    2. 有引用关系的表都加入table_non_LRU(dict_foreign_add_to_cache);
    3. 有全文索引的表都加入table_non_LRU(fts_optimize_add_table);
    4. 便于删表,删表前对将表加入table_non_LRU,删表时加载表时保证表仍然在缓存中,例如表corrupted时。
  • table_LRU
    不在table_non_LRU链表中的表都加入table_LRU链表中。

  • dict_table_t* sys_tables 等
    常用系统表单独标识出来,每次使用时直接取出,不需要从hash表查找。

  • LRU的维护
    既然存在table_LRU链表,我们就需要考虑LRU的调整:

    1. 将最近使用的表放入LRU头部(dict_move_to_mru
      每次按name和id查找时都会调整,参考dict_table_open_on_namedict_table_open_on_id

    2. LRU的淘汰

      • 淘汰哪些表
        LRU中表才可以淘汰,table_non_LRU中的表不参入淘汰。
        表引用计数必须为0(table->n_ref_count == 0)。
        表的索引被自适应哈希引用计数必须为0(btr_search_t->ref_count=0)。
      • 何时淘汰
        主线程控制每47(SRV_MASTER_DICT_LRU_INTERVAL)秒检查一次,只遍历一半LRU链表。
        主线程空闲时检查一次,但扫所有LRU链表,清理控制缓存表个数不能超过table_definition_cache。
      • 如何淘汰
        从LRU尾部开始,淘汰满足条件表(dict_make_room_in_cache)。

注:
1. table_non_LRU没有实际作用,主要用于debug;
2. 如果有较多引用约束的表,它们不受LRU管理,参数table_definition_cache的作用会弱化。

相关实践学习
自建数据库迁移到云数据库
本场景将引导您将网站的自建数据库平滑迁移至云数据库RDS。通过使用RDS,您可以获得稳定、可靠和安全的企业级数据库服务,可以更加专注于发展核心业务,无需过多担心数据库的管理和维护。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
目录
相关文章
|
7月前
|
缓存 关系型数据库 BI
使用MYSQL Report分析数据库性能(下)
使用MYSQL Report分析数据库性能
484 158
|
6月前
|
SQL 关系型数据库 MySQL
阿里云RDS云数据库全解析:产品功能、收费标准与活动参考
与云服务器ECS一样,关系型数据库RDS也是很多用户上云必买的热门云产品之一,阿里云的云数据库RDS主要包含RDS MySQL、RDS SQL Server、RDS PostgreSQL、RDS MariaDB等几个关系型数据库,并且提供了容灾、备份、恢复、监控、迁移等方面的全套解决方案,帮助您解决数据库运维的烦恼。本文为大家介绍阿里云的云数据库 RDS主要产品及计费方式、收费标准以及活动等相关情况,以供参考。
|
7月前
|
缓存 监控 关系型数据库
使用MYSQL Report分析数据库性能(中)
使用MYSQL Report分析数据库性能
500 156
|
7月前
|
缓存 监控 关系型数据库
使用MYSQL Report分析数据库性能(上)
最终建议:当前系统是完美的读密集型负载模型,优化重点应放在减少行读取量和提高数据定位效率。通过索引优化、分区策略和内存缓存,预期可降低30%的CPU负载,同时保持100%的缓冲池命中率。建议每百万次查询后刷新统计信息以持续优化
603 161
|
9月前
|
SQL 存储 关系型数据库
MySQL功能模块探秘:数据库世界的奇妙之旅
]带你轻松愉快地探索MySQL 8.4.5的核心功能模块,从SQL引擎到存储引擎,从复制机制到插件系统,让你在欢声笑语中掌握数据库的精髓!
266 26
|
11月前
|
存储 缓存 自然语言处理
评论功能开发全解析:从数据库设计到多语言实现-优雅草卓伊凡
评论功能开发全解析:从数据库设计到多语言实现-优雅草卓伊凡
324 8
评论功能开发全解析:从数据库设计到多语言实现-优雅草卓伊凡
|
SQL Linux 数据库
【YashanDB知识库】崖山数据库Outline功能验证
本文来自YashanDB官网,主要测试了数据库优化器在不同场景下优先使用outline计划的功能。测试环境包括相同版本新增数据、绑定参数执行、单机主备架构以及数据库版本升级等场景。通过创建表、插入数据、收集统计信息和创建outline等步骤,验证了在各种情况下优化器均能优先采用存储的outline计划。测试结果表明,即使统计信息失效或数据库版本升级,outline功能依然稳定有效,确保查询计划的一致性和性能优化。详情可见[原文链接](https://www.yashandb.com/newsinfo/7488286.html?templateId=1718516)。
【YashanDB知识库】崖山数据库Outline功能验证
|
NoSQL 关系型数据库 MongoDB
Apifox与Apipost数据库连接功能详细对比,让接口管理更高效!
在现代软件开发中,数据库是应用运行的核心组件,接口管理工具则是连接和调试数据库的重要桥梁。本文对比了 Apifox 和 Apipost 两款工具的数据库连接功能。Apipost 支持全面的关系型与非关系型数据库(如 MySQL、Redis、MongoDB),功能强大且免费,适合复杂项目;而 Apifox 在关系型数据库支持上表现良好,但非关系型数据库(尤其是 Redis)功能有限且收费,更适合中小项目以关系型数据库为主的需求。根据项目需求选择合适的工具,可显著提升开发效率和稳定性。

相关产品

  • 云数据库 RDS MySQL 版
  • 推荐镜像

    更多