MySQL table cache的分区方式

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

今天在跑高压力高并发下只读查询时,发现个比较有意思的小问题

先来看看performance schema

root@performance_schema 03:13:45>SELECT COUNT_STAR, SUM_TIMER_WAIT, AVG_TIMER_WAIT, EVENT_NAME FROM events_waits_summary_global_by_event_name where COUNT_STAR > 0 and EVENT_NAME like ‘wait/synch/%’ order by SUM_TIMER_WAIT desc limit 20;
+————-+——————+—————-+—————————————————+
| COUNT_STAR | SUM_TIMER_WAIT | AVG_TIMER_WAIT | EVENT_NAME |
+————-+——————+—————-+—————————————————+
| 794349716 | 9217250429384944 | 11603268 |wait/synch/mutex/sql/LOCK_table_cache |
| 395819330 | 8052052171747844 | 20342452 | wait/synch/rwlock/sql/LOCK_grant |
| 18792871674 | 3690042369314320 | 196200 | wait/synch/mutex/sql/THD::LOCK_query_plan |
| 11274795644 | 2143435212448448 | 190096 | wait/synch/mutex/sql/THD::LOCK_thd_data |

可以看到,目前排名最高的是LOCK_table_cache。 从backtrace中发现如下堆栈(简化版本):

18 __lll_lock_wait(libpthread.so.0)…,lock(thr_mutex.h:61),

open_table(thr_mutex.h:61),open_and_process_table(sql_base.cc:4903),open_tables(sql_base.cc:4903),

open_normal_and_derived_tables(sql_base.cc:6084),execute_sqlcom_select(sql_parse.cc:5004),……

大量线程被堵塞在open_table这里了,我们来看看具体的代码 (quoted from 5.7.5, sql/sql_base.cc)

3172 retry_share:

3173   {

3174     Table_cache *tc= table_cache_manager.get_cache(thd);

3175

3176     tc->lock();

3177

3178     /*

3179       Try to get unused TABLE object or at least pointer to

3180       TABLE_SHARE from the table cache.

3181     */

3182     table= tc->get_table(thd, hash_value, key, key_length, &share);

3183

我们知道从5.6开始可以对table cache进行分区,参数table_open_cache_instances来控制分区的个数,从而消除了之前版本的热点锁LOCK_open.

之前没看过这部分的代码,一直以为是根据表名之类的来进行分区的,今天才发现是根据线程id进行分区.

155   /** Get instance of table cache to be used by particular connection. */

156   Table_cache* get_cache(THD *thd)

157   {

158     return &m_table_cache[thd->thread_id() % table_cache_instances];

159   }

这种分区方式可以避免例如热点表这样的场景,但也可能带来负面的影响,例如别的分区里可能有大量空闲的TABLE对象,而当前线程的分区中没有,这种情况下依然要创建TABLE对象加入到当前分区中。

另外LOCK_open并不是能完全避免的,当无法从table cache中找到TABLE对象时,依然要持有LOCK_open来检查TABLE_SHARE的版本是否是有效的。不过创建TABLE对象及加入hash的过程无需持有LOCK_open。


相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://www.aliyun.com/product/rds/mysql 
相关文章
|
存储 关系型数据库 MySQL
MySQL技能完整学习列表5、数据库操作——1、创建数据库和表——2、修改表结构(ALTER TABLE)
MySQL技能完整学习列表5、数据库操作——1、创建数据库和表——2、修改表结构(ALTER TABLE)
368 0
|
5月前
|
NoSQL 算法 Redis
【Docker】(3)学习Docker中 镜像与容器数据卷、映射关系!手把手带你安装 MySql主从同步 和 Redis三主三从集群!并且进行主从切换与扩容操作,还有分析 哈希分区 等知识点!
Union文件系统(UnionFS)是一种**分层、轻量级并且高性能的文件系统**,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtual filesystem) Union 文件系统是 Docker 镜像的基础。 镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
689 7
|
8月前
|
关系型数据库 MySQL 索引
mysql中的索引和分区
在MySQL中,索引和分区是提高查询效率的关键技术。通过创建合适的索引,可以显著提升数据检索速度。而分区可以作为作为进一步提高查询效率的方式,在较大数据量时通常可以使用这两个结合的方式优化查询速度,所以这边将这两个进行整理,巩固个人知识,同时也希望帮助到有需要的朋友。
195 2
|
SQL 关系型数据库 MySQL
MySQL 8.0报错--1118-Row size too large. The maximum row size for the used table type, not counting BLOBs,is 8126,
MySQL 8.0报错--1118-Row size too large. The maximum row size for the used table type, not counting BLOBs,is 8126,
1839 56
MySQL 8.0报错--1118-Row size too large. The maximum row size for the used table type, not counting BLOBs,is 8126,
|
缓存 关系型数据库 MySQL
MySQL查询优化:提速查询效率的13大秘籍(合理使用索引合并、优化配置参数、使用分区优化性能、避免不必要的排序和group by操作)(下)
MySQL查询优化:提速查询效率的13大秘籍(合理使用索引合并、优化配置参数、使用分区优化性能、避免不必要的排序和group by操作)(下)
1072 0
|
SQL 监控 关系型数据库
MySQL如何查看每个分区的数据量
通过本文的介绍,您可以使用MySQL的 `INFORMATION_SCHEMA`查询每个分区的数据量。了解分区数据量对数据库优化和管理具有重要意义,可以帮助您优化查询性能、平衡数据负载和监控数据库健康状况。希望本文对您在MySQL分区管理和性能优化方面有所帮助。
1178 1
|
存储 关系型数据库 MySQL
MySQL 如何查看每个分区的数据量
MySQL 如何查看每个分区的数据量
976 3
|
SQL 关系型数据库 MySQL
MySQL异常一之: You can‘t specify target table for update in FROM clause解决办法
这篇文章介绍了如何解决MySQL中“不能在FROM子句中指定更新的目标表”(You can't specify target table for update in FROM clause)的错误,提供了错误描述、需求说明、错误做法和正确的SQL写法。
2825 0
|
关系型数据库 MySQL 数据库
在 MySQL 中使用 Alter Table
【8月更文挑战第11天】
2482 0
在 MySQL 中使用 Alter Table
|
DataWorks 安全 关系型数据库
DataWorks产品使用合集之如何实现MySQL数据库的自动分区
DataWorks作为一站式的数据开发与治理平台,提供了从数据采集、清洗、开发、调度、服务化、质量监控到安全管理的全套解决方案,帮助企业构建高效、规范、安全的大数据处理体系。以下是对DataWorks产品使用合集的概述,涵盖数据处理的各个环节。

推荐镜像

更多