MySQL的配置优化

需求:MySQL的参数优化对于不同的网站,极其在线量,访问量,帖子数量,网络情况,以及机器硬件配置都有关系,优化不可能一次万次,需要在工作当中不断的监控观察和调试,才能得到最佳的效果。性能优化影响最大的变量分为连接请求变量和缓冲区变量。

理论总结:

        修改vim/my.cnf

        max_connections = 1024    设置最大连接数为1024

        back_log = 100      暂存的连接数量 

        wait_timeout = 100

        interactive_timeout = 100 修改interactive的值

        key_bugger_size =268435456和key_buffer_size=256M   调整

        query_cache_size = 256M    缓存大小

        query_cache_type = 1    缓冲类型

        max_connect_errors = 20    开启安全有关的计数器,host连接请求多余20禁止连接请求

        sort_buffer_size = 2M     为进行排序的线程分配该大小的一个缓冲区

连接请求变量

    max_connections。如果服务器的并发连接请求量大,此值应相应调高。增加并行连接量是建立服务器能支撑的情况下,连接数越多,则mysql为内个连接提供连接缓冲区开销的内存越大,所以应适当调整该值。数值过小会经常出现错误ERROR 1040:Too many connections错误。

            show status like 'connections';通配符查看当前连接数量,无论是否成功都会记录。

            show variables like '%max_connections%'    最大连接数

            show status like '%max_used_connections'    响应连接数

            show variables like ’%wait_timeout%’    查看wait_timeout

            show variables like '%interactive_timeout%'   查看interactive

            show status like 'qcache%';    可以指定query_cache_size设置是否合理

            show variables like 'query_cache%';    验证query_cache配置是否开启

            max_used_connections跟max_connections相同那么就是max_connections设置过低或超过服务器负载上限,地狱10%则设置过大。

    暂存的连接数据:back_log。主要mysql线程在一个短时间内得到很多请求就会起作用。连接数值达到max_connections时,新来的请求将被存在堆栈中,等待某一连接释放资源。等待连接数量超过back_log则不被授予连接资源。back_log暂时停止回答新请求之前的短时间内有多少个请求可以被存在堆栈中。如果希望在短时间很多连接,需要增加back_log值。

                查看主机进程表:show variables processlist

                查看back_log的值:show variables like 'back_log'

                如果主机进程表中大量的待连接进程时,要加大max_connections的值。

     mysql关闭一个非交互的连接之前索要等待的秒数wait_timeout和interactive_timeout

            wait_timeout指mysql在关闭一个非交互的连接之前所要等待的秒数

            interactive_timeout指的是mysql在关闭一个交互的连接之前索要等待的秒数,就比如我们在终端上进入mysql管理,使用的即是交互式连接,如果操作时间超过了interactive_timeout设置的值,就会自动断开。

         对性能的影响 

            如果设置大小,连接关闭很快,使一些持久的连接不起作用

            如果设置太大,造成连接打开时间过长,如果执行show processlist能看到太多的sleep状态的连接,造成too many connections错误

            一般希望wait_timeout的值尽可能的低。interactive的设置对web application没有多大的影响

