status优化mysql

  1. 1.       慢查询。

mysql> show global variables like '%slow%' ; html

+---------------------+-------------------------------------+ mysql

| Variable_name       | Value                               | sql

+---------------------+-------------------------------------+ 缓存

| log_slow_queries    | ON                                  |  是否开启 服务器

| slow_launch_time    | 2                                   | 并发

| slow_query_log      | ON                                  | 高并发

| slow_query_log_file | /usr/local/mysql/var/LNMP4-slow.log |        存放位置 性能

+---------------------+-------------------------------------+ 大数据

4 rows in set (0.00 sec) 线程

 

mysql> show global status like '%slow%';

+---------------------+-------+

| Variable_name       | Value |

+---------------------+-------+

| Slow_launch_threads | 0     |

| Slow_queries        | 0    |         查看有多少条慢查询

+---------------------+-------+

2 rows in set (0.00 sec)

打开慢查询日志可能会对系统性能有一点点影响,若是你的mysql是主-从结构,能够考虑打开其中一台从服务器的慢查询日志,这样既能够监控慢查询,对系统性能影响又小。

 

  1. 2.       链接数。

 mysql> show global variables like '%max_connect%' ;

+--------------------+-------+

| Variable_name      | Value |

+--------------------+-------+

| max_connect_errors | 30000 |

| max_connections    | 5000  |              最大链接数

+--------------------+-------+

2 rows in set (0.00 sec)

 

mysql> show global status like 'Max_%connect%';

+----------------------+-------+

| Variable_name        | Value |

+----------------------+-------+

| Max_used_connections | 10    |

+----------------------+-------+

1 row in set (0.00 sec)

比较理想的设置是

max_used_connections / max_connections * 100% ≈ 85%

 

 

  1. 3.       Key_buffer_size

key_buffer_size是对myisam表性能影响最大的一个参数,下面一台以myisam为主要存储引擎服务器的配置:

mysql> show global variables like 'key_buffer_size';

+-----------------+-----------+

| Variable_name   | Value     |

+-----------------+-----------+

| key_buffer_size | 536870912 |                  512M

+-----------------+-----------+

分配了512mb内存给key_buffer_size,咱们再看一下key_buffer_size的使用状况:

1 row in set (0.00 sec)

mysql> show global status like '%key_read%';

+-------------------+-------+

| Variable_name     | Value |

+-------------------+-------+

| Key_read_requests | 7696  |

| Key_reads         | 99    |

+-------------------+-------+

2 rows in set (0.00 sec)

计算索引未命中缓存的几率:

key_cache_miss_rate = key_reads / key_read_requests * 100%

key_cache_miss_rate在0.1%如下都很好(每1000个请求有一个直接读硬盘),若是key_cache_miss_rate在0.01%如下的话,key_buffer_size分配的过多,能够适当减小。

 

 

mysql服务器还提供了key_blocks_*参数:

mysql> show global status like '%key_block%';

+------------------------+--------+

| Variable_name          | Value  |

+------------------------+--------+

| Key_blocks_not_flushed | 0      |

| Key_blocks_unused      | 428585 |

| Key_blocks_used        | 99     |

+------------------------+--------+

3 rows in set (0.00 sec)

key_blocks_unused表示未使用的缓存簇(blocks)数,key_blocks_used表示曾经用到的最大的blocks数,好比这台服务器,全部的缓存都用到了,要么增长key_buffer_size,要么就是过渡索引了,把缓存占满了。比较理想的设置:

key_blocks_used / (key_blocks_unused + key_blocks_used) * 100% ≈ 80%

 

  1. 4.       临时表

 mysql> show global status like '%created_tmp%';

+-------------------------+-------+

| Variable_name           | Value |

+-------------------------+-------+

| Created_tmp_disk_tables | 2     |

| Created_tmp_files       | 0     |

| Created_tmp_tables      | 162   |

+-------------------------+-------+

3 rows in set (0.00 sec)

 

每次建立临时表,created_tmp_tables增长,若是是在磁盘上建立临时表,created_tmp_disk_tables也增长,created_tmp_files表示mysql服务建立的临时文件文件数,比较理想的配置是:

  created_tmp_disk_tables / created_tmp_tables * 100% <= 25%好比上面的服务器created_tmp_disk_tables / created_tmp_tables * 100% = 1.20%,应该至关好了。咱们再看一下mysql服务器对临时表的配置:

mysql> show global variables where Variable_name = 'max_heap_table_size' or Variable_name = 'tmp_table_size';

