首页 数据库 mysql教程 改进MySQL的table_cache_MySQL

改进MySQL的table_cache_MySQL

Jun 01, 2016 pm 01:44 PM
工作

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
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

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

热门文章

<🎜>:泡泡胶模拟器无穷大 - 如何获取和使用皇家钥匙
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系统,解释
3 周前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

热门话题

Java教程
1664
14
CakePHP 教程
1423
52
Laravel 教程
1318
25
PHP教程
1269
29
C# 教程
1248
24
2023年我可以用Java技能申请哪些工作? 2023年我可以用Java技能申请哪些工作? Sep 21, 2023 am 11:41 AM

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

前端工程师职责解析:主要做什么工作? 前端工程师职责解析:主要做什么工作? Mar 25, 2024 pm 05:09 PM

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

ChatGPT等不会很快接管人类工作,易出错,AI也不会免费打工 ChatGPT等不会很快接管人类工作,易出错,AI也不会免费打工 May 21, 2023 am 08:49 AM

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

学java能找什么工作 学java能找什么工作 Jan 16, 2024 pm 05:18 PM

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

学java可以从事哪些工作 学java可以从事哪些工作 Jan 16, 2024 pm 04:58 PM

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

c语言以后做什么工作 c语言以后做什么工作 Jan 29, 2024 pm 02:47 PM

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

Hibernate二级缓存是如何工作的? Hibernate二级缓存是如何工作的? Sep 14, 2023 pm 07:45 PM

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

如何利用MySQL数据库技能找到理想工作? 如何利用MySQL数据库技能找到理想工作? Sep 09, 2023 pm 01:54 PM

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

See all articles