处理和解决游标独享问题_MySQL, Oracle及数据库讨论区_Weblogic技术|Tuxedo技术|中间件技术|Oracle论坛|JAVA论坛|Linux/Unix技术|hadoop论坛_联动北方技术论坛  
网站首页 | 关于我们 | 服务中心 | 经验交流 | 公司荣誉 | 成功案例 | 合作伙伴 | 联系我们 |
联动北方-国内领先的云技术服务提供商
»  游客             当前位置:  论坛首页 »  自由讨论区 »  MySQL, Oracle及数据库讨论区 »
总帖数
1
每页帖数
101/1页1
返回列表
0
发起投票  发起投票 发新帖子
查看: 4707 | 回复: 0   主题: 处理和解决游标独享问题        下一篇 
yang lin
注册用户
等级:上等兵
经验:144
发帖:8
精华:0
注册:2012-3-27
状态:离线
发送短消息息给yang lin 加好友    发送短消息息给yang lin 发消息
发表于: IP:您无权察看 2012-3-27 10:27:57 | [全部帖] [楼主帖] 楼主

处理和解决游标独享/更高的版本支持如下:

Oracle Server - Enterprise Edition


这篇文章使用于一些平台

目的

解决问题指南用于帮助解决SQL共享问题。如果有可能,检测工具被包含在文档中用于帮助解决问题。

最后审核时间

January 15, 2009


读者说明

     解决问题指南用于解决具体的错误。如果有可能,诊断工具被包含在文档中用于解决故障。

故障详情

1.       什么是SQL共享?

要记住的第一件事是所有的SQL都是隐含共享的。当一条SQL语句进入,关系数据库管理系统(RDBMS)将创建一个哈希值对于文本陈述,哈希值然后帮助RDBMS在共享池里面很容易的找到已经有的SQL。

例如:- 'select count(*) from emp' hashes to the value 4085390015

我们现在给SQL创建一个parent cursor和一个single child。这无所谓对于一条可能从未被共享的SQL语句来说-当第一次解析一个被创建的parent和单一的child。最简单的对这些理解的方法是PARENT cursor是代表哈希值child cursor(s)代表SQL的元数据。

什么是SQL‘元数据’?:

元数据是所有进入一条语句运行得信息。例如,我给予示例用户(scott)拥有EMP,因此,OBJECT_ID指向这些用户拥有的EMP表。当用户使用SCOTT登录时,优化程序在登录的时候被初始化,所以这也被优化,所以是元数据,在这篇文章中后面将会有其他的关于元数据的例子。

比如说这些登录退出系统并且立刻重新登录。然后再一次运行同样的命令(比如同样的用户)。这次在共享池里面已经有SQL(当是我们不知道)。我们混杂这些陈述然后再共享池里面寻找哈希值。如果我们找到,然后通过children寻找确定的如果有的话(比如:同样的元数据)。如果它是,我们就能够共享SQL语句。

现在又一个用户    ‘TEST’有EMP自己的版本。如果那些用户立刻运行上面的select语句然后将要发生:

1.       语句被弄散-值为4085390015

2.       SQL将在共享池里被发现当已经存在

3.       children被扫描(这时候我们有一个child)

4.       因为TEST拥有的EMP表的OBJECT_ID和scott我们有一个’mismatch’的OBJECT_ID不一样

5.  我们为此创建一个新的child-我们目前有一个PARENT 和 2 个CHILDREN。

6.       对于独享的游标,请阅读处理笔记和解析独享/更高的版本。

7.       请跟随步骤4学怎样运行verions_rpt脚本格式化在NOTE.438755.1.v$sql_shared_cursor。

2.       怎样查看版本,为什么不能独享?

运用上面的例子在共享池里检查我们可以看的SQL。

SCOTT runs select count(*) from emp


我们可以运行下面的指令来看PARENT声明和他们的哈希值与地址。

select sql_text, hash_value,address from v$sqlarea where sql_text like 'select count(*) from emp%';
SQL_TEXT                 HASH_VALUE    ADDRESS
------------------------------------- ----------------
select count(*) from emp 4085390015   0000000386BC2E58
To see the CHILDREN (I expect to see 1 at this point) :-
9i - select * from v$sql_shared_cursor where kglhdpar = '0000000386BC2E58'
10G - select * from v$sql_shared_cursor where address = '0000000386BC2E58'
ADDRESS          KGLHDPAR         U S O O S L S E B P I S T A B D L T R I I R L I O S M U T N F
---------------- ---------------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
0000000386BC2D08 0000000386BC2E58 N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N


我们可以看见我们有一个单一的single child (ADDRESS 0000000386BC2D08)。错配信息(USOOSL etc)全部是N因为这是第一个child,现在,如果我随着其他用户登录和运行同样的select (select count(*) from emp)会出现如下输出:

ADDRESS          KGLHDPAR         U S O O S L S E B P I S T A B D L T R I I R L I O S M U T N F
---------------- ---------------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
0000000386BC2D08 0000000386BC2E58 N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N
0000000386A91AA0 0000000386BC2E58 N N N N N N N N N N N N N Y N N N Y N N N N N N N N N N N N N


    我们现在可以看到第二个child ( 0000000386A91AA0),这就是为什么第一次不能被共享的原因,原因有(1)AUTH_CHECK_MISMATCH 和(2) TRANSLATION_MISMATCH,这是最主要的因为对象在我的新用户之下,不能映射到其他的SCOTT(当前的child)。所以,鉴定失败因为我不能访问SCOTTS对象,转换失败因为我们的object_ids不一样。

3.       v$SQL_SHARED_CURSOR的意义?

下面的原因清单给予了同样的一些可以执行的例子(标有**是经常见到的):

1.       UNBOUND_CURSOR-当前的child cursor没有被完全建立(换句话说,没有被充分运用)

2.       SQL_TYPE_MISMATCH –SQL类型不能匹配当前的child cursor

3.       **OPTIMIZER_MISMATCH –优化程序环境不能匹配当前的child cursor

select count(*) from emp; ->> 1 PARENT, 1 CHILD
alter session set optimizer_mode=ALL_ROWS
select count(*) from emp; ->> 1 PARENT, 2 CHILDREN (The optimizer mode has changed and therefore the existing child cannot be reused)
(The same applies with events - if I turned on tracing with 10046 than I would get the OPTIMIZER_MISMATCH again and a 3rd child)


OUTLINE_MISMATCH –大纲不能匹配当前的child cursor

如果我的用户对这些指令已经创建存储大纲,他们已经存储在seperate categories里面("OUTLINES1" 和 "OUTLINES2"):

alter session set use_stored_outlines = OUTLINES1;
select count(*) from emp;
alter session set use_stored_oulines= OUTLINES2;
select count(*) from emp;
è      Would create a 2nd child as the outline used is different than the first run.


STATS_ROW_MISMATCH –当前的统计不能匹配当前的child cursor

检查10046/sql_trace在期间没有开始所以会导致这些

LITERAL_MISMATCH - Non-data literal值不能匹配当前的child cursor

SEC_DEPTH_MISMATCH –安全级别不能匹配当前的child cursor

EXPLAIN_PLAN_CURSOR - child cursor是一个注释光标,不应该被共享

Explain plan statements will generate a new child by default-错配将是这个

BUFFERED_DML_MISMATCH –缓存数据操纵(DML)不能匹配当前的child cursor

PDML_ENV_MISMATCH – PDML环境不能匹配当前的child cursor

INST_DRTLD_MISMATCH - Insert direct load不能匹配当前的child cursor

SLAVE_QC_MISMATCH –当前的child cursor是一个从属的,新的一个被协调器创造

TYPECHECK_MISMATCH –当前的child cursor没有被充分的利用

AUTH_CHECK_MISMATCH –对当前的child cursor权限/转化检测失败

用户没有权限访问对象在游标的一些先前的版本。典型的例子就是即每个用户都有它自己的备份表

**BIND_MISMATCH –包装的元数据不能匹配当前的child cursor

variable a varchar2(100);
select count(*) from emp where ename = :a ->> 1 PARENT, 1 CHILD
variable a varchar2(400);
select count(*) from emp where ename = :a ->> 1 PARENT, 2 CHILDREN (The bind 'a' has now changed in definition)


DESCRIBE_MISMATCH - typecheck heap不能呈现在child cursor描述期间

LANGUAGE_MISMATCH –语言处理不能匹配child cursor

TRANSLATION_MISMATCH –当前child cursor的基本对象不能匹配

对象的定义不能匹配一些当前的版本。通常这是表示同样的错误"AUTH_CHECK_MISMATCH"无论对象不相同

ROW_LEVEL_SEC_MISMATCH –安全级别不能匹配

INSUFF_PRIVS –当前child cursor引用对象的权限不足

INSUFF_PRIVS_REM –当前child cursor应用远程的对象权限不足

REMOTE_TRANS_MISMATCH –当前child cursor的 remote base对象不能匹配

USER1: select count(*) from table@remote_db
USER2: select count(*) from table@remote_db (Although the SQL is identical, the dblink pointed to by remote_db may be a private dblink which resolves
to a different object altogether)
LOGMINER_SESSION_MISMATCH
INCOMP_LTRL_MISMATCH


OVERLAP_TIME_ error_on_overlap_time错配

SQL_REDIRECT_MISMATCH –SQL重定向错配

MV_QUERY_GEN_MISMATCH - materialized view query generation


USER_BIND_PEEK_MISMATCH - user bind peek错配

TYPCHK_DEP_MISMATCH - scursor has typecheck dependencie


NO_TRIGGER_ no trigger错配

FLASHBACK_CURSOR – 没有游标共享用于闪回

ANYDATA_TRANSFORMATION – anydata转换改变

INCOMPLETE_CURSOR –不完全的游标

当绑定长度可以升级(i.e.我们找到一个child cursor可以匹配所有的,除了绑定的长度没有足够的长度)。这种情况下,我们标记旧的游标是不可用的

创建一个新的。意思是足够版本可以被忽视。

TOP_LEVEL_RPI_CURSOR - top level/rpi cursor
In a Parallel Query invocation this is expected behaviour (we purposely do not share)


DIFFERENT_LONG_LENGTH –不同的长度

LOGICAL_STANDBY_APPLY –逻辑备用申请错配

DIFF_CALL_DURN –请求时间不同

BIND_UACS_DIFF - bind uacs错配

PLSQL_CMP_SWITCHS_DIFF plsql 编译器开关错配

CURSOR_PARTS_MISMATCH - cursor-parts executed错配

STB_OBJECT_MISMATCH – STB对象不同(当前的)

ROW_SHIP_MISMATCH - row shipping capability错配

PQ_SLAVE_MISMATCH - PQ slave错配

TOP_LEVEL_DDL_MISMATCH –顶级的DDL光标

MULTI_PX_MISMATCH - multi-px and slave-compiled cursor
BIND_PEEKED_PQ_MISMATCH - bind-peeked PQ cursor
MV_REWRITE_MISMATCH - MV rewrite cursor
ROLL_INVALID_MISMATCH - rolling invalidation window exceeded


See NOTE: 557661.1 .这是由于里DBMS_STATS里面的波动的无效的容量。Child不能被共享随着无效的窗口被共享。

OPTIMIZER_MODE_MISMATCH –优化程序模块错配

PX_MISMATCH - parallel query错配

如果运行11.1.0.6 和 RAC参见BUG7352775。检查如果paralle_instance_groups设置然后instance_groups is设置一样。

MV_STALEOBJ_MISMATCH - mv stale对象错配

FLASHBACK_TABLE_MISMATCH –闪回表错配

LITREP_COMP_MISMATCH - literal replacement compilation错配

New in 11g (incomplete):


PLSQL_DEBUG – 调试错配

调试参数plsql_debug设置为true

LOAD_OPTIMIZER_STATS  -负荷优化统计数据游标的共享

ACL_MISMATCH   - Check ACL错配

FLASHBACK_ARCHIVE_MISMATCH  -闪回存档错配

LOCK_USER_SCHEMA_FAILED  -无法锁定用户和模式

REMOTE_MAPPING_MISMATCH  - Remote mapping错配

LOAD_RUNTIME_HEAP_FAILED  -执行时间堆错配

HASH_MATCH_FAILED  -哈希错配

如果共享失败导致一个哈希错配,设置成”Y”

3.  Version_rpt脚本:

version_rp脚本也可以运行生成一个v$sql_shared_cursor的概要报表参加附加的诊断信息。

运行脚本—生成游标的所有报告和超过100个版本运用SQL_ID (10g and up):

select b.* from v$sqlarea a ,table(version_rpt(a.sql_id)) b where loaded_versions >=100;
-- Generate reports for all cursors with more than 100 versions using HASH_VALUE:
select b.* from v$sqlarea a ,table(version_rpt(null,a.hash_value)) b where loaded_versions>=100;
-- Generate the report for cursor with sql_id cyzznbykb509s:
select * from table(version_rpt('cyzznbykb509s'));


4. 进一步追踪可供使用的

解决方案:

在10G里面可能用到CURSORTRACE来帮助调查为什么游标没有被共享。为了得到详细的SQL语句描绘,你首先必须获得哈希值。然后设置跟踪使用:

改变系统设置事件

'immediate trace name cursortrace level 577, address hash_value';
(level 578/580 can be used for high level tracing (577=level 1, 578=level 2, 580=level 3)
This will write a trace file to user_dump_dest each time we try to reuse the cursor.
To turn off tracing use:-


改变系统设置事件

'immediate trace name cursortrace level 2147483648, address 1';


请注意:BUG5555371存于10.2(固定的10.2.0.4)这个地方游标跟踪不能完全关掉,单线线路将仍然被追踪

5.Are there any times when a high version count is expected even though BINDS are being used?

解决方案:

Consider the following where cursor_sharing=SIMILAR
select * from emp where sal > 100;
select * from emp where sal > 101;
select * from emp where sal > 102;
select * from emp where sal > 103;
select * from emp where sal > 104;
SELECT sql_text,version_count,address
FROM V$SQLAREA
WHERE sql_text like 'select %';
SELECT * FROM V$SQL_SHARED_CURSOR WHERE kglhdpar = '&my_addr';


你将会看到一些版本,每一个都不明显因为没有被共享

说明:

SIMILAR 和 FORCE的不同是SIMILAR分离类似的声明和共享SQL区域,没有退化执行计划。设置CURSOR_SHARING为FORCE分离类似的声明共享SQL区域,可能退化执行计划。

也可能出现10046追踪的报告(level 4/12 - BINDS)如果一个绑定被认为是存在不安全的

The flag oacfl2 in 9i and fl2 in 10g will show if a variable is unsafe.
BINDS #2:
bind 0: dty=2 mxl=22(04) mal=00 scl=00 pre=00 oacflg=10 oacfl2=500 size=24
offset=0
bfp=1036d6408 bln=22 avl=04 flg=09
value=16064
bind 1: dty=2 mxl=22(04) mal=00 scl=00 pre=00 oacflg=10 oacfl2=500 size=24
offset=0
bfp=1036d4340 bln=22 avl=04 flg=09




赞(0)    操作        顶端 
总帖数
1
每页帖数
101/1页1
返回列表
发新帖子
请输入验证码: 点击刷新验证码
您需要登录后才可以回帖 登录 | 注册
技术讨论