缓冲区变量

    全局缓冲

    指定索引缓冲区的大小,决定索引处理的速度,尤其是索引读的速度。

        状态值:key_read_requests和key_reads

                create_tmp_disk_tables

        key_reads/key_read_requests应该尽可能的低,至少是1:100,1:1000会更好

            show status like 'key_read%'

           show status like 'key_read%';

                 variables_name    value

                 key_read_requests  6

                 key_reads          3

                一共有6个索引读取请求,有3个请求在内存中没有找到直接从硬盘读取索引,计算索引未命中缓存的概率:

                key_cache_miss_rate = key_reads/key_read_requests * 100% = 50%

                key_buffer_size只对MyLSAM表起作用。即使不使用MyLSAM表,内部的临时磁盘表是MyLSAM表,也要使用该值

    查询缓冲简QC:query_cache_size

        使用查询缓冲,mysql将查询结果存放在缓冲区中,今后对于同样的select语句将直接从缓冲区中读取结果。

        一个sql语句,只要相差哪怕是一个字符,那么这两个sql将使用不同的一个CACHE

            show status like 'qcache%'

                variables_name        value

               qcache_free_blocks        1        缓冲中相邻内存块个数,该值较大,说明内存碎片多,FLUSH QUERY CACHE会对缓存中的碎片进行整理。

               qcache_free_memory        1031832    剩余的内存大小,可以较准确的观察当前系统中的quuery cache内存大小是否足够。

               qcache_hits               0    有多少命中缓存。来验证我们查询缓冲的效果,数字越大,缓冲效果明显

               qcache_inserts            0    多少此未命中然后插入,新来的sql请求的缓冲中未找到,不得不执行查询处理,值越大,表示查询缓存应用到的比较少,效果不理想。

               qcache_lowment_prunes     0    多少条query因为内存不足而被清理出query cache。通过qcache_lowmen_prunes和qcache_free_memory相互结合,更清楚了解系统中query cache的内存大小是否真足够,是否非常频繁的出现因为内存不足而又query被换出

               qcache_not_cached         1    不适合进行缓存的查询数量,这些查询不是select之类的函数。

               qcache_queries_in_cache   0    当前query cache中cache得到query数量

               qcache_total_blocks       1    当前query cache中block数量

        查询关于query_cache的配置:show variables like 'query_cache%';

                variables_name                value

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

                query_cache_min_res_unit    4096      缓冲快大小。默认是4kB,设置值大对大数据查询有好处,但如果查询都是小数据,就造成内存碎片和浪费

                query_cache_size             209715209    查询缓存大小

                query_cache_type            OFF    缓冲类型,决定缓冲什么样的查询,不能随便设置,必须设置为数字,可选项目

                    0    off,不缓冲或重新得到结果

                    1    on   缓存所有的结果,除了select sql_no_cache ...查询

                    2    dnmand 仅缓存select sql_cache...查询

                query_cache_wlock_invalidata   当有客户端正对MyLSAM表进行写操作,如果查询在query cache中,是否返回cache结果还是等写操作完成在读表获取结果

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

                       碎片率低于25%说明query_cache_size设置过大,可适当减小,查询缓冲利用率在80*以上而且qcache_lowmen_prunes>50说明query_cache_size可能有点小,要不碎片太多

                查询缓冲命中率=qcache_hits/(qcache_hits+qcache_inserts)*100%

              query cache的限制

                所有子查询中的外部查询sql不能被cache

                在procedure,function以及trigger中的query不能被cache

                包含其他很多每次执行可能得到不一样的结果的函数的query不能被cache

    mysql中与安全有关的计数器值:max_connect_errors,负责阻止过多尝试失败的客户端以防暴力破解密码,超过指定次数,将禁止host连接请求。直到mysl服务器重启或通过flush hosts命令清空此host的相关信息。

    需要进行排序的线程分配该大小的一个缓冲区:sort_buffer_size。加速order by或group by操作。sort_buffer_size是一个connections级参数,每个connection第一次需要使用这个buffer的时候,一次性分配设置的内存。这个值不是越大越好,过大高并发可能会耗尽传统内存资源

    限制server接收数据包大小,大的插入和更新会收max_allowed_packet参数限制,导致写入或者更新失败。最大值是1GB,必须设置1024的倍数。

    表间关联缓存的大小,与sort_buffer_size一样,对应的分配内存也是每个连接独享

    服务器线程缓存,表示可以重新利用保持在缓冲中线程的数量,端口连接时,客户端的线程放到缓存中以响应下一个客户而不是销毁,如果线程重新被请求,请求将从缓存中读取,缓存中是空的或者是新的请求,这个线程将被重新创建,如果有很多新线程,增加这个值可以改善系统性能,通过比较connections和threads_created状态的变量,可以看到这个变量的作用

        试图连接mysql的连接数:show status like 'conections';

        试图连接mysql的连接数(不管连接是否成功):show status like 'threads_%';

