{"id":871,"date":"2006-01-31T12:00:00","date_gmt":"2006-01-31T12:00:00","guid":{"rendered":"http:\/\/orcldoug.com\/blog\/?p=871"},"modified":"2006-01-31T12:00:00","modified_gmt":"2006-01-31T12:00:00","slug":"basic-blocking-lock-detection","status":"publish","type":"post","link":"http:\/\/orcldoug.com\/blog\/2006\/01\/31\/basic-blocking-lock-detection\/","title":{"rendered":"Basic Blocking Lock Detection"},"content":{"rendered":"<p>At work today we had a trouble ticket generated by BMC Patrol that complained of a &#8216;Locking Conflict&#8217;. Having no idea what this might mean, one of my colleagues (who is learning Oracle) asked how we&#8217;d detect a locking problem.<\/p>\n<p>Because we were in a hurry, I fell back on a very old, clunky, but reasonably reliable method to see if there really was a locking problem. I was a bit surprised that no-one seemed to know how to do this, because it&#8217;s pretty basic stuff, so there must be people out there who don&#8217;t and this is for them.<\/p>\n<p><span style=\"FONT-WEIGHT: bold\">Session 1<\/span><\/p>\n<pre>SQL&gt; connect testuser\/testuser<br\/>Connected.<br\/>SQL&gt; create table test_tab as select * from all_objects where rownum &lt;&gt; desc test_tab<br\/>Name                                      Null?    Type<br\/>----------------------------------------- -------- -----------------------<br\/>OWNER                                     NOT NULL VARCHAR2(30)<br\/>OBJECT_NAME                               NOT NULL VARCHAR2(30)<br\/>SUBOBJECT_NAME                                     VARCHAR2(30)<br\/>OBJECT_ID                                 NOT NULL NUMBER<br\/>DATA_OBJECT_ID                                     NUMBER<br\/>OBJECT_TYPE                                        VARCHAR2(19)<br\/>CREATED                                   NOT NULL DATE<br\/>LAST_DDL_TIME                             NOT NULL DATE<br\/>TIMESTAMP                                          VARCHAR2(19)<br\/>STATUS                                             VARCHAR2(7)<br\/>TEMPORARY                                          VARCHAR2(1)<br\/>GENERATED                                          VARCHAR2(1)<br\/>SECONDARY                                          VARCHAR2(1)<br\/><p><\/p><br\/>SQL&gt; select object_id, object_name from test_tab;<br\/><p><\/p><br\/>OBJECT_ID  OBJECT_NAME<br\/>---------- ------------------------------<br\/>258        DUAL<br\/>259        DUAL<br\/>311        SYSTEM_PRIVILEGE_MAP<br\/>313        SYSTEM_PRIVILEGE_MAP<br\/>314        TABLE_PRIVILEGE_MAP<br\/>316        TABLE_PRIVILEGE_MAP<br\/>317        STMT_AUDIT_OPTION_MAP<br\/>319        STMT_AUDIT_OPTION_MAP<br\/>605        MAP_OBJECT<br\/>886        RE$NV_LIST<br\/><p><\/p><br\/>10 rows selected.<br\/><p><\/p><br\/>SQL&gt; select object_id, object_name from test_tab<br\/>2  where object_id = 316<br\/>3  for update;<br\/><p><\/p><br\/>OBJECT_ID  OBJECT_NAME<br\/>---------- ------------------------------<br\/>316        TABLE_PRIVILEGE_MAP<\/pre>\n<p>This row is now locked by session 1.<\/p>\n<p><span style=\"FONT-WEIGHT: bold\">Session 2<\/span><\/p>\n<pre>SQL&gt; select object_id, object_name from test_tab<br\/>2  where object_id = 316<br\/>3  for update;<\/pre>\n<p>This session hangs because it&#8217;s waiting for the row locked by session 1.<\/p>\n<p>NOTE &#8211; If I&#8217;d added the NOWAIT keyword, I would have got this response instead<\/p>\n<pre>SQL&gt; select object_id, object_name from test_tab<br\/>2  where object_id = 316<br\/>3  for update nowait;<br\/>select object_id, object_name from test_tab<br\/>                         *<br\/>ERROR at line 1:<br\/>ORA-00054: resource busy and acquire with NOWAIT specified)<\/pre>\n<p>So we have a blocking lock problem &#8211; session 1 is blocking session 2 which is trying to lock the same row. The only way this situation will clear is if session 1 releases the lock (or a DBA kills the session ;-), which will achieve the same end).<\/p>\n<p>How would we know about this? There are a number of dictionary views that can help here &#8211; <a href=\"http:\/\/www.akadia.com\/services\/ora_locks_survival_guide.html\">this paper<\/a> is much more detailed than a mere blog and is worth a look &#8211; but the way I learnt to do this is<\/p>\n<pre>SQL&gt; connect \/ as sysdba<br\/>Connected.<\/pre>\n<p>Run the next script once, to create the additional dictionary views in this database if they don&#8217;t exist already.<\/p>\n<pre>SQL&gt; @?\/rdbms\/admin\/catblock<\/pre>\n<p>Now you can run utllockt.sql any time to see which sessions are blocking other sessions in a tree structure.<\/p>\n<pre>SQL&gt; @?\/rdbms\/admin\/utllockt<br\/><br\/>WAITING_SESSION   LOCK_TYPE         MODE_REQUESTED MODE_HELD<br\/>----------------- ----------------- -------------- --------------<br\/>LOCK_ID1          LOCK_ID2<br\/>----------------- -----------------<br\/>147               None<br\/>  141            Transaction       Exclusive      Exclusive<br\/>589830            1475<\/pre>\n<p>Here we can see that the session that isn&#8217;t indented at all &#8211; session id 147, is blocking session 141 (which is indented). If I add a third session trying to lock the same row, you&#8217;ll see the difference<\/p>\n<pre>SQL&gt; @?\/rdbms\/admin\/utllockt<br\/><br\/>WAITING_SESSION   LOCK_TYPE         MODE_REQUESTED MODE_HELD<br\/>----------------- ----------------- -------------- --------------<br\/>LOCK_ID1          LOCK_ID2<br\/>----------------- -----------------<br\/>147               None<br\/>  141            Transaction       Exclusive      Exclusive<br\/>589830            1475<br\/>  158            Transaction       Exclusive      Exclusive<br\/>589830            1475<\/pre>\n<p>Because sessions 141 and 158 are both waiting on session 147, they are indented to the same level. If I commit session 147, I&#8217;ll get this new output<\/p>\n<pre>WAITING_SESSION   LOCK_TYPE         MODE_REQUESTED MODE_HELD<br\/>-----------\n------ ----------------- -------------- --------------<br\/>LOCK_ID1          LOCK_ID2<br\/>----------------- ---------------\n--<br\/>141               None<br\/><br\/>  158            Transaction       Exclusive      Exclusive<br\/>917518\n      47<\/pre>\n<p>So now session 147 has released the lock, 141 has grabbed it and session 158 is waiting for it. If I commit in session 141, this is what I&#8217;ll get when I run utllockt<\/p>\n<pre>no rows selected<\/pre>\n<p>There are no blocked sessions now. Session 158 has the lock, but I&#8217;m not really interested in that if it&#8217;s not blocking anything<\/p>\n<p>What I like about this approach is that it&#8217;s available on every version of Oracle you&#8217;ll work with, on every platform and so when I needed to think quickly today, I knew I could rely on (and remember!) this. It has it&#8217;s problems, as discussed in the paper, but it will work well enough in most situations.<br \/><span style=\"FONT-WEIGHT: bold\">Updated &#8211; and as Nuno pointed out in the comments, there&#8217;s <a href=\"http:\/\/tinyurl.com\/b2dej\">DBA_WAITERS<\/a> too but I&#8217;m not 100% sure what version that first appeared.<\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>At work today we had a trouble ticket generated by BMC Patrol that complained of a &#8216;Locking Conflict&#8217;. Having no idea what this might mean, one of my colleagues (who is learning Oracle) asked how we&#8217;d detect a locking problem. Because we were in a hurry, I fell back on a very old, clunky, but&hellip; <a class=\"more-link\" href=\"http:\/\/orcldoug.com\/blog\/2006\/01\/31\/basic-blocking-lock-detection\/\">Continue reading <span class=\"screen-reader-text\">Basic Blocking Lock Detection<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-871","post","type-post","status-publish","format-standard","hentry","category-uncategorized","entry"],"jetpack_featured_media_url":"","jetpack-related-posts":[{"id":907,"url":"http:\/\/orcldoug.com\/blog\/2005\/11\/10\/10g-optimiser-environment-views\/","url_meta":{"origin":871,"position":0},"title":"10g Optimiser Environment Views","date":"November 10, 2005","format":false,"excerpt":"In a previous blog I mentioned that Julian Dyke had talked about these views during his presentation and I noticed Jonathan Lewis also includes it in an Appendix of his new book that I started reading last night. There are three versions of the viewConnected to:Oracle Database 10g Enterprise Edition\u2026","rel":"","context":"With 2 comments","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1563,"url":"http:\/\/orcldoug.com\/blog\/2010\/02\/22\/statistics-on-partitioned-tables-part-2\/","url_meta":{"origin":871,"position":1},"title":"Statistics on Partitioned Tables &#8211; Part 2","date":"February 22, 2010","format":false,"excerpt":"In the last part, I asked you to trust me that true Global Stats are a good thing so in this post I hope to show you why they are, to make sure you don't kid yourself that you can avoid them. (Updated later - this is all on 10.2.0.4)Why\u2026","rel":"","context":"With 6 comments","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1562,"url":"http:\/\/orcldoug.com\/blog\/2010\/02\/17\/statistics-on-partitioned-tables-part-1\/","url_meta":{"origin":871,"position":2},"title":"Statistics on Partitioned Tables &#8211; Part 1","date":"February 17, 2010","format":false,"excerpt":"If you've ever worked on large databases that use partitioned and subpartitioned tables, you'll be aware that there are significant challenges in maintaining up-to-date\/appropriate statistics. We've encountered a few problems at work recently and I decided it would be an idea to put together a series of posts covering the\u2026","rel":"","context":"With 11 comments","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1017,"url":"http:\/\/orcldoug.com\/blog\/2006\/07\/13\/alter-table-move-and-table-stats\/","url_meta":{"origin":871,"position":3},"title":"alter table &#8230; move and table stats","date":"July 13, 2006","format":false,"excerpt":"Howard Rogers left a comment on my last blog, showing an example of using alter table ... move on a 10gR2 database on Linux. In his example, unlike mine, the table rebuild did not nullify the table's statistics. I admit I was surprised myself when I ran my example yesterday\u2026","rel":"","context":"With 4 comments","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1016,"url":"http:\/\/orcldoug.com\/blog\/2006\/07\/12\/table-reorgs-and-statistics\/","url_meta":{"origin":871,"position":4},"title":"Table reorgs and statistics","date":"July 12, 2006","format":false,"excerpt":"While working on the ITL deadlock problem (which looks like it's been fixed by the initrans increase and table rebuild), the developers highlighted another table as hitting this problem in the past. When I investigated, I found that initrans had already been set to 6 so this had obviously happened\u2026","rel":"","context":"With 10 comments","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1477,"url":"http:\/\/orcldoug.com\/blog\/2009\/03\/30\/diagnosing-locking-problems-using-ash-part-1\/","url_meta":{"origin":871,"position":5},"title":"Diagnosing Locking Problems using ASH &#8211; Part 1","date":"March 30, 2009","format":false,"excerpt":"Some features in this post require a Diagnostics Pack license.There are few better illustrations of the utility of ASH data than the ability to detect and diagnose locking problems*, even after they've occurred. Because ASH is sampling all active sessions all of the time, you should have information both for\u2026","rel":"","context":"Similar post","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"_links":{"self":[{"href":"http:\/\/orcldoug.com\/blog\/wp-json\/wp\/v2\/posts\/871","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/orcldoug.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/orcldoug.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/orcldoug.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/orcldoug.com\/blog\/wp-json\/wp\/v2\/comments?post=871"}],"version-history":[{"count":0,"href":"http:\/\/orcldoug.com\/blog\/wp-json\/wp\/v2\/posts\/871\/revisions"}],"wp:attachment":[{"href":"http:\/\/orcldoug.com\/blog\/wp-json\/wp\/v2\/media?parent=871"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/orcldoug.com\/blog\/wp-json\/wp\/v2\/categories?post=871"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/orcldoug.com\/blog\/wp-json\/wp\/v2\/tags?post=871"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}