问题描述
对于单实例数据库而言,死锁的检测在秒级完成,而RAC环境则死锁的检测时间默认达到了1分钟。
专家解答
对于单实例环境如果出现了死锁,那么马上其中一个进程就被中止,用户可以快速的得到错误返回。而对于RAC而言,死锁的检测并不是实时完成,而是需要60秒左右的时间。
会话1执行:
SQL> CREATE TABLE t_deadlock (id NUMBER PRIMARY KEY, name varchar2(30)); TABLE created. Elapsed: 00:00:00.12 SQL> INSERT INTO t_deadlock VALUES (1, 'a'); 1 ROW created. Elapsed: 00:00:00.00 SQL> INSERT INTO t_deadlock VALUES (2, 'b'); 1 ROW created. Elapsed: 00:00:00.00 SQL> commit; Commit complete. Elapsed: 00:00:00.00 SQL> UPDATE t_deadlock SET name = 'a1' WHERE id = 1; 1 ROW updated. Elapsed: 00:00:00.00
会话2执行:
SQL> SET timing ON SQL> UPDATE t_deadlock SET name = 'b2' WHERE id = 2; 1 ROW updated. Elapsed: 00:00:00.00 SQL> UPDATE t_deadlock SET name = 'a2' WHERE id = 1;
此时,会话2等待会话1的最终操作,下面会话1更新被会话2锁定的行,引发死锁:
SQL> UPDATE t_deadlock SET name = 'b1' WHERE id = 2; UPDATE t_deadlock SET name = 'b1' WHERE id = 2 * ERROR at line 1: ORA-00060: deadlock detected while waiting FOR resource Elapsed: 00:01:00.12
可以看到,死锁的超时检测为1分钟。
而这个死锁的检测时间是可以调整的,Oracle通过隐含参数_lm_dd_interval控制:
SQL> conn / AS sysdba Connected. SQL> ALTER system SET "_lm_dd_interval" = 30 scope = spfile; System altered. SQL> shutdown immediate DATABASE closed. DATABASE dismounted. ORACLE instance shut down. SQL> startup ORACLE instance started. Total System Global Area 281018368 bytes Fixed SIZE 2095672 bytes Variable SIZE 104859080 bytes DATABASE Buffers 167772160 bytes Redo Buffers 6291456 bytes DATABASE mounted. DATABASE opened.
再次测试死锁的检测时间,会话1:
SQL> UPDATE t_deadlock SET name = 'a1' WHERE id = 1; 1 ROW updated. SQL> SET timing ON
会话2执行更新:
SQL> SET timing ON SQL> UPDATE t_deadlock SET name = 'b2' WHERE id = 2; 1 ROW updated. Elapsed: 00:00:00.02 SQL> UPDATE t_deadlock SET name = 'a2' WHERE id = 1;
会话1执行更新引发死锁:
SQL> UPDATE t_deadlock SET name = 'b1' WHERE id = 2; 大约30秒后,会话2报错ORA-60: <pre>update t_deadlock SET name = 'a2' WHERE id = 1 * ERROR at line 1: ORA-00060: deadlock detected while waiting FOR resource Elapsed: 00:00:30.27
在10.2.0.2版本上,Oracle存在一个bug,允许这个参数设置为0,在10.2.0.3以后,这个bug被修正,如果设置为0后,则数据库无法正常启动:
[oracle@node1 ~]$ sqlplus / AS sysdba SQL*Plus: Release 10.2.0.5.0 - Production ON Mon Jun 4 07:54:09 2012 Copyright (c) 1982, 2010, Oracle. ALL Rights Reserved. Connected TO an idle instance. SQL> startup ORA-00067: invalid VALUE 0 FOR parameter _lm_dd_interval; must be at least 1
最后修改隐含参数是Oracle不推荐的,而且修改这个参数势必会影响RAC的正常工作方式导致LDM进程的繁忙度增加,而且可能影响RAC环境的稳定性和可用性。
如果确实对于前台的死锁检查时间要求较高,建议在测试环境中详细测试后再部署到产品环境中。
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。