性能测试之mysql监控、优化

我们在做性能测试的目的是什么,就是要测出一个系统的瓶颈在哪里,到底是哪里影响了我们系统的性能,找到问题,然后解决它。当然一个系统由很多东西一起组合到一起,应用程序、数据库、服务器、中中间件等等很多东西。那我们测试的时候上面这些东西里面任何一个环节都可能会出问题,都可能会影响我们系统的性能。这篇博客主要讲下mysql数据库咱们在做性能测试的时候应该监控什么东西,又有哪些需要优化的地方。

一、哪些东西会影响mysql的性能?

  • 1.硬件
  • 2.系统配置
  • 3.数据库表结构
  • 4.SQL以及索引

硬件

硬件就指的是数据库服务器的配置,服务器说白了就是一台电脑而已,如果电脑的配置高,cpu处理能力强,内存大,硬盘是ssd的,那肯定性能好。当然这种方式成本也是最高的,要花钱的嘛。

系统配置

系统配置一个指的是操作系统的配置,有一些操作系统的配置会影响mysql的性能,现在咱们大多数服务器都是用的linux服务器,linux上面一切东西都是基于文件的,mysql数据里面的表、数据等等都是文件存在磁盘上的。

linux系统有一个系统配置是文件打开的数量,默认是1024,也就是最多只能打开1024个文件,那在数据库里面表比较多、并发大的情况下,这1024就不够用了,要想获取数据就得打开文件,但是打开文件的数量最多就1024个,就会导致有一些数据获取不到,就得等待别的文件关闭之后,才能打开。那就要修改系统的配置,在/etc/security/limits.conf文件里面可以修改最大打开文件的数量。

1

2

3

vi /etc/security/limits.conf

*    soft    nofile    65536

*    hard    nofile    65536

还有一些mysql配置参数会影响mysql的性能。

sleep超时时间

mysql的连接数是提前配置好的,如果程序里面代码写的不好,有一些数据库操作没有及时关闭数据库,那这个链接就不会释放会一直占用链接,这样子并发大的情况下,就会导致数据库连接数不够用了,就连接不上数据库了。mysql默认8小时不操作数据库才会自动关闭链接,所以这个sleep的超时时间会影响mysql的性能。

1

2

set global wait_timeout=600;  设置sleep的超时间,单位是秒

show variables like ‘%wait_timeout%‘;  查询超时时间

独立表空间设置

表空间是什么呢,就是每个表存放数据的地方。

举个例子,一个仓库,你要往仓库里面放东西的话,你来一些东西你就随便扔到里面,这样东西一多,你要找到一个东西就很难找了。那怎么办呢,我在仓库里面放几个货架,每个货架放同一个种类的东西,这样的话,找一个东西就很方便了。

表空间呢就和这个货架差不多,每个表我单独管理的话,那找数据就比较方便了。

mysql5.6.6之前默认是共享的表空间,mysql5.6.6之后默认是开启了独立表空间的。

那什么是共享表空间呢?

就是说这个空间是所有的表都共享的,所有的表的数据都存在一个地方的。

你想一下,所有的货架都存在一个仓库里面的话,快递员去拿货的时候,人一多,可能进出都要排队,拿货的时候就比较慢了。

所以说共享表空间如果在数据量和并发量比较大的情况下,对IO的消耗是比较大的,影响性能。

共享表空间还有一个缺点就是不能自动收缩,自动收缩是什么意思呢,刚建表的时候,表里面数据很少,就1条数据,可能占用空间就几kb,到后来数据多了,占用了10个G的空间,然后发现有一些数据都是垃圾数据,删了5个G,那这个时候表空间就不会自动减小了,它还是10个G,浪费空间。

而独立表空间就是每个表的表空间都是独享的,用仓库这个例子就是每个货架都单独在一个房间里头,这样的话快递员去拿哪个东西,直接去那个房间里就好了,不用都挤在一个仓库里了。

而使用了独立的表空间,每个表都有自己的表空间,删了数据也会自动收缩,就不会有上面的问题了。

1

2

set global innodb_file_per_table =ON;  设置独立表空间打开

show variables like ‘%per_table%‘;  #查询是否打开独立表空间

