Redo - Массовое пересоздание redo логов

Caution

Логи с отличным от дефолтного(512 байт) размером блока после превращения в архивлог, судя по всему не жрутся Informatiкой

Имеющиеся файлы и их размер

select group#,members,status,archived,bytes/1024/1024 as mb,first_time,next_time from v$log t order by 1;

Расположение файлов

SELECT * FROM v$logfile;

Добавление новых групп

ALTER DATABASE ADD LOGFILE GROUP 4 (
'/u01/db/system/DW/redo04a.log',
'/u01/db/system/DW/redo04b.log') SIZE 2048M;
ALTER DATABASE ADD LOGFILE GROUP 5 (
'/u01/db/system/DW/redo05a.log',
'/u01/db/system/DW/redo05b.log') SIZE 2048M;
ALTER DATABASE ADD LOGFILE GROUP 6 (
'/u01/db/system/DW/redo06a.log',
'/u01/db/system/DW/redo06b.log') SIZE 2048M;

Если нужно переключиться вручную на другую группу, то необходимо выполнить

Alter system switch logfile;
--Формирование чекпоинта, для перехода групп в состояние INACTIVE
alter system checkpoint;

Удаление группы

Перед удалением старых файлов необходимо удостовериться, что они в данный момент в состоянии INACTIVE и ARCHIVE предварительно выполнив запрос sql select group#,members,status,archived,bytes/1024/1024 as mb,first_time,next_time from v$log t order by 1;

После чего можно по одному удалять неактивные группы файлов. ora alter database drop logfile group 6;

Скрипт пересоздания логфайлов

--select group#,members,status,archived,bytes/1024/1024 as mb,first_time,next_time from v$log t order by 1;
--SELECT * FROM v$logfile;
declare
  l_path1    varchar2(400):= '/u01/db/redolog_a/CBSPROD/';
  l_path2    varchar2(400):= '/u01/db/redolog_b/CBSPROD/';--поставить null если нужОн только 1 член в группе
  l_size     varchar2(400):= '2048M';
  l_grpcnt   int:= 5; --Количество групп логов
  ---------------------------------------------------
  l_maxgrp#  int;
  l_curcnt   int;
  l_cmd      varchar2(4000);
begin
  execute immediate 'alter system switch logfile';
  execute immediate 'alter system checkpoint';
  select max( group#),count(1) into l_maxgrp#,l_curcnt from v$log t;
  DBMS_OUTPUT.PUT_LINE( 'max group# is '||l_maxgrp#);
  if l_maxgrp#-l_curcnt>greatest(l_curcnt,l_grpcnt) then
    l_maxgrp# :=0;
    DBMS_OUTPUT.PUT_LINE( 'max group# set to 0');
  end if;

  for r in (
    SELECT t.*,row_number() over (order by p#,next_time,group#) rn
    FROM   (
            SELECT group#,status,next_time,
                   decode(status,'UNUSED',1,'INACTIVE',2,'ACTIVE',3,'CURRENT',4) p#,count(1) over () as cnt
            FROM   v$log t
           ) t
    order by p#,next_time,group#
  ) loop
    if r.cnt-r.rn>1 then
      l_cmd:='alter database clear logfile group '||r.group#;
      DBMS_OUTPUT.PUT_LINE(l_cmd);
      execute immediate l_cmd;
      l_cmd:='alter database drop logfile group '||r.group#;
      DBMS_OUTPUT.PUT_LINE(l_cmd);
      execute immediate l_cmd;
    end if;
  end loop;
  for i in l_maxgrp#+1..l_maxgrp#+l_grpcnt loop
    if l_path2 is null then
      l_cmd := 'ALTER DATABASE ADD LOGFILE GROUP '||i||'('''||l_path1||'redo'||lpad(i,2,'0')||'.log'') SIZE '||l_size;
    else
      l_cmd := 'ALTER DATABASE ADD LOGFILE GROUP '||i||'('''||l_path1||'redo'||lpad(i,2,'0')||'.log'','''||l_path2||'redo'||lpad(i,2,'0')||'.log'') SIZE '||l_size;
    end if;
    DBMS_OUTPUT.PUT_LINE( l_cmd);
    execute immediate l_cmd;
  end loop;
  execute immediate 'alter system switch logfile';
  dbms_lock.sleep(2);
  execute immediate 'alter system switch logfile';
  dbms_lock.sleep(2);
  execute immediate 'alter system checkpoint';
  for r in (
    SELECT group#,status,row_number() over(order by next_time nulls last, group#) rn,count(1) over () as cnt,
           count(1) over () - row_number() over(order by next_time nulls last) d
    FROM   v$log t
    order by next_time nulls last,group#
  ) loop
    if r.cnt-r.rn>=l_grpcnt then
      l_cmd := 'alter database drop logfile group '||r.group#;
      DBMS_OUTPUT.PUT_LINE( l_cmd);
      execute immediate l_cmd;
    end if;
  end loop;
end;