Versionamento de objetos no Oracle Database 11gR2

Saudações pessoal, quem já precisou publicar algum objeto no Oracle do tipo package, procedure, trigger ou  function, mas não conseguiu porque o objeto em questão estava alocado por outra sessão ? em ambientes pequenos até podemos aguardar, ou baixar a aplicação, mas imagine em grandes corporações, onde a base trabalha com 50, 100, 200 sessões ativas ? – acreditem esses ambientes existem.Pois bem, até a versão 11gR2 o DBA precisava negociar uma parada da aplicação, ou um horário que ele tivesse certeza que o objeto não estaria em uso, (25 de dezembro talvez seja um bom dia), ou, abrir uma sessão no sqlplus, deixar o comando na manga, em outra sessão ficar fazendo um select repetidas vezes, verificando se o objeto está bloqueado, se ele não estiver ele volta para a sessão que o comando está pronto dá um enter, difícil né  !!!!, e isso sem considerar um alter system kill session immediate.Pois é pessoal,  no 11gR2 isso acabou, agora podemos trabalhar com versionamento de objetos, podemos ter objetos com o mesmo nome porem com código PL-SQL diferentes, trata-se da feature Edition Based Redefinition.

Existem basicamente três tipos:
– Edition: Para objetos PL-SQL como triggers procedures functions etc
– Edition Views: Para redefinições de tabelas, adicionamento ou exclusão de colunas
– Crossedition Triggers: Para forward ou backward dos dados.

Nesse artigo iremos simular o uso do Edition, onde atualizaremos uma procedure que estará alocada por outra sessão.Existem alguns documentos disponíveis na internet, utilizei papers do Tom Kyte, Daniel Morgan (que aliás foi uma das apresentações do GUOB Tech Day 2010) e um documento escrito pelo Bryn Llewellyn.
Ressalto que, o exemplo que veremos aqui, é apenas uma pequena funcionalidade dessa feature, o assunto é extenso.

1º  – Objetos que podem ser versionados
Todos objetos do tipo PL-SQL, synonyms e views, exceto, Java Class e tabelas.

2º -Mão na massa
Obs: Pessoal , eu não colo os outputs dos comandos, porque acredito ficar mais fácil para copiar do blog e implementar no ambiente de vocês, agradeço a compreensão.
export ORACLE_SID=dbprod11
sqlplus sys a sysdba
create user vendas_app identified by a;
grant resource to vendas_app;
grant create session to vendas_app;
alter user vendas_app quota unlimited on users;
conn vendas_app/a
create table tb_clientes (id number(10),descricao varchar2(50), horario date) tablespace users;
create sequence seq_id start with 1 increment by 1 nocache;
create or replace procedure prc_carga_clientes is
c number(28):=999999999;
b number(28):=0;
begin
loop
b:=b+1;
exit when b > c;
end loop;
insert into tb_clientes values (seq_id.nextval,’versão do objeto 1′,sysdate);
commit;
end;
/

3º – O problema
A procedure está demorando 2,5 minutos aproximadamente para cada execução, 60 sessões diferentes estão alocando ela, e o pior, novas sessões estão sendo abertas, as mais antigas estão saindo,  ou seja, ambiente de missão crítica. A equipe de negócio identifica um grave bug na procedure, e uma nova versão precisa subir o mais rápido possível.
OBS: Pessoal, não levem ao pé da letra, uma procedure demorando 2,5 minutos em um ambiente OLTP é catastrófico, eu utilizei esse exemplo para conseguir demonstrar a funcionalidade.

4º – O conceito
Todo banco possui um edtion, o default do Oracle é ORA$BASE, criaremos o edition ED_ATUALIZAR, que será filho do edition ORA$BASE. Para verificar qual é o default edition da sessão corrente, execute o comando abaixo em qualquer sessão, com qualquer usuário.
select sys_context(‘userenv’,’current_edition_name’) from dual;

Sempre que uma sessão é estabelecida pelo banco, ela herda o edition default do banco. O select abaixo mostra qual é o edition default da sua base.
select property_value
from database_properties
where property_name=’DEFAULT_EDITION’;

5º – Criação do versionamento ou criação do edition.
A criação do versionamento (edition), é realizada no nível de objeto, deve ser realizado por um usuário que tenha os privilégios create any edition, drop any edition, ou a role dba. Recomendo que essa tarefa fique somente a cargo do DBA, então, sysdba. Depois da criação do edition, concederemos ao usuário vendas_app o provilégio de utilização do novo edition.
sqlplus sys a sysdba
create edition ed_atualizar;
alter user vendas_app enable editions;

select * from dba_editions;
EDITION_NAME                   PARENT_EDITION_NAME    USA
——————————    ——————————          —
ORA$BASE                                                                                    YES
ED_ATUALIZAR                   ORA$BASE                                    YES

Observem o seguinte, o edition ED_ATUALIZAR é filho do edition ORA$BASE, até a versão 11gR2 esse comportamento é o default nas próximas versões esse comportamento mudará, guardem isso, utilizaremos mais a frente. Em seguida, precisamos conceder ao usuário vendas_app a permissão para utilizar o edition ed_atualizar.

grant use on edition ed_atualizar to vendas_app;

 6º – Execução da procedure prc_carga_clientes
conn vendas_app/a
set timi on
set time on
set lines 300
set pages 300
SQL> exec prc_carga_clientes;

PL/SQL procedure successfully completed.

Elapsed: 00:02:49.04
alter session set nls_date_format=’dd/mm/yyyy hh24:mi:ss’;
select * from Tb_clientes;
        ID DESCRICAO                                          HORARIO
———- ————————————————– ——————-
         1 versão do objeto 1                                 03/10/2011 21:16:04

