Script to add new Standby Logfile
col member format a60
set lines 200
set pages 999
set serveroutput on size 1000000
DECLARE
CURSOR c_inst IS
SELECT thread#, MIN(GROUP#) min_group, MAX(GROUP#) max_group, sum(members) cnt
FROM v$log
GROUP BY thread#
ORDER BY thread#;
CURSOR c_log (pTHREAD# IN NUMBER) IS
SELECT lf.group#, lf.member, l.thread#, l.sequence#, l.bytes/1024/1024 mb, lf.status
FROM v$logfile lf, v$log l
WHERE lf.group# = l.group#
AND l.thread# = pTHREAD#
-- AND lf.INST_ID = l.INST_ID
-- AND l.thread# = (SELECT MAX(thread#) FROM gv$log)
ORDER BY lf.group#, lf.member;
lv_thread NUMBER := 0;
lv_group_Min NUMBER := 0;
lv_group_Max NUMBER := 0;
lv_group_tot NUMBER := 0;
lv_group_Cur NUMBER := 0;
lv_group_Last NUMBER := 0;
lv_case NUMBER := 0;
lv_members NUMBER := 0;
lv_cnt NUMBER := 0;
lv_redo_seq VARCHAR2(12) := NULL;
lv_debug BOOLEAN := FALSE;
-- lv_debug BOOLEAN := TRUE;
lv_sql VARCHAR2(4000) := NULL;
lv_keyword VARCHAR2(8) := 'redo';
lv_last_gp NUMBER := 0;
lv_last_member varchar2(80);
lv_last_size NUMBER := 0;
lv_last_seq VARCHAR2(12) := NULL;
FUNCTION logfile_count (p_logfile_type VARCHAR2 DEFAULT 'ONLINE')
RETURN INTEGER
IS
lv_cnt INTEGER := 0;
BEGIN
SELECT COUNT(*) INTO lv_cnt
FROM v$logfile
WHERE type = UPPER(p_logfile_type); -- 'STANDBY';
RETURN lv_cnt;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RETURN 0;
WHEN OTHERS THEN
RETURN NULL;
END logfile_count;
BEGIN
IF logfile_count ('STANDBY') > 3 THEN
RETURN;
END IF;
BEGIN
SELECT MAX(GROUP#)
INTO lv_group_tot
FROM V$LOGFILE;
EXCEPTION
WHEN NO_DATA_FOUND THEN
lv_group_max := 0;
WHEN OTHERS THEN
RAISE;
END;
FOR c_inst_rec IN c_inst LOOP
lv_thread := c_inst_rec.thread#;
lv_group_min := c_inst_rec.min_group;
lv_group_max := c_inst_rec.max_group;
lv_members := c_inst_rec.cnt;
IF lv_debug THEN
DBMS_OUTPUT.PUT_LINE ('lv_group_min='||TO_CHAR(lv_group_min)||' lv_group_max='||TO_CHAR(lv_group_max)||
' lv_members='||TO_CHAR(lv_members));
END IF;
lv_sql := 'ALTER DATABASE ADD STANDBY LOGFILE THREAD '||TO_CHAR(lv_thread);
DBMS_OUTPUT.PUT_LINE (lv_sql);
IF lv_debug THEN
DBMS_OUTPUT.PUT_LINE (lv_sql);
END IF;
lv_group_cur := lv_group_tot + lv_group_min;
IF lv_debug THEN
DBMS_OUTPUT.PUT_LINE ('lv_group_cur='||TO_CHAR(lv_group_cur)||' lv_group_max='||TO_CHAR(lv_group_max));
END IF;
lv_cnt := 0;
FOR c_log_rec IN c_log (lv_thread) LOOP
IF lv_debug THEN
DBMS_OUTPUT.PUT_LINE ('The current group is : '||TO_CHAR(lv_group_cur));
END IF;
LV_REDO_SEQ := lv_keyword||LPAD(TO_CHAR(lv_thread), 2, '0')||'_'||LPAD(TO_CHAR(lv_group_cur), 2,'0')||'_sb';
IF lv_members = 2*(lv_group_max-lv_group_min+1) THEN
BEGIN
IF lv_group_last <> c_log_rec.group# THEN
IF lv_cnt = 0 THEN
DBMS_OUTPUT.PUT_LINE (' GROUP '||TO_CHAR(lv_group_cur)||' ('||''''||
REPLACE(c_log_rec.member, lv_keyword||SUBSTR(c_log_rec.member,
INSTR(c_log_rec.member, lv_keyword)+LENGTH(lv_keyword), 2),
lv_redo_seq)||''''||' ) SIZE ' || TO_CHAR(c_log_rec.MB) ||'M REUSE');
lv_sql := lv_sql||' GROUP '||TO_CHAR(lv_group_cur)||' ('||''''||
REPLACE(c_log_rec.member, lv_keyword||SUBSTR(c_log_rec.member,
INSTR(c_log_rec.member, lv_keyword)+LENGTH(lv_keyword), 2),
lv_redo_seq)||'''';
ELSE
DBMS_OUTPUT.PUT_LINE (', GROUP '||TO_CHAR(lv_group_cur)||' ('||''''||
REPLACE(c_log_rec.member, lv_keyword||SUBSTR(c_log_rec.member,
INSTR(c_log_rec.member, lv_keyword)+LENGTH(lv_keyword), 2),
lv_redo_seq)||''''||' ) SIZE ' || TO_CHAR(c_log_rec.MB) ||'M REUSE');
lv_sql := lv_sql||', GROUP '||TO_CHAR(lv_group_cur)||' ('||''''||
REPLACE(c_log_rec.member, lv_keyword||SUBSTR(c_log_rec.member,
INSTR(c_log_rec.member, lv_keyword)+LENGTH(lv_keyword), 2),
lv_redo_seq)||'''';
END IF;
lv_group_last := c_log_rec.group#;
lv_group_cur := lv_group_cur + 1;
END IF;
END;
ELSIF lv_members = lv_group_max-lv_group_min+1 THEN
BEGIN
IF lv_group_last <> c_log_rec.group# THEN
IF lv_cnt = 0 THEN
DBMS_OUTPUT.PUT_LINE (' GROUP '||TO_CHAR(lv_group_cur)||' ('||''''||
REPLACE(c_log_rec.member, lv_keyword||SUBSTR(c_log_rec.member,
INSTR(c_log_rec.member, lv_keyword)+LENGTH(lv_keyword), 2),
lv_redo_seq)||''''||') SIZE ' ||TO_CHAR(c_log_rec.MB) ||'M REUSE');
lv_sql := lv_sql||' GROUP '||TO_CHAR(lv_group_cur)||' ('||''''||
REPLACE(c_log_rec.member, lv_keyword||SUBSTR(c_log_rec.member,
INSTR(c_log_rec.member, lv_keyword)+LENGTH(lv_keyword), 2),
lv_redo_seq)||''''||') SIZE ' ||TO_CHAR(c_log_rec.MB) ||'M REUSE';
ELSE
DBMS_OUTPUT.PUT_LINE (', GROUP '||TO_CHAR(lv_group_cur)||' ('||''''||
REPLACE(c_log_rec.member, lv_keyword||SUBSTR(c_log_rec.member,
INSTR(c_log_rec.member, lv_keyword)+LENGTH(lv_keyword), 2),
lv_redo_seq)||''''||') SIZE ' ||TO_CHAR(c_log_rec.MB) ||'M REUSE');
lv_sql := lv_sql||', GROUP '||TO_CHAR(lv_group_cur)||' ('||''''||
REPLACE(c_log_rec.member, lv_keyword||SUBSTR(c_log_rec.member,
INSTR(c_log_rec.member, lv_keyword)+LENGTH(lv_keyword), 2),
lv_redo_seq)||''''||') SIZE ' ||TO_CHAR(c_log_rec.MB) ||'M REUSE';
END IF;
lv_group_last := c_log_rec.group#;
lv_group_cur := lv_group_cur + 1;
END IF;
IF lv_debug THEN
DBMS_OUTPUT.PUT_LINE ('LV_REDO_SEQ='||TO_CHAR(LV_REDO_SEQ));
DBMS_OUTPUT.PUT_LINE ('lv_group_cur='||TO_CHAR(lv_group_cur));
END IF;
END;
END IF;
LV_CNT := LV_CNT + 1;
lv_last_gp := lv_group_cur;
lv_last_member := c_log_rec.member;
lv_last_size := c_log_rec.MB;
-- lv_last_seq := lv_keyword||LPAD(TO_CHAR(lv_thread), 2, '0')||'_sb';
lv_last_seq := lv_keyword||LPAD(TO_CHAR(lv_thread), 2, '0')||'_'||LPAD(TO_CHAR(lv_last_gp), 2,'0')||'_sb';
END LOOP;
-- One extra logfile
DBMS_OUTPUT.PUT_LINE (', GROUP '||TO_CHAR(lv_last_gp)||' ('||''''|| REPLACE(lv_last_member, lv_keyword||
SUBSTR(lv_last_member, INSTR(lv_last_member, lv_keyword)+LENGTH(lv_keyword), 2), lv_last_seq)||''''||
' ) SIZE ' || TO_CHAR(lv_last_size) ||'M REUSE');
lv_sql := lv_sql||', GROUP '||TO_CHAR(lv_last_gp)||' ('||''''|| REPLACE(lv_last_member, lv_keyword||
SUBSTR(lv_last_member, INSTR(lv_last_member, lv_keyword)+LENGTH(lv_keyword), 2), lv_last_seq)||'''';
DBMS_OUTPUT.PUT_LINE ('/ ');
-- DBMS_OUTPUT.PUT_LINE (lv_sql);
-- EXECUTE IMMEDIATE lv_sql;
END LOOP;
END;
/