经过根据服务器目前情况,修改Mysql的系统参数,达到合理利用服务器现有资源,最大合理的提升MySQL性能。html
32G内存、4个CPU,每一个CPU 8核。mysql
MySQL目前安装,用的是MySQL默认的最大支持配置。拷贝的是my-huge.cnf.编码已修改成UTF-8.具体修改及安装MySQL,能够参考<<Linux系统上安装MySQL 5.5>>帮助文档。算法
打开MySQL配置文件my.cnfsql
vi /etc/my.cnf数据库 |
back_log=500缓存
back_log值指出在MySQL暂时中止回答新请求以前的短期内多少个请求能够被存在堆栈中。也就是说,若是MySql的链接数据达到max_connections时,新来的请求将会被存在堆栈中,以等待某一链接释放资源,该堆栈的数量即back_log,若是等待链接的数量超过back_log,将不被授予链接资源。将会报:unauthenticated user | xxx.xxx.xxx.xxx | NULL | Connect | NULL | login | NULL 的待链接进程时.安全 back_log值不能超过TCP/IP链接的侦听队列的大小。若超过则无效,查看当前系统的TCP/IP链接的侦听队列的大小命令:cat /proc/sys/net/ipv4/tcp_max_syn_backlog目前系统为1024。对于Linux系统推荐设置为小于512的整数。服务器 修改系统内核参数,)http://www.51testing.com/html/64/n-810764.html网络 查看mysql 当前系统默认back_log值,命令:数据结构 show variables like 'back_log'; 查看当前数量 |
wait_timeout=1800(单位为妙)
我对wait-timeout这个参数的理解:MySQL客户端的数据库链接闲置最大时间值。 说得比较通俗一点,就是当你的MySQL链接闲置超过必定时间后将会被强行关闭。MySQL默认的wait-timeout 值为8个小时,能够经过命令show variables like 'wait_timeout'查看结果值;。 设置这个值是很是有意义的,好比你的网站有大量的MySQL连接请求(每一个MySQL链接都是要内存资源开销的 ),因为你的程序的缘由有大量的链接请求空闲啥事也不干,白白占用内存资源,或者致使MySQL超过最大链接数历来没法新建链接致使“Too many connections”的错误。在设置以前你能够查看一下你的MYSQL的状态(可用show processlist),若是常常发现MYSQL中有大量的Sleep进程,则须要 修改wait-timeout值了。 interactive_timeout:服务器关闭交互式链接前等待活动的秒数。交互式客户端定义为在mysql_real_connect()中使用CLIENT_INTERACTIVE选项的客户端。 wait_timeout:服务器关闭非交互链接以前等待活动的秒数。在线程启动时,根据全局wait_timeout值或全局 interactive_timeout值初始化会话wait_timeout值,取决于客户端类型(由mysql_real_connect()的链接选项CLIENT_INTERACTIVE定义). 这两个参数必须配合使用。不然单独设置wait_timeout无效 |
max_connections=3000
max_connections是指MySql的最大链接数,若是服务器的并发链接请求量比较大,建议调高此值,以增长并行链接数量,固然这创建在机器能支撑的状况下,由于若是链接数越多,介于MySql会为每一个链接提供链接缓冲区,就会开销越多的内存,因此要适当调整该值,不能盲目提升设值。能够过'conn%'通配符查看当前状态的链接数量,以定夺该值的大小。 MySQL服务器容许的最大链接数16384; 查看系统当前最大链接数: show variables like 'max_connections'; |
max_user_connections=800
max_user_connections是指每一个数据库用户的最大链接 针对某一个帐号的全部客户端并行链接到MYSQL服务的最大并行链接数。简单说是指同一个帐号可以同时链接到mysql服务的最大链接数。设置为0表示不限制。 目前默认值为:0不受限制。 这儿顺便介绍下Max_used_connections:它是指从此次mysql服务启动到如今,同一时刻并行链接数的最大值。它不是指当前的链接状况,而是一个比较值。若是在过去某一个时刻,MYSQL服务同时有1000个请求链接过来,而以后再也没有出现这么大的并发请求时,则Max_used_connections=1000.请注意与show variables 里的max_user_connections的区别。默认为0表示无限大。 查看max_user_connections值 show variables like 'max_user_connections'; |
thread_concurrency=64
thread_concurrency的值的正确与否, 对mysql的性能影响很大, 在多个cpu(或多核)的状况下,错误设置了thread_concurrency的值, 会致使mysql不能充分利用多cpu(或多核), 出现同一时刻只能一个cpu(或核)在工做的状况。 thread_concurrency应设为CPU核数的2倍. 好比有一个双核的CPU, 那thread_concurrency 的应该为4; 2个双核的cpu, thread_concurrency的值应为8. 好比:根据上面介绍咱们目前系统的配置,可知道为4个CPU,每一个CPU为8核,按照上面的计算规则,这儿应为:4*8*2=64 查看系统当前thread_concurrency默认配置命令: show variables like 'thread_concurrency'; |
skip-name-resolve
skip-name-resolve:禁止MySQL对外部链接进行DNS解析,使用这一选项能够消除MySQL进行DNS解析的时间。但须要注意,若是开启该选项,则全部远程主机链接受权都要使用IP地址方式,不然MySQL将没法正常处理链接请求! |
skip-networking建议被注释掉,不要开启
开启该选项能够完全关闭MySQL的TCP/IP链接方式,若是WEB服务器是以远程链接的方式访问MySQL数据库服务器则不要开启该选项!不然将没法正常链接! |
default-storage-engine= InnoDB(设置InnoDB类型,另外还能够设置MyISAM类型)
设置建立数据库及表默认存储类型 show table status like ‘tablename’显示表的当前存储状态值 查看MySQL有哪些存储状态及默认存储状态 show engines; 建立表并指定存储类型 CREATE TABLE mytable (id int, title char(20)) ENGINE = INNODB; 修改表存储类型: Alter table tableName engine =engineName
备注:设置完后把如下几个开启: # Uncomment the following if you are using InnoDB tables innodb_data_home_dir = /var/lib/mysql #innodb_data_file_path = ibdata1:1024M;ibdata2:10M:autoextend(要注释掉,不然会建立一个新的把原来的替换的。) innodb_log_group_home_dir = /var/lib/mysql # You can set .._buffer_pool_size up to 50 - 80 % # of RAM but beware of setting memory usage too high innodb_buffer_pool_size = 1000M innodb_additional_mem_pool_size = 20M # Set .._log_file_size to 25 % of buffer pool size innodb_log_file_size = 500M innodb_log_buffer_size = 20M innodb_flush_log_at_trx_commit = 0 innodb_lock_wait_timeout = 50 设置完后必定记得把MySQL安装目录地址(咱们目前是默认安装因此地址/var/lib/mysql/)下的ib_logfile0和ib_logfile1删除掉。不然重启MySQL起动失败。 |
数据库属于IO密集型的应用程序,其主职责就是数据的管理及存储工做。而咱们知道,从内存中读取一个数据库的时间是微秒级别,而从一块普通硬盘上读取一个 IO是在毫秒级别,两者相差3个数量级。因此,要优化数据库,首先第一步须要优化的就是IO,尽量将磁盘IO转化为内存IO。本文先从MySQL数据库 IO相关参数(缓存参数)的角度来看看能够经过哪些参数进行IO优化 |
启动MySQL时就要分配而且老是存在的全局缓存。目前有:key_buffer_size(默认值:402653184,即384M)、innodb_buffer_pool_size(默认值:134217728即:128M)、innodb_additional_mem_pool_size(默认值:8388608即:8M)、innodb_log_buffer_size(默认值:8388608即:8M)、query_cache_size(默认值:33554432即:32M)等五个。总共:560M. 这些变量值均可以经过命令如:show variables like '变量名';查看到。
|
4.2.1.1:key_buffer_size,本系统目前为384M,可修改成400M
key_buffer_size=400M
key_buffer_size是用于索引块的缓冲区大小,增长它可获得更好处理的索引(对全部读和多重写),对MyISAM(MySQL表存储的一种类型,能够百度等查看详情)表性能影响最大的一个参数。若是你使它太大,系统将开始换页而且真的变慢了。严格说是它决定了数据库索引处理的速度,尤为是索引读的速度。对于内存在4GB左右的服务器该参数可设置为256M或384M. 怎么才能知道key_buffer_size的设置是否合理呢,通常能够检查状态值Key_read_requests和Key_reads ,比例key_reads / key_read_requests应该尽量的低,好比1:100,1:1000 ,1:10000。其值能够用如下命令查得:show status like 'key_read%'; 好比查看系统当前key_read和key_read_request值为: +-------------------+-------+ | Variable_name | Value | +-------------------+-------+ | Key_read_requests | 28535 | | Key_reads | 269 | +-------------------+-------+ 可知道有28535个请求,有269个请求在内存中没有找到直接从硬盘读取索引. 未命中缓存的几率为:0.94%=269/28535*100%. 通常未命中几率在0.1之下比较好。目前已远远大于0.1,证实效果很差。若命中率在0.01如下,则建议适当的修改key_buffer_size值。 http://dbahacker.com/mysql/innodb-myisam-compare(InnoDB与MyISAM的六大区别) http://kb.cnblogs.com/page/99810/(查看存储引擎介绍) MyISAM、InnoDB、MyISAM Merge引擎、InnoDB、memory(heap)、archive |
4.2.1.2:innodb_buffer_pool_size(默认128M)
innodb_buffer_pool_size=1024M(1G)
innodb_buffer_pool_size:主要针对InnoDB表性能影响最大的一个参数。功能与Key_buffer_size同样。InnoDB占用的内存,除innodb_buffer_pool_size用于存储页面缓存数据外,另外正常状况下还有大约8%的开销,主要用在每一个缓存页帧的描述、adaptive hash等数据结构,若是不是安全关闭,启动时还要恢复的话,还要另开大约12%的内存用于恢复,二者相加就有差很少21%的开销。假设:12G的innodb_buffer_pool_size,最多的时候InnoDB就可能占用到14.5G的内存。若系统只有16G,并且只运行MySQL,且MySQL只用InnoDB, 那么为MySQL开12G,是最大限度地利用内存了。 另外InnoDB和 MyISAM 存储引擎不一样, MyISAM 的 key_buffer_size 只能缓存索引键,而 innodb_buffer_pool_size 却能够缓存数据块和索引键。适当的增长这个参数的大小,能够有效的减小 InnoDB 类型的表的磁盘 I/O 。 当咱们操做一个 InnoDB 表的时候,返回的全部数据或者去数据过程当中用到的任何一个索引块,都会在这个内存区域中走一遭。 能够经过 (Innodb_buffer_pool_read_requests – Innodb_buffer_pool_reads) / Innodb_buffer_pool_read_requests * 100% 计算缓存命中率,并根据命中率来调整 innodb_buffer_pool_size 参数大小进行优化。值能够用如下命令查得:show status like 'Innodb_buffer_pool_read%'; 好比查看当前系统中系统中 | Innodb_buffer_pool_read_requests | 1283826 | | Innodb_buffer_pool_reads | 519 | +---------------------------------------+---------+ 其命中率99.959%=(1283826-519)/1283826*100% 命中率越高越好。 |
4.2.1.3:innodb_additional_mem_pool_size(默认8M)
innodb_additional_mem_pool_size=20M
innodb_additional_mem_pool_size 设置了InnoDB存储引擎用来存放数据字典信息以及一些内部数据结构的内存空间大小,因此当咱们一个MySQL Instance中的数据库对象很是多的时候,是须要适当调整该参数的大小以确保全部数据都能存放在内存中提升访问效率的。 这个参数大小是否足够仍是比较容易知道的,由于当太小的时候,MySQL会记录Warning信息到数据库的error log中,这时候你就知道该调整这个参数大小了。 查看当前系统mysql的error日志 cat /var/lib/mysql/机器名.error 发现有不少waring警告。因此要调大为20M. 根据MySQL手册,对于2G内存的机器,推荐值是20M。 32G内存的 100M |
4.2.1.4:innodb_log_buffer_size(默认8M)
innodb_log_buffer_size=20M
innodb_log_buffer_size 这是InnoDB存储引擎的事务日志所使用的缓冲区。相似于Binlog Buffer,InnoDB在写事务日志的时候,为了提升性能,也是先将信息写入Innofb Log Buffer中,当知足innodb_flush_log_trx_commit参数所设置的相应条件(或者日志缓冲区写满)以后,才会将日志写到文件 (或者同步到磁盘)中。能够经过innodb_log_buffer_size 参数设置其可使用的最大内存空间。 InnoDB 将日志写入日志磁盘文件前的缓冲大小。理想值为 1M 至 8M。大的日志缓冲容许事务运行时不须要将日志保存入磁盘而只到事务被提交(commit)。 所以,若是有大的事务处理,设置大的日志缓冲能够减小磁盘I/O。 在 my.cnf中以数字格式设置。 默认是8MB,系的如频繁的系统可适当增大至4MB~8MB。固然如上面介绍所说,这个参数实际上还和另外的flush参数相关。通常来讲不建议超过32MB 注:innodb_flush_log_trx_commit参数对InnoDB Log的写入性能有很是关键的影响,默认值为1。该参数能够设置为0,1,2,解释以下: 0:log buffer中的数据将以每秒一次的频率写入到log file中,且同时会进行文件系统到磁盘的同步操做,可是每一个事务的commit并不会触发任何log buffer 到log file的刷新或者文件系统到磁盘的刷新操做; 1:在每次事务提交的时候将log buffer 中的数据都会写入到log file,同时也会触发文件系统到磁盘的同步; 2:事务提交会触发log buffer到log file的刷新,但并不会触发磁盘文件系统到磁盘的同步。此外,每秒会有一次文件系统到磁盘同步操做。 实际测试发现,该值对插入数据的速度影响很是大,设置为2时插入10000条记录只须要2秒,设置为0时只须要1秒,而设置为1时则须要229秒。所以,MySQL手册也建议尽可能将插入操做合并成一个事务,这样能够大幅提升速度。根据MySQL手册,在存在丢失最近部分事务的危险的前提下,能够把该值设为0。 |
4.5.1.5:query_cache_size(默认32M)
query_cache_size=40M
query_cache_size: 主要用来缓存MySQL中的ResultSet,也就是一条SQL语句执行的结果集,因此仅仅只能针对select语句。当咱们打开了 Query Cache功能,MySQL在接受到一条select语句的请求后,若是该语句知足Query Cache的要求(未显式说明不容许使用Query Cache,或者已经显式申明须要使用Query Cache),MySQL会直接根据预先设定好的HASH算法将接受到的select语句以字符串方式进行hash,而后到Query Cache中直接查找是否已经缓存。也就是说,若是已经在缓存中,该select请求就会直接将数据返回,从而省略了后面全部的步骤(如SQL语句的解析,优化器优化以及向存储引擎请求数据等),极大的提升性能。根据MySQL用户手册,使用查询缓冲最多能够达到238%的效率。 固然,Query Cache也有一个致命的缺陷,那就是当某个表的数据有任何任何变化,都会致使全部引用了该表的select语句在Query Cache中的缓存数据失效。因此,当咱们的数据变化很是频繁的状况下,使用Query Cache可能会得不偿失 Query Cache的使用须要多个参数配合,其中最为关键的是query_cache_size和query_cache_type,前者设置用于缓存 ResultSet的内存大小,后者设置在何场景下使用Query Cache。在以往的经验来看,若是不是用来缓存基本不变的数据的MySQL数据库,query_cache_size通常256MB是一个比较合适的大小。固然,这能够经过计算Query Cache的命中率(Qcache_hits/(Qcache_hits+Qcache_inserts)*100))来进行调整。 query_cache_type能够设置为0(OFF),1(ON)或者2(DEMOND),分别表示彻底不使用query cache,除显式要求不使用query cache(使用sql_no_cache)以外的全部的select都使用query cache,只有显示要求才使用query cache(使用sql_cache)。若是Qcache_lowmem_prunes的值很是大,则代表常常出现缓冲. 若是Qcache_hits的值也很是大,则代表查询缓冲使用很是频繁,此时须要增长缓冲大小; 根据命中率(Qcache_hits/(Qcache_hits+Qcache_inserts)*100))进行调整,通常不建议太大,256MB可能已经差很少了,大型的配置型静态数据可适当调大. 能够经过命令:show status like 'Qcache_%';查看目前系统Query catch使用大小 | Qcache_hits | 1892463 | | Qcache_inserts | 35627 命中率98.17%=1892463/(1892463 +35627 )*100 |
除了全局缓冲,MySql还会为每一个链接发放链接缓冲。个链接到MySQL服务器的线程都须要有本身的缓冲。大概须要马上分配256K,甚至在线程空闲时,它们使用默认的线程堆栈,网络缓存等。事务开始以后,则须要增长更多的空间。运行较小的查询可能仅给指定的线程增长少许的内存消耗,然而若是对数据表作复杂的操做例如扫描、排序或者须要临时表,则需分配大约read_buffer_size, sort_buffer_size,read_rnd_buffer_size,tmp_table_size 大小的内存空间. 不过它们只是在须要的时候才分配,而且在那些操做作完以后就释放了。有的是马上分配成单独的组块。tmp_table_size 可能高达MySQL所能分配给这个操做的最大内存空间了 。注意,这里须要考虑的不仅有一点——可能会分配多个同一种类型的缓存,例如用来处理子查询。一些特殊的查询的内存使用量可能更大——若是在MyISAM表上作成批的插入 时须要分配 bulk_insert_buffer_size 大小的内存;执行 ALTER TABLE, OPTIMIZE TABLE, REPAIR TABLE 命令时须要分配 myisam_sort_buffer_size 大小的内存。 |
4.2.2.1:read_buffer_size(默认值:2097144即2M)
read_buffer_size=4M
read_buffer_size 是MySql读入缓冲区大小。对表进行顺序扫描的请求将分配一个读入缓冲区,MySql会为它分配一段内存缓冲区。read_buffer_size变量控制这一 缓冲区的大小。若是对表的顺序扫描请求很是频繁,而且你认为频繁扫描进行得太慢,能够经过增长该变量值以及内存缓冲区大小提升其性能. |
4.2.2.2:sort_buffer_size(默认值:2097144即2M)
sort_buffer_size=4M
sort_buffer_size是MySql执行排序使用的缓冲大小。若是想要增长ORDER BY的速度,首先看是否可让MySQL使用索引而不是额外的排序阶段。若是不能,能够尝试增长sort_buffer_size变量的大小 |
4.2.2.3: read_rnd_buffer_size(默认值:8388608即8M)
read_rnd_buffer_size=8M
read_rnd_buffer_size 是MySql的随机读缓冲区大小。当按任意顺序读取行时(例如,按照排序顺序),将分配一个随机读缓存区。进行排序查询时,MySql会首先扫描一遍该缓冲,以免磁盘搜索,提升查询速度,若是须要排序大量数据,可适当调高该值。但MySql会为每一个客户链接发放该缓冲空间,因此应尽可能适当设置该值,以免内存开 销过大。 |
4.2.2.4: tmp_table_size(默认值:8388608 即:16M)
tmp_table_size=16M
tmp_table_size是MySql的heap (堆积)表缓冲大小。全部联合在一个DML指令内完成,而且大多数联合甚至能够不用临时表便可以完成。大多数临时表是基于内 存的(HEAP)表。具备大的记录长度的临时表 (全部列的长度的和)或包含BLOB列的表存储在硬盘上。若是某个内部heap(堆积)表大小超过tmp_table_size,MySQL能够根据须要自 动将内存中的heap表改成基于硬盘的MyISAM表。还能够经过设置tmp_table_size选项来增长临时表的大小。也就是说,若是调高该值,MySql同时将增长heap表的大小,可达到提升 联接查询速度的效果。 |
4.2.2.5:record_buffer:(默认值:)
record_buffer每一个进行一个顺序扫描的线程为其扫描的每张表分配这个大小的一个缓冲区。若是你作不少顺序扫描,你可能想要增长该值。默认数值是131072 (128K) |
4.2.3.1:table_cache(默认值:512)
TABLE_CACHE(5.1.3及之后版本又名TABLE_OPEN_CACHE) table_cache指定表高速缓存的大小。每当MySQL访问一个表时,若是在表缓冲区中还有空间,该表就被打开并放入其中,这样能够更快地访问表内容。经过检查峰值时间的状态值Open_tables和Opened_tables,能够决定是否须要增长table_cache的值。若是你发现open_tables等于table_cache,而且opened_tables在不断增加,那么你就须要增长table_cache的值了(上述状态值可使用SHOW STATUS LIKE ‘Open%tables’得到)。注意,不能盲目地把table_cache设置成很大的值。若是设置得过高,可能会形成文件描述符不足,从而形成性能不稳定或者链接失败。 SHOW STATUS LIKE 'Open%tables'; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | Open_tables | 356 | | Opened_tables | 0 | +---------------+-------+ 2 rows in set (0.00 sec) open_tables表示当前打开的表缓存数,若是执行flush tables操做,则此系统会关闭一些当前没有使用的表缓存而使得此状态值减少; opend_tables表示曾经打开的表缓存数,会一直进行累加,若是执行flush tables操做,值不会减少。 在mysql默认安装状况下,table_cache的值在2G内存如下的机器中的值默认时256到512,若是机器有4G内存,则默认这个值 是2048,但这决意味着机器内存越大,这个值应该越大,由于table_cache加大后,使得mysql对SQL响应的速度更快了,不可避免的会产生 更多的死锁(dead lock),这样反而使得数据库整个一套操做慢了下来,严重影响性能。因此平时维护中仍是要根据库的实际状况去做出判断,找到最适合你维护的库的 table_cache值。 因为MySQL是多线程的机制,为了提升性能,每一个线程都是独自打开本身须要的表的文件描 述符,而不是经过共享已经打开的.针对不一样存储引擎处理的方法固然也不同 在myisam表引擎中,数据文件的描述符 (descriptor)是不共享的,可是索引文件的描述符倒是全部线程共享的.Innodb中和使用表空间类型有关,假如是共享表空间那么实际就一个数 据文件,固然占用的数据文件描述符就会比独立表空间少.
这个数据遭到不少质疑,table_cache够用就好,检查 Opened_tables值,若是这个值很大,或增加很快那么你就得考虑加大table_cache了. table_cache:全部线程打开的表的数目。增大该值能够增长mysqld须要的文件描述符的数量。默认值是64. |
4.2.3.2 thread_cache_size (服务器线程缓存)
thread_cache_size=64
默认的thread_cache_size=8,可是看到好多配置的样例里的值通常是32,64,甚至是128,感受这个参数对优化应该有帮助,因而查了下: mysql> show status like 'thread%'; 查看开机起来数据库被链接了多少次? mysql> show status like '%connection%'; 经过链接线程池的命中率来判断设置值是否合适?命中率超过90%以上,设定合理。 (Connections - Threads_created) / Connections * 100 % |