如何使用AWR报告来诊断数据库性能问题

如何使用AWR报告来诊断数据库性能问题,第1张

Interpretation

在处理性能问题时,我们最关注的是数据正在等待什么。

当进程因为某些原因不能进行 *** 作时,它需要等待。花费时间最多的等待事件是我们最需要关注的,因为降低它,我们能够获得最大的好处。

AWR报告中的"Top 5 Timed Events"部分就提供了这样的信息,可以让我们只关注主要的问题。

Top 5 Timed Events

正如前面提到的,"Top 5 Timed Events"是AWR报告中最重要的部分。它指出了数据库的sessions花费时间最多的等待事件,如下:

Top 5 Timed Events Avg %Total

~~~~~~~~~~~~~~~~~~ wait Call

Event Waits Time (s) (ms) Time Wait Class

------------------------------ ------------ ----------- ------ ------ ----------

db file scattered read 10,152,564 81,327 8 296 User I/O

db file sequential read 10,327,231 75,878 7 276 User I/O

CPU time 56,207 205

read by other session 4,397,330 33,455 8 122 User I/O

PX Deq Credit: send blkd 31,398 26,576 846 97 Other

-------------------------------------------------------------

Top 5 Events部分包含了一些跟Events(事件)相关的信息。它记录了这期间遇到的等待的总次数,等待所花费的总时间,每次等待的平均时间;这一部分是按照每个Event占总体call time的百分比来进行排序的。

根 据Top 5

Events部分的信息的不同,接下来我们需要检查AWR报告的其他部分,来验证发现的问题或者做定量分析。等待事件需要根据报告期的持续时间和当时数据

库中的并发用户数进行评估。如:10分钟内1000万次的等待事件比10个小时内的1000万等待更有问题;10个用户引起的1000万次的等待事件比

10,000个用户引起的相同的等待要更有问题。

就像上面的例子,将近60%的时间是在等待IO相关的事件。

• 事件"db file scattered read"一般表明正在做由全表扫描或者index fast full scan引起的多块读。

• 事件"db file sequential read"一般是由不能做多块读的 *** 作引起的单块读(如读索引)

其他20%的时间是花在使用或等待CPU time上。过高的CPU使用经常是性能不佳的SQL引起的(或者这些SQL有可能用更少的资源完成同样的 *** 作);对于这样的SQL,过多的IO *** 作也是一个症状。关于CPU使用方面,我们会在之后讨论。

在以上基础上,我们将调查是否这个等待事件是有问题的。若有问题,解决它;若是正常的,检查下个等待事件。

过多的IO相关的等待一般会有两个主要的原因:

• 数据库做了太多的读 *** 作

• 每次的IO读 *** 作都很慢

Top 5 Events部分的显示的信息会帮助我们检查:

• 是否数据库做了大量的读 *** 作:

上面的图显示了在这段时间里两类读 *** 作都分别大于1000万,这些 *** 作是否过多取决于报告的时间是1小

时或1分钟。我们可以检查AWR报告的elapsed time如果这些读 *** 作确实是太多了,接下来我们需要检查AWR报告中 SQL

Statistics 部分的信息,因为读 *** 作都是由SQL语句发起的。

• 是否是每次的IO读 *** 作都很慢:

上面的图显示了在这段时间里两类读 *** 作平均的等待时间是小于8ms的

至于8ms是快还是慢取决于底层的硬件设备;一般来讲小于20ms的都可以认为是可以接受的。

我们还可以在AWR报告"Tablespace IO Stats"部分得到更详细的信息

Tablespace IO Stats DB/Inst: VMWREP/VMWREP Snaps: 1-15

-> ordered by IOs (Reads + Writes) desc

Tablespace

------------------------------

Av Av Av Av Buffer Av Buf

Reads Reads/s Rd(ms) Blks/Rd Writes Writes/s Waits Wt(ms)

-------------- ------- ------ ------- ------------ -------- ---------- ------

