Controlfile Recovery Requires RESETLOGS

In response to a small discussion on the oracle-l mailing list last week I thought I’d put together a quick demo of exactly what I was referring to in my email. Basically I was discussing how even when you do a normal shutdown – leaving your database in a consistent state that doesn’t require recovery – if you lose your controlfiles then you still will need to execute the “recovery” commands and then open resetlogs.

Here’s the test, which I did on one of our lab systems…

Setup

nap01:~/oradata/jt10g$ sqlplus / as sysdba

SQL*Plus: Release 10.2.0.1.0 - Production on Wed May 9 12:55:07 2007

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

Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - 64bit Production
With the Partitioning, OLAP and Data Mining options

SQL> col member format a40
SQL> select l.status, member
  2  from v$logfile inner join v$log l using (group#);

STATUS           MEMBER
---------------- ----------------------------------------
INACTIVE         /u04/oracle/oradata/jt10g/redo03.log
CURRENT          /u04/oracle/oradata/jt10g/redo02.log
INACTIVE         /u04/oracle/oradata/jt10g/redo01.log

SQL> alter database backup controlfile
  2  to '/u04/oracle/oradata/jt10g/backup.ctl';

Database altered.

SQL> alter system switch logfile;

System altered.

SQL> shutdown immediate;
Database closed.
Database dismounted.
ORACLE instance shut down.
  1. We have a valid backup of the controlfile.

  2. I issued a logfile switch since Joel Patterson specifically asked about it in the email discussion.

  3. The database had a clean, normal shutdown.

Now let’s simulate the loss of controlfiles only and walk through the recovery:

nap01:~/oradata/jt10g$ rm control*.ctl
nap01:~/oradata/jt10g$ sqlplus / as sysdba

SQL> startup
ORACLE instance started.

Total System Global Area  629145600 bytes
Fixed Size                  1980712 bytes
Variable Size             180356824 bytes
Database Buffers          440401920 bytes
Redo Buffers                6406144 bytes
ORA-00205: error in identifying control file, check alert log for more info

SQL> shutdown abort;
ORACLE instance shut down.

Recovery

At this point we have lost all of our control files. Rather than just do the RESETLOGS right away, first we’ll try one or two other ideas.

First let’s just restore the backup controlfile and try to open the database with no recovery at all.

nap01:~/oradata/jt10g$ cp backup.ctl control01.ctl
nap01:~/oradata/jt10g$ cp backup.ctl control02.ctl
nap01:~/oradata/jt10g$ cp backup.ctl control03.ctl
nap01:~/oradata/jt10g$ sqlplus / as sysdba

SQL*Plus: Release 10.2.0.1.0 - Production on Wed May 9 13:22:24 2007

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

Connected to an idle instance.

SQL> startup
ORACLE instance started.

Total System Global Area  629145600 bytes
Fixed Size                  1980712 bytes
Variable Size             180356824 bytes
Database Buffers          440401920 bytes
Redo Buffers                6406144 bytes
Database mounted.
ORA-01589: must use RESETLOGS or NORESETLOGS option for database open

SQL>

Interesting. We know that the database itself doesn’t need recovery; in fact we just have a controlfile that’s less than five minutes out of date. So let’s just try opening NORESETLOGS.

SQL> alter database open noresetlogs;
alter database open noresetlogs
*
ERROR at line 1:
ORA-01610: recovery using the BACKUP CONTROLFILE option must be done

Oracle requires us to run the recovery command even though we had a clean shutdown. Huh? There are no archived logs to apply! Well I guess we can start by doing a CANCEL-based recovery and just canceling right away (since there are no archived logs to apply).

SQL> recover database using backup controlfile until cancel;
ORA-00279: change 775140 generated at 05/09/2007 07:00:38 needed for thread 1
ORA-00289: suggestion :
/u04/oracle/product/10.2.0/db_1/dbs/arch1_5_621627183.dbf
ORA-00280: change 775140 for thread 1 is in sequence #5

Specify log: {<RET>=suggested | filename | AUTO | CANCEL}
CANCEL
ORA-01547: warning: RECOVER succeeded but OPEN RESETLOGS would get error below
ORA-01152: file 1 was not restored from a sufficiently old backup
ORA-01110: data file 1: '/u04/oracle/oradata/jt10g/system01.dbf'

ORA-01112: media recovery not started

Well it claims that we can’t open the database but let’s just give it a try.

SQL> alter database open;
alter database open
*
ERROR at line 1:
ORA-01589: must use RESETLOGS or NORESETLOGS option for database open

SQL> alter database open noresetlogs;
alter database open noresetlogs
*
ERROR at line 1:
ORA-01588: must use RESETLOGS option for database open

SQL> alter database open resetlogs;
alter database open resetlogs
*
ERROR at line 1:
ORA-01152: file 1 was not restored from a sufficiently old backup
ORA-01110: data file 1: '/u04/oracle/oradata/jt10g/system01.dbf'

There you are. Looks like Oracle requires a RESETLOGS once you’ve even started that recovery process with the backup control file. This appears to be a rare case where you can do a complete recovery but Oracle still requires a RESETLOGS.

But even the RESETLOGS won’t work yet – we need to do some recovery first.

Things To Look Out For and Secret DBA Tricks

Well let’s finish up. First off, Oracle actually needs to look at the ONLINE logs. By the way, there’s one thing to be careful of here… check it out:

SQL> col member format a40
SQL> select l.status, member
  2  from v$logfile inner join v$log l using (group#);

STATUS           MEMBER
---------------- ----------------------------------------
INACTIVE         /u04/oracle/oradata/jt10g/redo01.log
CURRENT          /u04/oracle/oradata/jt10g/redo02.log
INACTIVE         /u04/oracle/oradata/jt10g/redo03.log

That information is actually WRONG. Why? Because we did a log switch right before we shutdown. This view is showing you the BACKUP controlfile. So the file redo02.log was CURRENT when we took the backup. However the file redo03.log is actually the one we want. This view will also have old values for log sequence numbers… so just be careful.

Last Monday (when we were originally doing this at our “tech night”) another guy at IT Convergence showed us another great Secret DBA Trick™ to confirm what file you need. Look above and note that Oracle will tell you exactly what sequence number it’s looking for. You can check the sequence number for any logfile on unix like this:

nap01:~/oradata/jt10g$ strings redo01.log|head -3
z{|}
JT10G
Thread 0001, Seq# 0000000004, SCN 0x0000000b05b5-0x0000000bd34f
nap01:~/oradata/jt10g$ strings redo02.log|head -3
z{|}
JT10G
Thread 0001, Seq# 0000000005, SCN 0x0000000bd34f-0x0000000bf612
nap01:~/oradata/jt10g$ strings redo03.log|head -3
z{|}
JT10G
Thread 0001, Seq# 0000000006, SCN 0x0000000bf612-0xffffffffffff

So you can see that Oracle is required to do manual recovery using an online log. Usually Oracle does this automatically – but in this specific scenario you have to do it manually!

In the spirit of experimentation we’ll first apply just log sequence 5 and try to open. If that doesn’t work then we’ll try log sequence 6. We will also still try to avoid the RESETLOGS if possible.

nap01:~/oradata/jt10g$ sqlplus / as sysdba

SQL> recover database using backup controlfile until cancel;
ORA-00279: change 775140 generated at 05/09/2007 07:00:38 needed for thread 1
ORA-00289: suggestion :
/u04/oracle/product/10.2.0/db_1/dbs/arch1_5_621627183.dbf
ORA-00280: change 775140 for thread 1 is in sequence #5

Specify log: {<RET>=suggested | filename | AUTO | CANCEL}
/u04/oracle/oradata/jt10g/redo02.log
ORA-00279: change 783890 generated at 05/09/2007 13:11:59 needed for thread 1
ORA-00289: suggestion :
/u04/oracle/product/10.2.0/db_1/dbs/arch1_6_621627183.dbf
ORA-00280: change 783890 for thread 1 is in sequence #6
ORA-00278: log file '/u04/oracle/oradata/jt10g/redo02.log' no longer needed for
this recovery

Specify log: {<RET>=suggested | filename | AUTO | CANCEL}
CANCEL
ORA-01547: warning: RECOVER succeeded but OPEN RESETLOGS would get error below
ORA-01152: file 1 was not restored from a sufficiently old backup
ORA-01110: data file 1: '/u04/oracle/oradata/jt10g/system01.dbf'

ORA-01112: media recovery not started

Looks like we still need to apply the last log.

SQL> recover database using backup controlfile;
ORA-00279: change 783890 generated at 05/09/2007 13:11:59 needed for thread 1
ORA-00289: suggestion :
/u04/oracle/product/10.2.0/db_1/dbs/arch1_6_621627183.dbf
ORA-00280: change 783890 for thread 1 is in sequence #6

Specify log: {<RET>=suggested | filename | AUTO | CANCEL}
/u04/oracle/oradata/jt10g/redo03.log
Log applied.
Media recovery complete.
SQL> alter database open noresetlogs;
alter database open noresetlogs
*
ERROR at line 1:
ORA-01588: must use RESETLOGS option for database open

Well there you have it. RESETLOGS is required.

SQL> alter database open resetlogs;

Database altered.

And after all of that work… we’re back online! New incarnation, but no data loss. And a neat new trick for checking logfile sequence numbers.

'Database > Oracle' 카테고리의 다른 글

Query 실행 과정 10g  (1) 2009.12.30
10g RAC의 Load Balancing과 Failover  (1) 2009.12.30
Admin Workshop 1 - 구조  (0) 2009.12.15
Query 실행 과정  (1) 2009.12.15
힌트 종류  (0) 2009.12.15
DBMS별 날짜 포멧
Oracle - MS SQL - DB2 UDB 의 서로 다른 날짜 형식을 맞추기위한 SQL문

--------------------------------------------------------------------------------
DBMS 별 시간, 날짜 조회 쿼리
--------------------------------------------------------------------------------
1. Oracle
- 날짜+시분초 까지 조회가능
select sysdate from dual;

- 날짜+밀리초+시간존 까지 조회
select current_timestamp from dual;

2. MS SQL
- 날짜 + 밀리초 단위까지 조회가능
select getdate();

3. DB2 UDB
- 날짜+밀리초까지 조회 가능
select current timestamp from sysibm.sysdummy1;
- 날짜만 조회
select current date from sysibm.sysdummy1;
- 밀리초 단위의 시간만 조회
select current time from sysibm.sysdummy1;

--------------------------------------------------------------------------------
DBMS 별 default date format
--------------------------------------------------------------------------------
1. Oracle
한글 : YYYY/MM/DD                       영어 : DD-MON-YYYY

2. MS SQL
한글 :  YYYY/MM/DD HH:MI:SS      영어 : MM-DD-YYYY HH:MI:SS

3. DB2 UDB
TIMESTAMP 타입 : YYYY-MM-DD-HH:MI:SS.MMMMMM
DATE 타입 : YYYY-MM-DD

TIME 타입 : HH:MI:SS.MMMMMM

--------------------------------------------------------------------------------
날짜 포맷 변환
--------------------------------------------------------------------------------
[ 형식 : 'YYYY.MM.DD' ]
1. Oracle : TO_CHAR(date_exp, 'YYYY.MM.DD')
2. MSSQL : CONVERT(VARCHAR, date_exp, 102)
3. DB2 : REPLACE(CHAR(DATE(date_exp),ISO), '-', '.')

[ 형식 : 'HH:MI:SS' ]
1. Oracle : TO_CHAR(date_exp, 'HH:MI:SS')
2. MSSQL : CONVERT(VARCHAR, date_exp, 108)
3. DB2 : CHAR(TIME(date_exp) , JIS )

[ 형식 : 'YYYY/MM/DD' ]
1. Oracle : TO_CHAR(date_exp, 'YYYY/MM/DD')
2. MSSQL : CONVERT(VARCHAR, date_exp, 111)
3. DB2 : REPLACE(CHAR(DATE(date_exp), ISO), '-', '/')

[ 형식 : 'YYYYMMDD' ]
1. Oracle : TO_CHAR(date_exp, 'YYYYMMDD')
2. MSSQL : CONVERT(VARCHAR, date_exp, 112)
3. DB2 : CHAR(DATE(date_exp))

[ 형식 : 'HH24:MI:SS' ]
1. Oracle : TO_CHAR(date_exp, 'HH24:MI:SS')
2. MSSQL : CONVERT(VARCHAR(8), date_exp, 114)
3. DB2 : CHAR(TIME(date_exp))

[ 형식 : 'YYYY.MM.DD HH24:MI' ]
1. Oracle : TO_CHAR(date_exp, 'YYYY.MM.DD HH24:MI')
2. MSSQL : CONVERT(VARCHAR, date_exp, 102) + ' ' + CONVERT(VARCHAR(5), date_exp, 114)
3. DB2 : REPLACE(CHAR(DATE(date_exp), ISO), '-', '.') || CAST( TIME(date_exp) AS CHAR(5))

[ 형식 : 'YYYY/MM/DD HH24:MI:SS' ]
1. Oracle : TO_CHAR(date_exp, 'YYYY/MM/DD HH24:MI:SS')
2. MSSQL : CONVERT(VARCHAR, date_exp, 111) + ' ' + CONVERT(VARCHAR(8), date_exp, 114)
3. DB2 : REPLACE(CHAR(DATE(date_exp), ISO), '-', '/') || CAST( TIME(date_exp))

- http://www.dbguide.net/ 발취

'Database' 카테고리의 다른 글

DBMS별 날짜 포멧  (0) 2010.01.27
오픈소스 DBMS 라이센스의 이해  (0) 2009.12.30
지금 우리에게 필요한 건 정렬의 제거이다  (0) 2009.12.04
1. Oracle Server
  1) Oracle instance : 메모리에서 일어나는 일(Ram)
  2) Oracle Database : 데이터 파일에 관한 일