+---------------------+-----------+

| Variable_name       | Value     |

+---------------------+-----------+

| max_heap_table_size | 268435456 |        256M

| tmp_table_size      | 134217728 |        128M

+---------------------+-----------+

2 rows in set (0.00 sec)

只有256mb如下的临时表才能所有放内存,超过的就会用到硬盘临时表。

  1. 5.       open table状况

 mysql> show global status like 'open%tables%';

+---------------+-------+

| Variable_name | Value |

+---------------+-------+

| Open_tables   | 142   |

| Opened_tables | 227   |

+---------------+-------+

2 rows in set (0.00 sec)

 open_tables表示打开表的数量,opened_tables表示打开过的表数量,若是opened_tables数量过大,说明配置中table_cache(5.1.3以后这个值叫作table_open_cache)值可能过小,咱们查询一下服务器table_cache值:

mysql> show global variables like '%open%';

+------------------+----------+

| Variable_name    | Value    |

+------------------+----------+

| open_files_limit | 99999    |

| table_open_cache | 2048     |

+------------------+----------+

3 rows in set (0.00 sec)

比较合适的值为:

open_tables / opened_tables * 100% >= 85%

open_tables / table_cache * 100% <= 95%

  1. 6.       线程使用状况

若是咱们在mysql服务器配置文件中设置了thread_cache_size,当客户端断开以后,服务器处理此客户的线程将会缓存起来以响应下一个客户而不是销毁(前提是缓存数未达上限)。

 

mysql> show global status like 'Thread%';

+-------------------+-------+

| Variable_name     | Value |

+-------------------+-------+

| Threads_cached    | 2     |

| Threads_connected | 5     |

| Threads_created   | 7     |

| Threads_running   | 2     |

+-------------------+-------+

4 rows in set (0.00 sec)

 

threads_created表示建立过的线程数,若是发现threads_created值过大的话,代表mysql服务器一直在建立线程,这也是比较耗资源,能够适当增长配置文件中thread_cache_size值,查询服务器thread_cache_size配置:

mysql> show global variables like '%thread_cache%';

+-------------------+-------+

| Variable_name     | Value |

+-------------------+-------+

| thread_cache_size | 64    |

+-------------------+-------+

1 row in set (0.00 sec)

  1. 7.       查询缓存(query cache)

   主要涉及两个参数,query_cache_size,query_cache_type

     mysql> show global status like 'qcache%';              

+-------------------------+-------+

| Variable_name           | Value |

+-------------------------+-------+

| Qcache_free_blocks      | 0     |

| Qcache_free_memory      | 0     |

| Qcache_hits             | 0     |

| Qcache_inserts          | 0     |

| Qcache_lowmem_prunes    | 0     |

| Qcache_not_cached       | 0     |

| Qcache_queries_in_cache | 0     |

| Qcache_total_blocks     | 0     |

+-------------------------+-------+

8 rows in set (0.00 sec)             因为服务器还未上线因此查询不多
 

mysql> show variables like 'query_cache%';

+------------------------------+---------+

| Variable_name                | Value   |

+------------------------------+---------+

| query_cache_limit            | 1048576 |

| query_cache_min_res_unit     | 4096    |

| query_cache_size             | 0       |

| query_cache_type             | ON      |

| query_cache_wlock_invalidate | OFF     |

+------------------------------+---------+

5 rows in set (0.00 sec)

 

各字段的解释:

query_cache_limit:超过此大小的查询将不缓存

query_cache_min_res_unit:缓存块的最小大小

query_cache_size:查询缓存大小

query_cache_type:缓存类型,决定缓存什么样的查询,示例中表示不缓存 select sql_no_cache 查询

query_cache_wlock_invalidate:当有其余客户端正在对myisam表进行写操做时,若是查询在query cache中,是否返回cache结果仍是等写操做完成再读表获取结果。

query_cache_min_res_unit的配置是一柄”双刃剑”,默认是4kb,设置值大对大数据查询有好处,但若是你的查询都是小数据查询,就容易形成内存碎片和浪费。

查询缓存碎片率 = qcache_free_blocks / qcache_total_blocks * 100%

若是查询缓存碎片率超过20%,能够用flush query cache整理缓存碎片,或者试试减少query_cache_min_res_unit,若是你的查询都是小数据量的话。

查询缓存利用率 = (query_cache_size - qcache_free_memory) / query_cache_size * 100%

