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

关于InnoDB中buf_page_is_corrupted的优化

阅读更多

函数buf_page_is_corrupted (innodb_plugin/buf/buf0buf.c)这个函数,是在InnoDB中获取page数据后,对page作校验,判断内容是否损坏。

在压力测试中发现,innodb.so最耗费cpu的就是这个buf_page_is_corrupted

       Percona对这个函数作了优化。本文介绍与此有关的配置、优化原理以及进一步的优化空间。(当前版本5.1.48 innodb-plugin 1.0.9)

1、函数主流程

每个page头部的前四个字节是本pagechecksum page写入时计算得到。因此函数主流程如下:

a)        读前四个字节得到checksum_field

b)        page重新计算checksum, buf_calc_page_new_checksum(read_buf)

c)        ab的结果相同则认为page未损坏。

 

2、              函数瓶颈

              显然函数主要计算时间在buf_calc_page_new_checksum中,后者直接调用ut_fold_binary(实现位置 ./include/ut0rnd.ic)。我们来看这个ut_fold_binary的函数实现:

UNIV_INLINE
ulint
ut_fold_binary(
/*===========*/
        const byte*     str,    /*!< in: string of bytes */
        ulint           len)    /*!< in: length */
{
        const byte*     str_end = str + len;
        ulint           fold = 0;
        ut_ad(str || !len);
        while (str < str_end) {
                fold = ut_fold_ulint_pair(fold, (ulint)(*str));
                str++;
        }   
        return(fold);
}

  

 

 

说明:其中ut_fold_ulint_pair的第二个参数表明,在该函数中,是以一个uint方式使用的(如下)。该函数在同一个文件中,通过两个uint的异或和移位得到返回值。但在第13行中的str++ 使得每个字节都被使用了4次。

ut_fold_ulint_pair(
/*===============*/
        ulint   n1,     /*!< in: ulint */
        ulint   n2)     /*!< in: ulint */
{
        return(((((n1 ^ n2 ^ UT_HASH_RANDOM_MASK2) << 8) + n1)
                ^ UT_HASH_RANDOM_MASK) + n2);
}

 

 

      

3、              优化

Percona版本的改进中,将实现了一个新的函数ut_fold_ulint_pair_32, 将步进修改为4个字节。

实际上,将16k数据签名成4个字节,使用前后两种方法的信息损失是相同的,因此优化版本概率上并不损失准确性。

 

64位机器上,若每次直接取两个unsigned longut_fold_ulint_pair操作(当然需要为此写一个ut_fold_ulint_pair_64函数),计算速度相同,但步进长度加倍,能够进一步优化此函数性能。

代码上需要作如下修改

a)        ./include/ut0rnd.ic ./include/ut0rnd.h 中增加ut_fold_binary_64的定义和声明

b)        buf/buf0buf.c中增加buf_calc_page_new_checksum_64, 并在buf_page_is_corrupted增加调用

c)        buf_flush_init_for_writing(buf/buf0flu.c)中,写入page前换用buf_calc_page_new_checksum_64得到checksum

 

4、              测试结果

sysbench作压力,并计算三种buf_calc_page_new_checksum的平均执行时间。得益于神器SystemTap,不需要再另外统计时间的代码(痛苦回忆中)

函数

平均执行时间

buf_calc_page_new_checksum

65ms

buf_calc_page_new_checksum_32

24ms

buf_calc_page_new_checksum_64

16ms

             

1
0
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics