Arquivo do mês: outubro 2011

PRKP-1030 : Failed to start the service servprod

Saudações pessoal, em algumas situações passei por esse tipo erro – não conseguir startar o serviço do RAC pelo utilitário srvctl na versão 10g.
Nesses casos existe um workaround. Já que não consigo pelo srvctl, podemos resolver stopando do serviço pelo pacote DBMS_SERVICE.

Vejam:
[oracle@producao1 /u01/app/oracle/base10g/admin/dbprod1/bdump]$srvctl start service -d dbprod1 -s servprod -i dbprod11
PRKP-1030 : Failed to start the service servprod.
CRS-0215: Could not start resource ‘ora.dbprod1.servprod.dbprod12.srv’.

Status dos serviços:
[oracle@producao1 /u01/app/oracle/base10g/admin/dbprod1/bdump]$crs_stat -t
Name           Type           Target    State     Host
————————————————————
ora….11.inst application    ONLINE    ONLINE     producao1
ora….12.inst application    ONLINE    ONLINE     producao2
ora….s11.srv application    ONLINE    UNKNOW  producao1
ora….s12.srv application    ONLINE    ONLINE     producao2
ora.dbprod1.db  application    ONLINE    ONLINE    producao1
ora….11.inst application    ONLINE    ONLINE     producao1
ora….12.inst application    ONLINE    ONLINE     producao2
ora….servprod.cs application    ONLINE    ONLINE producao1
ora….l11.srv application    ONLINE    ONLINE     producao1
ora….l12.srv application    ONLINE    ONLINE     producao2

Reparem, o serviço referente a instância dbprod11 está com status de UNKNOW.

Solução:
[oracle@producao1 /u01/app/oracle/base10g/admin/dbprod1/bdump]$export ORACLE_SID=dbprod11
[oracle@producao1 /u01/app/oracle/base10g/admin/dbprod1/bdump]$sqlplus
SQL*Plus: Release 10.2.0.4.0 – Production on Mon Oct 24 09:41:27 2011
Copyright (c) 1982, 2007, Oracle.  All Rights Reserved.
Enter user-name: sys as sysdba
Enter password:
Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 – Production
With the Partitioning, Real Application Clusters, Data Mining Scoring Engine and Real Application Testing options
SQL> show parameter service_name
NAME                                 TYPE        VALUE
———————————— ———– ——————————
service_names                        string      servprod

SQL> exec DBMS_SERVICE.STOP_SERVICE(service_name =>’servprod’ ,instance_name => ‘dbprod11’);
PL/SQL procedure successfully completed.

Depois disso, podemos realizar o startup pelo srvctl

[oracle@producao1 /u01/app/oracle/base10g/admin/dbprod1/bdump]$srvctl start service -d dbprod1 -s servprod -i dbprod11

[oracle@producao1 /u01/app/oracle/base10g/admin/dbprod1/bdump]$crs_stat -t
Name           Type           Target    State     Host
————————————————————
ora….11.inst application    ONLINE    ONLINE   producao1
ora….12.inst application    ONLINE    ONLINE    producao2
ora….s11.srv application    ONLINE    ONLINE   producao1
ora….s12.srv application    ONLINE    ONLINE    producao2
ora.dbprod1.db  application    ONLINE    ONLINE    producao1
ora….11.inst application    ONLINE    ONLINE    producao1
ora….12.inst application    ONLINE    ONLINE    producao2
ora….servprod.cs application    ONLINE    ONLINE    producao1
ora….l11.srv application    ONLINE    ONLINE    producao1
ora….l12.srv application    ONLINE    ONLINE    producao2
ora….11.inst application    ONLINE    ONLINE    producao1
ora….12.inst application    ONLINE    ONLINE    producao2
ora….p11.srv application    ONLINE    ONLINE    producao1
ora….p12.srv application    ONLINE    ONLINE    producao2
ora….21.inst application    ONLINE    ONLINE    producao1
ora….22.inst application    ONLINE    ONLINE    producao2
ora….p21.srv application    ONLINE    ONLINE    producao1
ora….p22.srv application    ONLINE    ONLINE    producao2
ora….SM1.asm application    ONLINE    ONLINE    producao1
ora….SM2.asm application    ONLINE    ONLINE    producao2

 Tudo online.

Abraços e até o próximo erro.

