[백업]
백업 대상 파일
1. parameter file
2. DB 구성파일(controlfile/redo log file/datafile)
3. controlfile 재생성 script
4. archive log file
백업 종류
cold backup(offline backup)
DB를 정상적으로 종료(immediate)한 후 수행.
global checkpoint 발생으로 인해 모든 파일의 시점 일치.
백업 시점의 DB가 언제나 기동 가능(별도의 recovery가 필요 없음)
no archive log mode 일 때도 백업 가능.
– controlfile, redo log file, datafile, (parameter file, controlfile script)
hot backup(online backup)
DB 운영 중에 백업 받는 방식.
archive log mode일 때만 백업 가능.
– datafile, archive log file (parameter file, controlfile script)
백업 주기
DB 업무 중요도에 따라 다르게 구성.
복구 수행 시간, 여유 공간 등을 고려하여 결정.
일/주/월 마다 백업 수행.
[hot backup]
1. 대상 확인
select tablespace_name, file_name, bytes
from dba_data_files;
2. 백업 모드 전환(tablespace begin backup)
begin backup 시 DBWR가 즉시 동작해서 datafile에 dirty buffer들이 써(저장)된다.
alter tablespace 테이블스페이스명 begin backup;
select 'alter tablespace '||tablespace_name||' begin backup;'
from dba_tablespaces
where tablespace_name not like 'TEMP%';
alter tablespace SYSTEM begin backup;
alter tablespace SYSAUX begin backup;
alter tablespace UNDOTBS1 begin backup;
alter tablespace USERS begin backup;
3. datafile cp
$ mkdir -p /oracle12/backup/hot_backup
select 'cp '||file_name||' /oracle12/backup/hot_backup'
from dba_data_files;
$ cp /home/oracle/oradata/db1/users01.dbf /oracle12/backup/hot_backup
$ cp /home/oracle/oradata/db1/undotbs01.dbf /oracle12/backup/hot_backup
$ cp /home/oracle/oradata/db1/sysaux01.dbf /oracle12/backup/hot_backup
$ cp /home/oracle/oradata/db1/system01.dbf /oracle12/backup/hot_backup
4. 백업 모드 중지(end backup)
alter tablespace 테이블스페이스명 end backup;
select 'alter tablespace '||tablespace_name||' end backup;'
from dba_tablespaces
where tablespace_name not like 'TEMP%';
alter tablespace SYSTEM end backup;
alter tablespace SYSAUX end backup;
alter tablespace UNDOTBS1 end backup;
alter tablespace USERS end backup;
5. 백업 상태 확인
select a.file#,
a.name,
a.bytes,
b.status,
b.change#,
b.time
from v$datafile a, v$backup b
where a.file#=b.file#;
-- 여기서 status 컬럼에서 begin인지 end인지 확인 가능.
-- begin backup 모드면 active, end backup 모드면 not active 라고 나옴.
6. controlfile script backup
alter database backup controlfile to trace as '/oracle12/backup/hot_backup/control.sql';
** 현업에서는 각 tablespace 1개씩 begin -> cp -> end 순서대로 하는 방식이 더 좋다.
만약 위에 방식처럼 싹 다 begin하고 cp하고 end하면 file size가 커서 cp에 시간이 너무 오래 걸린다. -> tablespace가 멈춰있는 시간이 길다. -> 거의 global checkpoint 느낌이니깐 별로임.
[hot_backup.sh – 미완성]
# hot_backup.sh
# 김성현이 만들었습니다
#!/bin/sh
# DB OPEN 상태인지 확인
sqlplus -s / as sysdba << _eof_ > ~/db_status.tmp
set head off
select status from v\$instance;
_eof_
grep OPEN ~/db_status.tmp > /dev/null
if [ $? -ne 0 ]
then
echo "DB가 OPEN되지 않았습니다. DB를 OPEN시킨 후에 실행해주세요"
exit 1
else
echo "DB OPEN 상태입니다"
fi
rm -rf ~/db_status.tmp
# backupdir 선언
backupdir=/oracle12/backup/hot_backup
# 기존 디렉토리 내용 삭제 후 재생성
rm -rf $backupdir
mkdir -p $backupdir
# tablespace begin backup
sqlplus -s / as sysdba << _eof_ > ~/begin_cp_end.tmp
set head off
set feedback off
select 'alter tablespace '||tablespace_name||' begin backup;'
from dba_tablespaces
where tablespace_name not like 'TEMP%';
_eof_
# tablespace cp
# 나중에 begin->cp->end 묶어서 진행하려고 할 때 쓸 방법
#select 'alter tablespace '||a.tablespace_name||' begin backup;',
# '!cp '||b.file_name||' /oracle12/backup/hot_backup',
# 'alter tablespace '||a.tablespace_name||' end backup;'
#from dba_tablespaces a, dba_data_files b
#where a.tablespace_name not like 'TEMP%'
#and b.file_name like '%'||lower(a.tablespace_name)||'%'
#or a.tablespace_name like 'UNDOTBS%'
#and b.file_name like '%undotbs%';
# controlfile 생성 스크립트 백업
sqlplus -s / as sysdba << _eof_
alter database backup controlfile to trace as '/oracle12/backup/cold_backup/control.sql';
_eof_
echo "control file 재생성 스크립트 백업"
# cp_file.sh 만들기
echo '#!/bin/sh' > ~/cp_file.sh
echo "cp_file.sh 초기화"
# control file cp 명령어 작성
sqlplus -s / as sysdba << _eof_ >> ~/cp_file.sh
set head off
set feedback off
select 'cp '||name||' /oracle12/backup/cold_backup' from v\$controlfile;
_eof_
echo "control file cp 명령어 작성"
# data file cp 명령어 작성
sqlplus -s / as sysdba << _eof_ >> ~/cp_file.sh
set head off
set feedback off
select 'cp '||name||' /oracle12/backup/cold_backup' from v\$datafile;
_eof_
echo "data file cp 명령어 작성"
# redo log file cp 명령어 작성
sqlplus -s / as sysdba << _eof_ >> ~/cp_file.sh
set head off
set feedback off
select 'cp '||member||' /oracle12/backup/cold_backup' from v\$logfile;
_eof_
echo "log file cp 명령어 작성"
# DB shutdown immediate
echo
echo "DB shutdown 시작..."
sqlplus -s / as sysdba << _eof_
shutdown immediate
_eof_
echo "DB shutdown 완료"
echo
# cp file. 파일들 복사
echo "cp_file.sh 시작..."
sh ~/cp_file.sh
echo "cp_file.sh 종료"
echo "shell 정상종료"
echo
exit 0
[online 백업본을 사용한 DB open – 1]
online 백업은 datafile만 백업을 받기 때문에 online 백업본을 restore 했을 경우 현재 redo, controlfile과의 시점 불일치 발생. -> recovery(완전 복구) 필수.
1. shutdown immediate
2. online backup file restore
$ cp /oracle12/backup/hot_backup/* /home/oracle/oradata/db1
3. startup (error)
> startup
ORA-01113: file 1 needs media recovery
ORA-01110: data file 1: '/home/oracle/oradata/db1/system01.dbf'
-- alert
ORA-01110: data file 3: '/home/oracle/oradata/db1/sysaux01.dbf'
ORA-01208: data file is an old version - not accessing current version
ORA-01110: data file 5: '/home/oracle/oradata/db1/undotbs01.dbf'
ORA-01208: data file is an old version - not accessing current version
ORA-01110: data file 7: '/home/oracle/oradata/db1/users01.dbf'
ORA-01208: data file is an old version - not accessing current version
4. 완전 복구 진행
> recover database
> alter database open;
-- noresetlogs 쓸 필요 없음.
번외. 현재 archive file 모두 삭제 & hot backup 다시 받기
백업본으로 과거로 돌아가는 작업을 많이 해서…?
-- archive file 삭제
$ rm /arch/*.dbf
-- hot backup
alter tablespace SYSTEM begin backup;
alter tablespace SYSAUX begin backup;
alter tablespace UNDOTBS1 begin backup;
alter tablespace USERS begin backup;
!cp /home/oracle/oradata/db1/users01.dbf /oracle12/backup/hot_backup
!cp /home/oracle/oradata/db1/undotbs01.dbf /oracle12/backup/hot_backup
!cp /home/oracle/oradata/db1/sysaux01.dbf /oracle12/backup/hot_backup
!cp /home/oracle/oradata/db1/system01.dbf /oracle12/backup/hot_backup
alter tablespace SYSTEM end backup;
alter tablespace SYSAUX end backup;
alter tablespace UNDOTBS1 end backup;
alter tablespace USERS end backup;
alter database backup controlfile to trace as '/oracle12/backup/hot_backup/control.sql';
-- log switch 10번 해서 archive 순서를 벌리기
alter system switch logfile;
-- 10번 하기.
[online 백업본을 사용한 DB open – 2]
1. shutdown immediate
2. online backup file restore
$ cp /oracle12/backup/hot_backup/* /home/oracle/oradata/db1
3. startup (error)
> startup
ORA-01113: file 1 needs media recovery
ORA-01110: data file 1: '/home/oracle/oradata/db1/system01.dbf'
-- alert
ORA-01110: data file 3: '/home/oracle/oradata/db1/sysaux01.dbf'
ORA-01208: data file is an old version - not accessing current version
ORA-01110: data file 5: '/home/oracle/oradata/db1/undotbs01.dbf'
ORA-01208: data file is an old version - not accessing current version
ORA-01110: data file 7: '/home/oracle/oradata/db1/users01.dbf'
ORA-01208: data file is an old version - not accessing current version
4. 불완전 복구를 해버린 경우
원래는 위에서한 1번의 경우처럼 완전 복구하면 알아서 잘 된다.
근데 만약 실수로 불완전 복구를 한다면 마지막 시점은 current redo log file 경로를 지정해줘야한다.
-- 실수로 불완전 복구 명령어 입력
> recover database until cancel
enter
auto
-- 1번부터 10번 시퀀스까지는 archive file이 있었음.
-- 11번은 file이 없어서 에러 발생함.
-- 따라서 11번은 current redo log file의 경로를 알려주면 됨
-- current가 뭔지 확인하기
> @log.sql
-- 나의 경우 지금은 2번이 current였음
-- 다시 recover할 때 current redo log file경로 지정해주기
> recover database until cancel
--
ORA-00279: change 2466167 generated at 12/09/2024 12:23:56 needed for thread 1
ORA-00289: suggestion : /arch/1_11_1187019470.dbf
ORA-00280: change 2466167 for thread 1 is in sequence #11
ORA-00278: log file '/arch/1_10_1187019470.dbf' no longer needed for this recovery
Specify log: {<RET>=suggested | filename | AUTO | CANCEL}
/home/oracle/oradata/db1/redo02.log
Log applied.
Media recovery complete.
--
-- db open
alter database open noresetlogs;
-- 불완전 복구 명령어(until cancel)를 썼기 때문에 noresetlogs인지 resetlogs인지를 선언해줘야 open이 된다.
-- 이 경우에 log 날려먹은게 없기 때문에 noresetlogs이 맞음.
[datafile 물리적 손상 장애(abort)]
문제발생을 막기위해서 현재 archive file 모두 삭제 -> hot backup 진행 -> log switch 5번 수행
1. data 생성
create table scott.recover_test5(no number) tablespace users;
insert into scott.recover_test5 values(1);
insert into scott.recover_test5 values(2);
insert into scott.recover_test5 values(3);
commit;
select * from scott.recover_test5;
2. datafile 삭제(물리적 손상)
$ rm /home/oracle/oradata/db1/users01.dbf
3. shutdown abort
4. startup (error)(mount단계)
5. datafile restore
$ cp /oracle12/backup/hot_backup/users01.dbf /home/oracle/oradata/db1
6. 장애 복구
> recover database
enter
auto
> alter database open;
[recover가 필요한 장애 종류]
** 물리 장애 : 물리적 손상(파일 삭제, 디스크 장애)
** 논리 장애 : 사용자의 실수로 데이터 삭제/변경
– dml 장애 : delete, update 실수
– ddl 장애 : truncate, drop purge
– user drop : cascade 옵션으로 user 삭제 시
– column drop
– tablespace drop
[recover를 사용한 논리 장애 복구]
step1. 복구 시점을 확인.(언제 시점까지 복구하고 싶은지)
step2. 최신 백업본 & 그 이후 연결되는 시점의 archive log file 필요.
-> archive log 이름, 용량 파악
step3. restore 수행(요청) -> target 서버 지정
step4. recovery
[실습 – truncate table]
1. 테이블 생성 및 log switch
create table scott.recover_test6(no number);
insert into scott.recover_test6 values(1);
commit;
alter system switch logfile;
insert into scott.recover_test6 values(2);
commit;
alter system switch logfile;
insert into scott.recover_test6 values(3);
commit;
2. 현재 시점 확인
select sysdate from dual;
-- 2024/12/09 16:00:27
-- 이게 복구 시점
3. log switch
alter system switch logfile;
alter system switch logfile;
alter system switch logfile;
4. 장애 발생 (truncate table)
truncate table scott.recover_test6;
5. 장애 복구 (불완전 recover)
-- step1) DB 중단
shutdown immediate
shutdown abort
-- 둘 중 아무거나 써도 상관 없음. 상황보고 빨리 DB 내리고 싶으면 abort 아니면 immediate 쓰면 될듯?
-- step2) datafile restore
$ cp /oracle12/backup/hot_backup/* /home/oracle/oradata/db1
-- 꼭 모든 datafile을 restore해야된다. -> DB 전체의 시점이 과거로 돌아가는 것이기 때문에 특정 datafile만 restore하는 건 안 된다.
-- step3) startup mount
-- step4) recover
recover database until time '2024/12/09 16:00:27'
-- step5) DB open
alter database open resetlogs;
6. 데이터 복구됐나 조회
select * from SCOTT.recover_test6;
-- 1,2,3 다 잘 나옴.
7. archive file 삭제 후 hot backup 다시 받기
resetlogs; 를 썼기 때문에 archive file 번호가 1번부터 다시 시작된다. 그러면 기존에 있던 file 번호랑 충돌나니깐 archive 삭제->hot backup->log switch 해두기.