`
丁林.tb
  • 浏览: 790513 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

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;

1
1
分享到:
评论

相关推荐

    percona-data-recovery-tool-for-innodb-0.5.tar.tar

    percona-data-recovery-tool-for-innodb-0.5.tar.tar

    percona XtraBackup2.4.28

    Percona XtraBackup是一个针对基于MySQL的服务的开源热备份实用程序,它在备份期间不会锁定 数据库。可以备份MySQL 5.1、5.5、5.6和5.7服务器上的InnoDB、XtraDB和MyISAM表上的数据, 以及具有XtraDB的Percona服务...

    InnoDB 中文参考手册

    MySQL 的企业级解决方案,高实用性以及强健的数据完整性 MySQL 事务,行级锁定,热备份以及外键支持 - - 无需损失 MySQL 的高速性能 ...InnoDB 是 MySQL 上第一个提供外键约束(FOREIGN KEY constraints)的表引擎。

    mysql 5.7 Percona Server

    Percona Server为 MySQL 数据库服务器进行了改进,在功能和性能上较 MySQL 有着很显著的提升。该版本提升了在高负载情况下的 InnoDB 的性能

    InnoDB官方文档中文翻译版

    InnoDB官方文档中文翻译版 InnoDB官方文档中文翻译版 InnoDB官方文档中文翻译版

    percona-xtrabackup-80-8.0.11-1.el7.x86_64.rpm

     Xtrabackup是一个对InnoDB做数据备份的工具,支持在线热备份(备份时不影响数据读写),是商业备份工具InnoDB Hotbackup的一个很好的替代品。  Xtrabackup有两个主要的工具:xtrabackup、innobackupex  1、...

    InnoDB存储引擎中有页(Page)的概念

    系统从磁盘读取数据到内存时是以磁盘块(block)为基本单位的,位于同一个磁盘块中的数据会被一次性读取出来,而不是需要什么取什么。 InnoDB存储引擎中有页(Page)的概念,页是其磁盘管理的最小单位。InnoDB存储...

    InnoDB 中文参考手册(CHM)

    InnoDB 中文参考手册

    InnoDB的关键特性-插入缓存,两次写,自适应hash索引详解

    InnoDB存储引擎的关键特性包括插入缓冲、两次写(double write)、自适应哈希索引(adaptive hash index)。这些特性为InnoDB存储引擎带来了更好的性能和更高的可靠性。 插入缓冲 插入缓冲是InnoDB存储引擎关键特性...

    MySQL数据库InnoDB数据恢复工具的使用小结详解

    本文从实际使用经验出发,介绍一款开源的MySQL数据库InnoDB数据恢复工具:innodb-tools,它通过从原始数据文件中提取表的行记录,实现从丢失的或者被毁坏的MySQL表中恢复数据。例如,当你不小心执行DROP TABLE、...

    InnoDB中文参考手册

    InnoDB 是 MySQL 上第一个提供外键约束(FOREIGN KEY constraints)的表引擎。 InnoDB 的设计目标是处理大容量数据库系统,它的 CPU 利用率是其它基于磁盘的关系数据库引擎所不能比的。 在技术上,InnoDB 是一套放在...

    percona-xtrabackup-24-2.4.20-1.el7.x86_64.rpm

     Xtrabackup是一个对InnoDB做数据备份的工具,支持在线热备份(备份时不影响数据读写),是商业备份工具InnoDB Hotbackup的一个很好的替代品。  Xtrabackup有两个主要的工具:xtrabackup、innobackupex  1、...

    MySQL技术内幕 InnoDB存储引擎.pdf

    6.3 InnoDB存储引擎中的锁 6.4 锁的算法 6.5 锁问题 6.6 阻塞 6.7 死锁 6.8 锁升级 7. 事务 7.1 概述 7.2 事务的实现 7.3 事务控制语句 7.4 隐式提交的SQL语句 7.5 不好的事务习惯 8 备份与恢复 8.1 ...

    MyISAM InnoDB 区别

     6、如果和MyISAM比insert写操作的话,Innodb还达不到MyISAM的写性能,如果是针对基于索引的update操作,虽然MyISAM可能会逊色Innodb,但是那么高并发的写,从库能否追的上也是一个问题,还不如通过多实例分库分表...

    MySQL体系结构及原理(innodb)图文完美解析

    MySQL体系结构及原理(innodb)图文完美解析

    MySQL Innodb 索引原理详解

    MySQL Innodb 索引原理详解

    MySQL Innodb锁解决并发问题

    MySQL Innodb锁解决并发问题.pdf

Global site tag (gtag.js) - Google Analytics