ITPub博客

首页 > Linux操作系统 > Linux操作系统 > Oracle 数据库常见问题

Oracle 数据库常见问题

原创 Linux操作系统 作者:chwang1984 时间:2010-10-23 12:19:45 0 删除 编辑
文件比控制文件更新 - 旧的控制文件:

问题描述:

数据库装载完毕。
ORA-01122: 数据库文件 1 验证失败
ORA-01110: 数据文件 1: 'C:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\SYSTEM01.DBF'
ORA-01207: 文件比控制文件更新 - 旧的控制文件

原因:使用过旧的控制文件造成控制文件比数据文件旧。

解决过程:

resetlogs与noresetlogs的区别
norestlogs,控制文件的scn是来自当前日志的high scn,而resetlogs控制文件的scn是来自数据文件。

1.sqlplus /nolog        
2.conn /as sysdba 

3.startup mount
4.alter database backup controlfile to trace; 生成跟踪文件

5.查看跟踪文件的路径:

SELECT a.VALUE||b.symbol||c.instance_name||'_ora_'||d.spid||'.trc' TRACE_FILE_NAME
    FROM (SELECT VALUE FROM v$parameter WHERE NAME='user_dump_dest') a,
         (SELECT SUBSTR(VALUE,-6,1) symbol FROM v$parameter WHERE NAME='user_dump_dest') b,
         (SELECT instance_name FROM v$instance) c,
         (SELECT spid FROM v$session s,v$process p,v$mystat m
          WHERE s.paddr=p.addr AND s.SID=m.SID AND m.statistic#=0) d

TRACE_FILE_NAME
---------------------------------------------------------------------------------------------
E:\ORACLE\PRODUCT\10.2.0\ADMIN\ORCL\UDUMP\orcl_ora_5724.trc
在这orcl_ora_5724.trc脚本中可以找到创建控制文件的两种方式noresetlogs/resetlogs.

首先我们来看noresetlogs

CREATE CONTROLFILE REUSE DATABASE "ORCL" NORESETLOGS  ARCHIVELOG
    MAXLOGFILES 16
    MAXLOGMEMBERS 3
    MAXDATAFILES 100
    MAXINSTANCES 8
    MAXLOGHISTORY 292
LOGFILE
  GROUP 1 'E:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\REDO01.LOG'  SIZE 50M,
  GROUP 2 'E:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\REDO02.LOG'  SIZE 50M,
  GROUP 3 'E:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\REDO03.LOG'  SIZE 50M
-- STANDBY LOGFILE
DATAFILE
  'E:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\SYSTEM01.DBF',
  'E:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\UNDOTBS01.DBF',
  'E:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\SYSAUX01.DBF',
  'E:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\USERS01.DBF',
  'E:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\EXAMPLE01.DBF',
  'E:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\FTITEM10G01',
  'E:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\EYGLE01.DBF',
  'E:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\FTTEST01',
  'E:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\USERS02.DBF',
  'E:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\ZXF1.DBF',
  'E:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\ZXF2.DBF',
  'E:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\TZX01.DBF'
CHARACTER SET ZHS16GBK
;

保存为recreate.sql,并放在Oracle_HOME目录下
6.SQL> @?\recreate.sql

7.SQL> alter database open

然后我们来看resetlogs

CREATE CONTROLFILE REUSE DATABASE "ORCL" RESETLOGS  ARCHIVELOG
    MAXLOGFILES 16
    MAXLOGMEMBERS 3
    MAXDATAFILES 100
    MAXINSTANCES 8
    MAXLOGHISTORY 292
LOGFILE
  GROUP 1 'E:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\REDO01.LOG'  SIZE 50M,
  GROUP 2 'E:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\REDO02.LOG'  SIZE 50M,
  GROUP 3 'E:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\REDO03.LOG'  SIZE 50M
-- STANDBY LOGFILE
DATAFILE
  'E:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\SYSTEM01.DBF',
  'E:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\UNDOTBS01.DBF',
  'E:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\SYSAUX01.DBF',
  'E:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\USERS01.DBF',
  'E:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\EXAMPLE01.DBF',
  'E:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\FTITEM10G01',
  'E:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\EYGLE01.DBF',
  'E:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\FTTEST01',
  'E:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\USERS02.DBF',
  'E:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\ZXF1.DBF',
  'E:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\ZXF2.DBF',
  'E:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\TZX01.DBF'
CHARACTER SET ZHS16GBK
;

保存为recreate.sql,并放在Oracle_HOME目录下
6.SQL> @?\recreate.sql

7.SQL>  recover database using backup controlfile until cancel;

指定日志: {=suggested | filename | AUTO | CANCEL}
C:\oracle\product\10.2.0\oradata\orcl\REDO02.LOG
已应用的日志。
完成介质恢复。

8.SQL>alter database open resetlogs;

控制文件大小不对:

ORA-00205: error in identifying control file, check alert log for more info
这里提示了控制文件有错误。

 C:\oracle\product\10.2.0\oradata\orcl 的目录

2010-10-28  19:18         7,392,195 CONTROL01.CTL
2010-10-28  19:17         7,389,184 CONTROL02.CTL
2010-10-28  19:17         7,389,184 CONTROL03.CTL
               3 个文件     22,170,563 字节
               0 个目录  2,365,071,360 可用字节

关闭数据库,将正常的cp给不正常的,然后重新启动数据库。

ORACLE 10g:联机日志文件丢失或损坏的处理方法

方法一:用cancel模式恢复数据库

1、 启动数据库

SQL>startup
ORACLE instance started.
Total System Global Area  353862792 bytes
Fixed Size                   730248 bytes
Variable Size             285212672 bytes
Database Buffers           67108864 bytes
Redo Buffers                 811008 bytes
Database mounted.
ORA-00313: open failed for members of log group 1 of thread 1
ORA-00312: online log 1 thread 1: '/T3/ORACLE/oradata/ORA9/redo01.log'

2、 查看当前日志状态
SQL>; select * from v$log;

    GROUP#    THREAD#  SEQUENCE#      BYTES    MEMBERS ARC STATUS
---------- ---------- ---------- ---------- ---------- --- ----------------
FIRST_CHANGE# FIRST_TIME
------------- ----------
         1          1          2  104857600          1 YES INACTIVE
       487837 01-9月 -05

         2          1          4  104857600          1 NO  CURRENT
       487955 01-9月 -05

         3          1          3  104857600          1 YES INACTIVE
       487839 01-9月 -05
看来redo01.log不是当前日志,对于这类非当前日志可以直接clear,系统会重新自动生成一个redo文件
3、 查看日志文件的丢失情况

C:\oracle\product\10.2.0\oradata\orcl>dir re*

发现日志文件全部丢失

4.利用cancel模式恢复数据库

SQL>; recover database until cancel;
Media recovery complete.
5.打开数据库

SQL>alter database open resetlogs;
Database altered.

SQL>;
数据一点儿都没有丢失

结论:
如果数据库是正常关闭的,用recover database until cancel可以轻松恢复或者说重新建立所有的redo,不再区分是否是当前日志,而且由于正常关闭,不会丢失任何数据,唯一可能丢失的情况就是如果日志还没有归档
这种恢复方法 由于要resetlogs,所以在恢复完成后,日志清零,以前的备份不再起作用,所以建议立即备份

查看归档模式:
SQL>archive log list;
Database log mode              Archive Mode
Automatic archival             Enabled
Archive destination            /T3/ORACLE/arch
Oldest online log sequence     0
Next log sequence to archive   1
Current log sequence           1

或者

SQL>select db_id,name,log_mod from v$database;

备注:Resetlogs其实就是根据控制文件让系统自动重新生成redo,如果noresetlog的话,就不会重新生成redo,缺少了文件,db自然无法启动) ,所有用 alter database open noresetlogs 不能恢复日志