TS_TX_DATA

14,246,367 283 76 46 145,263,880 2,883 3,844,161 83

USER

204,834 4 107 10 17,849,021 354 15,249 98

UNDOTS1

19,725 0 30 10 10,064,086 200 1,964 49

AE_TS

4,287,567 85 54 67 932 0 465,793 37

TEMP

2,022,883 40 00 58 878,049 17 0 00

UNDOTS3

1,310,493 26 46 10 941,675 19 43 00

TS_TX_IDX

1,884,478 37 73 10 23,695 0 73,703 83

>SYSAUX

346,094 7 56 39 112,744 2 0 00

SYSTEM

101,771 2 79 35 25,098 0 653 27

如上图,我们关心Av Rd(ms)的指标。如果它高于20ms并且同时有很多读 *** 作的,我们可能要开始从OS的角度调查是否有潜在的IO问题。

1、使用系统性能监视器监视当前SQL的工作性能(控制面板-->管理工具-->性能)可以查看SQL对磁盘、内存的总体占用

2、使用SQL 性能监视器(SQL Profiler)可以查看SQL 的执行事件,读写次数,起始和结束事件等等,可以保存死锁图形。

    具体问题具体分析,举例来说明为什么磁盘IO成瓶颈数据库的性能急速下降了。

   为什么当磁盘IO成瓶颈之后, 数据库的性能不是达到饱和的平衡状态,而是急剧下降。为什么数据库的性能有非常明显的分界点,原因是什么?

    相信大部分做数据库运维的朋友,都遇到这种情况。 数据库在前一天性能表现的相当稳定,数据库的响应时间也很正常,但就在今天,在业务人员反馈业务流量没有任何上升的情况下,数据库的变得不稳定了,有时候一个最简单的insert *** 作, 需要几十秒,但99%的insert却又可以在几毫秒完成,这又是为什么了?

dba此时心中有无限的疑惑,到底是什么原因呢 磁盘IO性能变差了?还是业务运维人员反馈的流量压根就不对? 还是数据库内部出问题?昨天不是还好好的吗?

 当数据库出现响应时间不稳定的时候,我们在 *** 作系统上会看到磁盘的利用率会比较高,如果观察仔细一点,还可以看到,存在一些读的IO 数据库服务器如果存在大量的写IO,性能一般都是正常跟稳定的,但只要存在少量的读IO,则性能开始出现抖动,存在大量的读IO时(排除配备非常高速磁盘的机器),对于在线交易的数据库系统来说,大概性能就雪崩了。为什么 *** 作系统上看到的磁盘读IO跟写IO所带来的性能差距这么大呢?

如果亲之前没有注意到上述的现象,亲对上述的结论也是怀疑。但请看下面的分解。

在写这个文章之前,作者阅读了大量跟的IO相关的代码,如异步IO线程的相关的,innodb_buffer池相关的,以及跟读数据块最相关的核心函数buf_page_get_gen函数以及其调用的相关子函数。为了将文章写得通俗点,看起来不那么累,因此不再一行一行的将代码解析写出来。

咱们先来提问题。 buf_page_get_gen函数的作用是从Buffer bool里面读数据页,可能存在以下几种情况。

提问 数据页不在buffer bool 里面该怎么办?

  回答:去读文件,将文件中的数据页加载到buffer pool里面。下面是函数buffer_read_page的函数,作用是将物理数据页加载到buffer pool, 中显示

buffer_read_page函数栈的顶层是pread64(),调用了 *** 作系统的读函数。

buf_read_page的代码

 如果去读文件,则需要等待物理读IO的完成,如果此时IO没有及时响应,则存在堵塞。这是一个同步读的 *** 作,如果不完成该线程无法继续后续的步骤。因为需要的数据页不再buffer 中,无法直接使用该数据页,必须等待 *** 作系统完成IO

再接着上面的回答提问:

