若是咱们须要挖掘正式生产环境上MySQL数据库服务的性能潜力,那么对MySQL数据库服务中的默认参数进行更改就是必需要作的事情。linux
在进行配置修改以前,咱们能够先看看当前MySQL数据库特别是InnoDB引擎的工做状态:算法
# 经过执行如下命令,咱们能够查看当前InnoDB引擎的工做状态
show engine innodb status;数据库
执行后能够获得相似以下的执行结果:服务器
innodb_log_file_size:单个日志文件的大小不宜太小,例如设置为500MB。因为InnoBD引擎对日志文件采用顺序写的操做方式,因此没必要担忧日志文件的操做消耗比数据文件操做更多的性能。dom
innodb_log_files_in_group:该参数控制了文件组中日志文件的总数。设置为2-5的范围都不会有太大影响。更重要的是读者应该清楚innodb_log_file_size * innodb_log_files_in_group就是InnoDB引擎在磁盘上可用日志空间的总大小。性能
innodb_log_buffer_size:这个参数决定了InnoDB引擎可以使用的日志内存空间。只要没有相似插入blob类型数据的操做(也不建议有这样的操做),这个内存空间都不须要设置得太大。5MB-10MB是一个推荐的设置值,不过这个参数仍是要和innodb_flush_log_at_trx_commit参数配合使用。测试
innodb_flush_log_at_trx_commit:该参数决定了InnoDB完成一个事务日志操做后,向磁盘进行持久化的写入策略。建议设置为2。spa
innodb_flush_log_at_trx_commit = 0时,InnoDB将按照1秒钟为单位向磁盘写入这个阶段全部已完成的事务日志信息。这时innodb_log_buffer_size的值就不能太小,由于在一个同步周期内若是待刷新的日志超过了innodb_log_buffer_size设置的大小,InnoDB就会强制执行同步操做。这里的写入成功并非说写入到Linux操做系统的Page Cache中就算成功,而是须要等待操做系统真正写到了物理磁盘上的通知。这意味着即便InnoDB Buffer Pool中的数据操做是成功的,可是一旦数据库系统异常崩溃,那么业务系统将会丢失前1秒内写入的数据:由于没有磁盘介质上的日志就没法在异常重启后恢复数据信息。操作系统
innodb_flush_log_at_trx_commit = 1时,InnoDB按照完成一个日志操做就向磁盘写入日志信息的方式来工做(执行一个事务就写入一个事务日志)。一样,这里的写入成功一样是要等待操做系统返回真正写入了物理磁盘的通知,能够打比方理解为BIO。.net
innodb_flush_log_at_trx_commit = 2时,InnoDB按照完成一个日志操做就向磁盘写入日志信息的方式来工做。可是,这种工做模式下InnoDB不会等待操做系统返回物理磁盘上写入成功的通知,就会继续工做,能够理解为NIO或MMF。实际上这个时候,数据通常还存在于Linux操做系统的cache memory区块中,因此这种模式下最好使用带有日志功能的文件系统,而且确认开启了文件系统的日志功能。
innodb_buffer_pool_size:这个参数调整分配给InnoDB引擎使用的可用数据内存区域的大小。实际上这个数据区域不止包括了本文中一直强调的Page Cache区域,它还有不少数据区域。例如InnoDB中用来进行查询排序的Sort Buffer区域。建议的设置大小是MySQL数据库所在服务器上物理总内存的60%——80%(文件系统的Cache Memory/Buffer Memory等其它程序还要使用)。8GB的物理服务器可设置6GB的InnoDB Buffer Pool可用内存区域。注意,当MySQL数据库启动时并非马上就会占据全部数据区域。
innodb_buffer_pool_instances:咱们常常说起到innodb_buffer_pool_size参数以及它的含义,这个参数值在生产环境下通常设置得都比较大(例如4GB、8GB、12GB、24GB等等)。可是因为脏数据刷盘的周期性,在I/O性能强劲的物理机器上可能就会存在I/O间歇性低谷,为了将I/O操做一直保持在必定的工做效能上,也为了发挥CPU的计算性能,InnoDB引擎容许将innodb_buffer_pool划分为多个独立的运行实例,当InnoDB须要读取新的Page时,它们会按照必定的算法被分配到某个独立运行的buffer pool instance中。这些buffer pool instance有各自独立的LRU算法队列、独立计算脏页比例,而且独立进行脏页刷新。innodb_buffer_pool_instances参数在具备较高I/O性能而且具备较大innodb_buffer_pool_size设定值的物理设备上可以对I/O性能产生很是明显的影响。若是您采用的是固态磁盘或者磁盘阵列做为MySQL服务器的硬件层存储介质,那么建议1-2GB的innodb_buffer_pool就分配一个独立的运行实例(这样算下来12GB的buffer pool能够设置6-12个运行实例)。但若是您只是使用的机械磁盘又或者innodb_buffer_pool_size的值并不大,那么将innodb_buffer_pool_instances参数设置为1就能够了。实例个数没有绝对值,须要根据测试状况而定。
innodb_io_capacity:该参数控制着InnoDB Buffer Pool数据内存区域进行磁盘同步时每次能够同步的脏页数量。在磁盘I/O性能不足时,若是innodb_io_capacity参数值过大就会形成I/O阻塞,而且形成InnoDB引擎性能较大的下降。但若是您使用的是固态硬盘或者RAID磁盘阵列,就能够将innodb_io_capacity参数默认的200设置大一些,例如设置成500——800)。
innodb_adaptive_flushing:该参数必定要打开,on,保证脏页的同步周期由InnoDB引擎根据实时I/O性能状况自行控制同步频率(实际上只有两种频率:1秒或者10秒)。
innodb_max_dirty_pages_pct:该参数默认为75,通常状况下无需更改。
innodb_io_capacity_max:表示当脏页数量在InnoDB Buffer Pool内存中的比例超过了innodb_max_dirty_pages_pct参数设置的上限后,就按照innodb_io_capacity_max设置的脏页数量强制进行脏页的刷新(建议采用默认值便可)。
可是设想一下这个问题:什么状况下最可能使脏页在内存中的占比超过上限呢?固然是InnoDB引擎的事务不断快速执行,而且I/O性能又不足以快速完成同步。这时InnoDB引擎将中止事务的执行,而且进行强制刷新。因此,当问题真正发生时innodb_io_capacity_max参数设置得再大也不可能解决I/O拥堵的问题,反而可能使问题更严重。
innodb_page_size:该参数决定了InnoDB引擎中每一页的大小。每个page包含多条row数据,更大的page size意味着内存中存储的每页信息有更多的数据条数。因为文件系统和底层硬件设置的结构,因此该值都为4KB的整数倍(默认值为16KB,可选值为4KB、8KB、16KB)。注意若是您须要更改这个参数值,那么就必须在MySQL数据库初始化启动时,就加入到my.cnf配置文件中。不然一旦建立了用户数据表,再对这个参数进行修改,MySQL数据库就会报错。
innodb_read_io_threads:该参数设置InnoDB数据库中的负责从磁盘上读取数据的线程数量,另外这些线程还负责在预读选项开启时承担起预读的工做任务。innodb_read_io_threads的建议值为CPU的内核数量。
innodb_write_io_threads:该参数设置InnoDB数据库中负责将脏页同步到磁盘上的线程数量。innodb_write_io_threads的建议值为CPU的内核数量。
innodb_read_ahead_threshold:该参数表示InnoDB引擎中的顺序预读阀值。在buffer pool中的page也有一个组织结构:64个page组成一个extent结构。当InnoDB发如今一个extent结构中**已经连续读取**N个page,那么InnoDB会接着将另外64 - N个后续的page读入到buffer pool中。顺序预读在“连续读”性能较高的硬件设备上,对性能的影响很是小。因此若是读者使用了I/O性能比较强劲的固态磁盘环境或者磁盘阵列环境,则建议直接关闭该功能(设置为0便可)。
innodb_random_read_ahead:该参数表示是否开启随机预读,默认是关闭的。
innodb_flush_neighbors:既然InnoDB引擎提供Page的预读功能,固然就提供预写功能。该参数表示当Buffer Pool中的脏页被同步到磁盘时,是否一块儿刷新和这个脏页临近的页信息。该参数在I/O性能比较强劲的固态磁盘环境或者磁盘阵列环境下,对性能提高并不明显。因此建议在这样的状况下直接关闭这个功能(设置为0便可)。
sort_buffer_size:该参数对数据库引擎的查询性能,特别是有对结果进行排序要求的查询性能影响很是大。
join_buffer_size:该参数对数据库引擎的查询性能,特别是有各类join链接要求的查询性能影响很是大。
binlog_cache_size:在MySQL数据库中处理InnoDB层存在“重作日志”之外,在数据库管理层还有一个独立工做的二进制日志模块。这个日志模块的工做方式和“重作日志”的工做方式类似,它们采用的办法都是在内存中进行日志数据变动,而后再按照必定的策略周期性/直接同步到磁盘上。binlog_cache_size参数设置的就是可供二进制日志在内存中进行暂存的空间大小。须要注意的是:binlog_cache_size和innodb_buffer_pool_size不一样的是,binlog_cache_size的大小以MySQL数据库的客户端链接为单位。也就是说MySQL数据库会为两个独立的数据库客户端链接分别分配独立运行的binlog cache空间。正式环境的数据库中为每个数据库链接设置的binlog cache空间不须要太大,固然这还要考虑实际的客户端请求频度和数据类型,还要考虑下面将介绍的sync_binlog参数设定。该参数建议的几个设置值为:32768(32KB为默认值,没有特别的要求能够保留该设置)、65536(64KB)、131072(128KB)、262144(KB)、524288(512KB)、1048576(1MB)之内。
sync_binlog:在MySQL数据库中除了InnoDB的“重作日志”须要同步之外,二进制日志也须要进行同步。这个参数是指MySQL数据库在内存中进行X次二进制日志操做后,就将内存中的二进制日志同步到磁盘中。
如下是一组能够在配置有固态硬盘和磁盘阵列的正式MySQL数据库环境下使用的配置项参考,主要是为读者总结InnoDB引擎中与I/O性能相关的重要参数。读者在进行参数配置时,仍须要按照本身团队的生产环境状况,对配置项进行调整(这些参数信息都在MySQL数据库的my.cnf主配置文件中进行设置)。
# 设置单个日志文件的大小为500MB
innodb_log_file_size = 524288000
# 设置日志文件组中有两个日志文件
innodb_log_files_in_group = 2
# 设置日志内存区域为10MB
innodb_log_buffer_size = 10485760
# 设置日志数据同步策略为“2”
innodb_flush_log_at_trx_commit = 2
# 设置buffer pool的大小为8GB
innodb_buffer_pool_size = 8G
# 设置正常状况下每一次脏页到磁盘的同步数量为800个
# (固然读者要肯定磁盘I/O性可以用,不然改大这个值有害无益)
innodb_io_capacity = 800
# 打开InnoDB提供的自监控频率
innodb_adaptive_flushing = on
# 脏页强制刷新策略
innodb_max_dirty_pages_pct = 75
innodb_io_capacity_max = 2000
# 设置InnoDB的buffer pool区域一共有8个独立运行的实例
innodb_buffer_pool_instances = 8
# 设置每个数据页“page”的大小为16KB。为4KB的整数倍
innodb_page_size = 16384
# 设置每次二进制日志操做都提交到文件系统的Cache中
sync_binlog = 0
# 也可设置二进制日志在内存区域每操做1000次后,就进行磁盘同步
#sync_binlog = 1000
# 关闭顺序预读
# 使用了I/O性能比较强劲的固态磁盘环境或者磁盘阵列环境,则建议直接关闭该功能
innodb_read_ahead_threshold = 0
# 关闭随机读
innodb_random_read_ahead = off
# 关闭临近写
# 使用了I/O性能比较强劲的固态磁盘环境或者磁盘阵列环境,则建议直接关闭该功能
innodb_flush_neighbors = 0
配置完成后,能够经过如下命令查看当前MySQL数据库和InnoDB引擎中相关的配置参数(为节约篇幅,已省去一部分查询结果):