改进MySQL的table_cache_MySQL
bitsCN.com
以下为本人在工作中的碎碎念,记录的比较凌乱……
........................................................................
在mysql里面有一个参数table_cache,当设置过大时,会产生明显的效率下降。这是因为扫描open_cache哈希表时,使用的线性扫描,时间复杂度为O(n),mysql的bug list上有人提供了一个patch(http://bugs.mysql.com/bug.php?id=33948),可以把时间降到o(1),其基本思想是为table实例增加三个指针,来维护一个空闲链表。
首先,我们分析一下mysql在打开一个表时如何工作:
在mysql里,table_cache是一个比较重要的参数。由于多线程机制,每个线程独自打开自己需要的标的文件描述符,而不是共享已经打开的。
1. table_cache key (见create_table_def_key)
在内存里,table cache使用hash表来存储,key为 database_name/0table_name/0+(可选的,用于临时表)
这里对于临时表会做特殊处理,需要增加额外的信息来保证临时表在slave端是唯一的
增加8个字节:前4个字节为master thread id,后4个字节为slavb
2.打开表时候的处理:open_table
***************
必要的检查:线程栈是否足够,thd是否被kill
**************
全局锁:lock_open
*************************
首先判断是否是临时表
*************************
这里有一段很有意思的逻辑,当需要打开表时,总是先从临时表链表中查找表。也就是说,当存在一个与实际表同名的临时表时,会总是操作临时表
if (!table_list->skip_temporary)
{
for (table= thd->temporary_tables; table ; table=table->next)
{
**********************************************
非临时表,且处于pre-locked 或lock_tables mode(thd->locked_tables || thd->prelocked_mode)
即该线程已经打开或锁定了一些表,从thd->open_tables里查询,当不存在时,返回error
**********************************************
if (thd->locked_tables || thd->prelocked_mode)
{ // Using table locks
TABLE *best_table= 0;
int best_distance= INT_MIN;
for (table=thd->open_tables; table ; table=table->next)
{
*******************************************************
正常情况:
1. 首先尝试从table cache中取table
2. 当找到的TABLE实例是nam-locked的,或者一些线程正在flush tables,我们需要等待,直到锁释放
3. 如果不存在这样的TABLE,我们需要创建TABLE,并将其加入到cache中
!这些操作都需要全局锁:LOCK_open,来保护table cache和磁盘上的表定义
*******************************************************
如果这是该query打开的第一个表:设置thd->version = refresh_version,这样,当我们打开剩余表的过程中,如果version发生了变化,则需要back off,关闭所有已经打开的并重新打开表
目前refresh_version只会被FLUSH TABLES命令改变
if (thd->handler_tables)
mysql_ha_flush(thd); //刷新(关闭并标记为re-open)所有需要reopen的表
查询table cache的过程:
for (table= (TABLE*) hash_first(&open_cache, (uchar*) key, key_length, //基于同一个key来查找hash表
&state);
table && table->in_use ;
table= (TABLE*) hash_next(&open_cache, (uchar*) key, key_length,
&state))
{
**********************************
flush tables marked for flush.
Normally, table->s->version contains the value of
refresh_version from the moment when this table was
(re-)opened and added to the cache.
If since then we did (or just started) FLUSH TABLES
statement, refresh_version has been increased.
For "name-locked" TABLE instances, table->s->version is set
to 0 (see lock_table_name for details).
In case there is a pending FLUSH TABLES or a name lock, we
need to back off and re-start opening tables.
If we do not back off now, we may dead lock in case of lock
order mismatch with some other thread:
c1: name lock t1; -- sort of exclusive lock
c2: open t2; -- sort of shared lock
c1: name lock t2; -- blocks
c2: open t1; -- blocks
*********************************
if (table->needs_reopen_or_name_lock()) //Is this instance of the table should be reopen or represents a name-lock?
{}
}
if (table)
************
从unused_tables链表中移除刚找到的table
************
else
***********
创建一个新的table实例,并插入到open cache中
***********
while (open_cache.records > table_cache_size && unused_tables) //当cache满时,从中释放未使用的TABLE实例
hash_delete(&open_cache,(uchar*) unused_tables);
if (table_list->create) //创建一个新表
{
*******
检查表是否存在:check_if_table_exists
*******
在table cache的hash中创建一个placeholder(占位符):table_cache_insert_placeholder
将占位符链到open tables list上:
table->open_placeholder= 1;
table->next= thd->open_tables;
thd->open_tables= table;
return table
}
创建一个新的table实例
分配内存table=(TABLE*) my_malloc(sizeof(*table),MYF(MY_WME))
error= open_unireg_entry(thd, table, table_list, alias, key, key_length,
mem_root, (flags & OPEN_VIEW_NO_PARSE));
如果是视图or error
my_hash_insert(&open_cache,(uchar*) table)
------------------------------------------------
patch:http://bugs.mysql.com/bug.php?id=33948
增加3个指针:
hash_head:
hash_prev: always point to unused table cached items
hash_next: always point to used table cached items
修改的函数:
free_cache_entry //释放一个表的内存。
close_thread_table //move one table to free list
reopen_name_locked_table //重新打开表,保持链表结构
table_cache_insert_placeholder
open_table
------------------------------------------------------------------------
总结:
增加了三个指针:
hash_head:
hash_prev:
hash_next:
!.............................!head!.........................!
head的左边为空闲item链表
head的右边为占用的item链表
所有item通过hash_prev和hash_next进行双向指针
右边的item的hash_head指向head
操作链表:
1)插入新空闲item:在head节点前加入
2)插入新的被占用item:在head后面加入
3)从链表中删除item:
---若该item为head,修改head右侧的item的hash_head指向head->next
---否则,直接删除item,并释放内存。。
查询空闲节点:
1) 找到head
2) 检测head是否in_use,为False则table = head, true则找到table = head->prev
3)当table 不为NULL时,表示找到一个item,将其插入到head右侧
3) table依旧为NULL---->创建新item,将其插入到head右侧
------------------------------
转载请注明:印风
bitsCN.com
热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