方法二:用命令清空日志组方法

SQL>startup
ORACLE instance started.
Total System Global Area  353862792 bytes
Fixed Size                   730248 bytes
Variable Size             285212672 bytes
Database Buffers           67108864 bytes
Redo Buffers                 811008 bytes
Database mounted.
ORA-00313: open failed for members of log group 1 of thread 1
ORA-00312: online log 1 thread 1: '/T3/ORACLE/oradata/ORA9/redo01.log'

2、 查看当前日志状态
SQL>; select * from v$log;

    GROUP#    THREAD#  SEQUENCE#      BYTES    MEMBERS ARC STATUS
---------- ---------- ---------- ---------- ---------- --- ----------------
FIRST_CHANGE# FIRST_TIME
------------- ----------
         1          1          2  104857600          1 YES INACTIVE
       487837 01-9月 -05

         2          1          4  104857600          1 NO  CURRENT
       487955 01-9月 -05

         3          1          3  104857600          1 YES INACTIVE
       487839 01-9月 -05
看来redo01.log不是当前日志,对于这类非当前日志可以直接clear,系统会重新自动生成一个redo文件

3.非当前(current)的未归档日志文件恢复alter database clear logfile group N;

--N就是日志组的顺序号。

归档日志文件恢复:
alter database clear logfile unarchived group N;
 
    SQL>alter database clear logfile group 1;
                 Database altered. 
    SQL>alter database clear logfile group 3;
                 Database altered.