Flashback Data Archive

Saudações pessoal, nesse artigo conheceremos o funcionamento do Flashback Data Archive, que é uma feature do Oracle Database 11g

I – Introdução

O Flashback Data Archive é uma estrutura lógica para o armazenamento de informações históricas para uma ou mais tabelas, e armazenar esse histórico em uma ou mais tablespaces. As informações nas tabelas serão retidas de acordo com uma política de retenção definifida no Flashback Data Archive. Quem realiza essa tarefa é novo processo background FBDA que, trabalha lendo o dado de undo no buffer cache, caso o dado de undo não estiver no buffer cache, então ele lê os dados de undo nos segmentos de undo, depois disso ele consolida das linhas necessárias e escreve no flashback data archive.  
Supondo que o período de retenção seja de 10 dias, toda a informação depois do décimo dia, será deletada do flashback data archive.
Os indices originais das tabelas não são mantidos no flashback data archive, pois partimos da premissa, que o dado que será recuperado do flashback data archive, será utilizado para propósitos diferentes do dado atual da tabela. Para suprir essa demanda é possível criar indices específicos para a tabela que está no modo flashback data archive.

II – O uso
Uma das situações mais críticas que passei, foi quando tive que retornar o dado que eu tinha acabado de atualizar. O analista me mandou um script com uma correção, eu executei , depois da execução ele percebeu o erro. A alternativa foi ler os dados que ainda estavam na retenção da UNDO. Essa técnica de leitura dos segmentos de UNDO é aplicável quando o erro é percebido rapidamente, pois a UNDO é ciclíca, logo, o dado pode ser reescrito. Outra técnica que pode ser utilizada é, configuração do banco em flashback (presente na versão 10g). Porem as duas técnicas apresentam limitação, pois a retenção do dado está limitado em relação a atividade do banco e a configuração do tempo de retenção. Quem tem uma UNDO retention de 5 anos ? Com o flashback data archive podemos alterar esse comportamento. Nele, podemos definir um período de retenção em dias, meses ou anos, e nos preocuparmos somente com espaço. Fazendo uma definição bem pobre, podemos dizer que o flashback da archive é nossa UNDO
sem a expiração em horas. Quer dizer que o dado nunca expira ? – Sim, ele nunca expira, antes da retenção definida no flashback data archive.

III – Pré requisitos
– Gerenciamento automático de undo : Init parameter UNDO_MANAGEMENT=’AUTO’
– Grant “flashback archive administer” para o usuário que estiver administrando o flashback data archive
– O banco não precisa estar em archive log mode
– Uma tablespace normal separada para o flashback data archive

IV – Construindo o ambiente
SQL> conn sys as sysdba
SQL> create tablespace tbsd_vendas datafile ‘+dg1’ size 1g;
SQL> create tablespace tbsd_flash_archive datafile ‘+dg1’ size 1g;
SQL> create user vendas identified by a default tablespace tbsd_vendas;
SQL> grant unlimited tablespace to vendas;
SQL> grant resource to vendas;
SQL> grant create sequence to vendas;
SQL> grant flashback archive administer to vendas;
SQL> grant create session to vendas;
SQL> conn vendas/a
SQL> create flashback archive flashvendas tablespace tbsd_flash_archive quota 500m retention 1 year;
SQL> create sequence seq_pedidos start with 1 increment by 1 nocache;
SQL> create table tb_pedidos (
   id number(5)
   ,cliente number(19)
   ,produto number(10)
   ,qtde number(5)
   ,horario date) tablespace tbsd_vendas;
SQL> alter table tb_pedidos flashback archive flashvendas;
SQL> begin
for r in 0..100 loop
insert into tb_pedidos values (seq_pedidos.nextval,1234,900,10,sysdate);
end loop;
commit;
end;
/

V – O caso
Vamos simular a necessidade de encontrar o valor, referente ao campo qtde, da tabela tb_pedidos referente ao id 27, no dia
19/10/2011 as 19:32:37.
Para isso iremos realizar um update alterando o seu valor de 10 para 36.

SQL> select to_char(sysdate,’dd/mm/yyyy hh24:mi:ss’) as horario from dual;
HORARIO
——————-
19/10/2011 19:32:37

SQL> select * from tb_pedidos where id=27;
        ID    CLIENTE    PRODUTO       QTDE        HORARIO
        27       1234        900                      10           19-OCT-11