2. Instance
  1) System Global Area(SGA) : 쿼리 등의 오라클을 실행하는 거
  2) Background processes(BS) : 뒷단에서 눈에 보이지 않는 작업을 하는 거

3. SGA
  1) Shared Pool
  2) Streams Pool
  3) Large Pool
  4) Java Pool
  5) Database Buffer Cache
  6) Redo Log Buffer

4. Background Processes : 메모리에서 일어나는 일들을 뒤에서 실행하는 거
  1) System Monitor(SMON)
  2) Process Moniter(PMON)
  3) DataBase Writer(DBWn)
  4) LogWriter(LGWR)
  5) Check Point(CKPT)

OWI : SQL 실행을 빠르게 하기 위한 개선책을 찾는 방법 (일종의 SQL튜닝?)

* 실행 과정
SQL(select * from emp)
-> user processer
-> server processer(문법 검사[Parsing] -> 권한 검사)
======================> SGA[Shared Pool]
-> 실행
======================> SGA[DB Buffer Cache] : HDD에 있는 걸 메모리에 올려주기 (속도 up) - 만약 파일 관리가 제대로 안된다면 속도 down
->


* full scan이 발생하면 DB Buffer Cache에 모든 block이 다 올라오기 때문에 기존에 있던 block들은 모두 해제된다.
그 후 full scan 후 다시 메모리에 올려야하기 때문에 속도 up, 시간 down