4.拷贝一个有效的当前日志,从有效的备份中cp一个
 
5.SQL>alter database clear unarchived logfile group 1 unrecoverable datafile;
6.SQL>alter database open;
 
结论:
如果数据库是正常shutdown,非当前日志都可以直接clear来重新生成,而且不丢失数据,因为正常关闭db,数据已经写入dbf文件了。唯独当前日志不可以,当前日志必须首先从有效的备份中拷贝一个日志文件过来
方法三:通过重新生成控制文件来恢复redo
1、生成跟踪文件
SQL>alter database backup controlfile to trace;

Database altered.

SQL> shutdown immediate
ORA-01109: database not open

Database dismounted.
ORACLE instance shut down.
2、 修改一下刚才生成的那个文件
CREATE CONTROLFILE REUSE DATABASE "ORA9"  RESETLOGS  ARCHIVELOG
--  SET STANDBY TO MAXIMIZE PERFORMANCE
    MAXLOGFILES 50
    MAXLOGMEMBERS 5
    MAXDATAFILES 100
    MAXINSTANCES 1
    MAXLOGHISTORY 226
LOGFILE
  GROUP 1 '/T3/ORACLE/oradata/ORA9/redo01.log'  SIZE 100M,
  GROUP 2 '/T3/ORACLE/oradata/ORA9/redo02.log'  SIZE 100M,
  GROUP 3 '/T3/ORACLE/oradata/ORA9/redo03.log'  SIZE 100M
-- STANDBY LOGFILE
DATAFILE
  '/T3/ORACLE/oradata/ORA9/system01.dbf',
  '/T3/ORACLE/oradata/ORA9/undotbs01.dbf',
  '/T3/ORACLE/oradata/ORA9/cwmlite01.dbf',
  '/T3/ORACLE/oradata/ORA9/drsys01.dbf',
  '/T3/ORACLE/oradata/ORA9/example01.dbf',
  '/T3/ORACLE/oradata/ORA9/indx01.dbf',
  '/T3/ORACLE/oradata/ORA9/odm01.dbf',
  '/T3/ORACLE/oradata/ORA9/tools01.dbf',
  '/T3/ORACLE/oradata/ORA9/users01.dbf',
  '/T3/ORACLE/oradata/ORA9/xdb01.dbf',
  '/T3/ORACLE/oradata/ORA9/test01.dbf'
CHARACTER SET ZHS16GBK
;
另存为一个脚本,运行他
SQL>@clone.sql
Control file created.
SQL>; alter database open resetlogs;
Database altered.
SQL>;

结论:这种方法的关键是重新创建控制文件,后面的步骤和前面的道理一样的
 
前面的三种方法都是假设db是正常关闭的,数据已经写入数据库文件中,所以不会由数据存在redo种,所以clear的话也不会有数据丢失
 
方法四:修改系统参数方法
1、 插入数据
SQL>select * from test;
TEL
----------
         1
         2
         3
         4

SQL>; insert into test values(5);

1 row created.

SQL>commit;

Commit complete.

2、 强行关闭
SQL>shutdown abort
ORACLE instance shut down.
3、 手工模拟删除redo
4、 启动db
SQL>startup
ORACLE instance started.

Total System Global Area  353862792 bytes
Fixed Size                   730248 bytes
Variable Size             285212672 bytes
Database Buffers           67108864 bytes
Redo Buffers                 811008 bytes
Database mounted.
ORA-00313: open failed for members of log group 3 of thread 1
ORA-00312: online log 3 thread 1: '/T3/ORACLE/oradata/ORA9/redo03.log'
ORA-27037: unable to obtain file status
SVR4 Error: 2: No such file or directory
Additional information: 3
5、 尝试使用前3中方法中最简单的
SQL>; recover database until cancel;
ORA-00279: change 550174 generated at 09/02/2005 16:00:19 needed for thread 1
ORA-00289: suggestion : /T3/ORACLE/arch/1_1.dbf
ORA-00280: change 550174 for thread 1 is in sequence #1
Specify log: {;=suggested | filename | AUTO | CANCEL}
看来不行
6、 修改init.ora,加入一行
_allow_resetlogs_corruption=true
7、 启动with pfile
SQL>startup
ORACLE instance started.
Total System Global Area  320308312 bytes
Fixed Size                   730200 bytes
Variable Size             285212672 bytes
Database Buffers           33554432 bytes
Redo Buffers                 811008 bytes
Database mounted.
ORA-01589: must use RESETLOGS or NORESETLOGS option for database open
SQL>alter database open resetlogs;
8、 检验数据
SQL>; select * from test.test;

       TEL