Vejam, o valor foi alterado para 36

– Tabela alterada, depois das 19:32:37, agora vamos descobrir o seu valor no horário 19:32:37
SQL> select * from tb_pedidos as of timestamp to_timestamp(’19/10/2011 19:32:37′,’dd/mm/yyyy hh24:mi:ss’) where id=27;
        ID    CLIENTE    PRODUTO       QTDE     HORARIO
        27       1234        900                       10        19-OCT-11

Pronto, o valor do campo qtde para o id 27 no horário 19/10/2011 19:32:37 era 10. Com essa informação posso reconstruir o dado.

VI – Gerenciando o flashback data archive.
– Podemos alterar a retenção do flashback data archive
SQL> alter flashback archive flashvendas modify retention 3 year;

– Podemos aumentar o espaço do flashback data archive
SQL> alter flashback archive flashvendas modify tablespace tbsd_flash_archive quota 800m;

– Podemos expurgar dados do flashback data archive
SQL> alter flashback archive flashvendas purge before timestamp(systimestamp – interval ’10’ day);

– Podemos dropar o flashback data archive.
SQL> alter table tb_pedidos no flashback archive;
SQL> drop flashback archive flashvendas;

VII – Restrições
Uma tabela onde o flashback data archive está ativado não pode sofrer:
– Adição de partições , subpartições ou movimentação
– Conversão de colunas do tip LONG para LOB
– Drop table
– Incluir clausula UPGRADE TABLE com ou sem a clausula INCLUDING DATA

VIII – Transparent schema evolution

O Flashback data archive suporta na release 11gR2:
– Drop de colunas e particões
– Modificação e renomeação de colunas
– Renomeação de tabelas
– Truncate de tabelas e partições.

O Flashback data archive suporta na release 11gR1:
– Adição de colunas

IX – Conclusão
Recomendo a aplicação desse recurso para as tabelas mais críticas do negócio. Mesmo tendo algumas restrições, ainda temos considerável grau de flexibilidade na manutenção de tabelas em modo flashback data archive. Reforço que, somente a leitura desse artigo não é o suficiente para uma implementação em produção, recomendo a leitura de material adicional e a máxima de sempre, para implementação em qualquer ambiente de produção, sempre, desenvolver, testar, homologar e depois implementar.

X – Referências Bibligráficas

ORACLE University. Oracle Database 11g New Features for Administrators: 19-Flashback Technology, Log Miner, and Data Pump Enhacements. California USA. 2.1 ed. Setembro 2010. v.II, p.212-230
Disponível em http://kamranagayev.com/2010/07/21/oracle-flashback-data-archive-total-recall/. Acesso em: 19 out. 2011.

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

Contato

Saudações pessoal, quero deixar para vocês mais duas fontes para nos mantermos em contato, o twitter @casadodba e o e-mail direto casadodba@gmail.com, agradeço também se puderem ajudar a divulgar.

Um forte abraço

Utilizando Invisible Index no Oracle 11g

Saudações pessoal, nesse artigo conheceremos a funcionalidade do invisible index, que é uma feature do Oracle Database 11g

I – Introdução

A feature invisible index foi introduzida no Oracle Database 11g, portanto está presente deste a release 1 do produto.
Essa feature torna um indice invisível para o otimizador, ou seja, o indice não será utilizado durante a composição do plano de execução. Diferentemente de um unusable index, ele será mantido pelo banco, logo, ele continuará sofrendo atualizações, inserções e deleções.

II – O uso
Dificil apontamos exatamente todas as situações em que esse recurso é aplicável, porem de cara temos duas situações.
1º –  Testar o comportamento de uma aplicação antes do drop de um indice.
Imaginem que, você tem um indice de 300 Gb (acreditem eles podem existir), depois de monitora-lo você conclui que pode dropa-lo, pois durante o período de monitoração ele não foi usado, ótimo perfeito, nesse momento é que entra o invisible index, ele se torna mais uma opção de garantir que não teremos nenhum problema se droparmos o indice. Tenha em mente, um indice de 300Mb eu crio rapidamente, mas um indice de 300 Gb, pode demorar horas, então, você pode tornar o indice invisível ao otimizador, aguardar um tempo, seja ele qual for e, depois disso dropa-lo.

