咱们究竟应该如何对MySQL数据库进行优化?下面我就从MySQL对硬件的选择、MySQL的安装、my.cnf的优化、MySQL如何进行架构设计及数据切分等方面来讲明这个问题。mysql
在挑选硬件服务器时,咱们应该从下面几个方面着重对MySQL服务器的硬件配置进行优化,也就是说将项目中的资金着重投入到以下几处:sql
一、磁盘寻道能力(磁盘I/O),咱们如今用的都是SAS15000转的硬盘,用6快这样的硬盘做RAID1+0。MySQL每一秒钟都在进行大量、复杂的查询操做,对磁盘的读写量可想而知,因此,一般认为磁盘I/O是约制MySQL性能的最大因素之一。对于日均访问量在100万PV以上的论坛(Discuz)、博客(Wordpress),若是性能很差,形成的直接后果就是MySQL的性能会很是低下!解决这一制约因素能够考虑解决访问是:使用RAID1+0磁盘阵列,注意不要尝试RAID5,MySQL在PAID5磁盘阵列上的效率不会像你期待的那样快,若是资金容许,能够选择固态硬盘SSD来替代SAS硬盘作RAID1+0。数据库
二、CPU对于MySQL的影响也是不容忽视的,建议选择运算能力强悍的CPU。推荐使用DELL R710(双四核),商家的卖点也是其强大的虚拟化和数据库能力。windows
三、对于一台使用MySQL的Database Server来讲,建议服务器的内存不要小于2GB,推荐使用4GB以上的物理内存,不过内存对于如今的服务器而言能够说是一个能够忽略的问题,若是是高端服务器,基本上内存都超过了32GB,咱们的数据流服务器都是32GB内存。缓存
我在工做中用的比较多的数据库服务器是DELL R710/R720,其稳定性和性能都不错,同时我也发现许多同行都是采用它做为数据库的服务器,因此在这里也向你们推荐一下。安全
关于MySQL数据库的线上环境安装,我建议采起编译安装的方式,这样性能会有较大的提高。服务器系统则建议CentOS6.7 X86_64,源码包的编译参数会默认以Debug模式生成二进制代码,而Debug模式给MySQL带来的性能损失是比较大的,因此当咱们编译准备安装的产品代码时,必定不要忘记使用--without-debug参数禁止Debug模式。若是把--with-mysqld-ldflags和--with-client-ld-flags两个编译参数设置为--all-static的话,能够告诉编译器以静态的方式编译,编译结果将获得最高的性能。使用静态编译和使用动态编译的代码相比,性能差距可能会达到5%至10%之多。在后面我会跟你们分享咱们线上MySQL数据库的编译参数,你们能够参考下,而后根据本身的线上环境自行修改内容。性能优化
[client]服务器
port = 3306 #客户端端口号为3306网络
socket =/data/3306/mysql.sock #数据结构
default-character-set = utf8 #客户端字符集,(控制character_set_client、character_set_connection、character_set_results)
[mysql]
no-auto-rehash #仅仅容许使用键值的updates和deletes
[mysqld] #组包括了mysqld服务启动的参数,它涉及的方面不少,其中有MySQL的目录和文件,通讯、网络、信息安全,内存管理、优化、查询缓存区,还有MySQL日志设置等。
user = mysql #mysql_safe脚本使用MySQL运行用户(编译时--user=mysql指定),推荐使用mysql用户。
port = 3306 #MySQL服务运行时的端口号。建议更改默认端口,默认容易遭受攻击。
socket =/data/3306/mysql.sock #socket文件是在Linux/Unix环境下特有的,用户在Linux/Unix环境下客户端链接能够不经过TCP/IP网络而直接使用unix socket链接MySQL。
basedir = /application/mysql #mysql程序所存放路径,经常使用于存放mysql启动、配置文件、日志等
datadir = /data/3306/data #MySQL数据存放文件(极其重要)
character-set-server = utf8 #数据库和数据库表的默认字符集。(推荐utf8,以避免致使乱码)
log-error=/data/3306/mysql_xuliangwei.err #mysql错误日志存放路径及名称(启动出现错误必定要看错误日志,百分之百都能经过错误日志排插解决。)
pid-file=/data/3306/mysql_xuliangwei.pid #MySQL_pid文件记录的是当前mysqld进程的pid,pid亦即ProcessID。
skip-locking #避免MySQL的外部锁定,减小出错概率,加强稳定性。
skip-name-resolv #禁止MySQL对外部链接进行DNS解析,使用这一选项能够消除MySQL进行DNS解析的时候。可是须要注意的是,若是开启该选项,则全部远程主机链接受权都要使用IP地址方式了,不然MySQL将没法正常处理链接请求!
skip-networking #开启该选项能够完全关闭MySQL的TCP/IP链接方式,若是Web服务器是以远程链接的方式访问MySQL数据库服务器的,则不要开启该选项,不然没法正常链接!
open_files_limit = 1024 #MySQLd能打开文件的最大个数,若是出现too mant openfiles之类的就须要调整该值了。
back_log = 384 #back_log参数是值指出在MySQL暂时中止响应新请求以前,短期内的多少个请求能够被存在堆栈中。若是系统在短期内有不少链接,则须要增长该参数的值,该参数值指定到来的TCP/IP链接的监听队列的大小。不一样的操做系统在这个队列的大小上有本身的限制。若是试图将back_log设置得高于操做系统的限制将是无效的,其默认值为50.对于Linux系统而言,推荐设置为小于512的整数。
max_connections = 800 #指定MySQL容许的最大链接进程数。若是在访问博客时常常出现 Too Many Connections的错误提示,则须要增大该参数值。
max_connect_errors = 6000 #设置每一个主机的链接请求异常中断的最大次数,当超过该次数,MySQL服务器将禁止host的链接请求,直到MySQL服务器重启或经过flush hosts命令清空此host的相关信息。
wait_timeout = 120 #指定一个请求的最大链接时间,对于4GB左右内存的服务器来讲,能够将其设置为5~10。
table_cache = 614K #table_cache指示表高速缓冲区的大小。当MySQL访问一个表时,若是在MySQL缓冲区还有空间,那么这个表就被打开并放入表缓冲区,这样作的好处是能够更快速地访问表中的内容。通常来讲,能够查看数据库运行峰值时间的状态值Open_tables和Open_tables,用以判断是否须要增长table_cache的值,即若是Open_tables接近table_cache的时候,而且Opened_tables这个值在逐步增长,那就要考虑增长这个值的大小了。
external-locking = FALSE #MySQL选项能够避免外部锁定。True为开启。
max_allowed_packet =16M #服务器一次能处理最大的查询包的值,也是服务器程序可以处理的最大查询
sort_buffer_size = 1M #设置查询排序时所能使用的缓冲区大小,系统默认大小为2MB。
注意:该参数对应的分配内存是每一个链接独占的,若是有100个链接,那么实际分配的总排序缓冲区大小为100 x6=600MB。因此,对于内存在4GB左右的服务器来讲,推荐将其设置为6MB~8MB
join_buffer_size = 8M #联合查询操做所能使用的缓冲区大小,和sort_buffer_size同样,该参数对应的分配内存也是每一个链接独享。
thread_cache_size = 64 #设置Thread Cache池中能够缓存的链接线程最大数量,可设置为0~16384,默认为0.这个值表示能够从新利用保存在缓存中线程的数量,当断开链接时若是缓存中还有空间,那么客户端的线程将被放到缓存中;若是线程从新被请求,那么请求将从缓存中读取,若是缓存中是空的或者是新的请求,那么这个线程将被从新建立,若是有不少线程,增长这个值能够改善系统性能。经过比较Connections和Threads_created状态的变量,能够看到这个变量的做用。咱们能够根据物理内存设置规则以下:1GB内存咱们配置为8,2GB内存咱们配置为16,3GB咱们配置为32,4GB或4GB以上咱们给此值为64或更大的值。
thread_concurrency = 8 #该参数取值为服务器逻辑CPU数量x 2,在本例中,服务器有两个物理CPU,而每一个物理CPU又支持H.T超线程,因此实际取值为4 x 2 = 8。这也是双四核主流服务器的配置。
query_cache_size = 64M #指定MySQL查询缓冲区的大小。能够经过在MySQL控制台观察,若是Qcache_lowmem_prunes的值很是大,则代表常常出现缓冲不够的状况;若是Qcache_hits的值很是大,则代表查询缓冲使用得很是频繁。另外若是改值较小反而会影响效率,那么能够考虑不用查询缓冲。对于Qcache_free_blocks,若是该值很是大,则代表缓冲区中碎片不少。
query_cache_limit = 2M #只有小于此设置值的结果才会被缓存
query_cache_min_res_unit = 2k #设置查询缓存分配内存的最小单位,要适当第设置此参数,能够作到为减小内存快的申请和分配次数,可是设置过大可能致使内存碎片数值上升。默认值为4K,建议设置为1K~16K。
default_table_type = InnoDB #默认表的类型为InnoDB
thread_stack = 256K #设置MySQL每一个线程的堆栈大小,默认值足够大,可知足普通操做。可设置范围为128KB至4GB,默认为192KB
#transaction_isolation = Level #数据库隔离级别 (READ UNCOMMITTED(读取未提交内容) READ COMMITTED(读取提交内容) REPEATABLE READ(可重读) SERIALIZABLE(可串行化))
tmp_table_size = 64M #设置内存临时表最大值。若是超过该值,则会将临时表写入磁盘,其范围1KB到4GB。
max_heap_table_size = 64M #独立的内存表所容许的最大容量。
table_cache = 614 #给常常访问的表分配的内存,物理内存越大,设置就越大。调大这个值,通常状况下能够下降磁盘IO,但相应的会占用更多的内存,这里设置为614。
table_open_cache = 512 #设置表高速缓存的数目。每一个链接进来,都会至少打开一个表缓存。所以, table_cache 的大小应与max_connections 的设置有关。例如,对于200 个并行运行的链接,应该让表的缓存至少有 200 × N ,这里 N 是应用能够执行的查询的一个联接中表的最大数量。此外,还须要为临时表和文件保留一些额外的文件描述符。
long_query_time = 1 #慢查询的执行用时上限,默认设置是10s,推荐(1s~2s)
log_long_format #没有使用索引的查询也会被记录。(推荐,根据业务来调整)
log-slow-queries = /data/3306/slow.log #慢查询日志文件路径(若是开启慢查询,建议打开此日志)
log-bin = /data/3306/mysql-bin #logbin数据库的操做日志,例如update、delete、create等都会存储到binlog日志,经过logbin能够实现增量恢复
relay-log = /data/3306/relay-bin #relay-log日志记录的是从服务器I/O线程将主服务器的二进制日志读取过来记录到从服务器本地文件,而后SQL线程会读取relay-log日志的内容并应用到从服务器
relay-log-info-file = /data/3306/relay-log.info #从服务器用于记录中继日志相关信息的文件,默认名为数据目录中的relay-log.info。
binlog_cache_size = 4M #在一个事务中binlog为了记录sql状态所持有的cache大小,若是你常用大的,多声明的事务,能够增长此值来获取更大的性能,全部从事务来的状态都被缓冲在binlog缓冲中,而后再提交后一次性写入到binlog中,若是事务比此值大,会使用磁盘上的临时文件来替代,此缓冲在每一个连接的事务第一次更新状态时被建立。
max_binlog_cache_size = 8M #最大的二进制Cache日志缓冲尺寸。
max_binlog_size = 1G #二进制日志文件的最大长度(默认设置1GB)一个二进制文件信息超过了这个最大长度以前,MySQL服务器会自动提供一个新的二进制日志文件接续上。
expire_logs_days = 7 #超过7天的binlog,mysql程序自动删除(若是数据重要,建议不要开启该选项)
key_buffer_size = 256M #指定用于索引的缓冲区大小,增长它可获得更好的索引处理性能。对于内存在4GB左右的服务器来讲,该参数可设置为256MB或384MB。
注意:若是该参数值设置得过大反而会使服务器的总体效率下降!
read_buffer_size = 4M #读查询操做所能使用的缓冲区大小。和sort_buffer_size同样,该参数对应的分配内存也是每一个链接独享。
read_rnd_buffer_size = 16M #设置进行随机读的时候所使用的缓冲区。此参数和read_buffer_size所设置的Buffer相反,一个是顺序读的时候使用,一个是随机读的时候使用。可是二者都是针对与线程的设置,每一个线程均可以产生两种Buffer中的任何一个。默认值256KB,最大值4GB。
bulk_insert_buffer_size = 8M #若是常常性的须要使用批量插入的特殊语句来插入数据,能够适当调整参数至16MB~32MB,建议8MB。
#myisam_sort_buffer_size = 8M #设置在REPAIR Table或用Create index建立索引或 Alter table的过程当中排序索引所分配的缓冲区大小,可设置范围4Bytes至4GB,默认为8MB
lower_case_table_names = 1 #实现MySQL不区分大小。(发开需求-建议开启)
slave-skip-errors = 1032,1062 #从库能够跳过的错误数字值(mysql错误以数字代码反馈,全的mysql错误代码大全,之后会发布至博客)。
replicate-ignore-db=mysql #在作主从的状况下,设置不须要同步的库。
server-id = 1 #表示本机的序列号为1,若是作主从,或者多实例,serverid必定不能相同。
myisam_sort_buffer_size = 128M #当须要对于执行REPAIR, OPTIMIZE, ALTER 语句重建索引时,MySQL会分配这个缓存,以及LOAD DATA INFILE会加载到一个新表,它会根据最大的配置认真的分配的每一个线程。
myisam_max_sort_file_size = 10G #当从新建索引(REPAIR,ALTER,TABLE,或者LOAD,DATA,TNFILE)时,MySQL被容许使用临时文件的最大值。
myisam_repair_threads = 1 #若是一个表拥有超过一个索引, MyISAM 能够经过并行排序使用超过一个线程去修复他们.
myisam_recover #自动检查和修复没有适当关闭的 MyISAM 表.
innodb_additional_mem_pool_size = 4M #用来设置InnoDB存储的数据目录信息和其余内部数据结构的内存池大小。应用程序里的表越多,你须要在这里面分配越多的内存。对于一个相对稳定的应用,这个参数的大小也是相对稳定的,也没有必要预留很是大的值。若是InnoDB用广了这个池内的内存,InnoDB开始从操做系统分配内存,而且往MySQL错误日志写警告信息。默认为1MB,当发现错误日志中已经有相关的警告信息时,就应该适当的增长该参数的大小。
innodb_buffer_pool_size = 64M #InnoDB使用一个缓冲池来保存索引和原始数据,设置越大,在存取表里面数据时所须要的磁盘I/O越少。强烈建议不要武断地将InnoDB的Buffer Pool值配置为物理内存的50%~80%,应根据具体环境而定。
innodb_data_file_path = ibdata1:128M:autoextend #设置配置一个可扩展大小的尺寸为128MB的单独文件,名为ibdata1.没有给出文件的位置,因此默认的是在MySQL的数据目录内。
innodb_file_io_threads = 4 #InnoDB中的文件I/O线程。一般设置为4,若是是windows能够设置更大的值以提升磁盘I/O
innodb_thread_concurrency = 8 #你的服务器有几个CPU就设置为几,建议用默认设置,通常设为8。
innodb_flush_log_at_trx_commit = 1 #设置为0就等于innodb_log_buffer_size队列满后在统一存储,默认为1,也是最安全的设置。
innodb_log_buffer_size = 2M #默认为1MB,一般设置为8~16MB就足够了。
innodb_log_file_size = 32M #肯定日志文件的大小,更大的设置能够提升性能,但也会增长恢复数据库的时间。
innodb_log_files_in_group = 3 #为提升性能,MySQL能够以循环方式将日志文件写到多个文件。推荐设置为3。
innodb_max_dirty_pages_pct = 90 #InnoDB主线程刷新缓存池中的数据。
innodb_lock_wait_timeout = 120 #InnoDB事务被回滚以前能够等待一个锁定的超时秒数。InnoDB在它本身的锁定表中自动检测事务死锁而且回滚事务。InnoDB用locak tables 语句注意到锁定设置。默认值是50秒。
innodb_file_per_table = 0 #InnoDB为独立表空间模式,每一个数据库的每一个表都会生成一个数据空间。0关闭,1开启。
独立表空间优势:
一、每一个表都有本身独立的表空间。
二、每一个表的数据和索引都会存在本身的表空间中。
三、能够实现单表在不一样的数据库中移动。
四、空间能够回收(除drop table操做处,表空不能本身回收。)
[mysqldump]
quick
max_allowed_packet = 2M #设定在网络传输中一次消息传输量的最大值。系统默认值为1MB,最大值是1GB,必须设置为1024的倍数。单位为字节。
[mysqld_safe]
值得注意:
强烈建议不要武断地将InnoDB的Buffer Pool值配置为物理内存的50%~80%,应根据具体环境而定。
若是key_reads太大,则应该把my.cnf中的key_buffer_size变大,保持key_reads/key_read_re-quests至少在1/100以上,越小越好。
若是qcache_lowmem_prunes很大,就要增长query_cache_size的值。
不过不少时候须要具体状况具体分析,其余参数的变动咱们能够等MySQL上线稳定一段时间后在根据status值进行调整。
这是一份电子商务网站MySQL数据库调整后所运行的配置文件/etc/my.cnf(服务器为DELL R7十、16GB内存、RAID10),你们能够根据实际的MySQL数据库硬件状况进行调整配置文件以下:
[client]
port = 3306
socket =/data/3306/mysql.sock
default-character-set = utf8
[mysqld]
user = mysql
port = 3306
character-set-server = utf8
socket =/data/3306/mysql.sock
basedir = /application/mysql
datadir = /data/3306/data
log-error=/data/3306/mysql_err.log
pid-file=/data/3306/mysql.pid
log_slave_updates = 1
log-bin = /data/3306/mysql-bin
binlog_format = mixed
binlog_cache_size = 4M
max_binlog_cache_size = 8M
max_binlog_size = 1G
expire_logs_days = 90
binlog-ignore - db = mysql
binlog-ignore - db = information_schema
key_buffer_size = 384M
sort_buffer_size = 2M
read_buffer_size = 2M
read_rnd_buffer_size = 16M
join_buffer_size = 2M
thread_cache_size = 8
query_cache_size = 32M
query_cache_limit = 2M
query_cache_min_res_unit = 2k
thread_concurrency = 32
table_cache = 614
table_open_cache = 512
open_files_limit = 10240
back_log = 600
max_connections = 5000
max_connect_errors = 6000
external-locking = FALSE
max_allowed_packet =16M
thread_stack = 192K
transaction_isolation = READ-COMMITTED
tmp_table_size = 256M
max_heap_table_size = 512M
bulk_insert_buffer_size = 64M
myisam_sort_buffer_size = 64M
myisam_max_sort_file_size = 10G
myisam_repair_threads = 1
myisam_recover
long_query_time = 2
slow_query_log
slow_query_log_file = /data/3306/slow.log
skip-name-resolv
skip-locking
skip-networking
server-id = 1
innodb_additional_mem_pool_size = 16M
innodb_buffer_pool_size = 512M
innodb_data_file_path = ibdata1:256M:autoextend
innodb_file_io_threads = 4
innodb_thread_concurrency = 8
innodb_flush_log_at_trx_commit = 2
innodb_log_buffer_size = 16M
innodb_log_file_size = 128M
innodb_log_files_in_group = 3
innodb_max_dirty_pages_pct = 90
innodb_lock_wait_timeout = 120
innodb_file_per_table = 0
[mysqldump]
quick
max_allowed_packet = 64M
[mysql]
no – auto - rehash
MySQL数据库上线后,能够等其稳定运行一段时间后再根据服务器的status状态进行适当优化,咱们能够用以下命令列出MySQL服务器运行的各类状态值:
mysql > show global status;
我我的比较喜欢的用法是 show status like '查询%';
有时咱们为了定位系统中效率比较低下的Query语法,须要打开慢查询日志,也就是Slow Que-ry log。打开慢查询日志的相关命令以下:
mysql> show variableslike '%slow%';
+---------------------+-----------------------------------------+
| Variable_name |Value |
+---------------------+-----------------------------------------+
| log_slow_queries | ON |
| slow_launch_time | 2 |
+---------------------+-----------------------------------------+
mysql> show globalstatus like '%slow%';
+---------------------+-------+
| Variable_name | Value|
+---------------------+-------+
| Slow_launch_threads | 0 |
| Slow_queries | 2128 |
+---------------------+-------+
打开慢查询日志可能会对系统性能有一点点影响,若是你的MySQL是主从结构,能够考虑打开其中一台从服务器的慢查询日志,这样既能够监控慢查询,对系统性能影响也会很小。另外,能够用MySQL自带的命令mysqldumpslow进行查询。好比:下面的命令能够查出访问次数最多的20个SQL语句:
mysqldumpslow-s c -t 20 host-slow.log
咱们若是常常碰见MySQL:ERROR1040:Too manyconnections的状况,一种状况是访问量确实很高,MySQL服务器扛不住了,这个时候就要考虑增长从服务器分散读压力。另一种状况是MySQL配置文件中max_connections的值太小。来看一个例子。
mysql>show variables like'max_connections';
+-----------------+-------+
| Variable_name | Value |
+-----------------+-------+
| max_connections | 800 |
+-----------------+-------+
这台服务器最大链接数是256,而后查询一下该服务器响应的最大链接数;
mysql> show global status like 'Max_used_connections';
+----------------------+-------+
| Variable_name | Value|
+----------------------+-------+
| Max_used_connections | 245 |
+----------------------+-------+
MySQL服务器过去的最大链接数是245,没有达到服务器链接数的上线800,不会出现1040错误。
Max_used_connections/max_connections * 100% = 85%
最大链接数占上限链接数的85%左右,若是发现比例在10%如下,则说明MySQL服务器链接数的上限设置得太高了。
key_buffer_size是设置MyISAM表索引缓存空间的大小,此参数对MyISAM表性能影响最大。下面是一台MyISAM为主要存储引擎服务器的配置:
mysql> show variables like 'key_buffer_size';
+-----------------+-----------+
| Variable_name | Value |
+-----------------+-----------+
| key_buffer_size | 536870912 |
+-----------------+-----------+
从上面能够看出,分配了512MB内存给key_buffer_size。再来看key_buffer_size的使用状况:
mysql> show global status like 'key_read%';
+-------------------+--------------+
| Variable_name | Value |
+-------------------+-------+
| Key_read_requests | 27813678766 |
| Key_reads | 6798830 |
+-------------------+--------------+
一共有27813678766个索引读取请求,有6798830个请求在内存中没有找到,直接从硬盘读取索引。
key_cache_miss_rate = key_reads /key_read_requests * 100%
好比上面的数据,key_cache_miss_rate为0.0244%,4000%个索引读取请求才有一个直接读硬盘,效果已经很好了,key_cache_miss_rate在0.1%如下都很好,若是key_cache_miss_rate在0.01%如下的话,则说明key_buffer_size分配得过多,能够适当减小。
当执行语句时,关于已经被建立了隐含临时表的数量,咱们能够用以下命令查询其具体状况:
mysql> show global status like 'created_tmp%';
+-------------------------+----------+
| Variable_name |Value |
+-------------------------+----------+
| Created_tmp_disk_tables | 21119 |
| Created_tmp_files |6 |
| Created_tmp_tables |17715532 |
+-------------------------+----------+
每次建立临时表时,Created_tmp_table都会增长,若是磁盘上建立临时表,Created_tmp_disk_tables也会增长。Created_tmp_files表示MySQL服务建立的临时文件数,比较理想的配置是:
Created_tmp_disk_tables/ Created_tmp_files * 100% <= 25%
好比上面的服务器Created_tmp_disk_tables/ Created_tmp_files * 100% =1.20%,就至关不错。咱们在看一下MySQL服务器对临时表的配置:
mysql> show variables where Variable_name in('tmp_table_size','max_heap_table_size');
+---------------------+---------+
| Variable_name |Value |
+---------------------+---------+
| max_heap_table_size | 2097152 |
| tmp_table_size |2097152 |
+---------------------+---------+
Open_tables表示打开表的数量,Opened_tables表示打开过的表数量,咱们能够用以下命令查看其具体状况:
mysql> show global status like 'open%tables%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Open_tables | 351 |
| Opened_tables | 1455 |
若是Opened_tables数量过大,说明配置中table_open_cache的值可能过小。咱们查询下服务器table_open_cache;
mysql> show variables like 'table_open_cache';
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| table_open_cache | 2048 |
+------------------+-------+
比较合适的值为:
open_tables/ opened_tables* 100% > = 85%
open_tables/ table_open_cache* 100% < = 95%
若是咱们在MySQL服务器的配置文件中设置了thread_cache_size,当客户端断开时,服务器处理此客户请求的线程将会缓存起来以响应一下客户而不是销毁(前提是缓存数未达上线)Thread_created表示建立过的线程数,咱们能够用以下命令查看:
mysql> show global status like 'thread%';
+-------------------+-------+
| Variable_name | Value |
+-------------------+-------+
| Threads_cached | 40 |
| Threads_connected | 1 |
| Threads_created | 330 |
| Threads_running | 1 |
+-------------------+-------+
若是发现Threads_created的值过大的话,代表MySQL服务器一直在建立线程,这也是比较耗费资源的,能够适当增大配置文件中thread_cache_size的值。查询服务器thread_cache_size配置以下:
mysql> show variables like 'thread_cache_size';
+-------------------+-------+
| Variable_name | Value |
+-------------------+-------+
| thread_cache_size | 100 |
+-------------------+-------+
示例中的MySQL服务器仍是挺健康的。
它主要涉及两个参数,query_cache_size是设置MySQL的Query Cache大小,query_cache_type是设置使用查询缓存的类型,咱们能够用以下命令查看其具体状况:
mysql> show global status like 'qcache%';
+-------------------------+-----------+
| Variable_name |Value |
+-------------------------+-----------+
| Qcache_free_blocks |22756 |
| Qcache_free_memory |76764704 |
| Qcache_hits | 213028692 |
| Qcache_inserts |208894227 |
| Qcache_lowmem_prunes |4010916 |
| Qcache_not_cached |13385031 |
| Qcache_queries_in_cache | 43560 |
| Qcache_total_blocks |111212 |
+-------------------------+-----------+
MySQL查询缓存变量的相关解释以下:
Qcache_free_blocks: 缓存中相领内存快的个数。数目大说明可能有碎片。flush query cache会对缓存中的碎片进行整理,从而获得一个空间块。
Qcache_free_memory:缓存中的空闲空间。
Qcache_hits:多少次命中。经过这个参数能够查看到Query Cache的基本效果。
Qcache_inserts:插入次数,没插入一次查询时就增长1。命中次数除以插入次数就是命中比率。
Qcache_lowmem_prunes:多少条Query由于内存不足而被清楚出Query Cache。经过Qcache_lowmem_prunes和Query_free_memory相互结合,可以更清楚地了解到系统中Query Cache的内存大小是否真的足够,是否很是频繁地出现由于内存不足而有Query被换出的状况。
Qcache_not_cached:不适合进行缓存的查询数量,一般是因为这些查询不是select语句或用了now()之类的函数。
Qcache_queries_in_cache:当前缓存的查询和响应数量。
Qcache_total_blocks:缓存中块的数量。
咱们在查询一下服务器上关于query_cache的配置命令:
mysql> show variables like 'query_cache%';
+------------------------------+---------+
| Variable_name | Value |
+------------------------------+---------+
| query_cache_limit | 1048576 |
| query_cache_min_res_unit | 2048 |
| query_cache_size | 2097152 |
| query_cache_type | ON |
| query_cache_wlock_invalidate | OFF |
+------------------------------+---------+
字段解释以下:
query_cache_limit:超过此大小的查询将不缓存。
query_cache_min_res_unit:缓存块的最小值。
query_cache_size:查询缓存大小。
query_cache_type:缓存类型,决定缓存什么样的查询,示例中表示不缓存select sql_no_cache查询。
query_cache_wlock_invalidat:表示当有其余客户端正在对MyISAM表进行写操做,读请求是要等WRITELOCK释放资源后再查询仍是容许直接从Query Cache中读取结果,默认为OFF(能够直接从Query Cache中取得结果。)
query_cache_min_res_unit的配置是一柄双刃剑,默认是4KB,设置值大对大数据查询有好处,但若是你的查询都是小数据查询,就容易形成内存碎片和浪费。
查询缓存碎片率 =Qcache_free_blocks /Qcache_total_blocks * 100%
若是查询碎片率超过20%,能够用 flushquery cache 整理缓存碎片,或者试试减小query_cache_min_res_unit,若是你查询都是小数据库的话。
查询缓存利用率 =(Qcache_free_size – Qcache_free_memory)/query_cache_size * 100%
查询缓存利用率在25%一下的话说明query_cache_size设置得过大,可适当减小;查询缓存利用率在80%以上并且Qcache_lowmem_prunes> 50的话则说明query_cache_size可能有点小,否则就是碎片太多。
查询命中率 = (Qcache_hits- Qcache_insert)/Qcache)hits * 100%
示例服务器中的查询缓存碎片率等于20%左右,查询缓存利用率在50%,查询命中率在2%,说明命中率不好,可能写操做比较频繁,并且可能有些碎片。
它表示系统中对数据进行排序时所用的Buffer,咱们能够用以下命令查看:
mysql> show global status like 'sort%';
+-------------------+----------+
| Variable_name | Value |
+-------------------+----------+
| Sort_merge_passes | 10 |
| Sort_range | 37431240 |
| Sort_rows | 6738691532|
| Sort_scan | 1823485 |
+-------------------+----------+
Sort_merge_passes包括以下步骤:MySQL首先会尝试在内存中作排序,使用的内存大小由系统变量sort_buffer_size来决定,若是它不够大则把全部的记录都读在内存中,而MySQL则会把每次在内存中排序的结果存到临时文件中,等MySQL找到全部记录以后,再把临时文件中的记录作一次排序。此次再排序就会增长sort_merge_passes。实际上,MySQL会用另一个临时文件来存储再次排序的结果,因此咱们一般会看到sort_merge_passes增长的数值是建临时文件数的两倍。由于用到了临时文件,因此速度可能会比较慢,增大sort_buffer_size会减小sort_merge_passes和建立临时文件的次数,但盲目地增大sort_buffer_size并不必定能提升速度。
咱们如今处理MySQL故障时,发现当Open_files大于open_files_limit值时,MySQL数据库就会发生卡住的现象,致使Nginx服务器打不开相应页面。这个问题你们在工做中应注意,咱们能够用以下命令查看其具体状况:
show global status like 'open_files';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Open_files | 1481 |
+---------------+-------+
mysql> show global status like 'open_files_limit';
+------------------+-------+
| Variable_name | Value |
+------------------+--------+
| Open_files_limit | 4509 |
+------------------+--------+
比较合适的设置是:Open_files/ Open_files_limit * 100% < = 75%
InnoDB存储引擎的缓存机制和MyISAM的最大区别就在于,InnoDB不只仅缓存索引,同时还会缓存实际的数据。此参数用来设置InnoDB最主要的Buffer的大小,也就是缓存用户表及索引数据的最主要缓存空间,对InnoDB总体性能影响也最大。
不管是MySQL官方手册仍是网络上许多人分享的InnoDB优化建议,都是简单地建议将此值设置为整个系统物理内存的50%~80%。这种作法其实不妥,咱们应根据实际的运行场景来正确设置此项参数。
不少时候咱们会发现,经过参数设置进行性能优化所带来的性能提高,并不如许多人想象的那样会产生质的飞跃,除非是以前的设置存在严重不合理的状况。咱们不能将性能调优彻底依托与经过DBA在数据库上线后进行参数调整,而应该在系统设计和开发阶段就尽量减小性能问题。(重点在于前期架构合理的设计及开发的程序合理)
若是凭借MySQL的优化任没法顶住压力,这个时候咱们就必须考虑MySQL的可扩展性架构了(有人称为MySQL集群)它有如下明显的优点:
成本低,很容易经过价格低廉Pc server搭建出一个处理能力很是强大的计算机集群。
不太容易遇到瓶颈,由于很容易经过添加主机来增长处理能力。
单节点故障对系统的总体影响较小。
目前可行的方案以下:
(1)MySQL Cluter
其特色为可用性很是高,性能很是好。每份数据至少可在不一样主机上存一份副本,且冗余数据拷贝实时同步。但它的维护很是复杂,存在部分Bug,目前还不适合比较核心的线上系统,因此暂时不推荐。
(2)DRBD磁盘网络镜像方案
其特色为软件功能强大,数据可在底层快设备级别跨物理主机镜像,且可根据性能可靠性要求配置不一样级别的同步。I/O操做会保持顺序,可知足数据库对数据一致性的苛刻要求。但非分布式文件系统环境没法支持镜像数据同时可见,性能和可靠性二者互相矛盾,没法适用于性能和可靠性要求都比较苛刻的环境,维护成本高于MySQL Replication。另外,DRBD是官方推荐的可用于MySQL的搞可用方案之一,你们可根据实际环境来考虑是否部署。
(3)MySQL Replication
在工做中,此种MySQL搞可用、高扩展性架构也是用得最多的,我也推荐此方案,一主多从、双主多从是生产环境常见的高可用架构方案。