读/写进程数配置

在mysql5.5之后读、写的进程数是可以配置的。默认读和写的进程数都是4个。

当然我们都知道,人多好干活嘛。进程多就是干活的人多,具体配置根据cpu的核数和业务逻辑来配置这两个值。

假如cpu是32核的,那么就是同时可以有32个进程在运行,就可以把这两个值给调大。

假如说是系统是一个内容类的网站,大多数操作都是读操作,那么就可以把读的进程数设置大一点,写的进程数设置的小一点。

怎么修改呢,找到mysql的配置文件,在[mysqld]节点下加入下面参数的即可

1

2

innodb_read_io_threads =5 读进程数

innodb_write_io_threads =3 写进程数

缓存配置

在说缓存配置之前咱们先了解清楚,计算机在处理任务的时候是怎么处理的,先从磁盘上读取数据,然后放到内存里面,cpu去内存里面拿数据,然后处理。

在写的时候正好相反,cpu处理完之后,把数据放到内存里面,内存再放到磁盘里。

那从上面,我们发现,如果数据直接从内存里面拿的话,那速度就快很多了,我们看下面的图,读1M的数据,内存里面比从磁盘上快多少。

从上面这个图我们发现从内存里面读数据比从磁盘里面取数据快了N倍。

那到mysql里面,如果取数据的时候,mysql先把一些数据缓存到内存里面的话,取数据直接从内存里面取不就快很多了。

咱们在说mysql缓存之前,先说下mysql在执行一条查询语句的时候都做了什么。

从上面的图我们发现,mysql是有两个地方检查了内存的。如果内存里面找到我们想要的数据,那么就不去磁盘上查询数据了。那么这两个缓存都是什么,怎么配置呢。

qcache配置
  • 缓存完整的SELECT语句和查询结果,当查询命中缓存,MySQL会立刻返回结果,跳过解析、优化和执行阶段。
  • 查询缓存会跟踪系统中的每张表,如果这些表发生变化,那么和这张表相关的所有查询缓存全部失效。
  • 在检查查询缓存的时候,MySQL不会对SQL进行任何处理,它精确的使用客户端传来的查询(select),只要字符大小写,或者注释有一点点不同,查询缓存就认为是不同的查询。
  • 任何一个包含不确定的函数(比如now(),current_date())的查询不会被缓存。
  • MySQL查询缓存可以改善性能,但是在使用的时候也有一些问题需要注意:

开启查询缓存对于读写都增加了额外的开销。对于读,在查询开始前需要先检查缓存;对于写,在写入后需要更新缓存。
一般情况这些开销相对较小,所以查询缓存一般还是有好处的。但也要根据业务特征权衡是否需要开启查询缓存。

怎么配置呢,找到mysql的配置文件,在[mysqld]节点下加入下面参数的即可

1

2

3

4

5

6

7

8

query_cache_size = 200M

分配给查询缓存的总内存,一般建议不超过256M

query_cache_limit = 1M

这个选项限制了MySQL存储的最大结果。如果查询的结果比这个大,那么就不会被缓存。

下面是查看qcache的状态的语句

SHOW VARIABLES LIKE ‘%query_cache%‘;#查看qcache状态

innodb_buffer_pool配置

mysql里面还有一个缓存配置就是innodb_buffer_pool的配置,innodb是现在mysql的默认存储引擎,存储引擎说白了就mysql存数据的时候到底是怎么存的。

就是一个仓库里面怎么摆放货物的。

buffer pool是innodb存储引擎带的一个缓存池,查询数据的时候,它首先会从内存中查询,如果内存中存在的话,直接返回,从而提高查询响应时间。
innodb buffer pool和qcache的区别是:qcacche缓存的是sql语句对应的结果集,buffer pool中缓存的是表中的数据。buffer pool一般设置为服务器物理内存的70%。

怎么配置呢,找到mysql的配置文件,在[mysqld]节点下加入下面参数的即可

1

2

3

4

5

innodb_buffer_pool_size=50M #Innodb_buffer_pool的大小

innodb_buffer_pool_dump_now=on #停止MySQL服务时,InnoDB将InnoDB缓冲池中的热数据保存到本地硬盘。