当第二会话线程执行sql的时候,也需要去访问相同的数据页,它是等待上面的线程将这个数据页读入到缓存中,还是自己再发起一个读磁盘的然后加载到buffer的请求呢?   代码告诉我们,是前者,等待第一个请求该数据页的线程读入buffer pool。

试想一下,如果第一个请求该数据页的线程因为磁盘IO瓶颈,迟迟没有将物理数据页读入buffer pool, 这个时间区间拖得越长,则造成等待该数据块的用户线程就越多。对高并发的系统来说,将造成大量的等待。 等待数据页读入的函数是buf_wait_for_read,下面是该函数相关的栈。

通过解析buf_wait_for_read函数的下层函数,我们知道其实通过首先自旋加锁pin的方式,超过设定的自旋次数之后,进入等待,等待IO完成被唤醒。这样节省不停自旋pin时消耗的cpu,但需要付出被唤起时的开销。

再继续扩展问题: 如果会话线程A 经过物理IO将数据页1001读入buffer之后,他需要修改这个页,而在会话线程A之后的其他的同样需要访问数据页1001的会话线程,即使在数据页1001被入读buffer pool之后,将仍然处于等待中。因为在数据页上读取或者更新的时候,同样需要上锁,这样才能保证数据页并发读取/更新的一致性。

由此可见,当一个高并发的系统,出现了热点数据页需要从磁盘上加载到buffer pool中时,造成的延迟,是难以想象的。因此排在等待热点页队列最后的会话线程最后才得到需要的页,响应时间也就越长,这就是造成了一个简单的sql需要执行几十秒的原因。

再回头来看上面的问题,mysql数据库出现性能下降时,可以看到 *** 作系统有读IO。 原因是,在数据库对数据页的更改,是在内存中的,然后通过检查点线程进行异步写盘,这个异步的写 *** 作是不堵塞执行sql的会话线程的。所以,即使看到 *** 作系统上有大量的写IO,数据库的性能也是很平稳的。但当用户线程需要查找的数据页不在buffer pool中时,则会从磁盘上读取,在一个热点数据页不是非常多的情况下,我们设置足够大的innodb_buffer_pool的size, 基本可以缓存所有的数据页,因此一般都不会出现缺页的情况,也就是在 *** 作系统上基本看不到读的IO。  当出现读的IO时,原因时在执行buf_read_page_low函数,从磁盘上读取数据页到buffer pool, 则数据库的性能则开始下降,当出现大量的读IO,数据库的性能会非常差。

以MySQL为例:

影响数据库性能的主要因素总结如下:

1、sql查询速度

2、网卡流量

3、服务器硬件

4、磁盘IO

以上因素并不是时时刻刻都会影响数据库性能,而就像木桶效应一样。如果其中一个因素严重影响性能,那么整个数据库性能就会严重受阻。另外,这些影响因素都是相对的。

例如:当数据量并没有达到百万千万这样的级别,那么sql查询速度也许就不是个重要因素,换句话说,你的sql语句效率适当低下可能并不影响整个效率多少,反之,这种情况,无论如何怎么优化sql语句,可能都没有太明显的效果。

相关内容拓展:

1、SQL查询速度

风险:效率低下的SQL

2、网卡流量

风险:网卡IO被占满(100Mb/8=100MB)

方案:

①减少从服务器的数量。从服务器都要从主服务器上复制日志,所以,从服务器越多,网络流量越大。

②进行分级缓存。前方大量缓存突然失效会对数据库造成严重的冲击。

③避免使用“select ”进行查询

④分离业务网络和服务器网络

3、磁盘IO

风险:磁盘IO性能突然下降。

方案:使用更好的磁盘设备解决。

以上就是关于如何使用AWR报告来诊断数据库性能问题全部的内容,包括:如何使用AWR报告来诊断数据库性能问题、如何查看sql数据库服务器性能、如何处理查找,处理数据库的性能瓶颈等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/sjk/9785130.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-02
下一篇2023-05-02

发表评论

登录后才能评论

评论列表(0条)

    保存