专栏首页7DGroup性能分析之子锁存器(latch)到SQL

性能分析之子锁存器(latch)到SQL

这几天碰到一个事情,有必要记录一下。

在一个项目中,压力测试工具中一个业务响应时间变长,数据库(oracle)CPU使用率99%以上。

从AWR报告上看到如下信息:

在性能项目的沟通中,经常是在这样的时候,我们就去告诉开发说现在的状态是CPU使用率高,把AWR报告往开发那里一发,性能团队的人员就喝咖啡去了。

但是性能如果只是做到这里,沟通其实没有在同一个界面上。

在这个典型的沟通过程中,上述结果也确实发给开发了。

开发反馈说,是因为在场景执行过程中表的数据量发生了变化,导致了SQL的执行计划发生了变化,进而导致了SQL慢,进而导致了latch: cache buffers chains的出现。所以要解决的话,要对数据库进行一次analyze,然后再测试。

在上述的背景中,看似没有漏洞,合情合理。

但是,

恰好碰到我这偏执的人,我要看到证据链

在沟通的来往中,我并没有看到证据链,这是我觉得不好的地方。哪里没有证据呢?就是数据量发生了变化导致了SQL的执行计划发生了变化。

如果有这样的怀疑,就要去证明这个怀疑是对的。

于是我查了SQL计划的历史变更记录。

根据SQLID查看执行计划的变更记录:

selectDISTINCT SQL_ID,PLAN_HASH_VALUE,TO_CHAR(TIMESTAMP,'yyyymmdd hh24:mi:ss') TIMESTAMPfrom dba_hist_sql_plan where sql_id='1wfsd2q8wc5uu'orderbyTIMESTAMP;

SQL_ID PLAN_HASH_VALUE TIMESTAMP

1 1wfsd2q8wc5uu 4188019746 2018040118:08:09

查询更详细的执行记录变更记录(我把结果中的时间戳删掉了,为了格式整齐点):

select plan_hash_value,id,operation,options,object_name,depth,cost,TO_CHAR(TIMESTAMP,'yyyymmdd hh24:mi:ss') from dba_hist_sql_plan where sql_id='1wfsd2q8wc5uu'and plan_hash_value in (4188019746) orderbyID,TIMESTAMP;

PLAN_HASH_VALUE ID OPERATION OPTIONS OBJECT_NAME DEPTH COST

1 4188019746 0 SELECT STATEMENT 0 2

2 4188019746 1 FILTER 1

3 4188019746 2 FAST DUAL 2 2

4 4188019746 3 TABLE ACCESS BY INDEX ROWID TABLE1 2 0

5 4188019746 4 INDEX RANGE SCAN TABLE1_IDX1 3 0

这个SQL的执行计划,只有4月1日一条记录,在最近几天的测试中,并没有发生变更。

这就是我要说的证据链,当给出执行计划发生变化这个结论时,就必须给出证明,而实际的数据证明这个结论是错的。

下面我们就来分析下怎么才是对的。

既然是latch: cache buffers chains,首先我们得知道这个值是什么意思。

简单回忆下latch的原理(如下部分是在网上抄的):

当一个数据块读入到SGA中时,该块的块头(BUFFERHEADER)会放置一个HASHBUCKET的链表(HASHCHAIN)中。该内存结构由一系列cachebuffers chains的子latch保护。对BUFFERCACHE中的块,要SELECT/UPDATE/INSERT/DELETER等操作都得先获得cachebuffers chains的子latch,以保证对CHAIN的排他访问。若在过程中发生争用,就会出现latch:cache buffers chains事件。

这个值的出现有两个含义:

  1. SQL的执行效率低:因为SQL低效,在并发会话时,无法得到相同的数据集,SQL执行时带有高BUFFER_GETS会导致latch争用。
  2. 数据热块。

这是两个完全不同的处理方向。

第一个处理方向,考虑到近期场景执行得比较频繁,数据库变更较多,所以先把数据库做个整体的分析,再来测试下。经过证明之后,发现果然分析了整库之后,时间刷刷的降低了很多,然后就把存储的IO压到80%以上了。

虽然开发说执行计划变更是错的,但是分析整库的处理方法是对的。

套用大话西游里说的:我猜中了结尾,但是没有蒙对过程。

看到这里,是不是觉得问题解决了?可以收工了?很开心的喝咖啡去了?


但是,我又偏执了。我考虑了下参数化的逻辑,我觉得数据热块应该是存在的。现在之所以没有暴露出来,是因为IO跟不上了。所以我要判断下,如果IO够用的话,热块会不会成为下一个瓶颈。于是,接着查。

先看看争用是否严重:

selectround((misses / gets) * 100) || '%', round(100 * immediate_misses /(immediate_gets + immediate_misses))|| '%' from v$latch wherename = 'cache buffers chains';

