改进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是一種開源的關聯式資料庫管理系統,由於