'Database > Oracle' 카테고리의 다른 글

10g RAC의 Load Balancing과 Failover  (1) 2009.12.30
Backup and Recover  (0) 2009.12.30
Query 실행 과정  (1) 2009.12.15
힌트 종류  (0) 2009.12.15
외래키 검색  (0) 2009.12.09
1. SELECT 실행 과정 {SELECT * FROM emp;}
-> user process (sqlplus)
-> server process : Parsing
  => ASCII 변환 (query를 변환)
  => Hash 함수
  => Cache가 있는지 확인
    ==> instance [Shared Pool:Library Cache] - soft parsing
  => 문법검사
    ==> instance [Shared Pool:Dictionary cache] - hard parsing
  => 권한검사
-> optimaser
  => 실행계획
    ==> 실행 계획까지의 모든 데이터를 저장
    ==> instance [Shared Pool:Library Cache]
    ==> Dictionary를 확인하고 계획을 세우기 때문에 Dictionary를 Update 해야함 [CBO:9i]
-> server process
  => Execute : 실행계획을 받아서 실행
    ==> Database buffer Cache에 있는지 확인
    ==> Data File에서 Block의 정보를 읽고 Database buffer Cache에 전체를 복사해서 결과 가지고 옴
  => Fetch
    ==> 필요한 정보만을 Block에서 간추린다. [PGA]
    ==> user process 전달