round((misses / gets) * 100) || '%'的值是3%。可见还是有一些热度的。

再来查下子锁存器视图,看是否有热块。看看倾斜度。

select * from (select addr,child#,gets,misses,sleepsfrom v$latch_children wherename='cachebuffers chains'orderby sleeps desc) whererownum<=20;

倾斜度是有的。再看下对象的热度:

select hladdr, obj, (select object_name from dba_objects where (data_object_id isnull andobject_id = x.obj) or data_object_id = x.obj andrownum = 1) as object_name, dbablk, tch from x$bh x where hladdr in ('00000005FCE6EAC0') orderby tch desc;

TCH是touch count,此值越高,则热度越高。

查找引起热块的SQL。

select * from (selectcount(*), sql_id, nvl(o.object_name, ash.current_obj#) objn, substr(o.object_type, 0, 10) otype, CURRENT_FILE# fn, CURRENT_BLOCK# blockn from v$active_session_history ash, all_objects o where event like'latch: cache buffers chains' ando.object_id(+) = ash.CURRENT_OBJ# GROUPBY SQL_ID, current_obj#, current_file#, current_block#, o.object_name, o.object_type orderbycount(*) desc) whererownum <= 10;

根据SQLID查一下SQL的文本,果然就是我们用到的那个查询业务SQL。

在性能分析中,我们太容易给自己定个范围或圈套了。有时觉得这个事情不该是自己做的。

如果单从职场的角度说,这样想并无不妥。

但是如果从技术角度说,这样想就必然会导致自己的能力受限。

所以不用给技术下个定义,在个人能力能达到的地方,都尽量去做,学无止境。

而从现象到瓶颈的性能分析是最需要一个人有足够的知识宽度的,因为你不知道在寻找瓶颈的过程中会遇到什么样的知识弱点。

今天碰到的是oracle,明天碰到mysql、HBase怎么办?啥也别想,二话不说,办它就对了。

本文分享自微信公众号 - 7DGroup(Zee_7DGroup)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2018-04-25

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • WGS的实战笔记(一)

    前言:开始WGS的分析的学习,记录下学习的过程了,说实话,在这之前我是跑过WGS的流程的,但是每步感觉跑的都不是很稳当,踏实。导致自己在后期的学习还是会出现各种...

    liu_ll
  • BBQ(生信基础问题)27:GENCODE与Ensembl GTF/GFF到底哪里不同?怎么下载?

      上个BBQ讲到了GTF/GFF3的一些介绍:https://www.jianshu.com/p/3eaeecfa7fd5。 今天我们主要关注的是不同基因注释...

    liu_ll
  • Java实现邮箱验证功能

    如题,我们做网站的时候,往往需要用户注册,很多用户选择用邮箱注册,为了获取用户的真实邮箱和防止恶意注册,可能需要做一个邮箱验证,此篇教程就是讲解如何用Java实...

    浩Coding
  • BBQ(生信基础问题14-15)-BLAST专题&BLAT

    上个BBQ介绍了基于动态规划算法的全局序列比对和局部序列比对,今天这篇笔记简单的介绍一下什么是BLAST和BLAT~

    liu_ll
  • Java EE实用教程笔记----(6)第六章 Struts 2综合应用案例

    本章主要内容是结合前面所学的Struts2框架知识,编写一个简单的借书系统的实例,其实这些主要是JavaWeb的知识,用Struts2开发而已,基础比较扎实的同...

    浩Coding
  • 设置MySQL数据库不区分大小写

    我们大家可能都碰到过这种情况:在Linux下,MySQL的表名区分大小写,而在Windows下是不区分,从Windows下导出的数据脚本中使用的是小写,而Hib...

    浩Coding
  • 图解数据库内连接、外连接、左连接、右连接、全连接等

    用两个表(a_table、b_table),关联字段a_table.a_id和b_table.b_id来演示一下MySQL的内连接、外连接( 左(外)连接、右(...

    浩Coding
  • mysql基础

    安装后,安装mysql,点击接受,默认安装,然后就是next,点击提示框的是,接着点击execute和next,设置密码和重复密码,windows servic...

    达达前端
  • 继AutoML后,第四范式发布软硬一体化AI集成系统SageOne

    6 月 20 日,AI产品和服务提供商第四范式宣布发布最新 AI 系列产品SageOne Appliance软硬一体化AI集成系统,性能较市面开源工具或GPU解...

    AI科技大本营
  • 什么是JDBC、JNDI和DBCP以及DataSource?

    JDBC:Java DataBase Connectivity,Java连接数据库和执行SQL语句的API。

    浩Coding

扫码关注云+社区

领取腾讯云代金券