Vejam, as 21:16:04 o insert foi concluído, agora entederemos o conceito.

 7º – Funcionamento do versionamento.
Abram uma nova sessão com o usuário  vendas_app, o editon será ORA$BASE, porque herda o default da base, em seguida, chame novamente a
procedure prc_carga_clientes, ela ficará alocada (e deverá). Abram mais uma sessão, com o usuário vendas_app, depois, alternar a sessão do
edition ORA$BASE para ED_ATUALIZAR, e publicar o código da nova procedure.

export ORACLE_SID=dbprod11
sqlplus vendas_app/a
SQL> select sys_context(‘userenv’,’current_edition_name’) from dual;
SYS_CONTEXT(‘USERENV’,’CURRENT_EDITION_NAME’)
——————————————————————————–
ORA$BASE

alter session set edition = ed_atualizar;
SQL> select sys_context(‘userenv’,’current_edition_name’) from dual;
SYS_CONTEXT(‘USERENV’,’CURRENT_EDITION_NAME’)
——————————————————————————–
ED_ATUALIZAR
create or replace procedure prc_carga_clientes is
c number(28):=9;
b number(28):=0;
begin
loop
b:=b+1;
exit when b > c;
end loop;
insert into tb_clientes values (seq_id.nextval,’versão do objeto 2′,sysdate);
commit;
end;
/
SQL> execute prc_carga_clientes;
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.02             
alter session set nls_date_format=’dd/mm/yyyy hh24:mi:ss’;
set lines 300
set pages 300
select * from tb_clientes order by 1 asc;
        ID DESCRICAO                                          HORARIO
———- ————————————————– ——————-
         1 versão do objeto 1                                 03/10/2011 21:16:04
         2 versão do objeto 1                                 03/10/2011 21:51:14
         3 versão do objeto 2                                 03/10/2011 21:58:29
         4 versão do objeto 1                                 03/10/2011 21:59:14
Vejam pessoal, a linha cujo ID é igual a três foi inserido as 21:58:29, e as 21:59:14 foi inserido a linha com ID igual a quatro, ou seja, enquanto a primeira sessão estava executando, foi possível publicar a mesma procedure com o mesmo nome e ainda executá-la na segunda sessão.
Mas como ? Para isso voltamos o conceito, (item quatro), o Oracle versiona os objetos por edition, sendo assim, ele mantem uma versão da procedure prc_carga_clientes no edition ORA$BASE e outra no edition ED_ATUALIZAR.
Mas existe um porem, as aplicações conectam no banco de forma dinâmica, não existe maneira de realizar um alter session no SQLPLUS para toda sessão, para resolver essa questão precisamos “automatizar” o método de conexão, para que o usuário da aplicação conect diretamente no editon ED_ATUALIZAR. Podemos realizar esse trabalho de duas maneiras.

– Definir o edition ED_ATUALIZAR no nível de banco.
SQL> conn sys as sysdba
Enter password:
Connected.
SQL> alter database default edition = ed_atualiar;
Database altered.
SQL> conn vendas_app/a
Connected.
SQL> select sys_context(‘userenv’,’current_edition_name’) from dual;

SYS_CONTEXT(‘USERENV’,’CURRENT_EDITION_NAME’)
——————————————————————————–
ED_ATUALIZAR

Definir o edition ED_ATUALIZAR no nível de serviço
[grid@racnode1 ~]$ srvctl config service -d dbprod1 -s srvprod1 -v
Service name: srvprod1
Service is enabled
Server pool: dbprod1_srvprod1
Cardinality: 2
Disconnect: false
Service role: PRIMARY
Management policy: MANUAL
DTP transaction: false
AQ HA notifications: false
Failover type: NONE
Failover method: NONE
TAF failover retries: 0
TAF failover delay: 0
Connection Load Balancing Goal: LONG
Runtime Load Balancing Goal: NONE
TAF policy specification: BASIC
Edition:
Preferred instances: dbprod11,dbprod12
Available instances:

[grid@racnode1 ~]$ srvctl modify service -d dbprod1 -s srvprod1 -t ‘ed_atualizar’
Obs: não existe downtime, é realizado a quente, a partir daqui as novas conexões utilizaram o edition ed_atualizar.
[grid@racnode1 ~]$ srvctl config service -d dbprod1 -s srvprod1 -v
Service name: srvprod1
Service is enabled
Server pool: dbprod1_srvprod1
Cardinality: 2
Disconnect: false
Service role: PRIMARY
Management policy: MANUAL
DTP transaction: false
AQ HA notifications: false
Failover type: NONE
Failover method: NONE
TAF failover retries: 0
TAF failover delay: 0
Connection Load Balancing Goal: LONG
Runtime Load Balancing Goal: NONE
TAF policy specification: BASIC
Edition: ed_atualizar
Preferred instances: dbprod11,dbprod12
Available instances:

Um pouco de trabalho né, porem nem tanto, e outra, pense pelo lado bom, podemos fazer a quente, tem mais,  o diretor vai agradecer.

7º – Considerações
Pessoal, reforço novamente, o que vimos referente ao Edition Based Redefinition, é só uma parte, e pequena, do que ele pode fazer, recomendo a leitura de outros documentos, quanto mais melhor, assim o conhecimento se consolida. Outra dica que sempre passo é, D-T-H-I, desenvolvam , testem, homologuem e por fim implementem, acreditem, isso faz a diferença.
Doc:
http://download.oracle.com/docs/cd/E14072_01/appdev.112/e10471/adfns_editions.htm

Um forte abraço e até a próxima.

Anúncios
Comente ou deixe um trackback: URL do Trackback.

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair /  Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair /  Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair /  Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair /  Alterar )

Conectando a %s

%d blogueiros gostam disto: