Limewire Tramadol cod Allstate car insurance Rivotril Cheap hotel Adalat Nfl handicapping Adipex phentermine Credit card debt help Child care Pharmacies Sex video Order phentermine Betting Amoxicillin rash Flowers Ultram online Free porn Nfl football predictions Buy adipex p Cheap fioricet Consolidate credit card Online casino gambling site Buy online viagra Youporn Football pool Travelocity Forex broker Nfl pool pick Xanax online Auto insurances Nolvadex Ambien Levaquin Casino bonus Buy nolvadex Casino online gambling Purchase phentermine Ritalin Caverta Debt negotiation Service Viagra cialis Wellbutrin sr Buy ultram Buying viagra online Cosmetologist Propecia online Adware Allegra Job Buy phentermine online Debt consolidation program Cheap viagra County Get fioricet Lortab Generic nexium Ultram online from dreampharmaceuticals Party poker bonus 
Home > Oracle RDBMS > CURSOR_SHARING = SIMILAR !

CURSOR_SHARING = SIMILAR !

August 16th, 2007

遭遇cursor_sharing = similar的问题,跟GSD在SR中多次沟通总算解决了问题,国外的同事shift了几轮,实在是我跟进最长的一个SR了。

问题发生在客户在压力测试的时候,数据库版本是RAC 10.2.0.3 on AIX,客户使用Loadrunner模拟10000用户在系统中做业务,当虚拟用户增加到1200左右的时候,明显看到事务的响应时间开始上升,从原本的40s升到70s,然后继续上升,到最后2000用户的时候,已经开始产生大量的失败事务,响应时间也升高到400s,而用户也无法再login了。

AWR报告显示:
Top 5 Timed Events Avg %Total
~~~~~~~~~~~~~~~~~~ wait Call
Event Waits Time (s) (ms) Time Wait Class
—————————— ———— ———– —— —— ———-
cursor: pin S wait on X 13,153,838 133,733 10 49.8 Concurrenc
latch: library cache 365,244 54,514 149 20.3 Concurrenc
kksfbc child completion 579,210 29,477 51 11.0 Other
cursor: mutex X 383,841,637 20,095 0 7.5 Concurrenc
CPU time 13,549 5.0

SQL ordered by Elapsed Time中显示一条SQL占据了90%以上的数据库时间,而同样的这条SQL消耗了将近1G的共享池,Version Count值也高达19000!

这条SQL非常简单,从一张表中通过索引获取1行数据,表中有超过1亿条数据,分区,单独执行SQL效率非常好,也只有15左右的一致读,但是执行次数巨多,而且应用中是写死了的literal sql,通过设置cursor_sharing = similar而让Oracle转换为绑定变量的样式,但是每一次执行却因为某种原因都无法共享SQL,都要产生一个新的cursor,因此随着执行次数的增多,version count就越来越多了。因为太多的Version Count,所以导致library cache竞争剧烈,系统性能急剧下降。

导致性能问题的罪魁祸首很明显,但是为什么会有这么多Version Count?为什么Oracle不能共享这个SQL的cursor?又如何避免这个问题?

通过长时间在SR以及AIM上跟GSD的同事交流,做各种各样的trace,systemstate dump,甚至将统计信息export出来让他们在那边搭建环境,最后GSD都认为是一个bug而提交到BDE去了,然而最终的结果是这是Oracle的正常举动。

产生这种情况的条件是:
1. cursor_sharing = similar
2. 收集了列上的histogram
3. SQL中使用到了此列作为条件,并且条件是“等于”
4. 这个SQL是没有绑定变量的

这时候,oracle会认为每个送上来的literal变量都是unsafe的,因此就不重用以前的cursor而新产生一个version。

解决方法是:
1. cursor_sharing = force
2. 删除列上的histogram

实际上Oracle也建议在OLTP系统中不要对所有列都收集histogram,只对那些distinct值比较少而且数据分布非常倾斜的列才去收集。