innodb_buffer_pool_load_at_startup =on #启动MySQL服务时,MySQL将本地热数据加载到InnoDB缓冲池中。

SHOW VARIABLES LIKE ‘%innodb_buffer_pool%‘;#查看buffer_pool的大小

mysql架构上的优化

读写分离

多点写入

数据库表结构优化

当然系统在设计表结构的时候,一般都是架构师和一帮开发已经把表结构设计好了,咱们没达到那个级别架构上的东西咱也不懂,就在设计表结构的时候需要注意的一些东西。

1、使用可以存下你的数据的最小数据类型

2、使用简单的数据类型,int类型和varchar类型上,mysql处理int类型更简单

3、尽可能的使用not null定义字段,可以为空的字段加上默认值

因为如果不限制not null的话,字段值是可以为空的,默认为空就是null,如果是not null的话字段值写空的话,就要写‘‘,一个空的字符串。

null它在mysql里面也是要占用空间的,也不能利用索引,而空的字符串在mysql是不占用空间的,也可以利用索引。

4、时间类型的,用UNIX_TIMESTAMP,因为是int类型的

mysql索引优化

索引是什么呢,就和字典的目录一样。有目录了,那咱们查数据就快了。

最适合建索引的列是出现在where子句后面的列。

唯一索引的效果最好,因为是唯一的。

利用最左前缀。

索引并不是越多越好。

mysql索引有4种类型

1、普通索引

最普通的索引,所有列都可以加

1

create index index_name on table_name (col);

2、主键索引

建表的时候加的主键

3、组合索引

1

create index index_name on table_name (col,col2);

4、唯一索引

1

2

CREATE UNIQUE INDEX index_name

ON table_name (column_name);

去除重复、冗余索引

因为每个开发的水平都不一样,不可避免的的会出现一些重复索引的问题。那我们怎么来查找有一些冗余的索引呢。

就要借助percona-toolkit这个工具了,它里面有pt-duplicate-key-checker这个工具可以帮咱们找出来哪些表里面有冗余的索引,并给出修改索引的语句。

1

pt-duplicate-key-checker -uroot -pxxx -dxx#-u指的是用户 -p是密码 -d是数据库

这个能帮咱们找出来重复的索引,那还有一些根本就没有必要用的索引,虽然索引建立的并不是重复,但是实际上并没用查询语句用到它,怎么办呢,percona-toolkit这个工具里还有一个工具是pt-index-usage,它可以读取慢查询日志,帮咱们找到那些没用的索引。

1

pt-index-usage /opt/data/slow.log #后面是慢查询日志

慢查询日志

什么是慢查询日志呢,它这个就是个神器了,对咱们测试特别有帮助,它会记录执行时间长的sql语句,这样咱们找问题的时候就比较方便了。

1

2

3

4

5

6

7

set global slow_query_log=on;#打开慢查询日志

set global long_query_time=1;#设置记录查询超过多长时间的sql

set global slow_query_log_file=‘/tmp/slow_query.log‘;#设置mysql慢查询日志路径,此路径需要有写权限

set global log_queries_not_using_indexes=ON; #设置没有使用索引的sql记录下来

SHOW VARIABLES LIKE ‘%slow%‘;#查看慢查询配置

mysql记录的日志里面,咱们看着比较不清晰,咱们使用pt-query-digest这个工具帮咱们解析慢查询日志,它会把所有的sql的执行时间以及具体sql,执行了多少次都帮咱们统计出来。

下面是pt-query-digest的用法

1

2

3

pt-query-digest --filter=‘$event->{fingerprint} =~ m/^select/i‘ slow.log #查看包含select语句的慢查询

pt-query-digest  --since=12h  slow.log #最近12小时的

pt-query-digest  --since ‘2017-12-01 09:30:00‘ --until ‘2017-12-02 10:00:00‘ --filter=‘$event->{fingerprint} =~ m/^select/i‘  slow.log #指定时间段

如果想实时的获取有没有执行时间长的sql,用下面这个sql语句

1

select id,`user`,`host`,DB,command,`time`,state,info from information_schema.PROCESSLIST where TIME>=60;

explain

