InnoDB中Adaptive hash index存在问题、Percona改进及一个bug

背景
  Adaptive hash index  (AHI) 是InnoDB中用于加速索引查找的一个结构。InnoDB本身不支持hash索引,所有的索引检索都走B树查询。AHI可以认为是“索引的索引”。当对一个页面的访问次数满足一定条件后,将这个页面的地址存在一个hash表中,下次查询可以直接访问到页面,不需要走B树查询。

问题
  天下没有免费的午餐,在加速查询的同时,AHI与其他缓存结构一样,也面临维护的问题。作为一个全局结构,在更新时必然有一个全局锁操作(btr_search_latch),一个查询里面可能会对其作多次加x_lock操作。

 

Percona的改进
    如同Buffer Pool可以用多个instance减少锁冲突,Percona也用类似的策略来处理AHI的锁问题。由于本身就是Hash结构,这个处理既自然又方便。所有的数据节点都必然属于一个索引,AHI就用索引id来作分区的key(block->index->id).计算规则为(index_id % btr_search_index_num), 这个 btr_search_index_num 就是 Percona中引入的只读参数 innodb_adaptive_hash_index_partitions。
  全局的btr_search_latch则分为btr_search_index_num 份,AHI中每个block中新增一个成员指向 btr_search_latch_part[i].

 

淘汰流程
  缓存结构必然还涉及一个淘汰流程,大致逻辑如下:
  a)x_lock(block->btr_search_latch);
  b)从hash表中删除这个page信息
  c)x_unlock

  但因为并非所有的page都在AHI中, 若所有的页面操作都作这个处理,则会导致很多额外的锁冲突(x_lock排他),因此需要一个“预判断“的流程。
  简单的判断流程是
  a) s_lock(block->btr_search_latch);
  b) 判断block->index是否为空
  c) 若为空则unlock后直接返回(说明没有在AHI中)
  ….
  (后续流程不表)

 

预判流程逻辑
  这个预判断流程在 btr_search_index_num =1时是没有问题的,但当btr_search_index_num>1时,由于block->btr_search_latch是可变的,也就说存在一种状态,在线程A访问这个锁的时候,线程B刚好把某个page替换掉,甚至于会将这个block用于缓存另外一个page。这样线程A就”锁错了“
  由于存在这种中间状态,在Percona现在的实现上面是通过double-check,在加锁之后作了若干判断,若出现上述的情况,则重试。代码在函数(btr_search_drop_page_hash_index)中

retry:
          if (btr_search_index_num > 1) {
                rw_lock_t*      btr_search_latch;

                /* FIXME: This may be optimistic implementation still. */
                btr_search_latch = (rw_lock_t*)(block->btr_search_latch);
                if (UNIV_LIKELY(!btr_search_latch)) {
                        if (block->index) {
                                goto retry;
                        }   
                        return;
                }   
                rw_lock_s_lock(btr_search_latch);
                if (UNIV_LIKELY(btr_search_latch != block->btr_search_latch)) {
                        rw_lock_s_unlock(btr_search_latch);
                        goto retry;
                }   
                if (UNIV_LIKELY(!block->index)) {
                        rw_lock_s_unlock(btr_search_latch);  //(*)
                        goto retry;
                }   
                index = block->index;
                ut_a(btr_search_latch == btr_search_get_latch(index->id));
         }

 

其中行(*)也是一种中间状态,表示这个block刚刚淘汰掉。因为这些状态被认为是出现在其他线程在AHI中作淘汰操作时出现的,因此多次重试可以认为是等待其他线程完成。

 

BUG描述
但在实现上却漏考虑了一个背景,就是虽然innodb_adaptive_hash_index_partitions是只读变量,但AHI确是可以动态开关的。当用户调用 set global innodb_adaptive_hash_index=off时,会将所有的block.index清空。虽然AHI被关闭后,不会再有“淘汰”的逻辑,但page从LRU list中被淘汰的时候,还是必须得调用btr_search_drop_page_hash_index的,上面的代码逻辑仍会走到(*)行。在这个线程中就出现了死循环,从客户端看,就是查询线程等待。


复现步骤
  1、设置my.cnf中
    innodb_adaptive_hash_index_partitions=8
    innodb_buffer_pool_size=32M
 
  2、souce ahi_loop.txt;
  
 现象是客户端出现等待,即使客户端取消该查询,但仍然占用一个cpu(死循环),若多次重试,CPU IDLE会跌为0

 

简单修改是在关闭AHI的时候,将block->index设置为NULL的同时,加一句 block->btr_search_latch = NULL;