SQL> alter index idx_tb_clientes invisible;
SQL> drop index idx_tb_clientes;

2º –  Nossa segunda opção é exatamente o contrário, posso criar um invisible index, e testar no nível de sessão se o novo indice
será benéfico ou não.

SQL> alter index idx_tb_clientes invisible;
SQL> drop index idx_tb_clientes;
SQL> explain plan for select * from tb_clientes where nome =’DANIEL DE OLIVEIRA’;
Explained.
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
————————————————————————————————————————————————————————————————————————————————————————————————————
Plan hash value: 3752082546
—————————————————————————————————-
| Id  | Operation                   | Name                 | Rows  | Bytes | Cost (%CPU)| Time     |
—————————————————————————————————-
|   0 | SELECT STATEMENT            |                      |     1 |    67 |     2   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| TB_CLIENTES          |     1 |    67 |     2   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | IDX_TB_CLIENTES_NOME |     1 |       |     1   (0)| 00:00:01 |
—————————————————————————————————-
Predicate Information (identified by operation id):
————————————————–
   2 – access(“NOME”=’DANIEL DE OLIVEIRA’)
Note
—–
   – dynamic sampling used for this statement
18 rows selected.

O resto da aplicação continua trabalhando sem utilizar o novo indice

III – Manipulação
Aqui, as técnias para a manipulação do invisible index.

SQL> alter index nome_do_indice invisible;
SQL> alter index nome_do_indice visible;
SQL> create index nome_do_indice on nome_da_tabela (coluna) invisible;

IV – Considerações
O parametro que determina do comportamento do invisible index se chama optimizer_use_invisible_indexes, o default é FALSE, ou seja,o otimizador não utilizará invible indexes na composição de um plano de execução, se alterarmos seu falor para TRUE, o otimizador passará a utilizar invisible indexes na composição de planos.

Esse parametro pode ser alterado no nível de sessão:
SQL> alter session set optimizer_use_invisible_indexes=true;

V – A prática
Vamos consolidar a teoria. Nesse exemplo, vamos simular uma situação onde eu tenho um indice (idx_tb_clientes_id), mas, eu não que o otimizador utilize-o para compor um plano.

1 – Criação do ambiente

SQL> set pages 300
SQL> set lines 300
SQL> create table tb_clientes (ID NUMBER(10),NOME VARCHAR2(50),ENDERECO VARCHAR2(50));
SQL> insert into tb_clientes values (1,’MARIA DA SILVA’,’RUA RUI BARBOSA 169′);
SQL> insert into tb_clientes values (2,’MARIA DA SILVA’,’RUA RUI BARBOSA 169′);
SQL> insert into tb_clientes values (3,’MARIA DA SILVA’,’RUA RUI BARBOSA 169′);
SQL> insert into tb_clientes values (4,’MARIA DA SILVA’,’RUA RUI BARBOSA 169′);
SQL> insert into tb_clientes values (5,’MARIA DA SILVA’,’RUA RUI BARBOSA 169′);
SQL> insert into tb_clientes values (6,’MARIA DA SILVA’,’RUA RUI BARBOSA 169′);
SQL> insert into tb_clientes values (7,’MARIA DA SILVA’,’RUA RUI BARBOSA 169′);
SQL> insert into tb_clientes values (8,’DANIEL DE OLIVEIRA’,’RUA PRUDENTE DE MORAIS 1524′);
SQL> commit;
SQL> create index idx_tb_clientes_id on tb_clientes(id);

2º – Verificando se o indice idx_tb_clientes_id está visível pelo otmizador

SQL> select index_name,table_name,visibility
SQL> from user_indexes                     
SQL> where table_name=’TB_CLIENTES’;        
INDEX_NAME                     TABLE_NAME                     VISIBILIT
—————————— —————————— ———
IDX_TB_CLIENTES_ID             TB_CLIENTES                    VISIBLE

Sim , ele está visível.

3º – Verificando se o otimizador está utilizando ele para compor planos de execução

SQL> explain plan for select * from tb_clientes where id =3;
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
————————————————————————————————————————————————————————————————————————————————————————————————————
Plan hash value: 3101714416
————————————————————————————————–
| Id  | Operation                   | Name               | Rows  | Bytes | Cost (%CPU)| Time     |
————————————————————————————————–
|   0 | SELECT STATEMENT            |                    |     1 |    67 |     2   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| TB_CLIENTES        |     1 |    67 |     2   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | IDX_TB_CLIENTES_ID |     1 |       |     1   (0)| 00:00:01 |
————————————————————————————————–
Predicate Information (identified by operation id):
—————————————————
   2 – access(“ID”=3)
