前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【DB笔试面试580】在Oracle中,什么是High Version Count?

【DB笔试面试580】在Oracle中,什么是High Version Count?

作者头像
小麦苗DBA宝典
发布2019-09-29 15:51:21
1.2K0
发布2019-09-29 15:51:21
举报

题目部分

在Oracle中,什么是High Version Count?

答案部分

一个父游标下对应的子游标个数被称为Version Count,每个子游标对应一个执行计划。对于一个特定的游标有多少个版本(Version Count)就属于高版本游标是没有明确定义的。对于不同的系统有不同的数量界定。High Version Count不仅产生的原因是多种多样的,而且会导致各种令人头痛的问题,轻则导致数据库的性能急剧下降,CPU利用率剧增,重则导致数据库挂起,触发ORA-04031或者其它BUG导致宕机。

在AWR报告中,Version Count大于20就会被报告出来,如下图所示:

SQL执行计划的生成,是受到很多因素影响的。相同父游标只是表示输入SQL的字面值相同。子游标对应的因素,如优化器类型、优化器的模式(OPTIMIZER_MODE)、对应对象权限等的差异,都会影响到子游标的共享。

在Oracle 11g中,V$SQL_SHARED_CURSOR可以用来诊断子游标不共享问题的原因。该视图通过SQL_ID和CHILD_NUMBER就可以定义某个特定子游标的信息。该视图中大部分列都是以VARCHAR2(1)的Y/N取值,每列的含义都是一个不能共享的理由。需要注意的是,这个理由N表示的是不能与第一个子游标(CHILD_NUMBER=0)共享的理由。

下面举一个由于优化器模式不同导致游标不能共享的例子:

代码语言:javascript
复制
SYS@lhrdb> SELECT * FROM SCOTT.EMP WHERE ROWNUM<=0;
no rows selected
SYS@lhrdb> select sql_id, version_count from v$sqlarea where sql_text like 'SELECT * FROM SCOTT.EMP WHERE ROWNUM<=0%';
SQL_ID        VERSION_COUNT
------------- -------------
7u75n20ktntsb             1
SYS@lhrdb>  show parameter optimizer_mode
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
optimizer_mode                       string      ALL_ROWS
SYS@lhrdb>  alter session set optimizer_mode=first_rows;
Session altered.
SYS@lhrdb> SELECT * FROM SCOTT.EMP WHERE ROWNUM<=0;
no rows selected
SYS@lhrdb> select sql_id, version_count,SQL_TEXT from v$sqlarea where sql_text like 'SELECT * FROM SCOTT.EMP WHERE ROWNUM<=0%';
SQL_ID        VERSION_COUNT
------------- -------------
7u75n20ktntsb             2
SYS@lhrdb>  select sql_id, child_number, OPTIMIZER_MODE from v$sql where sql_id='7u75n20ktntsb';
SQL_ID        CHILD_NUMBER OPTIMIZER_
------------- ------------ ----------
7u75n20ktntsb            0 ALL_ROWS
7u75n20ktntsb            1 FIRST_ROWS
SYS@lhrdb> select sql_id, child_number, OPTIMIZER_MODE_MISMATCH from v$sql_shared_cursor where sql_id='7u75n20ktntsb';
SQL_ID        CHILD_NUMBER O
------------- ------------ -
7u75n20ktntsb            0 N
7u75n20ktntsb            1 Y

有时候会遇到某些SQL的V$SQL_SHARED_CURSOR所有的字段的结果都为N,但是其Version Count还是很高的情况。这种情况主要的原因是存在部分BUG,可能导致V$SQL_SHARED_CURSOR的信息不准确。例如:

代码语言:javascript
复制
Bug 12539487 – gv$sql_shared_cursor may not show all reasons to not share a cursor (Doc ID 12539487.8)

--所以在Oracle 10g以上版本中可以使用cursortrace来查找High Version Count的原因,打开cursortrace的方法如下所示:
alter system set events 'immediate trace name cursortrace level 577, address <hash_value>';

--如需关闭cursortrace,则可以使用以下方式进行关闭:
alter system set events 'immediate trace name cursortrace level 2147483648, address 1';

--或者使用以下方式关闭:
alter session set events 'immediate trace name cursortrace level 128 , address <address>';

在MOS 438755.1中,Oracle提供了一个专门的脚本程序,用于协助诊断High Version Count问题。运行脚本version_rpt.sql可以创建函数VERSION_RPT。具体使用的方法有三个场景:

代码语言:javascript
复制
--① 列出Version Count大于某个阈值的报告,以SQL_ID方式显示
SELECT B.*
  FROM V$SQLAREA A, TABLE(VERSION_RPT(A.SQL_ID)) B
 WHERE LOADED_VERSIONS >= 4;

--② 列出Version Count大于某个阈值的报告,以SQL_HASH方式显示
SELECT B.*
  FROM V$SQLAREA A, TABLE(VERSION_RPT(NULL, A.HASH_VALUE)) B
 WHERE LOADED_VERSIONS >= 4;

--③ 列出某个特定SQL_ID的Version Count
SELECT * FROM TABLE(VERSION_RPT('7u75n20ktntsb'));

对于版本过多的SQL,一次软解析甚至不如重新执行一次硬解析来的高效,所以Oracle引入了一系列的控制手段来处理这些特殊的游标。从Oracle 11.2.0.3开始,Oracle提供了一个隐含参数“_CURSOR_OBSOLETE_THRESHOLD”,其作用是当SQL版本超过这个参数设定后,直接舍弃这个游标,重新解析,从头开始,该隐含参数的默认值为100。如果子游标的数量超过了这个阈值,那么父游标就会被废弃,并且同时重新创建一个新的父游标。如果Oracle数据库的版本低于11.2.0.3,那么除了需要给系统打Patch(Enhancement Request Bug 10187168 : OBSOLETE PARENT CURSORS IF VERSION COUNT EXCEEDS A THRESHOLD)外,还同时需要设置以下参数:

代码语言:javascript
复制
--Oracle 11.2.0.1:
SQL> alter system set "_cursor_features_enabled"=34 scope=spfile;
SQL> alter system set event='106001 trace name context forever,level 1024' scope=spfile;

--Oracle 11.2.0.2:
SQL> alter system set "_cursor_features_enabled"=1026 scope=spfile;
SQL> alter system set event='106001 trace name context forever,level 1024' scope=spfile;

& 说明:

有关Version Count的更多内容可以参考我的BLOG:http://blog.itpub.net/26736162/viewspace-2140136/

本文选自《Oracle程序员面试笔试宝典》,作者:李华荣。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-06-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 DB宝 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档