因果推断--PSM的原理和应用(二) 上一篇介绍了DID,本文介绍和DID可一起搭配使用的一种因果推断方法PSM。在正式介绍PSM之前,先来简单回顾一下为什么需要因果推断以及如何做因果推断。我们都知道相关非因果,比起相关我们更希望知道两个事件之间的因果关系,有了确切的因果关系,才能知道对A如何操作才能引起B的变化。解决因果推断问题,目前主要有两种框架,Rubin虚拟事实模型和Pearl因果图模型。站在数据分析的角度上,Rubin虚拟事实模型更容易理解,其核心思想是寻找恰当的对照组。 阅读详情

相关推荐

爬虫小例--爬药监局(上)

”明月如霜,好风如水,清景无限 “ 文远最近也算是爬虫入门吧,相信后面会慢慢熟悉。 壹 直接上例子,爬取药监局的数据。目的是得到每家公司的详情数据,例: 具体网址:http://scxk.nmpa.gov.cn:81/xk/ 这是主页,下面详情信息: 贰 分析,通过网页检查发现,主网页上没有公司相关数据,观察XHR中的Ajax请求发现,公司信息都是动态数据(方便更新),点击发现每个公司 的详情信息通过ID号这个参数区别,那么可以确定思路是先得到每个公司的ID号,然后在通过ID对应每一个详细网站,同样右键

john_ashley的博客 4556

非DBA人员从零到一,MySQL InnoDB数据库调优之路(二)-建立索引

非DBA人员从零到一,MySQL InnoDB数据库调优之路(一)-建立索引

kiranet的专栏 1132

扣子(coze)实战 | 一键生成爆款书单视频

摘要:本文介绍了一个基于DeepSeek和Coze平台实现短视频高效生成的工作流方案。该方案耗时仅1-2分钟即可完成"假如书籍会说话"类短视频制作,包含书籍内容深度解读、对话台词生成、自动配音、素材合成等环节,支持通过剪映进行二次编辑。作者分享了完整开发思路和8个工作模块,并开放了包含该工具在内的100+智能体共享空间,提供会员专属服务。该方案为非真人出镜短视频的批量化生产提供了可行方案。

yueyehuguang的博客 2396

mysql索引、储存引擎

什么是索引,常用索引? 快速查找排好序的一种数据结构。Mysql索引主要有两种结构:B+Tree索引和Hash索引。 主键索引:特殊的唯一索引,不允许有空值 唯一索引(UNIQUE):与“普通索引”类似,不同就是:索引值必须唯一,但是允许有空值。 普通索引(INDEX和normal):基本的索引,没有限制 全文索引(FULLTEXT):仅用于MyISAM表,对较大数据,生成全文索引很耗时、耗空间 组合索引:遵循“最左前缀”原则 聚集索引(主键索引)扩展: 辅助索引需找到主键索引才能找到数据;非集合..

weixin_43871041的博客 103

【python3.7】解决报错 error: Microsoft Visual C++ 14.0 or greater is required. Get it with “Microsoft C++

解决pip安装py7zr遇到的报错问题。

水w的博客 3944

Matlab实战:3种雷达间歇采样干扰的仿真与识别(附完整代码)

本文通过Matlab实战,详细仿真了雷达有源间歇采样干扰的三种核心样式:直接转发、重复转发和循环转发干扰。文章提供了完整的代码实现,并深入探讨了基于时频分析和循环平稳分析的特征提取与识别方法,为雷达抗干扰技术的学习与实践提供了清晰的工程实现路径。

weixin_29053695的博客 364

InnoDB关键特性之自适应hash索引

一、索引的资源消耗分析 1、索引三大特点   1、小:只在一个到多个列建立索引   2、有序:可以快速定位终点   3、有棵树:可以定位起点,树高一般小于等于3 2、索引的资源消耗点   1、树的高度,顺序访问索引的数据页,索引就是在列上建立的,数据量非常小,在内存中;   2、数据之间跳着访问     1、索引往表上跳,可能需要访问表的数据页很多; ...

aecuhty88306453的博客 1009

Agent 长期记忆三代演进:从 RAG 到 Memory Graph,mem0 / Zep / LangMem / Letta 深度横评

文章摘要 2026年,Agent长期记忆技术迎来关键突破,OpenAI、Anthropic等厂商通过扩大上下文窗口和推出记忆工具,推动长期记忆从工程补丁发展为独立技术层。本文通过分析三代记忆架构演进(RAG→结构化Fact→MemoryGraph)和四大方案(mem0/Zep/LangMem/Letta)的8维度横评,揭示以下核心观点: 长上下文≠长期记忆:128K上下文如同RAM,仍需硬盘式记忆层筛选和结构化存储,避免“Context Rot”导致的准确率下降。 三代架构演进: Gen1(RAG):向量检

LDZKKJ的博客 1444

科普文:软件架构数据库系列之【数据库内核月报:源码解读MySQL5.7自适应哈希InnoDB Adaptive hash index】

