MySQL源码之innodb_io_capacity

背景

这段时间公司新来了一个校招的小姐姐,来了之后一直在熟悉压测相关的,
经过了一段时间的压测,今天给我们做了一个分享,讲的确实挺好,挺全面,
参数啊结果都讲的挺不错的,但是,问题他这就来了:
在展示压测关于innodb_io_capacity参数值压测的时候,我人呆住了,
不论innodb_io_capacity的值变化多少,相同线程数量下,qps都是几乎完全相同的。
??????这就是我脑子当时的反应
没有任何变化,这一下子让我觉得不太可能,有问题
简单了解之后,压测的那台机器上数据库buffer_pool有300多g,机器总内存
500g,妥妥的高配机器
在这里插入图片描述
我最初的猜想就是buffer_pool太大,根本没有触发刷脏,所以导致innodb_io_capacity
参数根本就没有发挥作用。
带着这一系列的问题,就去查看了源码,好在源码这部分还算简单,搜索了一下主要和下面三个函数
有关系。

源码

一下源码中文注释都是我加上的有关于源码的英文注释翻译,
也有自己的理解注释,便于大家理解,其他都是源码内容并未改变
源码版本:5.7.33

源码位置:storage/innobase/srv/srv0srv.cc
内容:相关的定义

/*innodb主线程控制保持缓冲池中的脏页比例低于下列的值,但是在剧烈的高负载
更新插入下不一定能保持缓冲池中的脏页比例低于下列的值*/

/*
刷脏页的高水位,脏页比例到达该值回进行剧烈刷脏
相当于数据库中innodb_max_dirty_pages_pct参数,默认为75,单位百分比
*/
double	srv_max_buf_pool_modified_pct	= 75.0;   

/*刷脏页的低水位,该值开启之后会进行缓慢刷脏
相当于innodb_max_dirty_pages_pct_lwm 默认是0不开启*/
double	srv_max_dirty_pages_pct_lwm	= 0.0;      
源码位置: storage/innobase/buf/buf0flu.cc
函数作用:该函数就是计算根据脏页的数量判断是否需要进行刷脏
返回需要使用到innodb_io_capacity的多少(百分比),也就是需要多少io
能力去处理刷脏
/*********************************************************************//**
Calculates if flushing is required based on number of dirty pages in
the buffer pool.
@return percent of io_capacity to flush to manage dirty page ratio */
/**/
static
ulint
af_get_pct_for_dirty()
/*==================*/
{
	double	dirty_pct = buf_get_modified_ratio_pct();//获得当前buffer pool的脏页比例
	
	//如果脏页比例为0,说明没有操作,不进行任何刷脏
	if (dirty_pct == 0.0) { 
		/*不做任何修改,返回0,也就是innodb_io_capacity百分比为0 */
		return(0);
	}
    
    //低水位的参数是不是小于等于高水位的参数值
	ut_a(srv_max_dirty_pages_pct_lwm
	     <= srv_max_buf_pool_modified_pct);

    /*判断脏页低水位参数lwm是不是不开启*/
	if (srv_max_dirty_pages_pct_lwm == 0) {
		/*如果脏页低水位参数lwm不开启的话,脏页比例大于等于高水位参数 */
		if (dirty_pct >= srv_max_buf_pool_modified_pct) {
	//如果上面两个条件都满足了,返回100,也就是使用innodb_io_capacity 100%的能力进行刷脏
			return(100);
		}
	}
	/* 如果脏页低水位参数lwm开启了,即不为0的情况下,脏页大于低水位的参数之后,
	  开始进行缓慢逐步刷脏*/
	else if (dirty_pct >= srv_max_dirty_pages_pct_lwm) {
		/*
		这时候取innodb_io_capacity(dirty_pct * 100)/ (srv_max_buf_pool_modified_pct + 1)
		这个值去计算
		比如脏页现在占缓冲池30%,那么应该取(30*100)/(75+1)=39.473,再强转换为int为39
		所以这里将取(innodb_io_capacity*39)的值的能力去进行刷脏
		*/
		return(static_cast<ulint>((dirty_pct * 100)
		       / (srv_max_buf_pool_modified_pct + 1)));
	}
	
	//如果以上都不满足,那么返回0%,即不刷脏,也就不会使用到innodb_io_capacity的能力
	return(0);
}

总结

所以到这里差不多就懂了,因为缓冲池太大,再加上对应两个值都是默认值如下:
在这里插入图片描述

所以根本触发不到innodb_io_capacity刷脏能力,所以不管改多少,对数据库进行压测都是
没有作用,应该调整低水位参数以及将buffer_pool改小一点。

#写在最后
如果还想了解更深的朋友还可以查看以下源码:

代码位置:storage/innobase/buf/buf0flu.cc
函数名称:page_cleaner_flush_pages_recommendation
函数作用:mysql又一个专门的后台线程处理刷脏,叫做page_cleaner线程,
该函数是根据上边拿到的innodb_io_capacity值去进行清理,整理一些free list。
代码位置:storage/innobase/buf/buf0flu.cc
函数名称:af_get_pct_for_lsn
函数作用:返回刷新redo log的时候需要的io能力
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

渔不是鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值