Oracle 32일차

[DB startup 흐름]

1. parameter file 읽음(spfileSID.ora or initSID.ora) -> 성공하면 nomount 단계. 실패하면 nomount도 안됨.
2. parameter file 안에 있는 control files 읽음 -> mount 단계.
3. data files, redo log files를 읽고 필요하다면 instance recovery 진행 -> 성공하면(SCN 일치) open 단계. 실패하면 mount까지만.

[instance recovery]

shutdown abort 등의 비정상 DB 종료 시 수행되는 복구의 형태.
SMON background process가 담당.
startup 시 진행(mount 단계에서)
control files, data files, redo log files의 SCN 정보 확인 & 일치시키는 작업

** 과정

step1) DB 비정상 중단 시 redo log buffer 의 내용 -> redo log file 에 기록

step2) startup 시 control file, data file, redo log file의 SCN 정보 확인

step3) SCN 정보가 일치하지 않으면 해당 정보를 redo log file에서 찾아서 복구 진행
commit 된 정보 위주로 먼저 시점 일치 작업 진행 (roll forward)

step4) DB 정상 OPEN

step5) rollback 할 SCN 정보를 정리(roll backward)

[DB backup]

  1. offline backup = cold backup
    DB가 중단된 상태에서 database 구성 파일(control file, data file, redo log file) backup.
    3개 파일을 모두 backup한다는 점에서 가장 안전한 방식.
    DB를 중단시켜야 한다=그만큼 서비스를 중단하니 비용이 많이 든다 는 단점 존재.
  2. online backup = hot backup
    DB가 운영 중인 상태에서 data file 만 backup.
    backup mode로 전환 후(begin backup) backup 진행.

[offline backup (cold backup) 절차]

0. 혹시 모르니깐 parameter file backup

> show parameter pfile;
> create pfile from spfile;
> exit

$ cd $ORACLE_HOME/dbs
$ cp initdb1.ora /oracle12/backup/20241126
$ cp spfiledb1.ora /oracle12/backup/20241126

1. data file, redo log file, control file 조회

1) control file 조회

-- 그냥 조회만 할 경우
select name from v$controlfile;
-- /oracle12/app/oracle/oradata/db1/control01.ctl
-- /oracle12/app/oracle/oradata/db1/control02.ctl

-- shell 프로그래밍 할 때
select 'cp '||name||' /oracle12/backup/${todate}' from v$controlfile;

2) data file 조회

select name from v$datafile;
-- /oracle12/app/oracle/oradata/db1/system01.dbf
-- /oracle12/app/oracle/oradata/db1/sysaux01.dbf
-- /oracle12/app/oracle/oradata/db1/undotbs01.dbf
-- /oracle12/app/oracle/oradata/db1/users01.dbf

3. redo log file 조회

select member from v$logfile;
-- /oracle12/app/oracle/oradata/db1/redo03.log
-- /oracle12/app/oracle/oradata/db1/redo02.log
-- /oracle12/app/oracle/oradata/db1/redo01.log

2. db shutdown immediate

3. 파일들 cp script

mkdir -p /oracle12/backup/20241126
cp /oracle12/app/oracle/oradata/db1/control01.ctl /oracle12/backup/20241126
cp /oracle12/app/oracle/oradata/db1/control02.ctl /oracle12/backup/20241126
cp /oracle12/app/oracle/oradata/db1/system01.dbf /oracle12/backup/20241126
cp /oracle12/app/oracle/oradata/db1/sysaux01.dbf /oracle12/backup/20241126
cp /oracle12/app/oracle/oradata/db1/undotbs01.dbf /oracle12/backup/20241126
cp /oracle12/app/oracle/oradata/db1/users01.dbf /oracle12/backup/20241126
cp /oracle12/app/oracle/oradata/db1/redo03.log /oracle12/backup/20241126
cp /oracle12/app/oracle/oradata/db1/redo02.log /oracle12/backup/20241126
cp /oracle12/app/oracle/oradata/db1/redo01.log /oracle12/backup/20241126

[실습 – offline full backup을 사용한 복구]

1. 테이블 생성

create table table1(no number, name varchar2(10));
insert into table1 values(1, 'SMITH');
insert into table1 values(2, 'ALLEN');
insert into table1 values(3, 'KING');
commit;

2. DB shutdown

3. offline full backup본을 restore

데이터만 복구할 거면 parameter file은 복구 안 해도 됨.

