首頁 資料庫 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