Note
—–
   – dynamic sampling used for this statement
18 rows selected.

Sim, ele está sendo utilizado

4º – Tornando o indice idx_tb_clientes_id invisível pelo otmizador.

SQL> alter index idx_tb_clientes_id invisible;

5º – Verificando se o indice idx_tb_clientes_id está visível pelo otmizador

SQL> select index_name,table_name,visibility
SQL> from user_indexes                     
SQL> where table_name=’TB_CLIENTES’;        
INDEX_NAME                     TABLE_NAME                     VISIBILIT
—————————— —————————— ———
IDX_TB_CLIENTES_ID             TB_CLIENTES                    INVISIBLE

6º – Verificando novamente se o otimizador está utilizando ele para compor planos de execução

SQL> explain plan for select * from tb_clientes where id =3;
Explained.
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
————————————————————————————————————————————————————————————————————————————————————————————————————
Plan hash value: 2382977096
———————————————————————————
| Id  | Operation         | Name        | Rows  | Bytes | Cost (%CPU)| Time     |
———————————————————————————
|   0 | SELECT STATEMENT  |             |     1 |    67 |     4   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| TB_CLIENTES |     1 |    67 |     4   (0)| 00:00:01 |
———————————————————————————
Predicate Information (identified by operation id):
—————————————————
   1 – filter(“ID”=3)
Note
—–
   – dynamic sampling used for this statement
17 rows selected.

Não, agora o otimizador deixa de utilizar o indice idx_tb_clientes_id e faz um table access full. Esse foi um simples exemplo, em um ambiente pequeno, o conceito e aplicabilidade sempre vai alem.

VI – Conclusão.
Como vimos, a feature invisible index, torna a manutenção de indices mais flexível, diminuindo os riscos de perda parcial no nível de resposta de uma aplicação, rotina, ou o que for. A dica que dou é sempre a mesma, em qualquer ambiente de produção, sempre, Desenvolver, Testar, Homologar e Implementar.

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

 

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.

O parametro kernel.shmall

O problema:
SQL> startup nomount pfile=’/u01/pfile_producao.ora’
ORA-27102: out of memory
Linux-x86_64 Error: 28: No space left on device

Saudações pessoal, segue a técnica correta, para a configuração do parametro kernel.shmall nos sistemas operacionais Linux, se ele não estiver ajustado corretamente, podemos receber o erro acima durante o startup da instância ou , até mesmo depois da abertura do banco, o que talvez seja pior ainda.
A técnica, consiste em realizar uma conta com a soma de todas as SGA’s alocadas no servidor, dividido pelo valor do PAGE_SIZE do servidor.
Exemplo:
Tenho um servidor com 50Gb de RAM, onde aloco 3 bases, cada uma com 10Gb de SGA, totalizando 30Gb.
Se o valor do PAGE_SIZE for 4096 o valor de kernel.shmall será

kernel.shmall=Total da SGA (em bytes)/PAGE_SIZE (em bytes)
kernel.shmall=30*1024*1024*1024/4096
kernel.shmall=30*1024*1024*1024/4096
kernel.shmall=32212254720/4096
kernel.shmall=7864320

Lembrando que, o valor da SGA, pode ser definido pela combinação dos valores de SGA_MAX_SIZE/SGA_TARGET/MEMORY_TARGET/MEMORY_MAX_TARGET.
Os parametros MEMORY_TARGET e MEMORY_MAX_TARGET sobrepõe os valores SGA_MAX_SIZE e SGA_TARGET.

Verificando o atual valor de kernel.shmall:
cat /proc/sys/kernel/shmall

Verificando o valor do PAGE_SIZE do servidor:
getconf PAGE_SIZE

Alterando o valor de kernel.shmall (root):
– Editar o arquivo /etc/sysctl.conf
– Setar o valor para kernel.shmall
– Salvar e sair
– sysctl -p

Verificando se o parametro foi aletarado:
cat /proc/sys/kernel/shmall

Este parametro não requer reboot do servidor.

Abraços e até a próxima