2. UPDATE 실행계획{UPDATE emp SET name='홍길동' WHERE empno=100}
-> SELECT의 parsing까지 동일
-> server process
  => Execute : 실행계획을 받아서 실행
    ==> Database buffer Cache에 있는지 확인
    ==> Data File에서 Block의 정보를 읽고 Database buffer Cache에 전체를 복사해서 결과 가지고 옴
    ==> Redo log Buffer 작업 내용 저장[작업일지]
      ===> instance 이기 때문에 수시로 Redo log file에 저장
        ====> 속도 fast - 수정 및 저장 내용이 적고 간결, Block의 위치에 상관없기 때문에
        ====> LGWR
      ===> 만약 불가피하게 디비가 죽는다면 다시 디비를 올리면서 Database File의 데이터와
           Redo log file의 내용을 비교해서 변경사항이 있다면 Database File의 내용을 변경한다.
        ====> 아카이브 로그에 다시 백업 복사
    ==> undo segment에 원래 내용 저장[취소하기 위해서]
    ==> Database buffer Cache에 원하는 정보로 변경 [commit 전에 변경 완료]

'Database > Oracle' 카테고리의 다른 글

10g RAC의 Load Balancing과 Failover  (1) 2009.12.30
Backup and Recover  (0) 2009.12.30
Admin Workshop 1 - 구조  (0) 2009.12.15
힌트 종류  (0) 2009.12.15
외래키 검색  (0) 2009.12.09

+ Recent posts