cp /oracle12/backup/20241126/* /oracle12/app/oracle/oradata/db1

4. DB startup

5. 테이블 조회

select * from table1; — table or view does not exist 출력.

[control file]

parameter file에 control file 경로가 기록되어있음.
nomount에서 mount 단계로 갈 때 control file을 읽음.

.ctl최소 1개 이상 있어야 함.
다중화가 권고되고, 따라서 default는 2개임.
다중화 시 각 control file의 정보는 같음.

** control file 이 가진 정보
db 이름
archive log 모드, 위치
data file 위치, 이름
redo log file 위치, 이름
모든 시점 정보

** data file이 정상일 때 control file 재생성 가능.
but, 동적 변경 불가 -> DB 껐다 켜야 반영.

-- control file 스크립트 확인하려고 할 때 복사하는 방법
> alter database backup controlfile to trace as '/oracle12/backup/20241126/control.sql';

[실습 – control file 다중화]

1. control file 확인

pfile(initSID.ora) 확인

2. view 확인

select name from v$controlfile;

3. parameter file 수정

pfile : vi로 파일을 수정하여 파라미터의 값 변경 가능.

혹시 모르니까 pfile 만들어놓기
create pfile from spfile;

spfile : 변경 가능한 파라미터에 한해 DB 운영 중에 동적으로 변경 가능

alter system set 옵션
alter system set 파라미터명 = 값 scope = memory 또는 spfile 또는 both;
-- 1) memory : 현 시스템에 바로 적용되지만 spfile에 기록하지 않아서 재기동 시 원복됨.
-- 2) spfile : default값임. spfile에만 변경된 내용을 기록. 현 시스템에 적용 X. 재기동 이후 반영
-- 3) both : 현 시스템에 반영 + spfile에 기록. (동적 변경 가능한 경우)
alter system set control_files = '/oracle12/app/oracle/oradata/db1/control01.ctl',
                                        '/oracle12/app/oracle/oradata/db1/control02.ctl',
                                        '/oracle12/app/oracle/oradata/db1/control03.ctl' scope = spfile;

4. DB shutdown immediate 후 controlfile 물리적으로 새로 생성

ex)
$ cp /oracle12/app/oracle/oradata/db1/control01.ctl /oracle12/app/oracle/oradata/db1/control03.ctl

5. DB startup

혹시 startup 도중에 막혔다면 cp 제대로 됐나 확인하고,
alter database mount;
alter database open;
하든가,
아예 shutdown immediate 했다가 다시 startup으로 올리기

[실습 – pfile 환경에서 controlfile 다중화]

** pfile 생성 후 DB 종료.
create pfile from spfile;
shutdown immediate
exit

** parameter file 백업하든가 spfile 이름 변경해서 pfile로 부팅되도록 함.
cd dbs
cp initSID.ora /oracle12/backup/20241126
cp spfileSID.ora /oracle12/backup/20241126
해서 cp해놓든가
mv spfileSID.ora spfileSID.ora.bak
해서 이름 바꿔서 parameter file이 못 알아보게 함

** startup 후 pfile 인지 확인하기
ss
startup
show parameter pfile;

** pfile 개수 확인
select * from v$controlfile;

** db shutdown
shutdown immediate

** pfile 수정
cd /oracle12/app/oracle/product/12.2.0.1/db_1/dbs (=alias dbs)
vi initSID.ora
/oracle12/app/oracle/oradata/db1/control04.ctl 추가

** cp 명령어로 controlfile 복사
cd /oracle12/app/oracle/oradata/db1 (=alias data)
cp control01.ctl control04.ctl

** DB 기동 후 체크
ss
startup
select * from v$controlfile;

[실습 – 다시 spfile 환경으로 바꾸기]

** spfile 다시 만들기
create spfile from pfile;

** db shutdown
shutdown immediate

** db 재기동
startup

** parameter file 확인
show parameter pfile;

이러면 control file 4개인 상태된다~

[cold_backup.sh 만들기]

vim 편집기에서 # 주석처리 같은 거 했을 때 하이라이트(노란색) 처리되는데 그거 끄는 방법 ‘:noh’

쌤한테 받은 피드백 받은 부분

1. DB가 open 상태인지 체크하기

2. pfile 상태인지 spfile 상태인지 체크하고 spfile돌리기.

중간에 막히거나 어려웠던 부분

입력리다이렉션으로 sqlplus 쿼리문 작성하면서 저장할 경로(backupdir) 입력할 때 변수로는 잘 안돼서 그냥 쌩으로 경로 쓴 부분이 아쉬웠음.

show parameter pfile; 대신에 select value from v$parameter where name = ‘spfile’; 로 바꿔서 value값만 얻은 부분을 chatgpt가 알려줌.

chmod든 뭐든 파일명 쓰는 부분 나올 때 전체경로를 안 써놓고 왜 안되나 했던 부분 고쳐야 됨.
쉘 쓸 땐 전체경로로.

그리고 echo 안에 #!/bin/sh 같은 거 표현할 때는 double quote가 아니라 single quote로!

파일들 cp할 때 따로 sh 만들어서 한번에 실행시켜서 복사하는 방식도 chatgpt가 추천해줌.

# cold_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/latest
# 기존에 있던 파일들 모두 삭제 후 다시 생성
rm -rf $backupdir
mkdir -p $backupdir

# pfile 상태인지 spfile 상태인지 확인
sqlplus -s / as sysdba << _eof_ > ~/spfile_status.tmp
set head off
select value from v\$parameter where name = 'spfile';
_eof_

grep ${ORACLE_SID} ~/spfile_status.tmp > /dev/null
if [ $? -eq 0 ]
then
  # pfile 생성
  sqlplus -s / as sysdba << _eof_
  create pfile from spfile;
_eof_
echo "spfile 사용 중, pfile 복사완료"
else
  # spfile 생성
  sqlplus -s / as sysdba << _eof_
  create spfile from pfile;
_eof_
echo "pfile 사용 중, spfile 복사완료"
fi

rm -rf ~/spfile_status.tmp

# parameter file 복사
cd $ORACLE_HOME/dbs
cp init${ORACLE_SID}.ora $backupdir
cp spfile${ORACLE_SID}.ora $backupdir
echo "parameter file 둘 다 backup 완료"

if [ $? -ne 0 ]
then
  echo "parameter file backup failed."
  exit 1
fi

# 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/latest' 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/latest' 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/latest' 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 종료"

# DB 재기동
echo
echo "DB startup 시작..."
sqlplus -s / as sysdba << _eof_
startup
_eof_
echo
echo "DB startup 완료"
echo

echo "shell 정상종료"
echo
exit 0

Leave a Comment