ORA-00603,ORA-01114,ORA-27069同时出现的解决!

1、环境:

OS:WINDOWS SERVER 2003
ORACLE:9201

2、现象:

报表开发人员报怨涉及到lothistory表的SQL语句查询巨慢无比:
查看了一下v$session_wait出现了大量的全表扫描(db file scattered read)等待.
lothistory是个大表并且已经按照eventtime做了范围分区.有上亿条记录,没什么说的了,创建索引是必然的了.
综合一下开发人员提供的那些报表SQL,决定创建如下LOCAL索引:

SQL> CREATE INDEX lothistory_idx1 ON lothistory (eventname,areaname,reasoncode,productspecname,oldprocessoperationname,eventtime) LOCAL
(
PARTITION LOTHISTORY08Q4 TABLESPACE LOTHISTORY_IDX08Q4,
PARTITION LOTHISTORY09Q1 TABLESPACE LOTHISTORY_IDX09Q1,
PARTITION LOTHISTORY09Q2 TABLESPACE LOTHISTORY_IDX09Q2,
PARTITION LOTHISTORY09Q3 TABLESPACE LOTHISTORY_IDX09Q3,
PARTITION LOTHISTORY09Q4 TABLESPACE LOTHISTORY_IDX09Q4,
PARTITION LOTHISTORY10Q1 TABLESPACE LOTHISTORY_IDX10Q1
);

此语句运行了一段时间后.就出现了如下错误:

ORA-00603: ORACLE server session terminated by fatal error

3、分析:

看一下数据库后台到底是报了哪样的错误吧:

Errors in file i:\oracle\admin\q1spc01\udump\q1spc01_ora_4028.trc:
ORA-00603: ORACLE server session terminated by fatal error
ORA-01114: IO error writing block to file 201 (block # 523913)
ORA-27069: skgfdisp: attempt to do I/O beyond the range of the file
OSD-04026: 传递的参数无效。 (OS 523943)
ORA-01114: IO error writing block to file 201 (block # 523913)
ORA-27069: skgfdisp: attempt to do I/O beyond the range of the file
OSD-04026: 传递的参数无效。 (OS 523943)
ORA-01114: IO error writing block to file 201 (block # 523913)
ORA-27069: skgfdisp: attempt to do I/O beyond the range of the file
OSD-04026: 传递的参数无效。 (OS 523943)
ORA-01114: IO error writing block to file 201 (block # 523913)
ORA-27069: skgfdisp: attempt to do I/O beyond the range of the file
OSD-04026: 传递的参数无效。 (OS 523943)

那就看看file 201是哪个文件吧:

SQL> select file#,name from v$datafile where file#=201;

未选定行
不是吧?没有?
转了个metalink上的回复。

The file number should appear in v$datafile. If 201 is higher than the number set for db_files, the file is a temp file and you can try the

following:
SELECT name FROM v$tempfile WHERE file#=( - ;

If your DB_FILES parameter is set to 100 within the init.ora and your error shows a problem with file 101, you will know the problem is with

v$tempfile file# = 1.

This appears to be an operating system specific issue. You may be running into a OS file size limitation. You will want to check the event

viewer for further error messages. You should post to the Microsoft Installation/OS: RDBMS for further information as to why this problem is

occuring.

这样就可以找到201这个文件到底是什么了。
SQL> SELECT name FROM v$tempfile WHERE file#=1;

NAME
---------------------------------------------------

I:\ORACLE\ORADATA\Q1SPC01\TEMP01.DBF

竟然是个临时数据文件。

网上找了一下,PUB里就有一个一样的案例(可惜没有具体的解决方案):
http://www.itpub.net/viewthread. ... p;extra=&page=1

主要的说法有:
  1):数据文件数量超过了db_files的参数设定值了。(查了一下并没有超出)
SQL> show parameter db_files;

NAME                                 TYPE        VALUE
------------------------------------ ----------- -------
db_files                             integer     200

SQL> select count(*) from v$datafile;

  COUNT(*)
----------
        51

SQL> select count(*) from v$tempfile;

  COUNT(*)
----------
         7

  2):碰到数据库BUG了。

看了一下TEMP表空间的设置,发现file#=1的数据文件是自动扩展的,并且大小已经达到4GB。其余的都不能自动扩展。

现在意识到问题出在哪了:
可能是因为创建索引时导致tempfile1自动扩展到4GB,达到了操作系统的限制了。
但是比较奇怪的是,当我手动添加新的tempfile以增加TEMP表空间大小后。重新创建索引,问题重现了。
好象写完tempfile1后没办法跳到tempfile2继续写一样。
猜想一下要是不建这么多列的组合索引,只在eventtime一列上创建索引,那用的排序空间应该不会那么大了吧,应该不大于4GB吧,实验一下,真的成功了。
有趣吧?问题肯定就在tempfile1这里了。

4、解决:

问题找到了?如何解决呢?这真是ORACLE的BUG吗?那就升级吧……这是我的第一反应。
等等……
既然问题来自于tempfile的自动扩展至4GB这一操作系统限制,那就在TEMP表空间上面做点文章吧。
相信你也猜到了吧?
我重建一个不可自动扩展TEMP2表空间,然后将系统旧的TEMP表空间切换至TEMP2表空间。这样应该可以了吧?试试吧:

  1):查询用户的缺省临时表空间.
SQL> select username,temporary_tablespace from dba_users;

USERNAME                       TEMPORARY_TABLESPACE
------------------------------ ------------------------------
SYS                            TEMP
SYSTEM                         TEMP
DBSNMP                         TEMP
SPC                            TEMP
EDU01                          TEMP
BI                             TEMP
SSEXAM                         TEMP
CTXSYS                         TEMP
TRAC                           TEMP
COM                            TEMP
EC                             TEMP

USERNAME                       TEMPORARY_TABLESPACE
------------------------------ ------------------------------
EDU                            TEMP
OUTLN                          TEMP
WMSYS                          TEMP

  2):查询现在所用temp的路径.(为切换后的temp做准备)
