Refresh Group

Refresh group (RefGroup) é uma das milhares de funcionalidades que nosso querido Oracle DB possui.

O RefGroup serve para agrupar materialized views e atualizá-las de maneira única. O que pode facilitar a vida do DBA mas complicar o entendimento do banco por novos administradores.

Alguns problemas decorrentes de RefGroups.
no uso de RefGroups é que:
– O tempo de refresh da MView passa a ser do grupo na qual ela faz parte;
– O Enterprise Manager (versões antigas) não enxerga isto;
– A MView não precisa ter uma JOB associada ( o que dificulta encontrar aonde ela é atualizada );

Neste artigo exibirei como criar um RefGroup e como atualizar as views dele, algo bem simples 🙂

Criando um Refresh Group

Para criar um RefGroup usaremos a biblioteca DBMS_REFRESH e será necessário termos uma MaterializedView.

Criando uma materialized View

Como o foco de nosso artigo é Refresh Groups, vou criar uma tabela bem simples com uma Materialized View atualizada de 10 em 10 minutos.

Para isto, executei:

drop table dartanghan.log;
drop materialized view dartanghan.MV_LOG;

create table dartanghan.log (
	id number primary key,
	descr varchar2(512)
);
create materialized view log on dartanghan.log;
create materialized view dartanghan.MV_LOG
refresh fast next sysdate+10/24/60
as select id,descr from log;

Criando uma materialized view, o Oracle já cria uma Job e um grupo de atualização ( com apenas a MView criada ).
Com nossa materialized view criada, vamos verificar de quanto em quanto tempo ela será atualizada. Para verificar isto, podemos ver as jobs cadastradas em USER_JOBS

set pagesize 500;
col format what a45;
col interval format a30;
select job,interval,what from user_jobs;

       JOB INTERVAL                       WHAT
---------- ------------------------------ ----------------------------------------------
         4 sysdate+10/24/60               dbms_refresh.refresh('"DARTANGHAN"."MV_LOG"');

Como previsto, ao criar nossa Materialized View com a opção NEXT, o banco criou uma job para fazer a atualização.

Criando (finalmente) o Refresh Group

Agora que temos uma tabela e uma materialized view, podemos pensar no nosso Refresh Group.

Para criar um refresh group, usamos:

begin
DBMS_REFRESH.MAKE(
name=>'certbd_refgroup',
list=>'',
next_date => sysdate,
interval=>'sysdate+1/24/60',
lax=>true
);
end;
/

* Observe que não é sempre necessário criar uma refresh group. Estamos criando apenas para exemplificar o agrupamento de várias mviews em um só job.

No parâmetro LIST poderíamos ter informado o nome das Materialized Views, mas resolvi deixar para adicionar separadamente para vermos como funciona.

Para vermos os RefGroups cadastrados podemos executar:

select * from user_refresh;

e para ver os filhos de cada RefGroup:

select * from user_refresh_children;

Como ficou no nosso exemplo?

SQL> select * from user_refresh;

ROWNER                         RNAME                            REFGROUP I P R ROLLBACK_SEG             
------------------------------ ------------------------------ ---------- - - - ---------------------
DARTANGHAN                     CERTBD_REFGROUP                         8 N Y N                          
DARTANGHAN                     MV_LOG                                  7 Y Y N                          

SQL> select * from user_refresh_children;

OWNER                          NAME                           TYPE                           ROWNER     
------------------------------ ------------------------------ ------------------------------ -------
DARTANGHAN                     MV_LOG                         SNAPSHOT                       DARTANG

SQL>

* Veja que nosso grupo CERTBD_REFGROUP não possui MViews associadas.

Adicionando materialized View a um RefGroup

Agora que temos um grupo de atualização ( RefGroup ) que atualiza de minuto em minuto, vamos colocar nossa MView dentro dele e fazer com que ela seja atualizada na mesma forma:

begin
DBMS_REFRESH.ADD (
name=>'CERTBD_REFGROUP',
list=>'dartanghan.MV_LOG',
lax=>true
);
end;
/

E agora, como será que ficou nossos “Refresh Children”?

SQL> select * from user_refresh;

ROWNER                         RNAME                            REFGROUP I P R ROLLBACK_SEG             
------------------------------ ------------------------------ ---------- - - - -------------------
DARTANGHAN                     CERTBD_REFGROUP                         8 N Y N                          

SQL> select name,rname,refgroup,job from user_refresh_children;

NAME                           RNAME                            REFGROUP        JOB
------------------------------ ------------------------------ ---------- ----------
MV_LOG                         CERTBD_REFGROUP                         8         10

SQL>

Removendo um Refresh Group Children

Para remover uma Materialized View do RefGroup, usamos a proc SUBTRACT.

begin
DBMS_REFRESH.SUBTRACT (
name=>'CERTBD_REFGROUP',
list=>'dartanghan.MV_LOG'
);
end;
/

Removendo um Refresh Group

Muito simples, você precisa apenas do nome do grupo:

begin
DBMS_REFRESH.destroy(
name=>'certbd_refgroup'
);
end;
/

Para maiores detalhes dos parâmetros do DBMS_REFRESH, por favor, acesse:
http://docs.oracle.com/cd/E11882_01/server.112/e10707/rarrefreshpac.htm

Pessoal, este artigo é realmente muuuiiito pequeno sobre o conteúdo, mas espero que este possa ter ajudado em algum ponto no uso de Refresh Groups.

Caso existe algo incoerente, por favor, me ajudem a corrigir 😉