Mysql参数优化对于不同的网站,及在线量等,以及机器硬件的配置都有关系,优化不可能一次性完成,需要不断的观察以及调试,才有可能的得到最佳的效果
为了测试我们创建一个test1的库创建一个tb1的表,然后导入2万行数据,脚本如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
#!/bin/bash
HOSTNAME=
"localhost"
PORT=
"3306"
USERNAME=
"root"
PASSWORD
=
"pwd123"
DBNAME=
"test1"
TABLENAME=
"tb1"
#
create
database
mysql -h ${HOSTNAME} -P${PORT} -u${USERNAME} -p${
PASSWORD
} -e
"drop database if exists ${DBNAME}"
create_db_sql=
"create database if not exists ${DBNAME}"
mysql -h ${HOSTNAME} -P${PORT} -u${USERNAME} -p${
PASSWORD
} -e
"${create_db_sql}"
#
create
table
create_table_sql=
"create table if not exists ${TABLENAME}(stuid int not null primary key,stuname varchar(20) not null,stusex char(1)
not null,cardid varchar(20) not null,birthday datetime,entertime datetime,address varchar(100)default null)"
mysql -h ${HOSTNAME} -P${PORT} -u${USERNAME} -p${
PASSWORD
} ${DBNAME} -e
"${create_table_sql}"
#
insert
data
to
table
i=
"1"
while [ $i -le 20000 ]
do
insert_sql=
"insert into ${TABLENAME} values($i,'zhangsan','1','21276387261874682','1999-10-10','2017-10-24','beijingchangpingqu')"
mysql -h ${HOSTNAME} -P${PORT} -u${USERNAME} -p${
PASSWORD
} ${DBNAME} -e
"${insert_sql}"
let i++
done
#
select
data
select_sql=
"select count(*)from${TABLENAME}"
mysql -h ${HOSTNAME} -P${PORT} -u${USERNAME} -p${
PASSWORD
} ${DBNAME} -e
"${select_sql}"
|
1
2
3
4
5
6
7
|
mysql>
select
count
(*)
from
test1.tb1;
+
----------+
|
count
(*) |
+
----------+
| 20000 |
+
----------+
1 row
in
set
(0.15 sec)
|
在手动插入一条其他数据。
1
2
|
mysql>
insert
into
test1.tb1
values
(20001,
'admin'
,
'0'
,
'12322112123332'
,
'1999-1-1'
,
'2019-9-1'
,
'ppppppppppp'
);
Query OK, 1 row affected (0.00 sec)
|
在没有优化之前我们使用mysqlslap来进行压力测试
1
2
3
4
|
[root@yankerp ~]# mysqlslap
--defaults-file=/etc/my.cnf \
>
--concurrency=100 --iterations=1 --create-schema='test1' \
>
--query='select * from test1.tb1' engine=innodb \
>
--number-of-queries=2000 -uroot -ppwd123 -verbose
|
下面列出了对性能优化影响较大的主要变量,主要分为连接请求的变量和缓冲区的变量
1) 连接请求的变量
Max_connections
Mysql的最大连接数,如果服务器的并发请求量比较大,可以调高这个值,当然这是要建立在机器能够支撑的情况下,因为如果连接数越来越多,mysql会为每个连接提供缓冲区,就会开销的越多的内存,所以需要适当的调整该值,不能随便去提高设值。
1
|
Mysql>show variables
like
‘max_connections’最大连接数
|
1
|
Mysql>show status
like
‘max_user_connections’响应的连接数
|
如果max_used_connections跟max_connections相同那么就是max_connections设置过低或者超过服务器的负载上限了,低于10%则设置过大
1.首先查看mysql默认的最大连接数(默认为151)
1
2
3
4
5
6
7
|
mysql> show variables
like
"max_connections%"
;
+
-----------------+-------+
| Variable_name | Value |
+
-----------------+-------+
| max_connections | 151 |
+
-----------------+-------+
1 row
in
set
(0.02 sec)
|
修改/etc/my.cnf在[mysqld]下添加以下内容,设置最大连接数为1024,重启mysql服务验证
Max_connections=1024
查看修改后的最大连接数
1
2
3
4
5
6
7
|
mysql> show variables
like
"max_connections%"
;
+
-----------------+-------+
| Variable_name | Value |
+
-----------------+-------+
| max_connections | 1024 |
+
-----------------+-------+
1 row
in
set
(0.00 sec)
|
mysql能暂存的连接数量,当主要mysql线程在一个很短时间内得到非常多的连接请求时候它就会起作用,如果mysql的连接数据达到max_connections时候,新来的请求将会被存在堆栈中,等待某一连接释放资源,该推栈的数量及back_log,如果等待连接的数量超过back_log,将不被授予连接资源
back_log值指出在mysql暂时停止回答新请求之前的短时间内有多少个请求可以被存在推栈中,只有如果期望在一个短时间内有很多连接的时候需要增加它
当我们在观察主机进程列表
1
|
mysql>show
full
processlist
|
1
|
3 | root | localhost |
NULL
| Query | 0 | starting | show
full
processlist
|
1
2
3
4
5
6
7
|
mysql> show variables
like
'back_log'
;
+
---------------+-------+
| Variable_name | Value |
+
---------------+-------+
| back_log | 254 |
+
---------------+-------+
1 row
in
set
(0.00 sec)
|
1
2
3
4
5
6
7
|
mysql> show variables
like
'back_log'
;
+
---------------+-------+
| Variable_name | Value |
+
---------------+-------+
| back_log | 1024 |
+
---------------+-------+
1 row
in
set
(0.00 sec)
|
wait_timeout:指的是mysql在关闭一个非交互的连接之前所要等待的秒数
interactive_timeoutz:指的是mysql在关闭一个交互的连接之前所需要等待的秒数,比如我们在终端上进行mysql管理,使用的即使交互的连接,这时候,如果没有操作的时间超过了interactive_time设置的时间就会自动的断开,默认的是28800,可调优为7200。wait_timeout:如果设置太小,那么连接关闭的就很快,从而使一些持久的连接不起作用
如果设置太大,容易造成连接打开时间过长,在show processlist时候,能看到很多的连接 一般希望wait_timeout尽可能低
查看wait_timeout和interactive_timeout的设置
1
|
mysql> show variables
like
"%wait_timeout%"
;
|
1
|
mysql> show variables
like
"%interactive_timeout%"
;
|
修改/etc/my.cnf,添加以下内容
wait_timeout=100
interactive_timeout=100
重启mysql服务,再次查看
4)key_buffer_size
key_buffer_size指定索引缓冲区的大小,它决定索引处理的速度,尤其是索引读的速度,通过key_read_requests和key_reads可以直到key_baffer_size设置是否合理。
可以通过show status like "key_read%"查看
1
2
3
4
5
6
7
|
mysql> show variables
like
"key_buffer_size%"
;
+
-----------------+---------+
| Variable_name | Value |
+
-----------------+---------+
| key_buffer_size | 8388608 |
+
-----------------+---------+
1 row
in
set
(0.00 sec)
|
1
2
3
4
5
6
7
8
|
mysql> show status
like
"key_read%"
;
+
-------------------+-------+
| Variable_name | Value |
+
-------------------+-------+
| Key_read_requests | 6 |
| Key_reads | 3 |
+
-------------------+-------+
2
rows
in
set
(0.01 sec)
|
1
2
3
4
5
6
7
8
9
|
mysql> show status
like
"created_tmp%"
;
+
-------------------------+-------+
| Variable_name | Value |
+
-------------------------+-------+
| Created_tmp_disk_tables | 0 |
| Created_tmp_files | 5 |
| Created_tmp_tables | 0 |
+
-------------------------+-------+
3
rows
in
set
(0.00 sec)
|
key_buffer_size=128M
重启mysql服务后再次查看
5)query_cache_size(查询缓存简称QC)
使用查询缓冲,mysql将查询结果存放在缓冲区中,今后对于同样的select语句(区分大小写),将直接从缓冲区中读取结果。
一个sql查询如果以select开头,那么mysql服务器将尝试对其使用查询缓存。
注:两个sql语句,只要想差哪怕是一个字符(列如大小写不一样;多一个空格等),那么这两个sql将使用不同的一个cache。
上述状态值可以使用show status like 'Qcache%获得'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
mysql> show status
like
"%Qcache%"
;
+
-------------------------+---------+
| Variable_name | Value |
+
-------------------------+---------+
| Qcache_free_blocks | 1 |
| Qcache_free_memory | 1031832 |
| Qcache_hits | 0 |
| Qcache_inserts | 0 |
| Qcache_lowmem_prunes | 0 |
| Qcache_not_cached | 0 |
| Qcache_queries_in_cache | 0 |
| Qcache_total_blocks | 1 |
+
-------------------------+---------+
8
rows
in
set
(0.00 sec)
|
上图可以看出query_cache_type为off表示不缓存任何查询
各字段的解释:query_cache_type:缓存类型,决定缓存什么样的查询,注意这个值不能随便设置,必须设置为数字,可选项目以及说明如下:
如果设置为0,那么可以说,你的缓存根本就没有用,相当于禁用了。
如果设置为1,将会缓存所有的结果,除非你的select语句使用SQL_NO_CACHE禁用了查询缓存。
如果设置为2,则只缓存在select语句中通过SQL_CACHE指定需要缓存的查询。
修改/etc/my.cnf,配置完后的部分文件如下:
query_cache_size=256Mquery_cache_type=1
保存文件,重新启动MYSQL服务,然后通过如下查询来验证是否真正开启了:
6)max_connect_errors是一个mysql中与安全有关的计数器值,它负责阻止过多尝试失败的客户端以防止暴力破解密码等情况,当超过指定次数,mysql服务器将禁止host的连接请求,直到mysql服务器重启或通过flush hosts命令清空此host的相关信息 max_connect_errors的值与性能并无太大关系。
修改/etc/my.cnf文件,在[mysqld]下面添加如下内容
max_connect_errors=20
修改完后重启mysql服务
7)sort_buffer_size
每个需要进行排序的线程分配该大小的一个缓冲区。增加这值加速ORDER BY 或GROUP BY操作,Sort_Buffer_Size并不是越大越好,由于是connection级的参数,过大的设置+高并发可能会耗尽系统内存资源。列如:500个连接将会消耗500*sort_buffer_size(2M)=1G内存
修改/etc/my.cnf文件,在[mysqld]下面添加如下:
sort_buffer_size=2M
8)max_allowed_packet=32M
mysql根据配置文件会限制,server接受的数据包大小。有时候大的插入和更新会受max_allowed_packet参数限制,导致写入或者更新失败,更大值是1GB,必须设置1024的倍数
9)join_buffer_size=2M
用于表间关联缓存的大小,和sort_buffer_size一样,该参数对应的分配内存也是每个连接独享。
10)thread_cache_size = 300
服务器线程缓存,这个值表示可以重新利用保存在缓存中线程的数量,当断开连接时,那么客户端的线程将被放到缓存中以响应下一个客户而不是销毁(前提是缓存数未达上限),如果线程重新被请求,那么请求将从缓存中读取,如果缓存中是空的或者是新的请求,那么这个线程将被重新创建,如果有很多新的线程,增加这个值可以改善系统性能.通过比较 Connections 和 Threads_created 状态的变量,可以看到这个变量的作用。设置规则如下:1GB 内存配置为8,2GB配置为16,3GB配置为32,4GB或更高内存,可配置更大。服务器处理此客户的线程将会缓存起来以响应下一个客户而不是销毁(前提是缓存数未达上限)
试图连接到MySQL(不管是否连接成功)的连接数
1
2
3
4
5
6
7
8
9
10
|
mysql> show status
like
'threads_%'
;
+
-------------------+-------+
| Variable_name | Value |
+
-------------------+-------+
| Threads_cached | 0 |
| Threads_connected | 1 |
| Threads_created | 1 |
| Threads_running | 1 |
+
-------------------+-------+
4
rows
in
set
(0.00 sec)
|
Threads_cached :代表当前此时此刻线程缓存中有多少空闲线程。
Threads_connected :代表当前已建立连接的数量,因为一个连接就需要一个线程,所以也可以看成当前被使用的线程数。
Threads_created :代表从最近一次服务启动,已创建线程的数量,如果发现Threads_created值过大的话,表明MySQL服务器一直在创建线程,这也是比较耗资源,可以适当增加配置文件中thread_cache_size值。
Threads_running :代表当前激活的(非睡眠状态)线程数。并不是代表正在使用的线程数,有时候连接已建立,但是连接处于sleep状态。
11.innodb_buffer_pool_size
对于InnoDB表来说,innodb_buffer_pool_size的作用就相当于key_buffer_size对于MyISAM表的作用一样。InnoDB使用该参数指定大小的内存来缓冲数据和索引。对于单独的MySQL 数据库服务器,最大可以把该值设置成物理内存的80%。
1
|
mysql> show variables
like
'innodb_buffer_pool_size'
;
|
设置innodb_buffer_pool_size
修改/etc/my.cnf文件,在[mysqld]下面添加如下内容
1
|
innodb_buffer_pool_size= 2048M
|
重启MySQL Server进入后,查看设置已经生效。
12. innodb_flush_log_at_trx_commit
主要控制了innodb将log buffer中的数据写入日志文件并flush磁盘的时间点,取值分别为0、1、2三个。0,表示当事务提交时,不做日志写入操作,而是每秒钟将log buffer中的数据写入日志文件并flush磁盘一次;1,则在每秒钟或是每次事物的提交都会引起日志文件写入、flush磁盘的操作,确保了事务的ACID;设置为2,每次事务提交引起写入日志文件的动作,但每秒钟完成一次flush磁盘操作。
实际测试发现,该值对插入数据的速度影响非常大,设置为2时插入10000条记录只需要2秒,设置为0时只需要1秒,而设置为1时则需要229秒。因此,MySQL手册也建议尽量将插入操作合并成一个事务,这样可以大幅提高速度。
根据MySQL手册,在允许丢失最近部分事务的危险的前提下,可以把该值设为0或2。
13.innodb_thread_concurrency = 0
此参数用来设置innodb线程的并发数量,默认值为0表示不限制,若要设置则与服务器的CPU核数相同或是cpu的核数的2倍,建议用默认设置,一般为8.
14.innodb_log_buffer_size
此参数确定些日志文件所用的内存大小,以M为单位。缓冲区更大能提高性能,对于较大的事务,可以增大缓存大小。
innodb_log_buffer_size=32M
15. innodb_log_file_size = 50M
此参数确定数据日志文件的大小,以M为单位,更大的设置可以提高性能.
16. innodb_log_files_in_group = 3
为提高性能,MySQL可以以循环方式将日志文件写到多个文件。推荐设置为3
17.read_buffer_size = 1M
MySql 读入缓冲区大小。对表进行顺序扫描的请求将分配一个读入缓冲区,MySql会为它分配一段内存缓冲区。如果对表的顺序扫描请求非常频繁,并且你认为频繁扫描进行得太慢,可以通过增加该变量值以及内存缓冲区大小提高其性能。和 sort_buffer_size一样,该参数对应的分配内存也是每个连接独享
18.read_rnd_buffer_size = 16M
MySql 的随机读(查询操作)缓冲区大小。当按任意顺序读取行时(例如,按照排序顺序),将分配一个随机读缓存区。进行排序查询时,MySql会首先扫描一遍该缓冲,以避免磁盘搜索,提高查询速度,如果需要排序大量数据,可适当调高该值。但MySql会为每个客户连接发放该缓冲空间,所以应尽量适当设置该值,以避免内存开销过大。
注:顺序读是指根据索引的叶节点数据就能顺序地读取所需要的行数据。随机读是指一般需要根据辅助索引叶节点中的主键寻找实际行数据,而辅助索引和主键所在的数据段不同,因此访问方式是随机的。
19.bulk_insert_buffer_size = 64M
批量插入数据缓存大小,可以有效提高插入效率,默认为8M
20.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
相关优化参数总结:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
slow_query_log=1
slow_query_log_file = /usr/
local
/mysql/data/slow_query_log
long_query_time=1
log-queries-
not
-using-indexes
max_connections=1024
back_log=128
wait_timeout=60
interactive_timeout=7200
key_buffer_size=256M
query_cache_size=256M
query_cache_type=1
query_cache_limit=50M
max_connect_errors=20
sort_buffer_size=2M
max_allowed_packet=32M
join_buffer_size=2M
thread_cache_size=200
innodb_buffer_pool_size=2048M
innodb_flush_log_at_trx_commit=1
innodb_log_buffer_size=32M
innodb_log_file_size=128M
innodb_log_files_in_group=3
log-bin=mysql-bin
binlog_cache_size=2M
max_binlog_cache_size=8M
max_binlog_size=512M
expire_logs_days=7
read_buffer_size=1M
read_rnd_buffer_size=16M
bulk_insert_buffer_size=64M
server-id=1
|
希望对您有所帮助,再见!