----------
         1
         2
         3
         4

我们前面由于执行了SHUTDOWN ABORT,这时候对数据的修改还没有保存到数据文件中,虽然执行了COMMIT,这个时候还在联机日志中,等待CKPT触发DBWR写入DATAFILE,但是这个时候执行了SHUTDOWN ABORT,redo被删除后,里面的信息也就丢了,造成数据丢失
9、 备份,去掉那个参数
 
方法五:丢失当前日志组的成员
1、SQL>select * from v$logfile;

    GROUP# STATUS  TYPE  MEMBER
---------- ------- -------
--------------------------------------------------------------------------------
         3         ONLINE  /T3/ORACLE/oradata/ORA9/redo03.log

         2         ONLINE  /T3/ORACLE/oradata/ORA9/redo02.log

         1         ONLINE  /T3/ORACLE/oradata/ORA9/redo01.log


    GROUP# STATUS  TYPE  MEMBER
---------- ------- -------

--------------------------------------------------------------------------------
         1         ONLINE  /T3/ORACLE/oradata/ORA9/redo01a.log

         2         ONLINE  /T3/ORACLE/oradata/ORA9/redo02a.log

         3         ONLINE  /T3/ORACLE/oradata/ORA9/redo03a.log
SQL>select * from v$log;

    GROUP#    THREAD#  SEQUENCE#      BYTES    MEMBERS ARC STATUS
---------- ---------- ---------- ---------- ---------- --- ----------------
FIRST_CHANGE# FIRST_TIME
------------- ----------
         1          1          2  104857600          2 YES INACTIVE
       554599 02-9月 -05

         2          1          3  104857600          2 YES INACTIVE
       554601 02-9月 -05

         3          1          4  104857600          2 NO  CURRENT
       554603 02-9月 -05

3、 模拟插入数据
SQL>; conn test/test
Connected.
SQL>; select * from test;

       TEL
----------
         1
         2
         3
         4

SQL>; insert into test values(5);

1 row created.

SQL>; commit
  2  ;

Commit complete.
4、 shutdown db,模拟删除一个当前日志成员
$ cd oradata/ORA9
$ ls redo03*
redo03.log   redo03a.log
$ rm redo03a.log
5、 启动db,表面没有错误
SQL>startup
ORACLE instance started.

Total System Global Area  353862792 bytes
Fixed Size                   730248 bytes
Variable Size             285212672 bytes
Database Buffers           67108864 bytes
Redo Buffers                 811008 bytes
Database mounted.
Database opened.
6、 查看日至成员
SQL>select * from v$logfile;

    GROUP# STATUS  TYPE MEMBER
---------- ------- -------

--------------------------------------------------------------------------------
         3         ONLINE  /T3/ORACLE/oradata/ORA9/redo03.log

         2         ONLINE  /T3/ORACLE/oradata/ORA9/redo02.log

         1         ONLINE  /T3/ORACLE/oradata/ORA9/redo01.log


    GROUP# STATUS  TYPE MEMBER
---------- ------- -------

--------------------------------------------------------------------------------
         1         ONLINE  /T3/ORACLE/oradata/ORA9/redo01a.log

         2         ONLINE  /T3/ORACLE/oradata/ORA9/redo02a.log

         3 INVALID ONLINE  /T3/ORACLE/oradata/ORA9/redo03a.log
7、 删除出问题的联机日志文件
SQL>; alter database drop logfile member '/T3/ORACLE/oradata/ORA9/redo03a.log';
alter database drop logfile member '/T3/ORACLE/oradata/ORA9/redo03a.log'
*
ERROR at line 1:
ORA-01609: log 3 is the current log for thread 1 - cannot drop members
ORA-00312: online log 3 thread 1: '/T3/ORACLE/oradata/ORA9/redo03.log'
ORA-00312: online log 3 thread 1: '/T3/ORACLE/oradata/ORA9/redo03a.log'

看来当前日志成员是不允许删除的
SQL>alter system switch logfile;

System altered.

SQL> select * from v$log;

    GROUP#    THREAD#  SEQUENCE#      BYTES    MEMBERS ARC STATUS
---------- ---------- ---------- ---------- ---------- --- ----------------
FIRST_CHANGE# FIRST_TIME
------------- ----------
         1          1          5  104857600          2 NO  CURRENT
       557687 02-9月 -05

         2          1          3  104857600          2 YES INACTIVE
       554601 02-9月 -05

         3          1          4  104857600          2 YES ACTIVE
       554603 02-9月 -05