MySQL · 引擎特性 · InnoDB Adaptive hash index介绍 · 数据库内核月报 · 看云我们知道InnoDB的索引组织结构为Btree。通常情况下,我们需要根据查询条件,从根节点开始寻路到叶子节点,找到满足条件的记录。为了减少寻路开销,InnoDB本身做了几点优化。首先,对于连续记录扫描,InnoDB在满足比较严格的条件时采用row cache的方式连续读取8条记录(并将记录格式转换成MySQL Format),存储在线程私有的中;

为无为,事无事,味无味。 1308

C# HttpClient 实战:3步绕过Cloudflare指纹拦截,获取完整网页内容

本文详细介绍了如何使用C# HttpClient绕过Cloudflare指纹拦截,获取完整网页内容的3步实战方案。通过完美复制浏览器请求头、智能管理Cookie容器以及处理动态挑战页面,开发者可以有效突破Cloudflare的反爬机制,适用于爬虫开发和数据采集项目。

weixin_31856057的博客 321

基于深度学习 YOLOv11 的快递包裹检测系统(Python + PySide6 界面 + 训练代码)

成为亟需优化的重要环节。随着电子商务的快速发展,物流行业面临着越来越大的压力,为了解决这些问题,我们提出了一种。目标检测算法,实现快递包裹的。的界面,供用户进行实时监控。本项目的主要目标是利用。

斌擎科技 763

Mysql - InnoDB三大特性之自适应Hash索引(从数据结构角度分析Mysql中的Hash索引)

自适应Hash索引(Adatptive Hash Index,内部简称AHI)是InnoDB的三大特性之一,还有两个是 Buffer Pool简称BP、双写缓冲区(Doublewrite Buffer)。 ...

it_lihongmin的博客 4765

【数据集】全球陆地表面反照率Albedo

【数据集】全球陆地表面反照率Albedo

WW、forever的博客 1454

MySQL索引维护实战:DROP INDEX操作原理、场景与避坑指南

索引是数据库性能优化的核心技术,其本质是通过B-Tree等数据结构为数据建立快速访问路径。索引的工作原理基于排序与二分查找,通过减少全表扫描来提升查询效率。合理使用索引能显著降低系统I/O负载,其技术价值在于平衡读写性能,是支撑高并发在线事务处理(OLTP)系统的基石。在实际应用场景中,随着业务查询模式演变和数据增长,索引需要动态维护以避免冗余和低效。DROP INDEX命令正是用于删除冗余或低效索引的关键操作,它涉及元数据锁(MDL)管理与存储引擎空间回收,需在业务低峰期谨慎执行。通过分析执行计划、识别冗

weixin_34377919的博客 354

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

MySQL索引原理、优化与实战指南

数据库索引是提升SQL查询性能的关键技术,其核心原理是通过B+树等数据结构建立快速访问路径。索引通过将查询时间复杂度从O(n)降至O(log n)显著提升性能,但需要权衡存储开销和写入维护成本。在工程实践中,合理使用覆盖索引、组合索引和索引条件下推等技术能有效解决电商商品查询、用户认证等高并发场景的性能瓶颈。针对MySQL的InnoDB引擎,需要特别注意聚簇索引特性与最左前缀原则,同时通过EXPLAIN分析执行计划、监控索引使用率来持续优化。本文深入解析B+树索引和哈希索引的实现差异,并提供索引碎片整理、自

weixin_33850890的博客 704

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

drop table的优化

原文:http://mysql.taobao.org/monthly/2016/01/07/ 背景 系统为了加速对象的访问,通常都会增加一层缓存,以缓解下一层IO的瓶颈,OS的page cache和数据库的buffer pool都基于此。 但对象的删除,如果同步清理对象的缓存的话,不仅大大增加了延时,同时可能因为缓存过大导致IO blooding。所以针对缓存的清理,都会采用la

qiuyepiaoling的专栏 883

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

合并插入缓冲

插入缓冲是InnoDB存储引擎关键特性中最令人激动的。不过,这个名字可能会让人认为插入缓冲是缓冲池中的一个部分。其实不然,InnoDB缓冲池中有Insert Buffer信息固然不错,但是Insert Buffer和数据页一样,也是物理页的一个组成部分。 我们知道,主键是行唯一的标识符,在应用程序中行记录的插入顺序是按照主键递增的顺序进行插入的。因此,插入聚集索引一般是顺序的,不需要磁盘的随机读取...

慎独 2095

MySQL DELETE操作后磁盘空间不释放的原理与解决方案

