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

Paralelização de backup utilizando instâncias do Oracle RAC

Saudações pessoal, esse artigo tem o objetivo de mostrar como realizar o paralelismo no nível de instância para realização de backups.

Nesse caso a base possuia aproximadamente 370 Gb, o tempo de backup era de 1 hora, utilizando a técnica abaixo eu passei a realizar o backup em 30 minutos, ou seja, ganho de 100%.

Pré requisito:

Option de paralelização, encontrada na versão Enterprise do Oracle Database, e claro, nesse caso em específico, o ambiente estar em RAC.

Grant de sysdba para o usuário que for conectar remontamente na instância, nesse caso userbkp

Tnsnames configurados corretamente para cada instância, nesse caso dbprod1 (apontando para o nó1) e dbprod2 (apontando para o nó 2)

Script:

$ORACLE_HOME/bin/rman target / catalog usercatalog/******@db_catalog
run
  {
  allocate channel canal1_rman device type disk format ‘/disco1/rman/BKP_RMAN_LEVEL1_%d_%D_%M_%Y_%s_%p_%t’ maxopenfiles 8 connect ‘userbkp/****@dbprod1’;
  allocate channel canal2_rman device type disk format ‘/disco2/rman/BKP_RMAN_LEVEL1_%d_%D_%M_%Y_%s_%p_%t’ maxopenfiles 8 connect ‘userbkp/****@dbprod2’;
  allocate channel canal3_rman device type disk format ‘/disco3/rman/BKP_RMAN_LEVEL1_%d_%D_%M_%Y_%s_%p_%t’ maxopenfiles 8 connect ‘userbkp/****@dbprod1’;
  allocate channel canal4_rman device type disk format ‘/disco4/rman/BKP_RMAN_LEVEL1_%d_%D_%M_%Y_%s_%p_%t’ maxopenfiles 8 connect ‘userbkp/****@dbprod2’;
  crosscheck archivelog all;
  crosscheck backup;
  delete noprompt force obsolete;
  delete noprompt force expired backup;
  sql ‘alter system checkpoint global’;
  backup as compressed backupset incremental level 0 cumulative database;
  release channel canal1_rman;
  release channel canal2_rman;
  release channel canal3_rman;
  release channel canal4_rman;
}

 Vejam que, a novidade para nós, é o comando, connect na alocação do canal, ele recebe usuário,senha e a string do tnsnames, que deve apontar para a instância na qual queremos que trabalhe para nós.

É possível alocar todos os canais na mesma instância ? a resposta é sim, porem se eu alocar os quatro canais e uma instância só, talvez eu terei uma carga de trabalho muito alta em um nó só, e isso é ruim, não seria melhor pensar em dividir a carga ? dentre outras opções, é para isso que o RAC existe, para usufruirmos da possibilidade de balanceamento.  Essa regra vale para todos os backups ? concerteza não, caberá ao DBA definir a melhor estratégia para o seu ambiente, reforço que, o objetivo do artigo é mostrar a funcionalidade.

Outra máxima que precisamos considerar é , sempre que pensarmos em paralelismo, devemos considerar recursos físicos, basicamente processadores e discos, pensando em backups, a teoria diz que, teremos ganho se, alocarmos um canal por disco físico. Pensando em bases pequenas (penso eu as menores que 1Tb), talvez essa teoria talvez caia por terra, mas já pensou em bases com 40,50, 100 Tb ? concerteza o ganho será efetivo.

Uma forte dica para a utilização de paralelismo, tanto em backups, criação de indices online/offline, hints específicos para consultas, movimentação de tabelas, degree em objetos etc etc etc é, testar antes de implementar em produção, se não puderem testar, implementem aos poucos, coletem números, analisem ganhos, perdas, overhead,  paralelização é sério, acho sensacional, porem se mal implementada, a performance fica comprometida.

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

 

ORA-00600: internal error code, arguments: [kcbnew_3], [5], [1], [454544], [], [], [], []

Saudações pessoal, se alguem encontar o erro acima tente a seguinte solução.

Tentem aplicar o patch off 5558244 para a respectiva versão do SO, ou recriarem o indice que pode ser encontrado

Alterando o diagwait para 13 no Oracle Database 11gR2

Saudações Pessoal !!!

Uma dica rápida sobre esse assunto, conheço um bom e velho DBA que utilizou essa alternativa, para solucionar um grave problema de eviction entre os nós do Oracle RAC Isso causava reboot de um dos nós, durante o horário comercial, depois desta alteração, não ocorreu mais eviction entre os nós do Oracle RAC,  consequentemente, não ocorreu mais reboots.

Reforçando que isso não deve ser considerado normal, é necessário investigação com os Engenheiros da Oracle, a procura da causa raiz, de problemas como o eviction.

1º – Fazer em todos os nós como:

 [root@racnode2 bin]# ./crsctl stop crs -f 

2 – Constatando que os recursos estáo desligados.

[root@racnode1 grid]# /u01/app/11.2.0/grid/bin/oprocd stop
Jan 08 16:01:12.441 | ERR | failed to connect to daemon, errno(2)
[root@racnode1 grid]# ps -ef |egrep “crsd.bin|ocssd.bin|evmd.bin|oprocd”
root      7975  7916  0 16:01 pts/1    00:00:00 egrep crsd.bin|ocssd.bin|evmd.bin|oprocd

#crsctl set css diagwait 13 -force 

3º – Fazer em todos os nós como:

[root@racnode1 bin]# set css diagwait 13 -force
[root@racnode1 bin]# set css diagwait 14 -force
[root@racnode1 bin]# set css diagwait 15 -force
[root@racnode1 bin]# set css diagwait 40 -force
[root@racnode1 bin]# set css diagwait 999 -force
[root@racnode1 bin]# set css diagwait 13 -force

Oracle New Features 11gR2 – Gerenciando ASM Dynamic Volume Manager and ASM Cluster File System

http://imasters.com.br/artigo/19351/oracle/oracle_11gr2_gerenciando_asm_dynamic_volume_manager_e_asm_cluster_file_system/

Saudações pessoal, segue novo artigo referente ao que temos de novo na tecnologia de gerenciamento de Banco de Oracle 11g Release 2. Continuaremos discutir esse assunto.

Abraços

João Paulo Spaulonci – sharkagent@gmail.com

Cursos Oracle 11gR2

Saudações pessoal, nos próximos dias estarei realizando curso de Grid Infrastructure 11gR2 e Oracle RAC 11gR2 , no período de 16/11/2010 a 24/11/2010.

Abraços