通过慢查询日志我们可以找到有问题的sql语句,那我们怎么看这个sql哪有问题呢,就要使用explain了,只要在你要执行sql语句前面加上explain即可

all<index<range<ref<eq_ref<const,system sql执行type列里最差到最优

sql优化时候需要注意的

查询条件使用索引列,排序使用索引列

避免select *,一般select * 都会造成全表扫描

尽量避免子查询,MySQL 的子查询执行计划一直存在较大的问题,虽然这个问题已经存在多年,但是到目前已经发布的所有稳定版本中都普遍存在,一直没有太大改善。虽然官方也在很早就承认这一问题,并且承诺尽快解决,但是至少到目前为止我们还没有看到哪一个版本较好的解决了这一问题。

事物

银行存钱例子。

表级锁、行级锁。

SELECT * FROM information_schema.INNODB_TRX\G

mysql性能测试工具

mysqlslap是mysql自带的一个性能测试工具。它可以模拟各种并发,以及使用哪种sql,生成多少数据,运行多久,产生报告。

常用的选项

1

2

3

4

5

6

7

8

9

10

11

--concurrency    并发数量,多个可以用逗号隔开

--engines       要测试的引擎,可以有多个,用分隔符隔开,如--engines=myisam,innodb

--auto-generate-sql        用系统自己生成的SQL脚本来测试

--auto-generate-sql-load-type    要测试的是读还是写还是两者混合的(read,write,update,mixed)

--number-of-queries           总共要运行多少次查询。每个客户运行的查询数量可以用查询总数/并发数来计算

--debug-info               额外输出CPU以及内存的相关信息

--number-int-cols             创建测试表的int型字段数量

--number-char-cols             创建测试表的chat型字段数量

--create-schema             测试的database

--query 自己的SQL           脚本执行测试

--only-print                 如果只想打印看看SQL语句是什么,可以用这个选项

下面是使用的例子

1

2

3

4

5

6

7

8

100并发,运行1000次,写操作和读操作都有,自动生成sql,int类型字段2个,char类型10个,

mysqlslap -h127.0.0.1 -uroot -p123456 --concurrency=100 --auto-generate-sql --auto-generate-sql-load-type=mixed --engine=innodb --auto-generate-sql-add-autoincrement --number-int-cols=2 --number-char-cols=10 --number-of-queries=10

100并发,运行5000次,besttest这个数据库上执行sql

mysqlslap -h127.0.0.1 -uroot -p123456 --concurrency=100  --query=‘select * from stu;‘ -create-schema=besttest --engine=innodb --number-of-queries=5000 --debug-info

100并发,运行5000次,besttest这个数据库上执行指定的sql文件

mysqlslap -h127.0.0.1 -uroot -p123456 --concurrency=100  --query=/tmp/besttest.sql -create-schema=besttest --engine=innodb --number-of-queries=5000--debug-info

原文地址:https://www.cnblogs.com/linwenbin/p/11263319.html

时间: 2024-08-01 17:25:20

性能测试之mysql监控、优化的相关文章

MySql监控优化

MySQL监控 MySQL服务器硬件和OS(操作系统)调优: 1.有足够的物理内存,能将整个InnoDB文件加载到内存里 —— 如果访问的文件在内存里,而不是在磁盘上,InnoDB会快很多. 2.全力避免 Swap 操作 — 交换(swapping)是从磁盘读取数据,所以会很慢. 3.使用电池供电的RAM(Battery-Backed RAM). 4.使用一个高级磁盘阵列 — 最好是 RAID10 或者更高. 5.避免使用RAID5 — 和校验需要确保完整性,开销很高. 6.将你的操作系统和数据

mysql监控优化(二)主从复制

复制解决的基本问题是让一台服务器的数据和其他服务器保持同步.一台主服务器的数据可以同步到多台从服务器上.并且从服务器也可以被配置为另外一台服务器的主库.主库和从库之间可以有多种不同的组合方式. MySQL支持两种复制方案:基于语句的复制(statement-based replication)和基于行的复制(Row-based replication).基于语句的复制在MySQL3.23就已经存在,它是使用较多的复制方式.基于行的复制是MySQL5.1引入的.这2种复制方式都是通过记录主服务器的