SQL>alter database drop logfile member '/T3/ORACLE/oradata/ORA9/redo03a.log';

Database altered.

SQL>alter database add logfile member '/T3/ORACLE/oradata/ORA9/redo03a.log' to group 3;

Database altered.
SQL>select * from v$logfile;

    GROUP# STATUS  TYPE MEMBER
---------- ------- -------

--------------------------------------------------------------------------------
         3         ONLINE  /T3/ORACLE/oradata/ORA9/redo03.log

         2         ONLINE  /T3/ORACLE/oradata/ORA9/redo02.log

         1         ONLINE  /T3/ORACLE/oradata/ORA9/redo01.log


    GROUP# STATUS  TYPE MEMBER
---------- ------- -------

--------------------------------------------------------------------------------
         1         ONLINE  /T3/ORACLE/oradata/ORA9/redo01a.log

         2         ONLINE  /T3/ORACLE/oradata/ORA9/redo02a.log

         3 INVALID ONLINE  /T3/ORACLE/oradata/ORA9/redo03a.log
看来还得切换一下日至
SQL>; alter system switch logfile;

System altered.
SQL>select * from v$logfile;

    GROUP# STATUS  TYPE MEMBER
---------- ------- -------

--------------------------------------------------------------------------------
         3         ONLINE  /T3/ORACLE/oradata/ORA9/redo03.log

         2         ONLINE  /T3/ORACLE/oradata/ORA9/redo02.log

         1         ONLINE  /T3/ORACLE/oradata/ORA9/redo01.log


    GROUP# STATUS  TYPE MEMBER
---------- ------- -------

--------------------------------------------------------------------------------
         1         ONLINE  /T3/ORACLE/oradata/ORA9/redo01a.log

         2         ONLINE /T3/ORACLE/oradata/ORA9/redo02a.log

         3         ONLINE /T3/ORACLE/oradata/ORA9/redo03a.log


结论:
只要日志组的member不是一个,出现前面的4种可能性是非常小的,即使出现了也有相应的恢复方法,所以不必惊慌;
如果memer多于1个,即使坏了其中的几个,也不会 影响数据库的正常启动,启动后,再进行相应的操作即可, 所以这个时候每天察看alert.log就显得非常重要了。

Oracle 9i:

一.丢失inactive日志文件组的恢复:

  由于inactive日志文件组表示已经完成了检查点(dirty数据已经被写入数据文件)。数据库本身不会发生数据库丢失,如果在这个时候相应的redo丢失/损坏,可以通过clear重建日志文件组恢复。

  通过命令:

  alter database clear logfile group n

  如果数据库模式是archived的,则需要强制清除

  alter database clear unarchived logfile group n

  二.丢失active或current日志文件组的恢复:

  丢失情况分两种:

  一个是正常关闭数据库(如shutdown immediate)

  另一个是异常关闭数据库(如shutdown abort)

  1.在损失当前日志时,数据库是正常关闭状态。

  由于shutdown immediate会执行全面的checkpoint,所以当前日志在实例恢复时可以不需要redo

  在Oracle 8i中我们完全可以通过alter database clear logfile group n来进行恢复.

  但是在Oracle 9i中,则可能无法对current的redo日志进行clear,需要通过recover database until cancel恢复后(必须要做的)

  用resetlogs选项打开。

  比如:


  alter database clear logfile group n
  recover database until cancel;
  alter database open resetlogs;


  2.在损失当前日志时,数据库是异常关闭的:

  这种情况下,由于没有在执行全面检查点时,数据库就已经关闭了,那么Oracle在进行实例恢复的时候必须要求当前的日志,否则Oracle数据库将无法open.

  这样的情况下,我们通常需要从备份中恢复数据文件,通过应用归档日志进行向前推演。直到最后一个完好的日志文件,然后可以通过resetlogs启动数据库完成恢复。那么丢失的数据则是被损坏的日志文件中的数据。

  注意:_allow_resetlogs_corruption是Oracle中的一个隐含参数,如果系统实在不能resetlogs方式打开的后只能出此下策,在pfile进行相应设置打开数据库。该函数的含义是,允许在破坏一致性的情况下强制重置日志,打开数据库。_allow_resetlogs_corruption将使用所有数据文件最旧的SCN打开数据库,所以通常来讲需要保证SYSTEM表空间拥有最旧的SCN。在强制打开数据库之后,可能因为各种原因会有ora-600

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

请登录后发表评论 登录
全部评论

注册时间:2009-03-27

  • 博文量
    96
  • 访问量
    185873