mysql-analyze table导致waiting for table flush

embedded/2025/2/28 19:01:40/

一、背景

一次普通的analyze table操作却锁住了后续的查询

mysql> select sleep(100) from a;analyze table a;mysql> select * from a;# 遇到这种情况就需要查询阻塞的sql,然后kill掉,或者也可以等待
68050436 | test          | 2025-02-26 11:52:40 | select sleep(100) from a

二、源码分析

这是percona解决这个问题所涉及的改动,增加了一个skip_flush 的布尔常量

@@ -906,6 +906,9 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,}if (table->table){+      const bool skip_flush=
+        (operator_func == &handler::ha_analyze)
+        && (table->table->file->ha_table_flags() & HA_ONLINE_ANALYZE);if (table->table->s->tmp_table){/* 
@@ -915,7 +918,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
- 原逻辑:只要需要修改表或发生致命错误,就移除表缓存
- 新逻辑:当且仅当(不需要跳过刷新 且 需要修改表)或发生致命错误时,才移除表缓存
- 保留了致命错误时的强制刷新逻辑*/if (open_for_modify && !open_error)table->table->file->info(HA_STATUS_CONST);}
-      else if (open_for_modify || fatal_error)
+      else if ((!skip_flush && open_for_modify) || fatal_error){tdc_remove_table(thd, TDC_RT_REMOVE_UNUSED,table->db, table->table_name, FALSE);

下面是当前的完整代码

// 当表对象存在时
if (table->table)  
{// 判断是否需要跳过缓存刷新(在线分析且引擎支持在线分析时跳过)const bool skip_flush = (operator_func == &handler::ha_analyze) &&(table->table->file->ha_table_flags() & HA_ONLINE_ANALYZE);// 处理临时表逻辑if (table->table->s->tmp_table) {/*如果表未成功打开,则不尝试获取状态信息(修复Bug#47633)*/if (open_for_modify && !open_error)table->table->file->info(HA_STATUS_CONST); // 获取存储引擎状态信息}// 非临时表且满足以下条件时else if ((!skip_flush && open_for_modify) || fatal_error) {// 从表定义缓存中移除该表(非强制模式)tdc_remove_table(thd, TDC_RT_REMOVE_UNUSED,table->db, table->table_name, FALSE);/*可能有修改操作发生,因此需要使查询缓存失效*/table->table = 0;                        // 重置表指针(用于查询缓存失效)query_cache.invalidate(thd, table, FALSE); // 使该表的查询缓存失效}else {/*当执行 ALTER TABLE 的分区管理操作时(如 ANALYZE/CHECK PARTITION)重置需要处理的分区状态*/if (table->table->part_info &&lex->alter_info.flags & Alter_info::ALTER_ADMIN_PARTITION) {set_all_part_state(table->table->part_info, PART_NORMAL); // 将所有分区状态设为正常}}
}/* 错误处理路径:管理命令执行失败时 */
if (thd->transaction_rollback_request) 
{/*罕见情况:存储引擎请求事务回滚(例如发生死锁时),执行回滚操作*/if (trans_rollback_stmt(thd) || trans_rollback_implicit(thd))goto err; // 跳转到错误处理
}
else 
{// 正常提交事务if (trans_commit_stmt(thd) || trans_commit_implicit(thd))goto err; // 提交失败则跳转错误处理
}// 关闭线程相关的表对象
close_thread_tables(thd);  
// 释放事务相关的元数据锁
thd->mdl_context.release_transactional_locks();

三、percona解释

发生这种情况的原因是,在修复之前, ANALYZE TABLE 的 工作方式如下:

  1. 打开表统计信息:允许并发 DML 操作(INSERT / UPDATE / DELETE / SELECT )
  2. 更新表统计信息:允许并发 DML 操作
  3. 更新完成
  4. 使表定义缓存中的表条目无效:禁止并发 DML 操作
    4.1. 这里发生的事情是ANALYZE TABLE 将当前打开的表共享实例标记为无效。这不会影响正在运行的查询:它们将照常完成。但所有传入查询都将无法启动,直到它们可以重新打开表共享实例。并且这在所有当前正在运行的查询完成之前不会发生。
  5. 使查询缓存无效:禁止并发 DML 操作

最后两个操作通常很快,但如果另一个查询触及表共享实例或获取查询缓存互斥锁,则它们无法完成。反过来,它也无法允许传入查询启动。

但是ANALYZE TABLE 修改的是表统计信息,而不是表定义!实际上,它不会以任何方式影响已经运行的查询。如果查询在ANALYZE TABLE 完成更新统计信息之前启动,则它使用旧统计信息。ANALYZE TABLE不会影响表中的数据。因此,查询缓存中的旧条目仍然是正确的 。它没有更改表的定义。因此,无需将其从表定义缓存中删除。因此,我们避免了上面的操作 4 和 5。

对lp:1704195的修复(迁移至PS-2503)删除了这些额外的更新以及它们所需的锁,并使ANALYZE TABLE 始终能够在繁忙的生产环境中安全运行。

参考文章
八怪大佬的文章
percona解决的版本
mysql官方bug记录地址
percona解决的详细信息
percona解决的版本


http://www.ppmy.cn/embedded/168860.html

相关文章

泛微e-office sms_page.php sql注入漏洞复现(CNVD-2022-1)(附脚本)

免责申明: 本文所描述的漏洞及其复现步骤仅供网络安全研究与教育目的使用。任何人不得将本文提供的信息用于非法目的或未经授权的系统测试。作者不对任何由于使用本文信息而导致的直接或间接损害承担责任。如涉及侵权,请及时与我们联系,我们将尽快处理并删除相关内容。 0x0…

Pytorch 第六回:AlexNet卷积神经网络模型

Pytorch 第六回:AlexNet卷积神经网络模型 本次开启深度学习第六回,基于Pytorch的AlexNet卷积神经网络模型。在上回当中,我们采用深层神经网络,进行10分类;这次我们再拓展一下,采用卷积神经网络进行分类训练…

4个小时开发DeepSeek+baiduNaotu一键生成思维导图

一、引言 最近发现AI生成思维导图的解决方案普遍存在两个断层:用户需手动复制模型输出的JSON数据到脑图软件,且缺乏实时可视化反馈。基于日常使用的BaiduNaotu框架(其轻量级架构与简洁的UI设计已满足基础需求),我决定…

HTML邮件的制作以及可能遇到的问题

HTML 邮件制作方法 规划结构:通常由头部、主体和尾部构成。头部含发件人信息、主题等元数据;主体是核心,有文本、图片、链接等;尾部有版权信息、联系方式等。编写代码: 布局:优先用 table 布局,…

x64汇编下过程参数解析

简介 好久没上博客, 突然发现我的粉丝数变2700了, 真是这几个月涨的粉比我之前好几年的都多, 于是心血来潮来写一篇, 记录一下x64下的调用约定(这里的调用约定只针对windows平台) Windows下的x64程序的调用约定有别于x86下的"stdcall调用约定"以及"cdecl调用约…

Java实现斗地主-做牌以及对牌排序

卡牌类 public class Card {private String size;//大小private String color;//花色private int value;//权值public Card() {}public Card(String size, String color, int value) {this.size size;this.color color;this.value value;}public String toString(){return …

35. Spring Boot 2.1.3.RELEASE 应用监控【监控信息可视化】

在 Spring Boot 2.1.3.RELEASE 中实现监控信息可视化可以通过多种方式,下面为你详细介绍使用 Spring Boot Actuator 结合 Grafana 和 Prometheus 以及使用 Spring Boot Admin 这两种常见方法。 方法一:Spring Boot Actuator Grafana Prometheus 1. 添…

LE AUDIO广播学习笔记之BASE

背景需求 首先看一个有着实际需求情形的列子:比如有个足球吧里,屏幕上正在播放一场国际足球赛,这个吧里有英国人,西班牙人,中国人,德国人等等,大家都在一个屏幕上看球赛,这个时候&a…