在数据库管理中,DELETE操作是常见的数据清理手段,但其背后的存储机制往往被忽视。InnoDB存储引擎采用标记删除机制,当执行DELETE时,数据并非立即从物理磁盘擦除,而是被标记为可复用状态,这种设计基于事务回滚、MVCC多版本并发控制等核心原理。从技术价值看,延迟空间回收提升了数据库性能,避免了频繁的数据移动操作。在实际应用场景中,大量DELETE操作会导致表碎片化,虽然information_schema显示数据已删除,但磁盘空间并未释放给操作系统。针对MySQL空间回收问题,可以通过OPTIMIZ

weixin_30236595的博客 557

MySQL索引原理与调优:提升数据库性能的终极指南

MySQL数据库性能优化是每个开发者都必须掌握的核心技能,而索引优化则是其中最关键的一环。本文将深入探讨MySQL索引的工作原理、数据结构设计,并提供完整的性能调优解决方案,帮助你彻底掌握MySQL索引优化的精髓。 ## 📊 为什么需要索引?性能提升的关键 索引是存储引擎用于快速找到数据记录的一种数据结构,就好比一本教科书的目录部分,通过目录中找到对应文章的页码,便可快速定位到需要的文章。在

gitblog_00150的博客 920

MySQL问答200

本文涵盖MySQL全栈面试核心内容,包括:基础概念(关系型数据库特性、体系结构);存储引擎对比(InnoDB/MyISAM);索引原B+树、聚簇索引)与优化策略;事务ACID与隔离级别实现;锁机制(行锁、间隙锁)与MVCC原理;日志系统(redo/undo/binlog);SQL优化与执行计划分析;高可用方案(主从复制、分库分表);InnoDB底层机制(Buffer Pool、Checkpoint);以及MySQL 8.0新特性。

weixin_72753562的博客 827

mysql自学

目录一、数据库概念二、mysql安装2.1 ubuntu安装mysql2.2 rockylinux安装mysql2.3 windows安装mysql2.4 数据初始化2.5 修改密码2.6 创建用户2.7 忘记密码2.8 默认端口2.9 远程连接三、数据库管理工具Dbeaver四、mysql练习库4.1 world库4.2 sakila库4.3 employees库4.4 自建库导出4.5 全库备份与恢复(all-databases)4.6 查询结果导出五、SQL语言六、五种数据类型6.1 整数型6.2 浮

zhangli2009x的博客 259

Innodb 自适应哈希索引的优缺点

名称 自适应哈希索引 适合使用场景 适合使用 = 和 IN 操作符的等值查询 不合适场景 不适合使用 like 和 % 的范围查询和高并发的joins 优点 提高了Innodb的内存使用率和一些情况下二级索引的查询效率 缺点 占用Innodb的内存缓存,使用了 lacth 锁保护内存中的hash结构 mysql 术语列表中对自适应哈希索引的解释 AHI 自适应哈...

qq_36431213的博客 4445

MySQL · 引擎特性 · InnoDB Adaptive hash index介绍

我们知道InnoDB的索引组织结构为Btree。通常情况下,我们需要根据查询条件,从根节点开始寻路到叶子节点,找到满足条件的记录。为了减少寻路开销,InnoDB本身做了几点优化。首先,对于连续记录扫描,InnoDB在满足比较严格的条件时采用row cache的方式连续读取8条记录(并将记录格式转换成MySQL Format),存储在线程私有的中;这样一次寻路就可以获取多条记录,在server层处理完一条记录后,可以直接从cache中取数据而无需再次寻路,直到cache中数据取完,再进行下一轮。

Lixora's DB Home 484

MySQL的InnoDB存储引擎中的自适应哈希索引技术

MySQL的InnoDB存储引擎使用了一种叫做自适应哈希索引(Adaptive Hash Indexes)的技术。在某些索引值被频繁访问的情况下,InnoDB会自动在内存中为这些值建立哈希索引,以加速查询操作。

jkzyx123的博客 1124

【InnoDB 存储引擎】15.5.3 Adaptive Hash Index(InnoDB 中的自适应哈希索引,加快连接或查询速度)

InnoDB 存储引擎会自行针对二级索引来考虑是否建立自适应哈希索引

yuchangyuan5237的博客 963

mysql错误Warning: a long semaphore wait

之前运行mysql的时候好好的,今天建索引的时候出现一系列的warning: InnoDB: Warning: a long semaphore wait 接着出现错误: Error: semaphore wait has lasted > 600 seconds 随后服务自动关闭,网上资料说是因为哈希自适应索引的问题,mysql的哈希自适应索引是默认开启的,这样建立索引后,读取和写入的效率能提高2倍以上,但是有可能会出现死锁的问题,网上建议关闭 inno...

Data & Analysis 1626
上一篇: InnoDB中dict_update_statistics调用策略及问题
下一篇: 关于MySQL的 compound-statement SQL
iteye_621
博客等级 码龄8年 12粉丝 3原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值