配置InnoDB的几个变量

        修改/etc/my.cnf文件,在[mysqld]下面添加

            innoDB_buffer_pool_size = 2048M

    相当于key_buffer_size对于MyLSAM表的作用一样。InnoDB使用该参数指定大小的内存来缓冲数据和索引,单独的mysql数据库,最大可以把该值设成物理内存的80&innodb_buffer_pool_size

    控制innodb将log buffer中的数据写入日志文件并flush磁盘的时间点,取值分别是0,1,2.0表示事务提交时,不做日志写入操作,而是每秒钟将log buffer中的数据写入日志文件并flush磁盘一次;1在每秒钟或每次事务的提交会引起日志文件写入flush磁盘的操作,确保了事务的ACID;2每次事务提交引起写入日志文件的动作,但每秒钟完成一次flush磁盘操作。

                实际操作发现,该值对插入数据的速度影响大,设置为2是插入10000条记录只需要2秒,设置为0是只需1秒,设置为1是需要229秒。因此mysql手册建议尽量将插入操作合并和一个事务,可以提高速度。

    设置innodb线程的并发数量,默认值为0表示不限制,若要设置则与服务器cpu核数相同或是cpu的核数的2倍,建议使用默认设置,一般为8.:innodb_thread_concurrency = 0

    确定此日志文件所用内存大小,以M为单位,缓冲区更大能提高性能,对于较大的事务,可以增大缓存大小 innodb_log_bugger)size = 32M

    确定日志文件的大小,以M为单位,更大的设置可以提供性能:innodb_log_file_size = 50M

    提高性能,mysql可以以循环方式将日志文件写到多个文件,推荐设置为3:innodb_log_iles_in_group = 3

    mysql读入缓冲区大小,对表进行顺序扫描的请求将分配一个读入缓冲区,mysql会为它分配一端内存缓冲区,如果对表的顺序扫描请求非常频繁,并且认为频繁扫描进行太慢,可以通过增加该变量值以及内存缓冲区大小提高其性能。和sort_buffer_size一样,该参数对应的分配内存也是每个连接独享。read_buffer_size = 1M

    随机读缓冲区大小,当按任意顺序读取行时,将分配一个随机读缓冲区,进行排序查询是,mysql会首先扫描一遍该缓冲,以避免磁盘搜索,提高查询速度,如果需要排序大量数据,可适当调高该值。但mysql会为每个客户连接发放该缓冲空间,所以应尽量适当设置该值,避免内存开销过大。read_rnd_buffer_size = 16M

   

    bulk_insert_buffer_size = 64M 批量插入数据缓存大小,可以有效提高插入效率,默认为8M

    binary log

    log-bin=/usr/local/mysql/data/mysql-bin

    binlog_cache_size = 2M  //为每个session 分配的内存,在事务过程中用来存储二进制日志的缓存, 提高记录bin-log的效率。没有什么大事务,dml也不是很频繁的情况下可以设置小一点,如果事务大而且多,dml操作也频繁,则可以适当的调大一点。前者建议是--1M,后者建议是:即 2--4M

max_binlog_cache_size = 8M //表示的是binlog 能够使用的最大cache 内存大小

max_binlog_size= 512M  //指定binlog日志文件的大小,如果当前的日志大小达到max_binlog_size,还会自动创建新的二进制日志。你不能将该变量设置为大于1GB或小于4096字节。默认值是1GB。在导入大容量的sql文件时,建议关闭sql_log_bin,否则硬盘扛不住,而且建议定期做删除。

expire_logs_days = 7  //定义了mysql清除过期日志的时间。
二进制日志自动删除的天数。默认值为0,表示没有自动删除

mysqladmin flush-logs 也可以重新开始新的binarylog

在优化之前执行mysqlslap工具进行测试

[root@localhost ~]#mysqlslap--defaults-file=/etc/my.cnf --concurrency=10 --iterations=1--create-schema='test1' --query='select * from test1.tb1' --engine=innodb--number-of-queries=2000 -uroot -p123456 –verbose

显示结果:

Benchmark

        Runningfor engine innodb

        Averagenumber of seconds to run all queries: 13.837 seconds

        Minimumnumber of seconds to run all queries: 13.837 seconds

        Maximumnumber of seconds to run all queries: 13.837 seconds

        Numberof clients running queries: 10

        Averagenumber of queries per client: 200

优化之后执行mysqlslap工具进行测试

[root@localhost ~]#mysqlslap --defaults-file=/etc/my.cnf--concurrency=10 --iterations=1 --create-schema='test1' --query='select * fromtest1.tb1' --engine=innodb --number-of-queries=2000 -uroot -p123456 –verbose

显示结果:

Benchmark

        Runningfor engine innodb

        Averagenumber of seconds to run all queries: 4.199 seconds

        Minimumnumber of seconds to run all queries: 4.199 seconds

        Maximumnumber of seconds to run all queries: 4.199 seconds

        Numberof clients running queries: 10

        Averagenumber of queries per client: 200

猜你喜欢

转载自www.linuxidc.com/Linux/2017-03/141899.htm