原文地址:Mysql配置参数innodb_buffer_pool_size的学习与整理html
这半个月来,一直在作一些关于服务器交易端性能的提高工做,主要是分析和讨论交易端性能的瓶颈,找出致使性能减慢的缘由,拟定出合理的解决方案,主要是经过几个方面进行研究和学习,今天总算有了一点点突破,主要是涉及mysql核心参数innodb_buffer_pool_size的学习和讨论,这里简单的整理和总结一下。
mysql
首先简单的介绍一下服务器交易端的环境,使用的是Spring + MyBatis + Mysql的架构,代码中使用了Spring声明式事务进行管理,性能的瓶颈主要是存在于事务提交上面,经过测试和分析日志,发现代码在进行事务提交时耗时比较严重,这半个月的研究也走了许多弯路,总算有得有失,对于其中的一些知识也有了必定的理解,主要是包含下面几个方面:
MyBatis
sql
第一点想到的可能缘由是MyBatis对Connection的管理,因为对MyBatis的理解不深刻,简单的分析日志,发现MyBatis日志中出现大量的create SqlSession,因而简单的研究了一下MyBatis SqlSession,这里有一篇总结的文章:关于MyBatis sqlSession的一点整理
数据库
经过研究讨论和查阅源码,对MyBatis SqlSession有了必定的理解,发现问题可能再也不这里。
缓存
Mysql
服务器
Mysql的配置是怀疑致使性能瓶颈的缘由,不过没有证据证实,同事提到了thread_concurrency参数,因而开始了mysql配置参数的学习,可是mysql的配置参数不少,短期内没法作到面面俱到,因而经过分析线上运行的mysql的配置文件进行学习,这里也整理出了几篇文章:mysql优化
关于Mysql thread_concurrency和innodb_thread_concurrency参数的一点整理
架构
经过对线上mysql一些配置参数的学习和讨论,感受这些所了解到的参数的配置较为合理,因而研究的重心发生了偏移,转向了Spring事务管理机制的研究。
Spring
Spring的事务管理机制,本身的理解也不清晰,对于源码也没有过认真的研读,因而花费了点时间对Spring Transaction事务管理机制和MyBatis SqlSession进行了再次的学习和研究讨论,也算有了一点点收获,期间也作了总结和整理,并根据本身的理解作了时序图,详情见这里:Spring Transaction + MyBatis SqlSession事务管理机制研究学习
可是问题又来了,经过与同事的讨论和阅读源码,更加的迷惑了,好像性能的瓶颈也不是Spring Transaction的问题。不知道接下来该怎么突破了,一次偶然的与同事交流,出现了起色,在本机进行测试时,发现我本机的性能要明显优于同事的电脑,那么问题来了,是什么致使了性能的差别?
首先是硬件的不一样,虽然内存一致,可是CPU版本却彻底不一样,CPU的差别是致使性能的一部分缘由,这是第一个突破点;其次是本地mysql配置的不一样,发现我本地使用的是mysql默认生成的配置,同事本地使用的是服务器上的mysql配置,第二个突破点就是mysql配置的差别,主要是参数的不一样,因而重心又转移到了mysql配置文件的研究学习讨论上面。
Mysql
中间出现的曲折就不说了,说多了都是泪,结果反复的测试,发如今增大或减少一个参数的值时,性能差别明显,通过与同事讨论和测试,发现这个参数在高并发高I/O时正确的配置很是重要,可能带来很大的性能提高,这个参数就是innodb_buffer_pool_size,下面,就来详细的学习和整理一下这个参数的意义。
innodb_buffer_pool_size参数表示缓冲池字节大小,InnoDB缓存表和索引数据的内存区域。mysql默认的值是128M。最大值与你的CPU体系结构有关,在32位操做系统,最大值是 4294967295 (2^32-1) ,在64 位操做系统,最大值为18446744073709551615 (2^64-1)。在32位操做系统中,CPU和操做系统实用的最大大小低于设置的最大值。若是设定的缓冲池的大小大于1G,设置innodb_buffer_pool_instances的值大于1,在服务器繁忙的时候能够提升伸缩性,不过在实际的测试中,发现带来的性能提高并不明显,并且参考了这里的一篇文章mysql优化---第7篇:参数 innodb_buffer_pool_instances设置,初步设置innodb_buffer_pool_instances为1。
这个值设置的越大,在不止一次的访问相同的数据表数据时,消耗的磁盘I / O就越少。在一个专用的数据库服务器,则可能将其设置为高达80%的机器物理内存大小。不过在实际的测试中,发现无限的增大这个值,带来的性能提高也并不显著,对CPU的压力反而增大,设置合理的值才是最优。在出现如下问题时,你就须要考虑减小这个参数的值了:
物理内存的竞争可能会致使操做系统分页。
InnoDB储备额外的内存缓冲区和控制结构,以便总分配空间大于指定的大小大约是10%。
地址空间必须是连续的,在经过DLL加载特定地址的Windows系统中,这可能存在问题。
初始化缓冲池的时间大体与它的大小成正比。在大型系统中,初始化的时间可能很显著。例如:在现代化的Linux x86_64服务器上,初始化一个10GB的缓冲池大小,大约须要6秒钟。
在MySQL 5.7.5版本后,innodb_buffer_pool_size参数的值能够动态的设置,这意味着你能够在不启动服务器的状况下,从新设置缓冲区的大小。这种调整的操做是按块执行的。能够经过innodb_buffer_pool_chunk_size参数配置块的大小。Innodb_buffer_pool_resize_status状态变量记录了从调整操做的状态。
一样的,在mysql的众多参数中,关系到磁盘IO的参数还有两个,分别是:innodb_log_buffer_size和innodb_log_file_size。
innodb_log_buffer_size表示InnoDB写入到磁盘上的日志文件时使用的缓冲区的字节数,默认值为8M。一个大的日志缓冲区容许大量的事务在提交以前不写日志到磁盘。所以,若是你有不少事务的更新,插入或删除很操做,经过这个参数会大量的节省了磁盘I / O。
innodb_log_file_size表示在一个日志组每一个日志文件的字节大小。日志文件的总大小(innodb_log_file_size* innodb_log_files_in_group)不能超过最高值512GB。例如一对255 GB的日志文件,已经接近了极限,不能超过它。默认值是48M。比较合适的值的范围是从1MB到1 / N个的缓冲池大小,其中N是该组中的日志文件的数量。该值越大,缓冲池中必要的检查点刷新活动就会越少,节省磁盘I/ O。可是越大的日志文件,mysql的崩溃恢复就越慢,尽管在mysql5.5以后改进了恢复性能和日志文件恢复的代价。
上面的两个参数,并无进行mysql性能的测试,也并无特定的进行配置,下一步,会仔细的研究测试一下,敬请期待。