当我们谈论编程语言和工作时,我们想到的一种编程语言是Java。全世界大多数公司都使用Java。它很受欢迎,而且有很多工作机会。如果您想在2023年借助Java技能找到工作,那么这对您有好处,因为Java技能可以让您快速找到工作。此外,它还能快速提升你的职业生涯。没有什么魔法能让你快速找到工作。但你的技能对你来说就像魔法一样。选择一份让你满意的工作和一个能够极大提升你职业生涯的良好环境。如果你是一个刚入行且有经验的人,Java也给你提供了一份不错的工作。许多公司使用Java作为其开发的主要程序。它

前端工程师职责解析:主要做什么工作?随着互联网的快速发展,前端工程师作为一个非常重要的职业角色,扮演着连接用户与网站应用程序的桥梁,起着至关重要的作用。那么,前端工程师主要做些什么工作呢?本文将对前端工程师的职责进行解析,让我们来一探究竟。一、前端工程师的基本职责网站开发与维护:前端工程师负责网站的前端开发工作,包括编写网站的HTML、CSS和JavaScr

ChatGPT等大模型的相继发布,让很多人倍感压力,害怕AI会很快接管他们的工作。对此,OpenAI也曾发表过一项研究,表明ChatGPT的影响涵盖所有收入阶层,且高收入工作可能面临更大的风险。事实到底如何呢?我们应该将所有的工作,即使是那些令人满意的工作都实现自动智能化吗?这是未来生命研究所(FutureofLifeInstitute)最近提出的几个问题之一,该研究所呼吁暂停大型人工智能实验,目前埃隆・马斯克(ElonMusk)、SteveWozniak和AndrewYang等1万多人均已签署

学java能找的工作:1、企业级应用开发;2、网站开发;3、Android开发;4、嵌入式领域;5、大数据与云计算;6、游戏开发;7、科学应用;8、软件开发与维护;9、系统与网络编程;10、安全与加密;11、教育与培训;12、咨询与顾问。详细介绍:1、企业级应用开发,Java在企业级应用开发中占据着非常重要的地位,利用Java,可以开发出各种复杂的企业级应用,如OA系统等等。

可从事的工作:1、企业级应用开发;2、网站开发;3、移动应用开发;4、游戏开发;5、大数据分析;6、科学计算与人工智能;7、嵌入式系统开发;8、金融行业应用开发等。详细介绍:1、企业级应用开发:Java在企业级应用开发中占据重要地位,可以用于开发大型、复杂的系统,如ERP、CRM等。这些系统通常需要处理大量数据、支持高并发、保证系统稳定性;2、网站开发:包括前端和后端等等。

c语言以后可以做的工作:1、系统开发;2、游戏开发;3、网络开发;4、应用开发;5、编译器开发;6、算法工程师;7、网络安全;8、硬件开发;9、教育领域;10、数据分析与机器学习;11、软件开发与维护;12、软件测试。详细介绍:1、系统开发,C语言是系统级编程的常用语言,可以用于开发操作系统、嵌入式系统,掌握了C语言,可以成为一名系统开发工程师;2、游戏开发等等。

缓存有助于减少执行查询时的数据库网络调用。一级缓存与会话链接。它是隐式实现的。一级缓存存在直到会话对象存在为止。一旦会话对象终止/关闭,将会有没有缓存对象。二级缓存适用于多个会话对象。它是链接的与会话工厂。二级缓存对象可供所有会话使用单会话工厂。当特定会话发生时,这些缓存对象将被终止工厂已关闭。实现二级缓存我们需要添加以下依赖项才能使用二级缓存。<!--https://mvnrepository.com/artifact/net.sf.ehcache/ehcache--><de

如何利用MySQL数据库技能找到理想工作?摘要:在当今信息时代,数据库管理和数据分析等技能越来越受到重视。MySQL数据库是最常用的关系型数据库之一,掌握MySQL数据库技能为找到理想工作提供了很大的机会。本文将介绍如何利用MySQL数据库技能找到理想工作,并提供一些代码示例来展示MySQL数据库的应用。引言:MySQL是一种开源的关系型数据库管理系统,由于