Jmeter性能测试之Monitor监控(SSHMon Samples Collector)

前面写的一篇Monitor监控有缺陷, 这篇文章使用Jmeter4.0+的版本, 使用插件SSHMon Samples Collector来做资源监控 1. 官网下载插件: plugins-manager.jar , 然后放到lib/ext目录下, 重启Jmeter. 2. 打开Options--> Plugins Manager, 在"Available Plugins"一栏勾选SSHMon Samples Collector, 然后点击Apply Change and Res

性能测试之JVM监控

一.工具简介 VisualVM,能够监控线程,内存情况,查看方法的CPU时间和内存中的对象,已被GC的对象,反向查看分配的堆栈,从界面上看还是比较简洁的,左边是树形结构,自动显示当前本机所运行的Java程序,还可以添加远程的Java VM,其中括号里面的PID指的是进程ID.OverView界面显示VM启动参数以及该VM对应的一些属性.Monitor界面则是监控Java堆大小,Permgen大小,Classes和线程数量. 二.打开JVisualVM 1.打开JVisualVM 找到Jdkl安装

MySQL监控、性能分析——工具篇

MySQL越来越被更多企业接受,随着企业发展,MySQL存储数据日益膨胀,MySQL的性能分析.监控预警.容量扩展议题越来越多.“工欲善其 事,必先利其器”,那么我们如何在进行MySQL性能分析.监控预警.容量扩展问题上得到更好的解决方案,就要利用各种工具来对MySQL各种指标进行分 析.本文是读书笔记,下面提及的工具,读者可能都用过,或打算准备是使用.MySQL服务器的发布包没有包含那些能完成许多常见任务的工具,例如监控服务器的工具.比较服务器间数据的工具.我们把这些工具分成以下几类:界面.监

mysql监控、性能调优及三范式理解

原文:mysql监控.性能调优及三范式理解 1监控 工具:sp on mysql     sp系列可监控各种数据库 2调优 2.1 DB层操作与调优 2.1.1.开启慢查询 在My.cnf文件中添加如下内容(如果不知道my.cnf的路径可使用find / -name my.cnf进行查找): 在mysqld下添加 Log_slow_queries = ON  作用:开启慢查询服务 Log-slow-queries = /var/log/slowqueries.log 作用:慢查询日志存储路径.

MySQL性能调优与架构设计——第 18 章 高可用设计之 MySQL 监控

第 18 章 高可用设计之 MySQL 监控 前言: 一个经过高可用可扩展设计的 MySQL 数据库集群,如果没有一个足够精细足够强大的监控系统,同样可能会让之前在高可用设计方面所做的努力功亏一篑.一个系统,无论如何设计如何维护,都无法完全避免出现异常的可能,监控系统就是根据系统的各项状态的分析,让我们能够尽可能多的提前预知系统可能会出现的异常状况.即使没有及时发现将要发生的异常,也要在异常出现后的第一时间知道系统已经出现异常,否则之前的设计工作很可能就白费了. 18.1 监控系统设计 系统监控

京东MySQL监控之Zabbix优化、自动化

随着京东业务的飞速发展, MySQL数据库的使用更加普及.服务器量级飞速增长,这对京东MySQL DBA团队的要求也越来越高.监控系统为数据库管理和维护提供了精确的数据依据,是数据库运维人员的千里眼和顺风耳. 准确.及时.有效的监控,能够使运维人员对生产服务系统运行情况了如指掌.通过分析获得的监控信息,判断被监控数据库的运行状态,对可能出现的问题进行预测,可以及时制定出适当的优化方案,从而保证整个系统正常.高效地运行.这也就在很大程度上保证了数据库的安全性,避免了一些不必要的损失.所以,我们有必

主从同步、读写分离、mysql性能调优(软优化)

配置mysql主从同步1 主从同步的作用:让slave身份的数据库服务器自动同步 master身份的数据库服务器上的数据. 一.主数据库服务器的配置192.168.4.121 用户授权mysql> grant replication slave on *.* to [email protected]"192.168.4.11" identified by "123456";2 启用binlog日志vim /etc/my.cnf[mysqld]server_id