查询缓存利用率在25%如下的话说明query_cache_size设置的过大,可适当减少;查询缓存利用率在80%以上并且qcache_lowmem_prunes > 50的话说明query_cache_size可能有点小,要不就是碎片太多。

查询缓存命中率 = (qcache_hits - qcache_inserts) / qcache_hits * 100%

示例服务器 查询缓存碎片率 = 20.46%,查询缓存利用率 = 62.26%,查询缓存命中率 = 1.94%,命中率不好,可能写操做比较频繁吧,并且可能有些碎片。

 

  1. 8.       排序使用状况

  mysql> show global status like 'sort%';

+-------------------+-------+

| Variable_name     | Value |

+-------------------+-------+

| Sort_merge_passes | 0     |

| Sort_range        | 0     |

| Sort_rows         | 0     |

| Sort_scan         | 0     |

+-------------------+-------+

4 rows in set (0.00 sec)

  

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 并不必定能提升速度,见 how fast can you sort data with mysql?(引自http://qroom.blogspot.com/2007/09/mysql-select-sort.html,貌似被墙)

另外,增长read_rnd_buffer_size(3.2.3是record_rnd_buffer_size)的值对排序的操做也有一点的好处,参见:http://www.mysqlperformanceblog.com/2007/07/24/what-exactly-is-read_rnd_buffer_size/

 

 

  1. 9.       文件打开数

 mysql> show global status like 'open_files';

+---------------+-------+

| Variable_name | Value |

+---------------+-------+

| Open_files    | 23    |

+---------------+-------+

1 row in set (0.01 sec)

  mysql> show global variables like '%open_file%';

+------------------+-------+

| Variable_name    | Value |

+------------------+-------+

| open_files_limit | 99999 |                    该参数修改LINUX内核

+------------------+-------+

1 row in set (0.00 sec)

 

比较合适的设置:open_files / open_files_limit * 100% <= 75%

 

 

  1. 10.   锁表状况

 mysql> show global status like 'table_lock%';

+-----------------------+-------+

| Variable_name         | Value |

+-----------------------+-------+

| Table_locks_immediate | 17    |

| Table_locks_waited    | 0     |

+-----------------------+-------+

2 rows in set (0.00 sec)

table_locks_immediate表示当即释放表锁数,table_locks_waited表示须要等待的表锁数,若是table_locks_immediate / table_locks_waited > 5000,最好采用innodb引擎,由于innodb是行锁而myisam是表锁,对于高并发写入的应用innodb效果会好些。示例中的服务器table_locks_immediate / table_locks_waited = 235,myisam就足够了。

 

  1. 11.   表扫描状况

   mysql> show global status like '%handler_read%';

+-----------------------+-------+

| Variable_name         | Value |

+-----------------------+-------+

| Handler_read_first    | 3     |

| Handler_read_key      | 0     |

| Handler_read_next     | 0     |

| Handler_read_prev     | 0     |

| Handler_read_rnd      | 0     |

| Handler_read_rnd_next | 120   |

+-----------------------+-------+

6 rows in set (0.00 sec)

 Handler_read_first 此选项代表SQL是在作一个全索引扫描,注意是所有,而不是部分,因此说若是存在WHERE语句,这个选项是不会变的。若是这个选项的数值很大,既是好事也是坏事。说它好是由于毕竟查询是在索引里完成的,而不是数据文件里,说它坏是由于大数据量时,简即是索引文件,作一次完整的扫描也是很费时的

Handler_read_key 此选项数值若是很高,那么恭喜你,你的系统高效的使用了索引,一切运转良好。

Handler_read_next 此选项代表在进行索引扫描时,按照索引从数据文件里取数据的次数。

Handler_read_prev 此选项代表在进行索引扫描时,按照索引倒序从数据文件里取数据的次数,通常就是ORDER BY ... DESC。

Handler_read_rnd 简单的说,就是查询直接操做了数据文件,不少时候表现为没有使用索引或者文件排序。

Handler_read_rnd_next 此选项代表在进行数据文件扫描时,从数据文件里取数据的次数。

 

 

mysql> show global status like '%com_select%';

+---------------+-------+

| Variable_name | Value |

+---------------+-------+

| Com_select    | 1137  |

+---------------+-------+

1 row in set (0.00 sec)

 

计算表扫描率:

表扫描率 = handler_read_rnd_next / com_select

若是表扫描率超过4000,说明进行了太多表扫描,颇有可能索引没有建好,增长read_buffer_size值会有一些好处,但最好不要超过8mb。

相关文章
相关标签/搜索