前几天收到过应用人员的一个报障称,应用程序无法连接数据库,报了ORA的错误,这是一个Oracle 9.2.0.8的RAC数据库(历史够悠久了吧),人工使用sqlplus连接报错如下:
tstdb1@jq570322b:/home/tstdb1>sqlplus wangguan/773946@tstdb1
SQL*Plus: Release 9.2.0.8.0 - Production on Fri Nov 15 21:27:27 2015
Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.
ERROR:
ORA-04088: error during execution of trigger 'BOMS30.ON_CONNECT'
ORA-01403: no data found
ORA-06512: at line 4
Enter user-name:
可以看出登陆时调用了一个trigger,错误是由trigger抛出的
使用sqlplus '/as sysdba'连上数据库查看一下BOMS30.ON_CONNECT这个trigger
SP2-0575: Use of Oracle SQL feature not in SQL92 Entry Level. <----虽然登陆成功了,但正常登陆的情况下应该是没有这句话的,当时觉得数据库里肯定有异常
SYS@tstdb1-SQL> select source from dba_source where;
---trigger内容如下:
create or replace TRIGGER BOMS30.ON_CONNECT AFTER LOGON ON DATABASE
DECLARE
guser varchar2(30);
begin
SELECT sys_context('USERENV','SESSION_USER') into guser FROM dual;
if guser='BOMS30' THEN
EXECUTE IMMEDIATE 'alter session set nls_timestamp_format = ''YYYY-MM-DD HH24:MI:SS.FF''';
内容很简单,于是手工逐句调试,发现下面获取环境变量的语句尽然没有输出
SYS@tstdb1-SQL> SELECT sys_context('USERENV','SESSION_USER') FROM dual;
no rows selected
因为是双节点的RAC,之后又尝试查询gv$session、gv$instance等视图都报了ORA-00600错误
select * from gv$instance;
ORA-00600: internal error code, arguments: [15555], [], [], [], [], [], [], []
alert.log里Job进程也报了类似的错误:
Errors in file /oracle/app/oracle/admin/newshwg/bdump/newshwg2_j000_503990.trc:
ORA-00600: internal error code, arguments: [15555], [], [], [], [], [], [], []
ORA-06512: at "WANGGUAN.RECORD_SESSION", line 3
ORA-06512: at line 1
*** newshwg2_j000_503990.trc文件记录的主要内容如下:
ksedmp: internal or fatal error
ORA-00600: internal error code, arguments: [15555], [], [], [], [], [], [], []
Current SQL statement for this session:
INSERT INTO WANGGUAN.SESSION_RECORD SELECT SYSDATE FROM_TIME, A.* FROM GV$SESSION A
----- PL/SQL Call Stack -----
object line object
handle number name
70000046fdf4208 3 procedure WANGGUAN.RECORD_SESSION
7000004dcee7188 1 anonymous block
。。。省略了部分内容
但是查询非gv$开头的本地视图都是OK的
看到的第一反应是dual表记录被删了,果不其然
select * from dual;
no rows selected
解决方法很简单,插入一条记录即可
insert into dual values('X');
commit;
SYS@tstdb1-SQL> select * from dual;
D
-
X
之前的若干诡异问题均恢复了:用户能正常登陆数据库,sqlplus登陆时不再显示"SP2-0575: Use of Oracle SQL feature not in SQL92 Entry Level.",gv$视图也能正常查询了;
故障解决了,接着简单探究一下DUAL表:
DUAL是SYS下的一张表,其上还建有一个public synonym,我们平时用非SYS用户访问的都是同义词DUAL
col object_name format a10
set linesize 80
select owner,object_name from dba_objects where object_name='DUAL';
SYS@tstdb1-SQL> select owner,object_type,object_name from dba_objects where object_name='DUAL';
OWNER OBJECT_TYPE OBJECT_NAM
------------------------------ ------------------- ----------
SYS TABLE DUAL
PUBLIC SYNONYM DUAL
---往DUAL表insert一条记录,显示插入成功,但dual表里依然只显示一条记录
SYS@tstdb1-SQL> select * from dual;
D
-
X
SYS@tstdb1-SQL> insert into dual values('A');
1 row created.
SYS@tstdb1-SQL> select * from dual;
D
-
X
SYS@tstdb1-SQL> commit;
Commit complete.
SYS@tstdb1-SQL> select * from dual;
D
-
X
***虽然只显示一条记录,但实际在磁盘上存放了两条记录,通过dump block可以验证
SYS@tstdb1-SQL> select dbms_rowid.rowid_block_number(rowid),dbms_rowid.rowid_relative_fno(rowid) from dual;
DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID) DBMS_ROWID.ROWID_RELATIVE_FNO(ROWID)
------------------------------------ ------------------------------------
929 1
SYS@tstdb1-SQL> alter system dump datafile 1 block 929;
System altered.