函数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头部的前四个字节是本page的checksum, 在page写入时计算得到。因此函数主流程如下:
a) 读前四个字节得到checksum_field
b) 对page重新计算checksum, buf_calc_page_new_checksum(read_buf)
c) 若a、b的结果相同则认为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 long作ut_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
|
分享到:
相关推荐
py_innodb_page_info工具为《INNODB存储引擎》作者姜承尧写的。 该工具用来分析表空间中的各页得类型和信息,用python编写。 网上多是python2版本的,这里给出python3版本的。
《mysql技术内幕-InnoDB存储引擎》中使用的页分析工具类py_innodb_page_info
使用py_innodb_page_info 查看分析各种log以及data file,深入研究mysql的存储引擎底层原理与实现。 mysql innodb undo redo
使用py_innodb_page_info 查看分析各种log以及data file,深入研究mysql的存储引擎底层原理与实现
在测试环境下没有设置过多的详细参数就初始化并启动了服务,后期优化的过程中发现innodb_data_file_path设置过小: root@node1 14:59: [(none)]> show variables like '%innodb_data_file_path%'; +
InnoDB存储引擎中默认每个页的大小为16KB,可通过参数innodb_page_size将页的大小设置为4K、8K、16K,在MySQL中可通过如下命令查看页的大小: mysql> show variables like 'innodb_page_size'; 而系统一个磁盘块的...
在innodb存储引擎中数据访问以page为单位,page也是innodb管理数据库的最小磁盘单位,每个page的默认大小为16KB(可以通过参数innodb_page_size进行调整,在5.7增加了对32KB和64KB的大小支持,在此之前的版本支持4KB,...
主要介绍了使用innodb_force_recovery解决MySQL崩溃无法重启问题,这只一个成功案例,并不是万能的解决方法,需要酌情考虑,需要的朋友可以参考下
MySQL Innodb 参数详解与优化实践
内容包括: 1.MySQL的Innodb引擎配置 1.如何配置MySQL服务器的最大连接数量 2.如何配置innodb_open_files,table_open_cache,innodb_file_io_threads和innodb_buffer_pool_size,innodb_log_file_size
MyISAM可以在默认的 key_buffer_size 设置下运行的可以,然而Innodb在默认的 innodb_buffer_pool_size 设置下却跟
mysql 5.6 新特性 innodb
mysql 存储引擎 innodb 日志结构 非常好用,欢迎大家下载!
innodb_autoinc_lock_mode这个参数控制着在向有auto_increment 列的表插入数据时,相关锁的行为; 通过对它的设置可以达到性能与安全(主从的数据一致性)的平衡 【0】我们先对insert做一下分类 首先insert大致上可以...
如果你的服务器的CPU或者IO使用接受饱和,特别是偶尔出现峰值,这时候系统想在超载时能正常处理查询,那么强烈建议关注innodb_thread_concurrency
4> innodb_data_home_dir = /usr/local/mysql/var/存放innodb表引擎表空间的地方 5> innodb_data_file_path = ibdata1:10M:autoextend表空间的名字以8M增长,可以将其大小修改:例如50M 6> innodb_log_group_home_...
innodb 存储引擎性能优化,mysql 5.6
MySQL技术InnoDB存储引擎_姜承尧_第2版