有兴趣的朋友可以去metalink上查看SR 6470259.992,这个SR中不但对这个问题有详细的说明,而且涉及了很多诊断问题的方法,包括
1. 如何生成hanganalyze的trace
2. 如何生成systemstate dump
3. 如何在普通SQL*Plus命令已经无法登录数据库的时候还能登录数据库 (sqlplus -prelim “/ as sysdba”)
4. 如何禁用mutex而使用以前版本的library cache latch机制
5. 如何跟踪cursor (使用cursortrace事件)
6. 如何导出统计信息而迅速生成另外一个测试环境

结论:
各位写应用程序的哥们儿还是尽量从一开始就绑定变量吧,不要依靠Oracle的cursor_sharing帮你作这件事情。
不是收集越多的信息给Oracle就越好,有时候不需要的信息反而容易引起问题,比如这里的列上的histogram。

SR 6470259.992 Uploaded

kamus Oracle RDBMS


  1. August 16th, 2007 at 22:15 | #1

    Force 了?

    估计你接下来就该遇到更多的Bug了

  2. August 17th, 2007 at 07:46 | #2

    Binding Variable + Thinking in Set

    这是我找工作必须提出的两点主张.

    也许我换工作太频繁了, 嘻嘻.

  3. victor666666
    August 17th, 2007 at 08:34 | #3

    如果我没记错的的话,biti_rainy 在cnoug上有个关于similar/histogram/version count/soft parse的讨论贴

  4. August 18th, 2007 at 12:13 | #4

    Fenng on August 16, 2007 at 10:15 pm said:

    Force 了?

    估计你接下来就该遇到更多的Bug了

    没有,我是建议删除列上的histogram了。

  5. kangbiao
    August 18th, 2007 at 20:38 | #5

    产生这种情况的条件是:
    1. cursor_sharing = similar
    2. 收集了列上的histogram
    3. SQL中使用到了此列作为条件,并且条件是“等于”
    4. 这个SQL是没有绑定变量的

    这四个条件是必要的吗?
    我记得似乎就是绑定了变量,还是会出现这种情况的

  6. linyiyong
    August 19th, 2007 at 12:50 | #6

    请问需要什么样级别的CSI才能看这个SR?

  7. August 19th, 2007 at 15:20 | #7

    @kangbiao
    在我们的系统上是未绑定变量的,我不确认如果变量绑定了并且cursor_sharing = exact仍然会出现这个问题

    @linyiyong
    需要能够浏览其他SR的权限,我不知道Customer的CSI会不会有这个级别,也许不会吧。。。

  8. 马艺桐mayitong@hotmail.com
    August 20th, 2007 at 09:45 | #8

    开不到你的sr detial,不同CSI号没办法看,不如将SR 粘贴出来,过滤到客户的信息即可!

  9. ynhoo
    August 21st, 2007 at 17:03 | #9

    直接查6470259.992

  10. August 22nd, 2007 at 13:15 | #10

    这个SR好长!
    看到了内部员工与普通partner和最终用户在SR服务上的区别了。
    内部员工的SR随时有人回,而且可以通过AIM(内部交流似乎都用这个).

  11. August 22nd, 2007 at 13:19 | #11

    还有其中给的文章连接都是直接指向WEBIV的,比如Note 377847.1,Note 390249.1 How To Quickly Add/Remove Column Statistics (Histograms)

  12. August 22nd, 2007 at 13:40 | #12

    @boypoo
    不是内部员工和最终用户有区别,实际上Oracle的SR服务是更看重最终用户的,这个SR之所以随时有人回复,是因为我开了Sev 1,也就是所谓的一级TAR,因此是24小时有人应答的。

    Add/Remove Column Statistics其实就是DBMS_STATS.DELETE_COLUMN_STATS函数的普通功能,单单这个倒还真不用WebIV,呵呵。

  13. truezxd
    August 22nd, 2007 at 17:17 | #13

    叹气,我还是看不到!没有权限。。。

  14. Fishyu
    August 23rd, 2007 at 14:01 | #14

    我的metalink帐号没有权限那,强烈建议kamus能够贴出来看看,如果不方便的话发一个到我邮箱撒!:)谢谢!

  15. August 23rd, 2007 at 14:53 | #15

    呵呵,我看是Quickly,以为还有特殊方法呢:)

  16. August 25th, 2007 at 20:53 | #16

    看来loadrunner测试还真是好用。本来不想用了,看来这把我也好好测试一把。

  17. 马艺桐mayitong@hotmail.com
    August 27th, 2007 at 11:54 | #17

    看不到这些信息呀,楼主能不能帖出来
    sqlplus -prelim “/ as sysdba”)
    如何禁用mutex而使用以前版本的library cache latch机制
    如何跟踪cursor (使用cursortrace事件)

  18. August 27th, 2007 at 16:04 | #18

    现在外地出差,metalink我自己都很难登录上。。。
    等回到公司,我把这个SR保存成html,然后当附件上传上来好了。
    等几天,我会更新这个帖子的。

  19. September 3rd, 2007 at 13:30 | #19

    已经把完整的SR保存为htm页面上载到本文章最后了,有兴趣的朋友可以下载去看看

  20. koko
    September 6th, 2007 at 15:57 | #20

    产生这种情况的条件是:
    1. cursor_sharing = similar
    2. 收集了列上的histogram
    3. SQL中使用到了此列作为条件,并且条件是“等于”
    4. 这个SQL是没有绑定变量的

    这四个条件是必要的吗?
    我记得似乎就是绑定了变量,还是会出现这种情况的

    我这里就是这个现象
    1. cursor_sharing = exact
    2 .未收集列上的histogram
    3. insert sql
    4.绑定了变量

    version_count>32767 因此oracle在查一个sql有没有一个可用的执行计划的时候 child table >32767 抱了一个ora600的错

  21. September 8th, 2007 at 13:23 | #21

    @koko
    如果是这样的话,那应当是另外一个问题。
    能否给出你的SQL,执行计划以及相关表信息。
    你的情况是最普通的绑定变量应用,如果仅仅是因为绑定变量就导致version count过高,那这个世界早就乱了。。。

  22. koko
    September 10th, 2007 at 11:01 | #22

    早些时候我在论坛发过一个帖子 你也参与了的 你可能忘记了

    http://www.itpub.net/763469,0.html

  23. koko
    September 10th, 2007 at 11:08 | #23
  24. September 13th, 2007 at 11:00 | #24

    @koko
    你说的那个帖子我有印象,那其实也是varchar2变长的问题,而且还必须是后出现的SQL中绑定的变量长度要大于前面一个SQL,所以也并不仅仅是你说的只要满足那4个条件就可以,你说的那4个条件太普遍了。

  25. koko
    September 14th, 2007 at 15:34 | #25

    恩 而且我觉得这种情况太容易发生了
    一个sql如果出现了多个varchar2(4000)很有可能在将来的莫个时候
    出现问题
    我就在怀疑
    这种varchar2节约空间的机制 真的有必要吗?

  26. ma.qy
    April 27th, 2009 at 14:51 | #26

    我来说说这个问题。当cursor_sharing=similar
    1:从metalink 377847.1来看,不论有无histgram,都不会共享游标。
    2:这个问题与是否有histogram无关。而在如“377847.1”所说的dynamic sampling,是否有关?从我的测试结果来看,应该是有关的。但是在tom的文章里面,tom明确说明dynamic sampling只在hard parse才发生。
    3:我已经测试到没有histogram的时候也会发生bind peek导致游标不共享。而且肯定可以重复

  27. April 27th, 2009 at 16:27 | #27

    @ma.qy
    你提到的这篇文档并没有指出histogram的存在与此问题无关。相反地,倒是我这篇文章一份很好的注脚 :D
    比如你说dynamic sampling会导致游标不共享,原因在于“even if there are no histograms (or even statistics) on a table (since dynamic sampling will create these in the background.”
    当然,还有其它情况也会导致CBO认为bind is unsafe,但是正如你提到的文档中所说,“This occurs in a few scenarios but the most common is with histogram stats on an equality predicate.”
    同时,这篇文档也说明了为什么设置CURSOR_SHARING = FORCE也可以解决这个问题。

  1. October 10th, 2007 at 11:31 | #1
  2. October 27th, 2007 at 13:09 | #2
o-o >:) >:( :D :? :-S :) :( :! *(
Proudly using Dynamic Headers by Nicasio Design