Backup 이란 장애가 발생해서 DB가 사용할 수 없는 상태가 되었을 때 이를 고치기 위해
필요한 파일들을 미리 정해진 경로에 복사해 두는 것을 말합니다.
디스크의 장애가 발생하든지 또는 사용자가 실수를 하든지 여러 가지 경우에 얼마든지 그리고 언제든지 장애는 발생할 수 있으므로
이런 장애 상황을 대비해서 Database 관리자는 복구에 필요한 파일들을 규칙적으로 백업을 받아야 합니다.
이 책에서는 백업 받는 경로를 디스크(20GB정도)를 하나 추가해서 /data 로 마운트 해서
닫힌 백업은 /data/backup/close ,
열린 백업은 /data/backup/open ,
RMAN 백업은 /data/backup/rman 으로 설정했습니다.
또한 위 경로에 oracle 계정이 Read / Write 권한을 가지고 있어야 합니다.
위의 경로가 아니더라도 원하는 곳으로 경로만 변경해서 실습하시면 됩니다.
1. 백업 대상
만약을 위해 백업을 받아야 하는 대상은 필수 파일이 있고 선택파일이 있습니다.
필수적인 파일로는 Data Files, Redo Log Files, Control Files 이 있고,
선택적인 파일은 Parameter file , Password file , sqlnet.ora , listener.ora , tnsnames.ora 파일 등이 있습니다.
1) Data file 조회하기
실제 데이터가 저장되어 있는 파일입니다.
현재 사용중인 Data file을 확인해서 자주 백업을 받아두셔야 합니다.
아래와 같이 조회하면 됩니다.
SQL> set line 200;
SQL> col name for a50
SQL> select name , status from v$datafile;
위에서는 Oracle을 설치했을 때 기본적인 파일만 나오지만 업무별로 많은 Tablespace를 생성하셨다면
더 많은 파일이 보일 것입니다. 그 Data File들이 전부 백업 대상입니다.
2) Control File 조회하기
Control file은 DB를 운영하는데 중요한 내용이 들어 있는 파일입니다.
Control file 은 현재 사용중인 파일만 쓸 수 있고 과거에 썼던 파일은 백업 받아도 쓸 수 없다는 것을
꼭 기억해야 하고 현재 운영중인 Control File 을 조회해서 백업을 수행해야 합니다.
SYS>col name for a60
SYS>select name from v$controlfile;
위와 같이 조회되는 Control File 만 사용 가능한 파일이고 혹시 서버에 위 파일들 말고
다른 Control file이 존재한다 하더라도 사용할 수 없는 파일이라는 점을 꼭 기억하시기 바랍니다.
3) Redo Log File 조회하기
데이터에 변경이 일어난 내용을 복구에 사용하기 위해 저장하고 있는 파일입니다.
SYS>!vi log.sql
set line 200
col group# for 999
col mb for 999
col member for a45
col seq# for 999
col status for a8
col arc for a5
select a.group#,a.member,b.bytes/1024/1024 MB,b.sequence# "SEQ#",b.status , b.archived "ARC"
from v$logfile a, v$log b
where a.group#=b.group#
order by 1,2
/
:wq!
SYS>@log
4) Parameter File / Password File 조회하기
Parameter file 은 Oracle 서버를 운영하는데 필요한 각종 설정 정보를 저장하고 있는 파일로
이 파일이 손실될 경우 Oracle 서버가 시작이 되지 않습니다.
그리고 초기 설치 후 운영하면서 많은 사항들이 변경 되었을텐데
만약 그걸 다 기억하지 못한다면 다시 각 파라미터의 최적의 값을 찾기 위해 고생을 해야 할 것입니다.
반드시 받아야 하는 파일은 아니지만 백업 받아 두시는 것이 훨씬 유용할 것입니다.
만약 이 파일이 손실되었을 경우 이 책의 Parameter File 관리 및 응급복구 편의 내용을 참고하여 대처를 하시면 됩니다.
또한 Password File 은 sysdba 권한의 암호를 저장하는 파일입니다.
일반적으로 사용자의 암호는 딕셔너리에 저장이 되어서 DB가 오픈 된 후에 사용자들이 DB에 로그인을 할 경우에 조회됩니다.
여기서 중요한 부분은 DB가 OPEN 이 된 후에 딕셔너리에 접근할 수 있다는 사실입니다.
만약 DB가 shutdown 될 경우에는 아무도 DB 에 로그인 할 수 없는 이유입니다.
그런데 종료된 DB를 Startup 하기 위해서는 sys 사용자가 sysdba 권한으로 로그인 해야 하는데
sys 계정의 암호를 딕셔너리에 저장해 둔다면 심각한 문제가 생깁니다.
즉 DB가 종료가 되어 있으면 sys 계정으로 로그인을 못하게 되고
로그인을 못하면 DB를 시작할 수 없게 된다는 것입니다.
이런 문제 때문에 Oracle은 sys 계정의 암호를 딕셔너리가 아니라
DB 외부의 일반 OS 파일에 저장해 놓고 사용하며 이 파일을 Password File 이라고 합니다.
Parameter File 과 Password File 은 $ORACLE_HOME/dbs 디렉토리 밑에 저장되어 있습니다.
만약 Password File 이 삭제되거나 손상되었다면 orapwd 라는 유틸리티를 이용하여 재생성하면 됩니다.
이 장의 마지막에 Password File 관리하기 에서 실습으로 배우겠습니다.
5) sqlnet.ora & listener.ora & tnsnames.ora 파일 조회하기
이 파일들은 외부에서 DB 서버로 접속을 할 때 중요한 역할을 하는 Listener (리스너) 라는 프로그램의 설정파일입니다.
필수 파일은 아니지만 이 파일이 잘못 설정될 경우 외부에서 DB 서버로 접속을 할 수 없게 되므로 가급적 백업을 받아 두는 것이 좋습니다.
이 파일들은 서버의 $ORACLE_HOME/network/admin 디렉토리 아래에 있습니다.
SYS>!ls $ORACLE_HOME/network/admin
listener.ora samples shrept.lst sqlnet.ora tnsnames.ora
2. 백업의 종류
1)닫힌 백업 (cold backup / closed backup)
닫힌 백업은 데이터베이스를 종료 시킨 후 ( shutdown ) 위에서 살펴본 전체 파일들을 백업 받는 것입니다.
특별히 어렵지는 않지만 몇 가지 주의사항만 살펴보겠습니다.
(1) 모든 파일은 동일한 시점의 Checkpoint SCN을 가져야 합니다.
이 말은 shutdown 한 시점이 같아야 한다는 말입니다.
예를 들어 1일 24:00 분에 DB를 shutdown immediate 한 후 Data File 만 백업 받은 후
Database를 다시 open 해서 사용하다가 2일 01:00 분에 다시 shutdown immediate 하고
Redo Log File 과 Control File 을 백업 받게 되면 이 파일들은 함께 복구에 사용될 수 없는 백업세트가 됩니다.
Archive Log File 이 있다면 복구가 될 수 도 있겠지만 일반적으로 올바른 닫힌 백업이 아니라는 말입니다.
(2) Shutdown 은 정상적인 shutdown 이어야만 합니다.
Shutdown immediate, Shutdown transactional, Shutdown normal 은 Commit된 데이터는 저장되고
Commit 안 된 데이터는 롤백이 되어 clean database 가 된 상태로 정상 종료 되지만
shutdown abort , startup force , instance crash 의 경우는 비정상 종료가 되어
각종 파일이 일관성이 흐트러진 상태이기 때문에 복구에 사용 될 수 없습니다.
또한 offline 되어 있는 Data File 역시 마찬가지입니다.
Offline 상태의 Data File 에는 운영 중에 변경된 내용이 저장되지 않기 때문에 다른 Data File 들과 Checkpoint 관련 정보가 다르기 때문입니다.
(3) 이 방법은 Archive Log Mode 나 No Archive Log Mode 에 상관없이 모두 사용될 수 있습니다.
(4) Data Files, Online Redo Log Flies, Control Files 을 백업 받을 수 있습니다.
* 실습 1. 닫힌 백업 수행하기
STEP1 백업 대상 확인하기
SQL> select name , status from v$datafile;
NAME ST ATUS
---------------------------------------------------------- --------------
/app/oracle/oradata/testdb/system01.dbf SYSTEM
/app/oracle/oradata/testdb/undotbs01.dbf ONLINE
/app/oracle/oradata/testdb/sysaux01.dbf ONLINE
/app/oracle/oradata/testdb/users01.dbf ONLINE
/app/oracle/oradata/testdb/example01.dbf ONLINE
SYS>@log
GROUP# MEMBER MB SEQ# STATUS ARC
---------- --------------------------------------------- -------- ------- -------------- ----------
1 /app/oracle/oradata/testdb/redo01.log 50 49 INACTIVE YES
2 /app/oracle/oradata/testdb/redo02.log 50 50 CURRENT NO
3 /app/oracle/oradata/testdb/redo03.log 50 48 INACTIVE YES
SYS>select name from v$controlfile;
NAME
----------------------------------------------------------------------------------------------------
/app/oracle/oradata/testdb/control01.ctl
/app/oracle/fast_recovery_area/testdb/control02.ctl
SYS>!ls $ORACLE_HOME/dbs/
hc_DBUA0.dat hc_testdb.dat init.ora lkTESTDB orapwtestdb spfiletestdb.ora
SYS>!ls $ORACLE_HOME/network/admin
listener.ora samples shrept.lst sqlnet.ora tnsnames.ora
STEP2 DB 종료 하기 (반드시 정상 종료 해야 합니다)
SYS> shutdown immediate;
Database closed.
Database dismounted.
ORACLE instance shut down.
SYS> !
STEP3 전체 파일 백업 수행
(백업 경로는 /data/backup/close/ 란 곳으로 하겠습니다.
다른 경로를 원하시는 분들은 그 부분만 바꿔서 하시면 됩니다)
[oracle@testdb ~]$ cp /app/oracle/oradata/testdb/*.dbf /data/backup/close/
[oracle@testdb ~]$ cp /app/oracle/oradata/testdb/*.log /data/backup/close/
[oracle@testdb ~]$ cp /app/oracle/oradata/testdb/control01.ctl /data/backup/close/
[oracle@testdb ~]$ cp /app/oracle/fast_recovery_area/testdb/control02.ctl /data/backup/close/
[oracle@testdb ~]$ cp $ORACLE_HOME/dbs/*.ora /data/backup/close/
[oracle@testdb ~]$ cp $ORACLE_HOME/dbs/orapwtestdb /data/backup/close/
[oracle@testdb ~]$ cp $ORACLE_HOME/network/admin/* /data/backup/close/
STEP4 DB OPEN
[oracle@testdb ~]$ exit
exit
SYS> startup
ORACLE instance started.
Total System Global Area 285212672 bytes
Fixed Size 1267068 bytes
Variable Size 92277380 bytes
Database Buffers 188743680 bytes
Redo Buffers 2924544 bytes
Database mounted.
Database opened.
위와 같이 닫힌 백업을 수행 한 후 반드시 백업 내역을 확인해야 합니다.
2) 열린 백업 ( Hot backup / Open backup / Begin backup )
(1) 열린 백업의 원리
앞에서 수행한 닫힌 백업의 치명적인 단점은 DB를 종료하고 수행해야 한다는 점입니다.
만약 DB를 절대로 중단할 수 없는 상태인데 백업을 받아야 한다면 수행 할 수 없다는 뜻이며
그래서 등장한 방법이 이번에 살펴 볼 열린 백업 (hot backup) 입니다.
Oracle에서는 어떤 파일이든지 사용 중 일 때 절대로 복사나 이동 작업을 해서는 안됩니다.
백업 작업도 파일들을 복사하는 작업이므로 해당 파일을 사용 중일 때는 백업을 할 수 없습니다.
그런데 열린 백업은 DB가 Open 상태에서 수행하는 백업이므로 모순이 있는 것 같습니다.
그래서 열린 백업은 원리를 이해하시는 것이 아주 중요합니다
열린 백업을 수행하기 위해서는 닫힌 백업과는 다르게 몇 가지 과정이 추가가 됩니다.
우선 닫힌 백업은 DB를 종료한 후 전체 데이터베이스를 백업 받게 되지만
열린 백업은 Tablespace 단위로 백업을 수행하게 됩니다.
11g부터는 Database 전체를 한꺼번에 백업 모드로 설정할 수 있는 옵션이 있지만
열린 백업 모드로 변경 한 후부터는 Redo Log 발생량이 많이 생기기 때문에 권장하지 않습니다.
그래서 백업을 받기 전에 해당 Tablespace를 백업 모드로 설정한 후 백업을 수행하고
백업이 끝나게 되면 백업 모드를 해제 해 줘야 하는 과정이 추가가 됩니다.
그리고 열린 백업을 받기 위해서는 반드시 DB가 Archive Log Mode 이어야만 합니다.
만약 no archive log mode 에서 열린 백업을 받으려면 아래와 같은 에러가 발생합니다.
SQL> archive log list;
Database log mode No Archive Mode
Automatic archival Disabled
Archive destination /data/arc2
Oldest online log sequence 246
Current log sequence 248
SQL> alter tablespace users begin backup;
alter tablespace users begin backup
*
ERROR at line 1:
ORA-01123: cannot start online backup; media recovery not enabled
( 참고로 Archive Log Mode 에서 No Archive Log Mode 로 변경하는 방법은 mount 상태에서 Alter database noarchivelog ; 하면 됩니다)
그럼 이제 다시 archive log mode 로 변경 한 후 USERS Tablespace를 백업 모드로 설정해서 백업하는 예를 보겠습니다
SQL> alter tablespace users begin backup ; <-- users Tablespace 를 백업모드로 변경합니다.
Tablespace altered.
SQL> ! cp /app/oracle/oradata/testdb/users01.dbf /data/backup/open/
SQL> alter tablespace users end backup; <-- users Tablespace 를 백업모드에서 종료합니다.
Tablespace altered.
위 명령어 중에서 alter tablespace users begin backup ; 명령어가
users Tablespace를 백업모드로 설정하는 명령어 입니다.
이제 중요한 원리를 살펴보겠습니다.
alter tablespace users begin backup ; 명령어를 수행할 때 내부적으로 어떤 일이 일어나는지를 잘 이해하셔야 합니다.
먼저 begin backup 명령어 수행전의 Control file 내용을 보겠습니다.
(아래의 Control File 을 dump 하는 방법은 이 책의 Oracle Recover y 원리 부분을 참고하세요)
…………………윗부분 생략합니다.
DATA FILE #4:
(name #4) /app/oracle/oradata/testdb/users01.dbf
creation size=0 Block size=8192 status=0xe head=4 tail=4 dup=1
tablespace 4, index=4 krfil=4 prev_file=0
unrecoverable scn: 0x0000.00000000 01/01/1988 00:00:00
Checkpoint cnt:347 scn: 0x0000.0016f143 02/27/201008:21:39
Stop scn: 0xffff.ffffffff 02/27/2010 08:20:32
Creation Checkpointed at scn: 0x0000.00002a01 02/17/2008 01:51:16
thread:0 rba:(0x0.0.0)
enabled threads: 00000000 00000000 00000000 00000000 00000000 00000000
(지면 관계상 이하 생략합니다)
윗부분에 음영 처리된 부분을 보면 checkpoint cnt 값이 347 이고
scn : 0x0000.0016f143입니다.
Stop scn: 0xffff.ffffffff라는 의미는 앞에서 살펴 본 대로 현재 이 파일이 사용 중이라는 뜻입니다.
users Tablespace 를 Begin Backup 모드로 변경 후 다시 Control File 을 dump 해서 같은 부분을
비교해 보겠습니다. .
DATA FILE #4:
(name #4) /app/oracle/oradata/testdb/users01.dbf
creation size=0 Block size=8192 status=0xe head=4 tail=4 dup=1
tablespace 4, index=4 krfil=4 prev_file=0
unrecoverable scn: 0x0000.00000000 01/01/1988 00:00:00
Checkpoint cnt:348 scn: 0x0000.0016f6f8 02/27/201009:07:27
Stop scn: 0xffff.ffffffff 02/27/2010 08:20:32
Creation Checkpointed at scn: 0x0000.00002a01 02/17/2008 01:51:16
thread:0 rba:(0x0.0.0)
enabled threads: 00000000 00000000 00000000 00000000 00000000 00000000
(지면 관계상 아래 부분은 생략하겠습니다 )
Begin backup 후의 상태를 보면 checkpoint cnt 값이 347 -> 348 로 변경되었고
scn 값도 0x0000.0016f143 -> 0x0000.0016f6f8 값으로 변경 되었음을 발견할 수 있습니다.
즉 begin backup 명령어를 수행하게 되면 Checkpoint 가 발생해서
DB Buffer Cache에 있는 해당 Tablespace 에 소속된 Commit 된 내용이 Data File로 내려 써지게 됩니다.
그리고 그 작업이 끝난 최종 SCN 정보가 Data File과 Control File에 기록이 되며
해당 Tablespace 의 Data File 헤더에 Hot-backup-in-progress 라는 플래그값이 표시됩니다.
만약 최종 SCN 이후에 변경된 값이 생긴다면 변경된 데이터가 저장되어 있는 블록을 전부 Redo Log에 기록합니다.
여기서 Begin Backup 을 수행할 경우 Redo Log 양이 많이 발생하는 이유가 나옵니다.
예를 들어서 홍길동을 일지매로 update 를 수행할 경우 Begin Backup Mode 가 아닐 경우는
해당 데이터의 Change Vector 만 Redo Log 에 기록되면 되지만 만약 Begin Backup Mode 일 경우는
홍길동 데이터가 저장되어 있는 Block 전체를 Redo Log 에 저장을 하기 때문에 Redo Log 양이 많이 발생하는 것입니다.
Hot backup 을 수행하는 동안 해당 Tablespace를 사용하지 못하는 것도 아닙니다.
아래의 실습으로 확인해 보겠습니다.
SYS>create tablespace test
2 datafile '/app/oracle/oradata/testdb/test01.dbf' size 10M;
Tablespace created.
SYS>!vi dd.sql
set line 200
col tablespace_name for a10
col file_name for a45
select tablespace_name,bytes/1024/1024 MB,file_name
from dba_data_files
/
:wq!
SYS> @dd
TABLESPACE MB FILE_NAME
----------------- ---------- -----------------------------------------------------
EXAMPLE 100 /app/oracle/oradata/testdb/example01.dbf
USERS 11.25 /app/oracle/oradata/testdb/users01.dbf
SYSAUX 340 /app/oracle/oradata/testdb/sysaux01.dbf
UNDOTBS1 50 /app/oracle/oradata/testdb/undotbs01.dbf
SYSTEM 480 /app/oracle/oradata/testdb/system01.dbf
TEST 10 /app/oracle/oradata/testdb/test01.dbf
6 rows selected.
위 테이블 스페이스 중 test 테이블 스페이스에 테스트용 테이블 scott.gogak1 테이블 을 생성 한 후
begin backup 을 설정하고 대량 데이터 입력해서 용량이 늘어나는지 테스트 해 보겠습니다.
SYS> alter database datafile '/app/oracle/oradata/testdb/test01.dbf'
2 autoextend on;
Database altered.
SYS> create table scott.gogak1 (no number,name varchar2(20)) tablespace test;
Table created.
아래 쿼리로 현재 각 데이터파일의 실제 사용량을 조회하겠습니다.
SYS> !vi ddd.sql
set line 200 ;
col file# for 999 ;
col ts_name for a10 ;
col total_Blocks for 9999999 ;
col used_Blocks for 9999999
col pct_used for a10
select distinct d.file_id file#,
d.tablespace_name ts_name,
d.bytes /1024 / 1024 MB,
d.bytes / 8192 total_Blo cks,
sum(e.Blocks) used_Bloc ks,
to_char( nvl( round( sum(e.Blocks)/(d.bytes/8192), 4),0) *100,'09.99') || ' %' pct_used
from dba_extents e, dba_data_files d
where d.file_id = e.file_id(+)
group by d.file_id , d.tablespace_name , d.bytes
order by 1,2
/
:wq!
SYS> @ddd
FILE# TS_NAME MB TOTAL_BLOCKS USED_BLOCKS PCT_USED
----- ---------------- ---------- ------------------ ----------------- --------------
1 SYSTEM 480 61440 60632 98.68 %
2 UNDOTBS1 50 6400 1440 22.50 %
3 SYSAUX 340 43520 42512 97.68 %
4 USERS 11.25 1440 456 31.67 %
5 EXAMPLE 100 12800 8760 68.44 %
6 TEST 10 1280 1064 83.13 %
6 rows selected.
SYS> alter tablespace test begin backup; <- begin backup 설정 했습니다.
Tablespace altered.
-- 대량 데이터를 입력합니다
SYS> begin
2 for i in 1..100000 loop
3 insert into scott.gogak1 values (i,dbms_random.string('A',19));
4 end loop;
5 commit;
6 end;
7 /
PL/SQL procedure successfully completed.
다시 test 테이블 스페이스 사용량 조회합니다.
SQL> @ddd
FILE# TS_NAME MB TOTAL_BLOCKS USED_BLOCKS PCT_USED
-------- ----------------- ---------- ------------------- ----------------- ---------------
1 SYSTEM 480 61440 60632 98.68 %
2 UNDOTBS1 50 6400 2336 36.50 %
3 SYSAUX 340 43520 42512 97.68 %
4 USERS 11.25 1440 456 31.67 %
5 EXAMPLE 100 12800 8760 68.44 %
6 TEST 14 1792 1568 87.50 %
6 rows selected.
TEST Tablespace 가 Begin Backup 모드이지만 용량이 늘어난 것을 확인 할 수 있습니다.
이번에는 update 로 내용을 변경하겠습니다.
SQL> alter table scott.gogak1
2 modify name varchar2(40);
Table altered.
SQL> update scott.gogak1 set name='AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' ;
100000 rows updated.
SQL> @ddd
FILE# TS_NAME MB TOTAL_BLOCKS USED_BLOCKS PCT_USED
------- ----------------- ---------- ------------------- ------------------ --------------
1 SYSTEM 480 61440 60632 98.68 %
2 UNDOTBS1 50 6400 5152 80.50 %
3 SYSAUX 340 43520 42512 97.68 %
4 USERS 11.25 1440 456 31.67 %
5 EXAMPLE 100 12800 8760 68.44 %
6 TEST 17 2176 1952 89.71 %
앞의 테스트에서 hot backup 중에도 해당 데이터파일에 내용이 변경될 경우 변경되는 내용이 즉시 저장되는 것을 확인 할 수 있습니다.
여기서 우리가 한가지 기억해야 하는 것은 Begin backup 시에
최종 SCN이후에 변경되는 사항이 Redo Log 에 기록될 때는
Row 단위가 아닌 해당 데이터가 속해있는 Block 단위로 저장이 된다는 점입니다.
이것은 Checkpoint의 원리를 생각하면 당연합니다.
만약 begin backup 상태가 아닐 때 checkpoint 가 일어나면
DB Buffer Cache 에서 해당 Row만 DB Buffer Cache 에서 Data File로
저장되지 않고 해당 row가 속해있는 Block 전체가 Data file로 저장이 되는 것이니까요.
이런 이유 때문에 begin backup 중에 발생되는 redo log의 양과 archive log 파일의 용량이 아주 많아지는 것입니다.
그런데 왜 오라클은 Begin Backup 시에 변경되는 내용이 아닌 블록 전체를 Redo Log 에 저장을 할까요?
이것은 Split Block 현상 때문입니다.
Oracle Block 1개는 OS 블록 여러 개를 합친 것입니다.
즉 만약 OS Block이 512Byte 이고 Oracle Block 이 8Kbytes 라면 16개의 OS 블록을 합쳐서 Oracle Block 을 만드는 것입니다.
이렇게 하나의 Oracle Block 을 이루는 16개의 OS Block은 항상 SCN 버전이 동일해야 합니다.
그런데 만약 하나의 Oracle Block 에 1건의 데이터가 변경이 되었을 경우에 16개의 블록 중 하나만 바꾸게 된다면
Oracle Block 을 구성하는 OS 블록의 정보가 서로 달라지기 때문에 문제가 됩니다.
그래서 Oracle은 1건의 데이터가 바뀐다 하더라도 디스크에 저장할 때 블록 전체를 저장하게 되는 것입니다.
OS 명령어로 복사가 끝난 후에는 아래의 명령으로 반드시 백업이 끝났다는 사실을 알려줘야 합니다.
SQL> alter tablespace users end backup ;
Tablespace altered.
이 명령 후 Control File의 내용을 보겠습니다.
(dump 를 수행한 후 users Tablespace 의 데이터 파일 부분을 봅니다)
DATA FILE #4:
(name #4) /app/oracle/oradata/testdb/users01.dbf
creation size=0 Block size=8192 status=0xe head=4 tail=4 dup=1
tablespace 4, index=4 krfil=4 prev_file=0
unrecoverable scn: 0x0000.00000000 01/01/1988 00:00:00
Checkpoint cnt:349 scn: 0x0000.0016f6f8 02/27/2010 09:07:27
Stop scn: 0xffff.ffffffff 02/27/2010 08:20:32
Creation Checkpointed at scn: 0x0000.00002a01 02/17/2008 01:51:16
thread:0 rba:(0x0.0.0)
enabled threads: 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
(지면 관계상 이하 내용은 생략합니다)
위 출력 결과에서 Checkpoint cnt : 값이 348에서 349 로 변경된 것이 확인 됩니다.
역시 Checkpoint scn 값도 변경되었습니다.
즉 Begin Backup 명령을 수행하면 현재까지의 모든 Commit 된 데이터를 Checkpoint해서 DB Buffer Cache에서 Data File로 저장 한 후
tablespace altered. 라는 문구를 보여주고 End backup 명령어가 들어오면 다시 checkpoint 를 일으키는 것입니다.
Alter tablespace users end backup ; 명령어는 현재 해당 Data File에 적용된 가장 마지막 SCN
(begin backup 명령 때 적용된 SCN)을 시작으로 하는 redo record 를 만듭니다.
이것을 통해서 백업하는 동안 변경된 SCN을 가진 데이터들이 어느 redo 위치에 있는지를 찾아내서 Checkpoint를 수행하는 것입니다.
만약 begin backup 상태에서 해당 Data file에 checkpoint 가 수행되어 변경사항이 redo log 에 기록되고 있는 도중에
end backup 이 수행되면 redo log에 블록이미지 기록이 중단되고 Data file에 Checkpoint가 우선적으로 수행되게 됩니다.
Hot backup 을 수행하는 도중에는 shutdown immediate 나 shutdown normal 명령어로 DB 를 종료할 수 없습니다.
그리고 해당 Tablespace를 offline 할 수도 없습니다.
만약 end backup 이 수행되지 않아서 종료 마커 (end maker) 가 생성되지 못한 상태에서 DB가 강제 종료되면
다시 시작될 때 해당 파일에 문제가 있다고 에러 메시지를 보이고 복구를 해야만 합니다.
아래 내용을 참고하세요.
아래 내용은 users tablespace 를 Begin backup 한 후 shutdown abort; 로 강제 종료 한 후 아래와 같이 다시 startup 한 화면입니다.
SQL> startup
ORACLE instance started.
Total System Global Area 422670336 bytes
Fixed Size 1344616 bytes
Variable Size 331352984 bytes
Database Buffers 83886080 bytes
Redo Buffers 6086656 bytes
Database mounted.
ORA-10873: file 4 needs to be either taken out of backup mode or media recovered
ORA-01110: data file 4: '/app/oracle/oradata/testdb/users01.dbf' <- 예상대로 에러납니다.
SQL> alter database datafile '/app/oracle/oradata/testdb/users01.dbf' end backup;
Database altered.
SQL> alter database open;
Database altered.
또 한가지 중요한 내용은 Hot Backup 으로 Data File 과 Control File 은 백업 받을 수 있으나
운영중인 Online Redo Log File 은 백업 받지 못합니다.
End Backup 이 수행되었는지 아닌지는 아래의 쿼리를 수행하면 알 수 있습니다.
SYS>set line 200
SYS>col name for a50
SYS>col status for a15
SYS>select a.file#,a.name,b.status,to_char(b.time,'YYYY-MM-DD:HH24:MI:SS') as time
2 from v$datafile a, v$backup b
3 where a.file#=b.file# ;
FILE# NAME STATUS TIME
---------- --------------------------------------------------------- --------------- -------------------
1 /app/oracle/oradata/testdb/system01.dbf NOT ACTIVE
2 /app/oracle/oradata/testdb/sysaux01.dbf NOT ACTIVE
3 /app/oracle/oradata/testdb/undotbs01.dbf NOT ACTIVE
4 /app/oracle/oradata/testdb/users01.dbf NOT ACTIVE
5 /app/oracle/oradata/testdb/example01.dbf NOT ACTIVE
6 /app/oracle/oradata/testdb/test01.dbf NOT ACTIVE
6 rows selected.
SYS>save bg.sql
Created file bg.sql
앞의 쿼리 결과에서 status 부분에 ACTIVE 로 되어 있으면 begin backup 상태라는 의미이며
NOT ACTIVE 는 end backup 상태이거나 begin backup 을 수행하지 않았다는 의미입니다.
또한 위 4번 파일 뒤에 나오는 시간은 가장 마지막에 begin backup 받은 시간을 의미합니다.
아래의 예로 확인 해 보겠습니다.
SYS>alter tablespace test begin backup;
Tablespace altered.
SYS>alter tablespace test end backup;
Tablespace altered.
SYS>alter tablespace users begin backup;
Tablespace altered.
SYS>@bg
FILE# NAME STATUS TIME
---------- ----------------------------------------------------- --------------- -------------------------
1 /app/oracle/oradata/testdb/system01.dbf NOT ACTIVE
2 /app/oracle/oradata/testdb/sysaux01.dbf N OT ACTIVE
3 /app/oracle/oradata/testdb/undotbs01.dbf N OT ACTIVE
4 /app/oracle/oradata/testdb/users01.dbf ACTIVE 2013-03-31:11:02:21
5 /app/oracle/oradata/testdb/example01.dbf NOT ACTIVE
6 /app/oracle/oradata/testdb/test01.dbf NOT ACTIVE 2013-03-31:11:02:03
6 rows selected.
위 결과에서 4번 users Tablespace 는 아직 Begin Backup 상태이므로 STATUS 컬럼에 ACTIVE 로 나오고
6번 test Tablespace 는 End Backup 을 수행해서 NOT ACTIVE 로 조회됩니다.
* 실습 2. Hot backup 수행하기
열린 백업을 받는 간단한 스크립트를 만들어서 백업 받도록 하겠습니다
SQL> ! vi /app/oracle/open_backup.sql
conn / as sysdba;
alter tablespace users begin backup;
! cp -av /app/oracle/oradata/testdb/users01.dbf /data/backup/open/
alter tablespace users end backup;
alter tablespace sysaux begin backup;
!cp -av /app/oracle/oradata/testdb/sysaux01.dbf /data/backup/open/
alter tablespace sysaux end backup;
alter tablespace undotbs1 begin backup;
!cp -av /app/oracle/oradata/testdb/undotbs01.dbf /data/backup/open/
alter tablespace undotbs1 end backup;
alter tablespace system begin backup;
!cp -av /app/oracle/oradata/testdb/system01.dbf /data/backup/open/
alter tablespace system end backup;
alter tablespace example begin backup;
!cp -av /app/oracle/oradata/testdb/example01.dbf /data/backup/open/
alter tablespace example end backup;
alter tablespace test begin backup;
!cp -av /app/oracle/oradata/testdb/test01.dbf /data/backup/open/
alter tablespace test end backup;
alter database backup controlfile to ‘/data/backup/open/control01.ctl’;
:wq!
SQL>@/app/oracle/open_backup.sql
Connected.
Tablespace altered.
`/app/oracle/oradata/testdb/users01.dbf' -> `/data/backup/open/users01.dbf'
Tablespace altered.
( 지면 관계상 중간 결과는 생략합니다 )
Database altered.
SQL> alter system checkpoint ;
위 스크립트는 관리자가 Begin Backup을 수행할 Tablespace를 직접 다 적어줘야 하기 때문에 여러 서버에 사용하기 불편합니다.
그래서 실무에서 즉시 쓸 수 있는 Hot Backup 스크립트를 아래에 소개하고자 합니다.
업무에 도움이 되시길 바랍니다.
아래의 스크립트를 crontab 같은 OS 작업 스케줄러에 등록해서 사용하시면 주기적으로 일자 별로 자동으로 hot backup을 받을 수 있습니다.
리눅스용 Bash Shell 을 기준으로 만들었지만 조금만 수정하시면 타 유닉스와 Shell 에서도 사용 가능 할 것입니다.
* 실습 3.
일자 별로 자동으로 백업 디렉터리를 생성해서 begin backup 을 수행하는 백업 스크립트
실습의 편의상 모든 스크립트를 /app/oracle/ 에 두겠습니다.
스크립트는 총 5개이며 main_backup.sh 가 수행되면서 각 단계별로 해당 스크립트를 호출하게 됩니다.
순서는 일단 백업 대상 Tablespace를 begin backup 상태로 만들고 (begin_backup.sh)
그 후에 지정된 경로에 백업을 수행하는 날짜 이름으로 디렉토리 만들어서
Data File과 Control File을 복사하고 (copy_backup.sh)
복사하는 작업이 끝나면 Tablespace를 end backup 해서 마무리 하는 것입니다.
1. !vi main_backup.sh
export LANG=C
export ORACLE_BASE=/app/oracle
export ORACLE_HOME=$ORACLE_BASE/product/10g
export PATH=$ORACLE_HOME/bin:$PATH
export ORACLE_SID=testdb
touch /home/oracle/total.log
echo ""
echo "set begin backup mode~~"
time sh /home/oracle/begin_backup.sh >> /home/oracle/total.log
echo ""
echo "end begin backup mode~~"
echo ""
echo "start file copy....................."
time sh /home/oracle/copy_backup.sh >> /home/oracle/total.log
echo "end file copy~"
echo ""
echo "set end backup mode~~"
time sh /home/oracle/end_backup.sh >> /home/oracle/total.log
echo "complete hot backup~!"
2. !vi begin_backup.sh <-Tablespace 조회해서 begin backup 상태로 만드는 스크립트입니다
export LANG=C
export ORACLE_BASE=/app/oracle
export ORACLE_HOME=$ORACLE_BASE/product/10g
export PATH=$ORACLE_HOME/bin:$PATH
export ORACLE_SID=testdb
sqlplus /nolog <<EOF1
conn / as sysdba
set head off
set feedback off
set time off
set timing off
set echo off
spool /tmp/online.tmp
select 'alter tablespace '|| tablespace_name ||' begin backup;' \
from dba_tablespaces \
where status='ONLINE' \
and contents != 'TEMPORARY';
spool off
!cat /tmp/online.tmp | egrep -v spool | egrep -v SQL | egrep -v [2-4] > /home/oracle/begin.sh
@/home/oracle/begin.sh
!sh /home/oracle/status.sh
exit
EOF1
3. !vi copy_backup.sh <- 일자 별로 디렉터리 만들어서 파일을 복사하는 스크립트입니다.
export LANG=C
export ORACLE_BASE=/app/oracle
export ORACLE_HOME=$ORACLE_BASE/product/10g
export PATH=$ORACLE_HOME/bin:$PATH
export ORACLE_SID=testdb
sqlplus /nolog << EOF3
conn / as sysdba
set head off
set time off
set timing off
set feedback off
set echo off
set line 200
col name for a100
spool /home/oracle/cp.tmp
select 'mkdir /data/backup/open/'||to_char(sysdate,'YYYY-MM-DD-HH24-MI-SS') from dual;
select 'cp -av '||name||' /data/backup/open/'||to_char(sysdate,'YYYY-MM-DD-HH24-MI-SS') "name"
from v\$datafile;
spool off
spool /home/oracle/control.tmp
alter session set nls_date_format='YYYY-MM-DD-HH24-MI-SS';
select 'alter database backup controlfile to ''/data/backup/open/'||sysdate||\
'/'||sysdate||'.ctl'' ; ' from dual;
spool off
!cat /home/oracle/cp.tmp | egrep -v SQL > /home/oracle/cp.sh
!cat /home/oracle/control.tmp | egrep -v SQL > /home/oracle/control.sql
!sh /home/oracle/cp.sh
@/home/oracle/control.sql
exit
EOF3
4. !vi end_backup.sh <- 백업이 끝나고 end backup 으로 변경하는 스크립트 입니다.
export LANG=C
export ORACLE_BASE=/app/oracle
export ORACLE_HOME=$ORACLE_BASE/product/10g
export PATH=$ORACLE_HOME/bin:$PATH
export ORACLE_SID=testdb
sqlplus /nolog << EOF4
conn / as sysdba
set head off
set feedback off
set time off
set timing off
set echo off
spool /tmp/online.tmp
select 'alter tablespace '|| tablespace_name ||' end backup;' \
from dba_tablespaces \
where status='ONLINE' \
and contents != 'TEMPORARY';
spool off
!cat /tmp/online.tmp | egrep -v spool | egrep -v SQL | egrep -v [2-4] > /home/oracle/end.sh
@/home/oracle/end.sh
!sh /home/oracle/status.sh
exit
EOF4
5. begin backup 모드 상태를 보는 !vi status.sh
export LANG=C
export ORACLE_BASE=/app/oracle
export ORACLE_HOME=$ORACLE_BASE/product/10g
export PATH=$ORACLE_HOME/bin:$PATH
export ORACLE_SID=testdb
sqlplus /nolog << EOF2
conn / as sysdba
set head on
set echo off
set feedback off
spool /tmp/status.tmp
set line 200
col name for a50
col status for a15
select a.file#,a.name,b.status,to_char(b.time,'YYYY-MM-DD:HH24:MI:SS') "Time" \
from v\$datafile a ,v\$backup b \
where a.file#=b.file#;
spool off
exit
EOF2
위의 5개 스크립트를 전부 /app/oracle/ 밑에 두고 실제로 실행시켜 테스트합니다.
[oracle@testdb ~]$ sh main_backup.sh
set begin backup mode~~
real 0m0.660s
user 0m0.003s
sys 0m0.164s
end begin backup mode~~
start file copy.....................
real 4m22.541s
user 0m0.591s
sys 0m45.131s
end file copy~
set end backup mode~~
real 0m2.469s
user 0m0.024s
sys 0m0.344s
complete hot backup~!
[oracle@testdb ~]$
실제 로그 파일은 /home/oracle/total.log 파일에 기록되게 되어 있습니다.(main_backup.sh참조)
내용이 너무 길어서 이 로그파일은 직접 수행시키시고 확인해보시기 바랍니다.
리눅스에 최적화 되어 있지만 다른 쉘이나 다른 유닉스에서도 조금만 수정하시면 사용 가능하니까
지금 운영 중이신 OS Shell 에 맞게 수정해서 유용하게 사용하세요.
main_backup.sh 를 crontab 에 등록해두시면 아주 쉽게 주기적으로 백업을 수행할 수 있겠죠?
이상으로 Oracle 에서 백업이 수행되는 원리와 백업을 하는 방법을 알아 보았습니다.
백업을 소홀히 하시면 장애가 발생했을 때 큰일 날 수 있으니 꼭 부지런히 백업을 받으시길 바랍니다.
실습 4. Password File 관리하기
4-1. sys 계정으로 로그인 시 암호 묻도록 설정하기
Oracle 을 처음 설치하시면 sys 계정으로 접속할 때 암호를 안 묻고 누구나 쉽게 login 을 허용해주게 됩니다.
이로 인해서 아주 심각한 문제를 초래할 수 도 있습니다. 그래서 처음 설치 후 별도의 작업을 해서 passwd 파일이 있어도
sys 계정의 암호를 꼭 물어보도록 설정을 변경해야 합니다. 아래와 같이 sqlnet.ora 파일을 변경하면 됩니다.
$ sqlplus / as sysdba
SQL> exit
$ cd $ORACLE_HOME/network/admin
# ls
Step1. 먼저 Oracle Server 에 oracle 계정으로 로그인 한 후 터미널에서 netca 를 실행합니다.
Step2. 아래와 같이 local naming, Easy connect naming 을 오른쪽으로 보냅니다.
위와 같이 한 후 next 눌러서 종료하면 sqlnet.ora 파일이 생성됩니다.
$ ls
$ vi sqlnet.ora
NAMES.DIRECTORY_PATH=(TNSNAMES, EZCONNECT)
ADR_BASE = /app/oracle
SQLNET.INBOUND_CONNECT_TIMEOUT = 10
sqlnet.authentication_service=(none)
:wq!
$ sqlplus / as sysdba
Enter user_name: sys/oracle as sysdba
계정과 암호를 입력해야 합니다.
실습 2. 패스워드 파일 이 삭제되었을 경우 조치법
[oracle@localhost admin]$ cd $ORACLE_HOME/dbs
[oracle@localhost dbs]$ ls
hc_DBUA0.dat init.ora lkTESTDB spfiletestdb.ora
hc_testdb.dat orapwtestdb <-- password file 입니다
[oracle@localhost dbs]$ rm -fr orapwtestdb <- 삭제합니다
[oracle@localhost dbs]$ sqlplus sys/oracle as sysdba <-- 정상적으로 접속 시도합니다.
SQL*Plus: Release 11.2.0.2.0 Production on Thu Aug 8 07:44:55 2013
Copyright (c) 1982, 2010, Oracle. All rights reserved.
ERROR:
ORA-01031: insufficient privileges
Enter user-name: sys/oracle as sysdba <-- 올바른 계정과 암호를 입력하지만 에러납니다
ERROR:
ORA-01031: insufficient privileges
Enter user-name:
위와 같이 Password File 이 삭제될 경우 올바른 계정과 암호를 입력해도 로그인이 안됩니다.
orapwd 유틸리티를 사용하여 Password File 을 새로 생성하면 해결됩니다.
아래를 참고하세요.
[oracle@localhost dbs]$ orapwd
Usage: orapwd file=<fname> entries=<users> force=<y/n> ignorecase=<y/n> nosysdba=<y/n>
where
file - name of password file (required),
password - password for SYS will be prompted ifnot specified at command line,
entries - maximum number of distinct DBA (optional),
force - whether to overwrite existing file (opt ional),
ignorecase - passwords are case-insensitive (optional),
nosysdba - whether to shut out the SYSDBA logon(optional Database Vault only).
There must be no spaces around the equal-to (=) character.
여러 가지 옵션이 나오는데 sys의 암호를 oracle 로 설정해서 생성하겠습니다.
[oracle@localhost dbs]$ orapwd file=/app/oracle/product/11g/dbs/orapwtestdb
Enter password for SYS: (이곳에 sys의 암호를 입력합니다)
[oracle@localhost ~]$ sqlplus sys/oracle as sysdba
SQL*Plus: Release 11.2.0.2.0 Production on Thu Aug 8 07:50:30 2013
Copyright (c) 1982, 2010, Oracle. All rights reserved.
Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
이 두 번째 tip 을 이용하면 sys 계정의 암호를 몰라 로그인을 못할 경우 암호를 새로 설정 할 수 도 있습니다.
즉 기존에 설정된 sys 계정의 암호를 모를 경우 기존 orapwSID 파일 을 삭제 한 후 orapwd 유틸을 이용하여
암호파일을 다시 생성하면서 새로운 암호를 설정하시면 sys 계정의 암호가 새로운 암호로 변경되고 sys 계정으로 로그인 할 수 있습니다.
유용하기도 하지만 보안상 위험하기도 하니 잘 관리하시길 바랍니다.