[dash shell 설치 & 원복]
현재 oel7은 sh 사용 시 bourne shell이 아니라 bash shell 이 실행 되는 중이었음.
$ su – root
$ which sh # sh 위치 확인
$ cd /usr/bin/
$ ll sh # 링크 걸려있는 상태 확인
$ rm sh # sh 링크 걸린 거 삭제
$ yum -y install dash # dash shell 설치
$ ln -sf /bin/dash /bin/sh # 링크 걸기
$ ll sh # 링크 걸려있는 상태 확인
근데 그렇게 했을 때 vmware환경에서 로그인이 안되는 문제가 발생하니깐 다시 bash로 원복시켜놓자.
DB가 망가졌을 때 복구 방법
[offline full restore]
offline backup 파일을 사용하여 백업 시점으로 DB를 되돌리는 작업.
환경 설정 실패로 DB가 정상적으로 startup 되지 않는 경우 원복 작업.
현재 data file들을 모두 지우고 restore함 + control file + parameter file까지 restore해야 됨.
step1) DB 종료
shutdown abort
step2) ‘data’ alias 디렉토리로 이동하여 file 전체 삭제
$ cd /oracle12/app/oracle/oradata/db1
$ rm *
step3) control file , data file, redo log file restore
$ cp /oracle12/backup/cold_backup/* .
step4) parameter file restore
$ cd /oracle12/app/oracle/product/12.2.0.1/db_1/dbs 또는 cd $ORACLE_HOME/dbs
$ cp /oracle12/backup/cold_backup/*.ora .
step5) DB 기동
> startup
만약 안 되면 backup본에 문제있으니까 옆에 친구한테 부탁하자.
[redo log file]
redo log buffer에 있는 내용이 기록되는 database 내 파일
** LGWR 동작 시점
buffer의 1/3 초과 시.
변경량 1MB 초과 시.
매 3초마다.
DBWR 동작 전. (write log ahead)
[redo log file 구성]
1. 그룹과 멤버로 구성.
(그룹은 멤버를 묶는 논리적 개념, 멤버가 실제 파일 형태로 생성됨)
2. 하나의 그룹에는 최소 한 개의 멤버 구성 (default : 각 그룹별 1개 멤버로 구성)
3. 그룹은 최소 2개 이상 필수. (default : 3개 그룹 생성)
[실습 – redo log file 조회]
@log.sql
-- member 이름
select *
from v$logfile;
-- 각 그룹에 대한 seq, size, archive 여부, 현재 상태, 시점
select *
from v$log;
-- 위 두 view를 조인해서 사용
select a.group#, a.member, b.bytes/1024/1024 as "SIZE(MB)", b.archived, b.status, b.sequence#
from v$logfile a, v$log b
where a.group# = b.group#;
-- ~/log.sql 에 저장할 내용
set pages 1000
set lines 1000
col group# format 999999
col member format a45
col status format a10
col seq# format 99
select a.group#,
a.member,
b.bytes/1024/1024 as "SIZE(MB)",
b.archived,
b.status,
b.sequence# as seq#
from v$logfile a, v$log b
where a.group# = b.group#
order by 1,2
/
위의 쿼리를 리눅스 ~/log.sql에 저장.
후에 sqlplus로 들어가서 @log.sql 쓰면 실행가능.
[redo log group status(상태)]
INACTIVE -> CURRENT -> ACTIVE -> INACTIVE 순서로 status 가 변함.
CURRENT : 현재 redo log buffer 내용을 기록 중인 그룹. DB online 중 삭제, 변경할 수 없다.
ACTIVE : 해당 redo log file을 가지고 DBWR가 data file에 내려쓰는 중인 상태. CURRENT 가 log switch 되면 ACTIVE가 됨. DB online 중 삭제, 변경 불가능.
INACTIVE : ACTIVE group의 내용을 모두 동기화 후 되는 상태. LGWR, DBWR 둘 다 작동하지 않는 그룹. DB online 중 삭제, 변경 가능.
[log switch]
current redo log group 에 기록할 내용이 가득찰 경우 current 를 다른 그룹으로 바꾸는 행위.
Thread checkpoint 발생 -> DBWR가 동작함.
RR(round robin) 방식으로 다음 current redo group 할당.
** RR (Round Robin) 스케줄링
- 선점 스케줄링 알고리즘
- 준비 큐에 도착한 순서에 따라 디스패치하지만
- 정해진 시간 할당량에 의해 실행을 제한
- 시간 할당량 안에 완료되지 못한 프로세스는 준비 큐의 맨 뒤에 배치 • 대화형 운영체제에 유용
장점
- CPU를 독점하지 않고 공평하게 이용
- 대화형 운영체제에 유용
단점
- 시간 할당량이 너무 작으면 문맥 교환에 따른 오버헤드가 크게 증가함
- 시간 할당량이 너무 크면 FCFS 스케줄링과 같아짐
빈번한 log switch 는 DB 장애 및 성능 저하 유발!
변경량이 많아질 때 log switch 잦아짐. 특히 새벽에 batch파일들 돌아갈 때.
ACTIVE가 2개고 나머지 1개가 CURRENT인 상태가 발생함.
** ORA-01171 checkpoint not complete
1) 현상 :
active 였던 redo log group에 log switch 가 발생하면서 내용을 덮어쓰려고 할 때 아직 DBWR에 의해 동기화를 완료하지 못했으므로 덮어쓸 수 없는 상황
2) 원인 :
잦은 log switch <- 대용량 batch작업, DBMS 구조적 문제(redo log file의 size가 작거나, group의 수가 적거나 등), 개발자의 잦은 commit.
3) 해결 :
구조적 문제 – redo log file size 늘리기, group 추가.
코드 문제 – 잦은 commit 못하게.
alter system switch logfile;
명령어 치고 바로 @log.sql 명령어 실행시키면
SQL> @log.sql
GROUP# MEMBER SIZE(MB) ARC STATUS SEQ#
------- --------------------------------------------- ---------- --- ---------- ----
3 /oracle12/app/oracle/oradata/db1/redo03.log 200 NO INACTIVE 3
2 /oracle12/app/oracle/oradata/db1/redo02.log 200 NO CURRENT 5
1 /oracle12/app/oracle/oradata/db1/redo01.log 200 NO INACTIVE 4
SQL> alter system switch logfile;
System altered.
SQL> @log.sql
GROUP# MEMBER SIZE(MB) ARC STATUS SEQ#
------- --------------------------------------------- ---------- --- ---------- ----
3 /oracle12/app/oracle/oradata/db1/redo03.log 200 NO CURRENT 6
2 /oracle12/app/oracle/oradata/db1/redo02.log 200 NO ACTIVE 5
1 /oracle12/app/oracle/oradata/db1/redo01.log 200 NO INACTIVE 4
SQL> alter system checkpoint;
System altered.
SQL> @log.sql
GROUP# MEMBER SIZE(MB) ARC STATUS SEQ#
------- --------------------------------------------- ---------- --- ---------- ----
3 /oracle12/app/oracle/oradata/db1/redo03.log 200 NO CURRENT 6
2 /oracle12/app/oracle/oradata/db1/redo02.log 200 NO INACTIVE 5
1 /oracle12/app/oracle/oradata/db1/redo01.log 200 NO INACTIVE 4
이렇게 ACTIVE, SEQ순서의 차이를 확인할 수 있다.
switch logfile 사용 시 : CURRENT -> ACTIVE, 나머지 중 하나가 CURRENT가 됨. SEQ에 변화 생김.
checkpoint 사용 시 : ACTIVE -> INACTIVE
[redo log member 구성]
각 그룹별 하나의 멤버 필수 (2개 이상 권고 -> 안정성).
여러 멤버 구성 시 각 멤버를 서로 다른 디스크에 생성 권고 -> 각 멤버에 병렬 기록 가능.
online 중에 redo log group/member 추가 가능(shutdown 필요 없음)
current redo log group에 member 추가가 online중 가능하나, 가급적 부하가 없을 때 작업 권고
[실습 – group 추가]
1. 현재 redo log 확인
@log.sql
2. 그룹 추가
alter database add logfile group 4 '/oracle12/app/oracle/oradata/db1/redo04.log' size 200M;
-- 그룹 추가 시 멤버도 최소 1개 같이 선언돼야 함.
3. 추가된 그룹 확인
@log.sql
[실습 – 각 group에 member 추가]
1. 현재 redo log 확인
@log.sql
2. 각 그룹별 멤버 추가
alter database add logfile member '/oracle12/app/oracle/oradata/db1/redo01_2.log' to group 1;
alter database add logfile member '/oracle12/app/oracle/oradata/db1/redo02_2.log' to group 2;
alter database add logfile member '/oracle12/app/oracle/oradata/db1/redo03_2.log' to group 3;
alter database add logfile member '/oracle12/app/oracle/oradata/db1/redo04_2.log' to group 4;
3. 새로 추가한 멤버 확인
@log.sql
[redo log group/member 삭제]
current, active redo group은 member 삭제 불가. inactive redo group은 언제나 그룹, 멤버 삭제 가능
다중화 구성의 경우 : current redo group의 member는 삭제 불가. active redo group의 member는 삭제 가능.
current redo 삭제
1. 현재 상태 확인
@log.sql
2. 1번 그룹을 current 로 만들기
alter system switch logfile;
-- 과 위 단락에 있는 확인 쿼리를 번갈아 수행해서 확인해가며 1번 그룹을 current로 만들기
3. current 인 그룹 삭제
alter database drop logfile group 1; -- current라서 삭제 안되는 게 정상
4. current 인 그룹의 member 삭제
alter database drop logfile member '/oracle12/app/oracle/oradata/db1/redo01_2.log'; -- 삭제 불가
active redo 삭제
1. 확인
@log.sql
2. log switch로 2번을 current로 변경. 1번은 active가 됨.
alter system switch logfile;
3. active인 그룹 삭제(불가).
alter database drop logfile group 1;
4. active인 그룹의 일부 member 삭제(가능)
alter database drop logfile member '/oracle12/app/oracle/oradata/db1/redo01_2.log';
5. 1번만 1개의 member 가지고 있는 것 확인
@log.sql
inactive redo group 삭제
1. 확인
@log.sql
2. 4번그룹이 inactive 이라면 4번 그룹 삭제
alter database drop logfile group 4;
3. 결과확인. -> 1번은 멤버 한개, 4번 그룹은 삭제돼서 없음
물리적으로 삭제 됐는지 확인
$ cd /oracle12/app/oracle/oradata/db1
$ ll
삭제해서 안 보이는 파일들이 남아있다.
즉, controlfile에서만 지워진 느낌.
직접 파일 삭제 해줘야 됨.
$ rm redo01_2.log
$ rm redo04*
만약 삭제 안 하고 다시 1번 그룹에 두번째 멤버 추가 시 파일이 이미 존재한다는 오류 발생.
alter database add logfile member '/oracle12/app/oracle/oradata/db1/redo01_2.log' to group 1;
-- '/oracle12/app/oracle/oradata/db1/redo01_2.log' - file cannot be created
-- ORA-27038: created file already exists
[redo member rename]
1. redo file 이름 변경
ex) redo01.log -> redo01_1.log
2. redo file 위치 변경
노후화된 디스크 장비 교체 작업 시.
ex) /oracle12/…/redo01.log -> /oradata/…/redo01.log
방법1 : DB offline(mount) 상태에서 작업
control file은 읽고 수정해야 하지만, 로그파일이 current 상태면 안되는 상황이니깐, DB startup 중 mount단계에서 작업하는 것.
-- 확인
> @log.sql
-- rename 시도 (오류남)
> alter database rename file '/oracle12/app/oracle/oradata/db1/redo01.log' to '/oracle12/app/oracle/oradata/db1/redo01_1.log'
-- DB shutdown
> shutdown immediate
-- DB mount
> startup mount
-- rename 시도 (오류남)
> alter database rename file '/oracle12/app/oracle/oradata/db1/redo01.log' to '/oracle12/app/oracle/oradata/db1/redo01_1.log';
-- 리눅스 서버에 파일 생성
$ data (=cd /oracle12/app/oracle/oradata/db1)
$ mv redo01.log redo01_1.log
$ mv redo02.log redo02_1.log
$ mv redo03.log redo03_1.log
-- rename 시도 (정상)
> alter database rename file '/oracle12/app/oracle/oradata/db1/redo01.log' to '/oracle12/app/oracle/oradata/db1/redo01_1.log';
> alter database rename file '/oracle12/app/oracle/oradata/db1/redo02.log' to '/oracle12/app/oracle/oradata/db1/redo02_1.log';
> alter database rename file '/oracle12/app/oracle/oradata/db1/redo03.log' to '/oracle12/app/oracle/oradata/db1/redo03_1.log';
-- DB open
> alter database open;
방법2 : DB online 상태에서 작업
DB online 상태에선 어떤 redo log file도 rename할 수 없음(물리적인 cp, mv가 불가능)
새로 rename할 파일(멤버) 생성 후 기존 파일 삭제하는 방식.
current는 불가능함. 따라서 current를 제외한 그룹에 대해 rename을 진행하고, log switch를 이용해서 상태를 current에서 active로 변경해주고, rename 하는 방식.
redo01_1.log -> redo01.log 기존 이름으로 변경
-- 현재 어떤 그룹이 current인지 확인
@log.sql
-- 멤버 추가
alter database add logfile member '/oracle12/app/oracle/oradata/db1/redo01.log' to group 1;
alter database add logfile member '/oracle12/app/oracle/oradata/db1/redo02.log' to group 2;
alter database add logfile member '/oracle12/app/oracle/oradata/db1/redo03.log' to group 3;
-- current인 그룹 빼고 삭제할 기존 멤버들 삭제
alter database drop logfile member '/oracle12/app/oracle/oradata/db1/redo01_1.log';
alter database drop logfile member '/oracle12/app/oracle/oradata/db1/redo01_2.log';
alter database drop logfile member '/oracle12/app/oracle/oradata/db1/redo02_1.log';
alter database drop logfile member '/oracle12/app/oracle/oradata/db1/redo02_2.log';
alter database drop logfile member '/oracle12/app/oracle/oradata/db1/redo03_1.log';
alter database drop logfile member '/oracle12/app/oracle/oradata/db1/redo03_2.log';
-- log switch 해서 current였던 그룹에도 멤버 삭제
alter system switch logfile;
-- 삭제하다가 보면 만든지 얼마 안돼서 아직 syn가 안된 멤버 파일 있으면 삭제가 안되는 경우가 있다. 그러면 바로 윗줄의 log switch 명령어로 한바퀴 돌려준 뒤에 다시 삭제 시도하면 잘 지워진다.
-- 현재 상태 확인
@log.sql
-- 서버에 파일도 rm으로 삭제하기
$ data
$ rm redo01_*
$ rm redo02_*
$ rm redo03_*
$ ll