Find waiter with Oradebug 11gR2

原文链接自:Miladin Modrakovic’s Blog – Oraclue

实际上,昨天刚有朋友问怎么找到TX enqueu的锁对象以及语句。在Oracle11gR2中我们可以使用oradebug unit_test per_session_find_one_waiter语句来进行简单的blocker定位。

oradebug unit_test per_session_find_one_waiter的用法如下:

usage: 
  oradebug unit_test per_session_find_one_waiter
    find_waiters_for=
    wait_event=""
    waiter_min_secs_blkd=
    min_results=
    [ timeout_mins= ]

实际测试如下,还是测试简单的enq: TX – row lock contention等待事件。

在第1个session中:
[sourcecode language=”sql”]SQL> create table t (n int primary key);

Table created.

SQL> insert into t values(1);

1 row created.

SQL> commit;

Commit complete.

SQL> update t set n=2 where n=1;

1 row updated.[/sourcecode]

在第2个session中:
[sourcecode language=”sql” light=”true”]SQL> update t set n=3 where n=1;[/sourcecode]

在第3个session中:
[sourcecode language=”sql” light=”true”]SQL> update t set n=4 where n=1;[/sourcecode]

在另外一个session中用sysdba登陆,然后执行oradebug。
[sourcecode language=”sql”]SQL> oradebug unit_test per_session_find_one_waiter find_waiters_for=all_local_sess wait_event="enq: TX – row lock contention" waiter_min_secs_blkd=1 min_results=1
WAITERS_FOUND_BEGIN
(inst=1, sid=16, osid=30658) is blocking (inst=1, sid=17) for at least 501 secs
(inst=1, sid=17, osid=30668) is blocking (inst=1, sid=25) for at least 486 secs
WAITERS_FOUND_END[/sourcecode]

从以上的输出中可以得知:
1. sid=16的会话锁住了sid=17的会话,已经有至少501秒
2. sid=17的会话锁住了sid=25的会话,已经有至少486秒

此时如果commit会话1,那么会话2和会话3的”enq: TX – row lock contention” 锁都会消失,但是两个会话都不会更新到任何记录,因为n=1的记录已经被会话1更新为n=2。

在目前的测试中,如果在oradebug中指定的wait_event在当前数据库中并不存在,那么oradebug命令将长时间没有反应,并最终报出ORA-00600的错误,这应该是bug,有望在今后的版本中得到修改。

[sourcecode language=”sql”]SQL> oradebug unit_test per_session_find_one_waiter find_waiters_for=current_sess wait_event="enq: TX – row lock contention" waiter_min_secs_blkd=1 min_results=1

ORA-00600: internal error code, arguments: [ksdhng:waiting_sessions_not_found], [enq: TX – row lock contention], [10], [10], [], [], [], [], [], [], [], [][/sourcecode]

Oracle Database Instance Startup Fails With Error ORA-27302 ORA-27301

今天启动Oracle Enterprise Linux 5虚拟机中的Oracle11gR2数据库,但是报错。

[oracle@dbserver ~]$ sqlplus / as sysdba

SQL*Plus: Release 11.2.0.1.0 Production on Wed Dec 16 13:28:44 2009

Copyright (c) 1982, 2009, Oracle.  All rights reserved.

Connected to an idle instance.

SQL> startup
ORA-27154: post/wait create failed
ORA-27300: OS system dependent operation:semget failed with status: 28
ORA-27301: OS failure message: No space left on device
ORA-27302: failure occurred at: sskgpsemsper

sskgpsemsper函数可以很简单的猜测是跟semaphore有关,而ORA-27301则是No space left on device,那么很容易判断应该是操作系统内核参数中semaphore设置的问题。

[root@dbserver ~]# /sbin/sysctl -a | grep sem
kernel.sem = 250        100     32      128

而实际上,安装Oracle11gR2的semaphore需求是:
semmsl:250
semmns:32000
semopm:100
semmni:128

很明显semmns和semopm都不足。

[root@dbserver ~]# /sbin/sysctl -w kernel.sem="250 32000 100 128"
kernel.sem = 250 32000 100 128
[root@dbserver ~]# /sbin/sysctl -a | grep sem
kernel.sem = 250        32000   100     128
[root@dbserver ~]# echo "kernel.sem = 250 32000 100 128"  >> /etc/sysctl.conf
[root@dbserver ~]# 

重新启动数据库实例正常。

How to Set Power Auras Multiple Conditions in WoW

Power Auras插件是WoW中非常实用的插件,用自定义的图像自定义的方式,根据不同的触发条件在屏幕上显示提示信息,以醒目的方式提醒玩家做相应的操作。

先看一篇简单的POWA插件使用指南

在中文版的任何文章中,都没有提到如何设定复合条件,比如对于术士来说,如果想设定“敌方目标存在献祭效果,并且自己的焚烧可用”情况下,提示使用焚烧技能。这一需求是因为焚烧雕文的出现,焚烧并不会吞蚀献祭的效果,而献祭的时长又长于焚烧的CD时间,因此在长期的战斗过程中,往往一次献祭之后可以多次焚烧,那么必须要有一个醒目的提示来让玩家及时使用焚烧。

1. 首先设置献祭的提示,设置敌方目标身上存在献祭的情况下,触发该特效。然后将此特效置为禁用(Shift+鼠标左键点击图标)。在鼠标提示上可以看到[7]的字样,这是该特效的ID,记住。
POWA Multiple Conditions 1

2. 再设置焚烧的提示,设置自己焚烧技能CD的时候,触发该特效。然后,就是最重要的部分,在“精确匹配名称”后面的输入框内,输入献祭特效的ID,在本例中就是7。这部分表示只有在特效7和自身条件同时满足的情况下,特效才会触发。这里可以写多个特效ID,也就是允许无限多的复合条件。
POWA Multiple Conditions 2

3. 如果再设置一个献祭在敌方目标身上不存在则触发的特效,就可以在战斗中实现下面的效果。

当献祭在对方目标身上不存在的时候,特效提示补献祭。
POWA Multiple Conditions 3

当献祭在对方目标身上存在,并且自己焚烧CD的时候,特效提示补焚烧。
POWA Multiple Conditions 4

不需要再紧盯着面板和技能条,享受POWA带来的战斗新感觉吧。