MySQL有大量能够修改的参数--但不该该随便去修改。一般只须要把基本的项配置正确(大部分状况下只有不多一些参数是真正重要的),应该将更多的时间花在schema的优化、索引,以及查询设计上。在正确地配置了MySQL的基本配置项以后,再花力气去修改其它配置项的收益一般就比较小了。web
1.建立MySQL配置文件算法
建议不要使用操做系统的安装包自带的配置文件,最好从头开始建立一个配置文件。(首先要肯定MySQL使用了哪一个配置文件!)数据库
2.InnoDB缓冲池(Buffer Pool)缓存
有一个流行的经验法则说,应该把缓冲池大小设置为服务器内存的约75~80%,但并不老是正确的。有一个更好的办法来设置缓冲池大小,大体以下:安全
一、从服务器内存总量开始服务器
二、减去操做系统的内存占用数据结构
三、减去一些MySQL自身须要的内存并发
四、减去足够让操做系统缓存InnoDB日志文件的内存,至少是足够缓存最近常常访问的部分。svg
五、减去其余配置的MySQL缓冲和缓存须要的内存,例如查询缓存,MYISAM键缓存
六、除以105%,把结果向下取一个合理的数值。
若是大部分都是InnoDB表,InnoDB缓冲池或许比其余任何东西更须要内存。InnoDB缓冲池并不只仅缓存索引:它还缓存行的数据、自适应哈希索引、插入缓存(Insert buffer)、锁、以及其余内部数据结构。InnoDB还使用缓冲池来帮助延迟写入,这样就能合并多个写入操做,而后一块儿顺序地写回。总之InnoDB严重依赖缓冲池,你必须确认为它分配了足够的内存。
若是数据量不大,而且不会快速增加,就不必为缓冲池分配过多的内存。把缓冲池配置得比须要缓存的表和索引还要大不少实际上没有什么意义。固然,对一个迅速增加的数据库作超前的规划没有问题,但有时咱们也会看到一个巨大的缓冲池只缓存了一点点数据,这就没有必要了。
很大的缓冲池也会带一些挑战,例如,预热和关闭都会花费很长的时间。若是有不少脏页在缓冲池里,InnoDB关闭时可能会花费较长的时间把脏页写回数据文件。固然也能够强制快速关闭,可是重启时就必须作更多的恢复工做。
当脏页的百分比超过了innodb_max_dirty_pages_pct阈值,InnoDB将快速地刷写脏页,尝试让脏页的数量更低。当事务日志没有足够的空间剩余时,InnoDB将进入“激烈刷写”模式,这就是大日志能够提高性能的一个缘由。
若是不能快速预热,能够在重启后当即进行全表扫描或者索引扫描,把索引载入缓冲池。也可使用init_file设置,把SQL放在一个文件里,而后当MySQL启动的时候来执行。
3.线程缓存
线程缓存保存那些当前没有与链接关联可是为后面新的链接服务的线程。当一个新的链接建立时,若是缓存中有线程存在,MySQL从缓存中删除一个线程,而且把它分配给这个新的链接。当链接关闭时,若是线程缓存还有空间的话,MySQL又会把线程放回缓存。若是没有空间的话,MySQL会销毁这个线程。只要MySQL在缓存里还有空闲的线程,它就能够迅速地响应链接请求,由于这样就不用为每一个链接建立新的线程。
一个好的办法是观察Threads_connected变量而且尝试设置thread_cache_size足够大以便能处理业务压力正常的波动。每一个在线程缓存中的线程或者休眠状态的线程,一般使用256K左右的内存。相对于正在处理查询的线程来讲,这个内存不算很大。
4.表缓存
表缓存能够重用资源。当一个查询请求访问一张MYISAM表,MySQL能够从缓存的对象中获取到文件描述符,避免打开一个文件描述符的开销。对MYISAM表来讲,表缓存的真正好处是可让服务器避免修改MYISAM文件头来标记表“正在使用中”,表缓存对于InnoDB重要性就小得多,由于InnoDB不依赖它来作那么多事,例如持有文件描述符等。
5.InnoDB I/O配置(事务日志)
InnoDB使用日志来减小提交事务时的开销。由于日志中已经记录了事务,就无须在每一个事务提交时把缓冲池的脏块刷新(flush)到磁盘中。事务修改的数据和索引一般会映射到表空间的随机位置,因此刷新这些变动到磁盘须要不少随机IO。InnoDB假设使用常规磁盘,随机IO比顺序IO昂贵得多,由于一个IO请求须要时间把磁头移到正确的位置,而后等待磁盘上读出须要的部分,再转到开始位置。
InnoDB用日志把随机IO变成顺序IO。一旦日志安全写到磁盘,事务就持久化了,即便断电了,InnoDB能够重放日志而且恢复已经提交的事务。
InnoDB使用一个后台线程智能地刷新这些变动到数据文件。这个线程能够批量组合写入,使得数据写入更顺序,以提升效率。
总体的日志文件大小受控于innodb_log_file_size和innodb_log_files_in_group两个参数,这对写性能很是重要。日志文件的总大小是每一个文件的大小之和。
InnoDB使用多个文件做为一组循环日志。一般不须要修改默认的日志数量,只修改每一个日志文件的大小便可。要修改日志文件大小,须要彻底关闭MySQL,将旧的日志文件移到其余地方保存,从新配置参数。
要肯定理想的日志文件大小,必须权衡正常数据变动的开销和崩溃恢复须要的时间,若是日志过小,InnoDB必然将作更多的检查点,致使更多的日志写。若是日志太大,在崩溃恢复时InnoDB可能不得不作大量的工做。
当InnoDB变动任何数据时,会写一条变动记录到内存日志缓冲区中。在缓冲满的时候,事务提交的时候,或者每一秒钟,这三个条件不管哪一个先达到,InnoDB都会刷新缓冲区的内容到磁盘日志文件。变量innodb_log_buffer_size能够控制日志缓冲区的大小,默认为1M。一般不须要把日志缓冲区设置得很是大。推荐的范围是1~8M。做为一个经验法则,日志文件的所有大小,应该足够容纳服务器一个小时的活动内容。
InnoDB怎么刷新日志缓冲?当InnoDB把日志缓冲刷新到磁盘日志文件时,会先使用一个Mutex锁住缓冲区,刷新到所须要的位置,而后移动剩下的条目到缓冲区的前面。日志缓冲必须被刷新到持久化存储,以确保提交的事务彻底被持久化了。若是和持久相比更在意性能,能够修改innodb_flush_log_at_trx_commit变量来控制日志缓冲刷新的频繁程度。可能的设置以下:
0:每秒一次把日志缓冲写到日志文件,可是事务提交时不作任什么时候。
1:将日志缓冲写到日志文件,而后每次事务提交都刷新到持久化存储(默认而且最安全的设置),该设置保证不会丢失任何已提交的事务。
2:每秒钟作一次刷新,但每次提交时把日志缓冲写到日志文件,可是不刷新到持久化存储。
“把日志缓冲写到日志文件”和“把日志刷新到持久化存储”是不一样的。在大部分操做系统中,把缓冲写到日志只是简单地把数据从InnoDB的内存缓冲转移到了操做系统的缓存,也是在内存里,并无真正把数据写到持久化存储。
若是MySQL崩溃了或者断电了,设置0和2一般会致使最多1秒的数据丢失,由于数据可能存在于操做系统的缓存中。
相反,把日志刷新到持久化存储意味着InnoDB请求操做系统把数据刷出缓存,而且确认写到磁盘了,这是一个阻塞IO的调用,直到数据被彻底写回才会完成,当写数据到磁盘比较慢,而该配置项设置为1时,可能明显地下降InnoDB每秒能够提交的事务数。
6.InnoDB并发配置
InnoDB有本身的“线程调度器”控制线程怎么进入内核访问数据,以及它们在内核中一次能够作哪些事。最基本的限制并发方式是使用innodb_thread_concurrency变量,它会限制一次性能够有多少线程进入内核,0表示不限制。
理论上,能够参考下面的公式:并发值=CPU数量*磁盘数量*2
另外,也能够经过线程池(Thread Pool)来限制并发。
7.优化排序(Filesorts)
若是查询中全部须要的列和order by的列总大小超过max_length_for_sort_data字节,则采用two-pass算法,不然采用single-pass算法。
8.其余配置项
1.max_connections:这个设置的做用就像一个紧急刹车,以保证服务器不会因应用程序激增的链接而不堪重负。若是应用程序有问题,或者服务器遇到如链接延迟的问题,会建立不少新链接,可是若是不能执行查询,那打开一个链接没有好处,因此被“太多的链接”的错误拒绝是一种快速而代价小的失败方式。
要时时当心可能遇到链接限制的忽然袭击。例如,若重启应用服务器,可能没有把它的链接关闭干净,同时MySQL可能没有意识到它们已经被关闭了。当应用服务器从新开始运行,并试图打开到数据库的链接,就可能因为挂起的链接尚未超时,致使新链接被拒绝。观察max_used_connections状态变量随着时间的变化,若是这个值达到了max_connections,说明客户端至少被拒绝了一次。
2.thread_cahce_size:观察Threads_connected状态变量而且找到它在通常状况下的最大值和最小值。能够设置为波动范围2~3倍大小。可是也不用设置得很是大,由于保持大量等待链接的空闲线程并无什么真正的用处。
也能够观察threads_created状态随时间的变化,若是这个值很大或者一直增加,这可能在告诉你,须要调大thread_cahce_size变量。查看threads_cached来看有多少线程已经在缓存中了。
另外一个相关的状态变量是slow_launch_threads。这个状态若是很大,那么意味着某些状况延迟了链接分配新线程。通常来讲多是系统过载了,致使操做系统不能为新建立的线程调度CPU。
总之,若是使用的是InnoDB,最重要的配置项是如下两个:innodb_buffer_pool_size和innodb_log_file_size