SQL> select name from v$tempfile;

NAME
-----------------------------------------

I:\ORACLE\ORADATA\Q1SPC01\TEMP01.DBF
I:\ORACLE\ORADATA\Q1SPC01\TEMP02.DBF
I:\ORACLE\ORADATA\Q1SPC01\TEMP03.DBF
I:\ORACLE\ORADATA\Q1SPC01\TEMP04.DBF
I:\ORACLE\ORADATA\Q1SPC01\TEMP05.DBF
I:\ORACLE\ORADATA\Q1SPC01\TEMP06.DBF
I:\ORACLE\ORADATA\Q1SPC01\TEMP07.DBF

  3):重建新的临时表空间
create temporary tablespace temp2 tempfile 'I:\ORACLE\ORADATA\Q1SPC01\TEMP2_1.DBF' size 2000M;
alter tablespace temp2 add tempfile 'I:\ORACLE\ORADATA\Q1SPC01\TEMP2_2.DBF' size 2000M;
alter tablespace temp2 add tempfile 'I:\ORACLE\ORADATA\Q1SPC01\TEMP2_3.DBF' size 2000M;
alter tablespace temp2 add tempfile 'I:\ORACLE\ORADATA\Q1SPC01\TEMP2_4.DBF' size 2000M;

  4):切换临时表空间.
alter database default temporary tablespace temp2;
select username,temporary_tablespace from dba_users; (查询的结果应和1相同)
SQL> select username,temporary_tablespace from dba_users;

USERNAME                       TEMPORARY_TABLESPACE
------------------------------ ------------------------------
SYS                            TEMP2
SYSTEM                         TEMP2
DBSNMP                         TEMP2
SPC                            TEMP2
EDU01                          TEMP2
BI                             TEMP2
SSEXAM                         TEMP2
CTXSYS                         TEMP2
TRAC                           TEMP2
COM                            TEMP2
EC                             TEMP2

USERNAME                       TEMPORARY_TABLESPACE
------------------------------ ------------------------------
EDU                            TEMP2
OUTLN                          TEMP2
WMSYS                          TEMP2

  5):确认临时表空间为不可自动扩展模式.
SQL> col file_name for a40
SQL> col tablespace_name for a10
SQL> select file_name,tablespace_name,autoextensible from dba_temp_files;

FILE_NAME                                TABLESPACE  AUT
---------------------------------------- ----------  ---
I:\ORACLE\ORADATA\Q1SPC01\TEMP2_1.DBF     TEMP2       NO
I:\ORACLE\ORADATA\Q1SPC01\TEMP2_2.DBF     TEMP2       NO
I:\ORACLE\ORADATA\Q1SPC01\TEMP2_3.DBF     TEMP2       NO
I:\ORACLE\ORADATA\Q1SPC01\TEMP2_4.DBF     TEMP2       NO

  6):如果原临时表空间无用户使用,我们可以删除该表空间.
drop tablespace temp;

  7):好了,TEMP表空间切换完成了。重新执行一下一开始的创建索引的语句吧。

good!这次成功了。将刚开始创建的那个单列eventtime索引 drop了。

5、总结:

  1):TEMP,UNDO表空间最好不要设置成autoextensible,避免带来不必要的麻烦。
  2):注意下数据库的小版本号,有机会可以选择升级至更高的小版本。
  3):前面猜想的原因可能是因为文件大于4GB受操作系统限制了,可是网上查了一下,ntfs说是单个文件可以支持到64GB的呀,为什么才到4GB就出问题了?

[ 本帖最后由 zuohao_lu 于 2009-4-29 16:57 编辑 ]

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/12045182/viewspace-592277/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/12045182/viewspace-592277/

你可能感兴趣的:(ORA-00603,ORA-01114,ORA-27069同时出现的解决!)