CHAINED ROWS

maio 29th, 2009 por David Ricardo

Oba! Como estamos hoje? Espero que bem.
Estou aqui para trocar uma idéia com vocês sobre um assunto que eu particularmente “NUNCA”, ouvi e nem vi pelos lugares que passei, os analistas, desenvolvedores e até mesmo DBA’s comentando. Porém esse assunto sempre me chamou atenção desde que eu iniciei minhas atividades como DBA, visto que nessa época tudo que mais se quer é fazer todo e qualquer tipo de teste e de implementações de recursos para otimizar e consequentemente mostrar serviço. Mas nessa época eu humildemente um DBA Jr. fui vetado, pois bem, hoje acredito que posso arriscar bater um papo sobre este assunto que acredito ser deveras interessantes, não só para os mais experientes como também para aqueles que desejam agregar mais conhecimentos sobre Oracle e assuntos nem sempre tão abordados.
Vamos lá então!?!

CHAINED ROWS ( ou Linhas Encadeadas)

CONCEITO : Trata-se das linhas divididas entre blocos diversos, causando um aumento da linha de acordo com as atualizações dessas linhas.

Bom, mas para que fique mais claro, precisamos entender onde exatamente se encaixa esse tipo de atividade, e a qual conceito esta intimamente ligada.

Estamos falando de FRAGMENTAÇÃO. Ora, fragmentação é coisa de disco rigido ( Hard Disk) e é mais coisa de sistema operacional e não de Banco.Não é? Errado, as fragmentações também ocorrem no Oracle , e como tudo que é fragmentado afetam diretamente o bom andamento e a boa continuidade das atividades diárias do seu Banco de Dados.

Vamos entender melhor o que é FRAGMENTAÇÃO e alguns de seus tipos:

Na tentativa de definir de maneira clara e objetiva o que seria fragmentação, podemos encontrar várias definições, mais ao meu ver a que mais se adequa ao termo é, “distribuição de blocos de maneira não contigua no banco de Dados, impossibilitando uma leitura integra, e forçando o Banco de dados a ter que praticamente buscar os blocos que precisam serem lidos.

Não precisamos nem dizer que, é bem melhor eu ler 100 blocos continuamente do que eu ter que ler de 20 em 20 esparsamente, demandaria mais tempo e custaria mais recursos para gerar essa leitura.

Dentre os tipos mais famosos e mais problematicos encontramos :

FRAGMENTAÇÃO DE TABLESPACE: ocorre quando o freespace dentro de um Tablespace em especifico se encontra fragmentado em pequenos pedaços, ao invés de ser um único pedaço livre, oq ue faz com que as novas requisições de alocação de extents não encontrem um espaço continuo suficiente para realizar a tarefa. De certa maneira isso pode ser evitado controlando e definindo de maneira lógica e objetiva as clausulas de STORAGE, neste caso em particular estamos falando do PCTINCREASE, que deve ser definido como zero.

Como definir então esse PCTINCREASE ? Simples, por meio de dois comandos, digo 2 comandos porque isso se aplica tanto a INDICES quanto a TABELAS. Só isso não basta, devemos definir também o parametro pctincrease como zero também para os TABLESPACES, tudo isso pelo simples fato de que se você definir na tabela e no indice e não no TABLESPACE, os objetos nele hospedados herdaram suas caracteristicas, consequentemente irão gerar fragmentação se este não estiver definido como zero.

Vejamos:

alter table xx storage(pctincrease 0);
alter index xx_id storage(pctincrease 0);
alter tablespace xx_dt default storage(pctincrease 0);

Pronto, definimos nossa tabela, indice e tablespace para 0 (zero).

Mas onde se concentra a problematica das fragmentações? Bom questionamento este, estão exatamente ligados as definições de INITIAL e NEXT, é ai que mora o segredo de se eliminar boa parte de suas fragmentações. É de bom tom também que sempre procuremos fazer uma boa coleta de informações, para que possamos mensurar melhor o quanto será necessário para uma tabela , seja em termos de ,INITIAL ou em termos de ,NEXT, como exemplo posso citar o seguinte. Se você tem uma tabela de 1GB , não ha porque definila com next de 64KB, é obvio que isso vai gerar muito stress, e conseguemtemente fragmentações imensas, e elevadissimas quantidades de extent’s em seu objeto, ao invés de fazermos isso devemos procurar definir um tamanho para o ,NEXT uniforme de acordo com a necessidade e tamanho correto para a tabela, podemos usar como padrão para o ,NEXT neste caso 1MB.
Veja a seguir como proceder :

alter table xx storage(next 1m);
alter index xx_id storage(next 1m);

FRAGMENTAÇÃO POR BLOCO: este tipo de fragmentação é ligado mais aos comandos de exclusão, porque quando linhas são eliminadas de uma tabela , deixam uma lacuna não só nos blocos de dados como nos blocos de indices respectivamente, blocos esses que correspondem ao objeto envolvido na transação. E esse tipo de fragmentação esta ligado aos parametros PCTFREE : e PCTUSED:, os quais podem ser ajustados e alterados para se adequarem as necessidades do sistema. Note que é pura matemática e estatistica nada além disso, associados a raciocinios lógicos e objetivos, afim de proporcionar uma melhor utilização dos seus blocos de banco de dados e com isso assegurar que seu sistema terá uma boa performance sem comprometer o Banco de Dados.

Bem, voltemos ao nosso assunto principal as CHAINED ROWS, ou LINHAS ENCADEADAS para quem preferir.

Podemos detecta-las de maneira simples não é nada do outro mundo, iniciamos o processo de verificação com a utilização da DBMS_STATS utilizando a Procedure GATHER_TABLE_STATS para fazermos uma analise primaria da tabela e coletar as informações que serão usadas no processo em si. Instintivamente podemos pensar que, um número elevado de linhas encadeadas, pode e vai gerar muito stress no seu dia-a-dia, principalmente se seu Banco de Dados for de altos indices de QUERY’s ( consultas), isso pode ser solucionado aumentando o PCTFREE para que haja mais espaço dispobivel no bloco para as leituras e expansão das linhas. Veja como realizar a tarefa :

1.) exec dbms_stats.gather_schema_stats(‘Nome do Esquema’,cascade=>true);
Obs.: aqui coletaremos informações sobre todas as tabelas de um único esquema.

2.) vamos listar as linhas encadeadas após a coleta :

select table_name,
num_rows,
chain_cnt,
avg_row_len,
pct_free,
pct_used
from dba_tables
where chain_cnt > 0
order by chain_cnt desc;

ELIMINANDO AS LINHAS ENCADEADAS

Antes de começar o processo, verifique se em seu Banco existe a tabela CHAINED_ROWS, caso ela não tenha sido criada em outro momento, faça isso agora através do script “ORACLE_HOME/rdbms/admin/UTLCHAIN.SQL

**Atenção: este processo deve ser preferencialmente executado sem que outras sessões estejam sendo executadas no momento, para que com isso possamos garantir a integridade dos dados, isso é facil de obter colocando o banco em RESTRICT MODE ou simplesmente bloqueando o objeto em questão ( LOCK TABLE ).

Iniciando o processo:
analyze table xx list chained rows into CHAINED_ROWS;
create table temp_xx as select * from xx
where rowid in (select head_rowid from chained_rows
where table_name = 'xx'
and owner= 'OWNER');

Obs.: Neste passo transferimos os dados para uma tabela auxiliar para nos ajudar com o processo de eliminação das linhas encadeadas.delete from xx
where rowid in (select head_rowid from chained_rows
where table_name = 'xx'
and owner= 'OWNER');

insert into xx select * from temp_xx;

drop table xx_temp;

Bem é isso pessoal, espero que gostem e que consigam realizar sem maiores problemas , atentem para que no Banco versão 9i podemos trabalhar com várias blocagens, o que nos possibilida melhores e maiores flexibilidades. Boa sorte á todos e Sucesso.

Abraço á todos.

David

Clone Database ( Old School)

maio 27th, 2009 por David Ricardo

Olá pessoal, tudo certo?!?
Bem eu estava revirando alguns livros e artigos que possuo em minha casa, e me deparei com uma documentação bem antiga, da época em que fiz meus cursos de Oracle Database 8i.
O que me chamou bastante atenção foi no capitulo dedicado a BACKUP e RECOVER, onde tinha um subtitulo de CLONE DATABASE, eis que então que me ocorreu a idéia de fazer um post dedicado a esse momento saudoso. Vamos lá então, espero que gostem.

CLONANDO SEU BANCO DE DADOS

É público e notorio que atualmente na era 11g, e até podemos dizer era GRID CONTROL também, que as estratégias de backup e recover ficaram muito mais simplicadas, pois com alguns poucos clicks, já é possivel ter uma rotina de backup agendada em seu ambiente. Mas ainda ha aqueles que gostam de escrever as boas e velhas linhas de comando, uns como uma forma de não esquecer, uma espécie de exercicio para a memória, outros como forma de aprendizado mesmo, para que numa determinada ocasião quando o ambiente “grafico” lhe faltar, não seja pego de calças na mão.
Pois bem, então podemos dizer que, atualmente basta você definir uma boa e sólida estratégia de Backup, e assim com ela em mãos batalhar para melhor implementar em seu ambiente, afim de proporcionar aos seus superiores e ao negócio da sua empresa, uma maior disponibilidade e segurança de dados, o que nos dias de hoje é sem dúvida alguma a menina dos olhos de muitas empresas.
Bem, tendo dito isso vamos ao assunto deste Post, a CLONAGEM DE BANCO.

CONCEITO: Consiste em um processo onde teremos um ambiente de produção e um suposto ambiente ( o Clone), que será gerado apartir do ambiente principal, se tornando assim bases identicas em termos fisicos (Datafiles e arquivos de dados) e lógicos ( linhas contendo informações sobre seus objetos etc e tal), ou podemos ainda conceituar como cópia fiel de produção pra uma finalidade qualquer ( Teste, Homologação, Desenvolvimento, Laboratório, Stress Test, etc)

Então vamos dividir as etapas deste processo, opa!!! mas surgiu uma dúvida : QUANDO DEVO CLONAR MEU BANCO? E QUANTAS VEZES EU POSSO FAZER ISSO?
Interessante, mais a resposta é simples, desde que não gere stress em seu ambiente principal, pois precisaremos de uma cópia deste mesmo ambiente , você pode fazer a qualquer momento, já no que diz respeito a quantas vezes podemos fazer, isso vai depender do quanto de espaço fisico em disco você tem no seu servidor onde hospedara seu clone.

Muito bem, respondido esse questionamento básico vamos ao processo. Hum!!.Ainda não me convenci da necessidade de Clonagem por esse método, eu posso usar IMPORT e EXPORT?
Sim, claro que pode, este é um outro método de clonagem também, só que temos que levar em consideração o tempo que seria gasto no preparo do ambiente ( criação de banco de dados, estrutura de datafiles e tablespaces, criação de usuáriosm permissões, recompilações de objetos, etc e tal), ou seja um processo mais demorado, se você contar com tempo de sobra pode até executar dessa maneira até mesmo para adquirir um know-how e visão estatisticas de quanto tempo leva um processo e comparar com o outro processo.

Aos olhos dos iniciantes na minha época era meio dificil imaginar um Junior clonando uma base de dados, e eu como todo bom e sábio Junior, não me metia nessas enrrascadas, exceto quando não era em produção. Mas para que fique bem claro para todos os níves, uma tarefa bem executada com respaldo técnico e com uma boa documentação, tem minimas senão nenhuma chance de sair algo errado, por isso aqueles que nunca fizeram isso, eu RECOMENDO, no máximo você vai pecar uma ou duas vezes em uma primeira tentativa até acertar 100%, é pra isso que servem os erros, pra nos ensinar a não errarmos mais.

Bom, filosofias a parte vamos ao processo.

STEP BY STEP do Procedimento de Clonagem

a) Faça um backup full do seu banco de ORIGEM.

b) Verifique se há disponibilidade de espaço fisico no seu ambiente DESTINO.

c) Tranferir os dados , conjunto de arquivos do seu banco origem ( redo’s,control’s e datafile’s), para o seu ambiente DESTINO, obedecendo a mesma estrutura do ambiente de ORIGEM, isso pode ser feito por meio de FTP, XCOPY, ou até mesmo o famoso OCOPY, lembrando que uma cópia consistente deve ser feita com seu ambiente em modo OFFLINE, ou seja faça um SHUTDOWN em seu ambiente ORIGEM e realize as cópias, assim você evita que o Oracle esteja usando algum recurso no momento da cópia. Você pode obter as informações do que você deve copiar através das visões V$DATAFILE, V$LOGFILE e V$CONTROLFILE. Com essas informações em mãos você monta uma espécie de checklist para ao final do processo fazer uma verificação se tudo foi copiado conforme a origem.

d) Altere os arquivos relacionados a parte de conectividade Oracle, são eles, LISTENER.ORA e TNSNAMES.ORA, para que os mesmos apontem para o seu novo ambiente ( hostname, port, SID e no caso de quem usa DOMINIO o nome correto do novo dominio).
Aos fãs da padronização de ambiente e instalação OFA, os arquivos neste item citados podem ser encontrados no diretório ORACLE_HOME/network/admin
.

e) **Atenção**: Alterar o arquivo de inicialização ( init.ora ), para que reflita exatamente em sua parametrização no seu novo ambiente, atente para os seguintes parametros DB_NAME, CONTROL_FILES,BACKGROUND_DUMP_DEST, USER_DUMP_DEST e LOG_ARCHIVE_DEST.

f) Você vai precisar recriar o arquivo de controle ( CONTROLFILE), caso queira mudar o nome da instancia DESTINO. Veremos como proceder a seguir.

g) E por fim inicializar seu novo Ambiente.

COMO RECRIAR SEU CONTROLFILE

Os motivos pelos quais devemos recriar o controlfile são :

- para alterar o nome do banco de dados
- quando todos os arquivos de controle se perderem : esse motivo é óbviamente muito relevante, pois é no arquivo de controle , como o próprio nome diz, que o Oracle busca as diretrizes do que tem, onde esta e como está, ou seja é o primeiro acesso feito pelo Oracle onde há os ponteiros e “id’s”, dos seus arquivos que compõem seu Banco de Dados, pois caso você tenha perdido um arquivo de dados como por exemplo algum respectivo a Tablespace, basta que você coloque o mesmo em modo OFFLINE e seu banco abrirá, note que neste caso foi um arquivo de dados perdido e não um CONTROLFILE. Para efeito de informações o Oracle suporta até 1 controlfile apenas disponivel para abrir seu ambiente, por isso é super e de extrema importancia manter os CONTROLFILES multiplexados ( dividos em discos distintos) e também sempre estar realizando bancups periódicos do seu controlfile. Há outras maneiras de contornar essa situação de perda de controlfile, não tão ortodoxas mais que servem também em determinadas situações.
- para reinicializar parametros como MAXLOGFILES, MAXDATAFILES,MAXLOGMEMBERS e etc.

Vejamos então como proceder para a recriação dos arquivos de Controle, é importante ter o conhecimento estrutural de seu ambiente, para saber exatamente onde estão os arquivos, quais os nomes etc , é possivel fazer isso por meio de um TRACING (rastreamento) do seu controlfile.
OPA PERAI, MAIS TRACE NÃO É PARA AVALIAR A PERFORMANCE DE BANCO? IDENTIFICAR PROBLEMAS COM QUERYS OU DE PARAMETRIZAÇÕES ?

Correto, os arquivos de trace tem inumeras funcionalidades, por isso temos estruturas próprias para cada tipo de Trace gerado pelo seu Banco de dados, basta nos lembrar dos diretórios UDUMP, BDUMP, CDUMP etc, cada um tem sua finalidade em armazenar arquivos de trace gerados por razões distintas e segregadas.
Bom voltemos ao nosso processo de reciação. Para gerar um trace do seu arquivo de controle, deve ser executado a seguinte instrução :

ALTER DATABASE BACKUP CONTROLFILE TO TRACE;

Esta opção irá gerar dentro do diretório USER_DUMP_DEST um arquivo com a nomenclatura padrão de trace contendo as informações do seu ambiente.

Podemos também gerar este mesmo trace, para esta mesma finalidade, só que determinando um nome especifico para ele, até para efeitos de melhor identificação, basta que coloquemos a seguinte instrução :

ALTER DATABASE BACKUP CONTROLFILE TO ‘CAMINHO DETERMINADO’;

Bom, feito isso o nosso arquivo de trace contendo o nosso backup ficará com a seguinte cara:

STARTUP NOMOUNT
CREATE CONTROLFILE REUSE DATABASE “ORADB” NORESETLOGS ARCHIVELOG
MAXLOGFILES 16
MAXLOGMEMBERS 3
MAXDATAFILES 100
MAXINSTANCES 8
MAXLOGHISTORY 292
LOGFILE
GROUP 1 ‘/redo/oradb/redo01.log’ SIZE 50M,
GROUP 2 ‘/redo/oradb/redo02.log’ SIZE 50M,
GROUP 3 ‘/redo/oradb/redo03.log’ SIZE 50M
DATAFILE
‘/oradata/oradb/system01.dbf’,
‘/oradata/oradb/undotbs01.dbf’,
‘/oradata/oradb/sysaux01.dbf’,
‘/oradata/oradb/users01.dbf’,
‘/oradata/oradb/example01.dbf’
CHARACTER SET WE8ISO8859P1
;

É aqui que entra uma pequena intervenção caso seja necessário recriar o ambiente destino com um nome diferente do seu ambiente de origem, pois onde se lê REUSE DATABASE “ORADB” devemos colocar SET DATABASE “ORADB2″, com isso recriaremos o próximo banco com o SID igual á ORADB2, ficando então da seguinte forma:

CREATE CONTROLFILE SET DATABASE “ORADB2″ NORESETLOGS ARCHIVELOG
MAXLOGFILES 16
MAXLOGMEMBERS 3
MAXDATAFILES 100
MAXINSTANCES 8
MAXLOGHISTORY 292
LOGFILE
GROUP 1 ‘/redo/oradb2/redo01.log’ SIZE 50M,
GROUP 2 ‘/redo/oradb2/redo02.log’ SIZE 50M,
GROUP 3 ‘/redo/oradb2/redo03.log’ SIZE 50M
DATAFILE
‘/oradata/oradb2/system01.dbf’,
‘/oradata/oradb2/undotbs01.dbf’,
‘/oradata/oradb2/sysaux01.dbf’,
‘/oradata/oradb2/users01.dbf’,
‘/oradata/oradb2/example01.dbf’
CHARACTER SET WE8ISO8859P1
;

Note a sutil diferença em ambos, é apenas uma palavra que irá determinar se serão Gêmeos Idênticos ou não os seus Bancos, isso a níevl apenas de nomenclatura.

Feitas as modificações em seu arquivo de trace, você precisa criar o arquivo de controle com a sua instãncia em modo NOMOUNT, veja abaixo como proceder :

$sqlplus "/as sysdba"
SQL>startup nomount
SQL>@controlfile_ORADB2.sql
SQL>alter database open resetlogs;

Uma vez criado o arquivo de controle, você deve abrir sua instancia com a opção de RESETLOGS, para que o Oracle redefina os SCN’s ( System Change Number) dos arquivos de logs ( redo ). É nesse momento tambem que você pode aproveitar para alterar seus parametros de MAXDATAFILES, MAXLOGMEMBERS etc.

E “Congratulations”, você acaba de clonar seu primeiro Banco de dados, curta esse momento, é único, e vale muito a pena realizar, pela razões que eu já descrevi aqui e por outras tantas.
Espero que tenham curtido essa viagem no tempo ( Old School) e que apreciem o material.

Abraço á todos.

David

Bloqueios (Lock’s)

maio 26th, 2009 por David Ricardo

Olá á todos, hoje resolvi falar sobre um assunto que acredito ser interessante, este assunto por vezes nos assalta todos os dias, quem é que já não passou pela seguinte situação, estamos trabalhando eis que derepente chega um developer e nos faz a pergunta chave : “Tem como você ver se alguem esta “lockando” essa tabela?”
Pois bem, iremos navegar um pouco por esse assunto agora, os LOCK’S, espero que apreciem.

Conceito:
- Os lock’s se dão, de um modo geral, quando duas ou mais transações concorrem em relação a um determinado recurso em especifico, concorrem no sentido de utilização, os tipos de recursos aqui citados serão melhor explicados e citados quais seus respectivos tipos. Portanto quando uma determinada sessão de banco de dados esta transacionando e utilizando um determinado recurso, e esta por sua vez não o libera, uma sessão subsequente que tentar utilizar este recurso poderá entrar em estado de “WAIT”, pelo fato de a sessão que entrou e “reservou” aquele recurso para efetuar sua tarefa primeiramente estar “lockando”, ha então neste caso uma situação tipica de LOCK presente.
Esta situação pode ser solucionada por dois meios simples, ou você finaliza a sessão com um KILL SESSION ou então simplesmente a conclui por meio do COMMIT , caso tenha certeza de sua efetivação ou ainda por meio de um ROLLBACK caso haja dúvidas quando a certeza de sua transação.

Vejamos agora algumas incidências dos Lock’s, até para que possamos ilustrar melhor tal problemática.

BLOQUEIOS REGULARES:
- ocorre quando uma transação aguarda pela iberação de um recurso que esta sendo usado por outra sessão.
Veja:

update emp
set name='YourName'
where id=10;

Aqui temos um lock do tipo bloqueio a nível de linha realizado pela clausula ID = 10, que só será liberado após a transação principal realizar seu COMMIT ou ROLLBACK. Poderiamos então sugerir o seguinte questionamento: Porque o Oracle faz isso? E a resposta é quase que automatica, para que possamos manter a integridade dos dados, já pensou se todos pudessem atualizar, deletar ou inserir tudo a todo momento sem nenhum tipo de controle? É quase que impossível de imaginar tal CAOS.

DEADLOCK:
- ocorrem quando duas transações ( um conjunto de declarações SQL que executam uma ação especifica),ficam aguardando que uma libere um determinado recurso para que outra o utilize.
Essa situação pode acabar por acontecer pelo fato de existir essa “co-espera”, por parte das transações, onde fatalmente entraram em uma situação de deadlock. E como o Oracle entene isso? Bem, internamente o Banco de Dados Oracle , possui um algoritmo identificador desses casos, que vai não só localizar essas situações dentre as transações correntes como também vai soluciona-las. Uma desvantagem é que o Banco de Dados tem seu próprio tempo para que entre em ação esse algoritimo solucionador, e se no caso esta situação estiver gerando problemas maiores, então se faz necessário uma intervenção do DBA para que possa dar rápida resolução a questão. Vale lembrar que as soluções para essa situação é a mesma que o próprio algoritimo faria, ou seja, eliminar uma das transações envolvidas em DEADLOCK, no entanto o melhor mesmo é identificar essas situações e tomar providencias para que não ocorram novamente em seu sistema.

TIPOS DE RECURSOS

Abaixo elecanrei algumas tipagens de recursos que são envolvidos em situações de lock, são eles:
- Tabela(s)
- Linhas de uma Tabela
- Pacotes Armazenados

TIPOS DE BLOQUEIOS

Dentre os vários tipos de locks existentes , nós podemos separa-los em :bloqueios implícitos,bloqueios explicitos,bloqueios no nivel de linha e bloqueios no nivel de tabela.

Vamos analisar cada uma dessas situações.
BLOQUEIOS IMPLICITOS : São os bloqueios que o próprio sistema mantém como forma de garantir a integridade das informações contidas nas tabelas, como ocorre em incidências de comandos do tipo UPDATE, onde ha um lock exclusivo que só será liberado após um COMMIT ou ROLLBACK.

BLOQUEIOS EXPLICITOS : São os bloqueios por vontade o usuário, quando serão realizadas algumas tarefas a nível de testes e o usuário que acesso exclusivo naquele objeto, e pode ser obtido através da instrução LOCK TABLE, muito usada pelos developer’s de um modo geral. Este tipo de bloqueio deve ser usado com responsábilidade , pois implicará em indisponibilidade de um ou mais objetos por parte de quem estiver precisando acessar os objetos envolvidos nesse tipo de bloqueio, portanto muita atenção ao utiliza-lo.

BLOQUEIOS A NÍVEL DE LINHA : esses são os lock’s comuns diários efetuados por usuários durante o dia-a-dia de uma base de dados transacional, onde vários usuários podem fazer bloqueios compartilhados ao mesmo tempo.

BLOQUEIO A NÍVEL DE TABELA : apenas um bloqueio pode se colocado neste nível, e se compara muito ao bloqueio exclusivo só que á nivel de tabela.

De acordo com as afirmações do autor do livor ORACLE DBA Scripts de Automação - Rajendra Gutta, ocorre o seguinte :

“Se apenas um usuário colocar um bloqueio compartilhado, ele pode inserir,excluir ou atualizar. Se mais de um usuário colcoar um bloqueio compartilhado na mesma tabela, ninguém mais pode inserir, excluir ou atualizar.”
Nessa linha de raciocinio podemos concluir que, uma pessoa com um bloqueio do tipo exclusivo tem a opção de fazer insert’s, update’s e delete’s nesta tabela e quando ocorrer de mais pessoas realizarem bloqueios nas tabelas do tipo compartilhado a essas serão concedidos direitos de realizarem inserções, atualizações e deleções.

As transações de um modo geral consistem em comandos DDL ( Data Definition Language ), ou ainda DML ( Data Manipulation Language ). Podemos encontrar várias instruções DML ao mesmo tempo, essas formam uma transação que necessitam de processo manual de conclusão através das opções já citadas COMMIT ou ROLLBACk, o que não processa para as transações DDL, essas formam suas próprias transações.

Porque há a necessidade de acesso exclusivo para as declarações DDL’s? Pelo fato de que essas irão alterar a estrutura do objeto, e podem ser do tipo CREATE ou ALTER.

Para as declarações DML’s, podemos identificar quase que todos os tipos de bloqueios, para essas encontramos os comandos INSERT, UPDATE, DELETE e SELECT. Em um jogo de palavras podemos dizer que :
- SELECT esta para lock share e UPDATE esta para LOCK EXCLUSIVE.

Em determinadas situações o Oracle nos permite fazer o lock de alguns registros apenas, para que não haja um comprometimento do objeto como um todo. E para que esse mecanismo fique claro vamos ver o que Rajendra Gutta diz em seu livro :

“…um bloqueio nunca evita que os outros usuários consultem a tabela, e uma consulta nunca coloca um bloqueio em uma tabela, exceto quando uma consulta de atualização é feita.”

SITUAÇÕES COMUNS ONDE PODEMOS TER PROBLEMAS

- Lock por falta de indice em tabela.
- Lock por Resurce Busy ou por um processo ou uma transação.

SCRIPTS PARA IDENTIFICAR LOCKS:
Fonte : ORACLE DBA Scripts de Automação
Autor: Rajendra Gutta

/* Displays locks on the objects and
also gives the SQL statement causing the lock */

set echo off
set feedback on
set linesize 1000
col sid format 99999
col serial format 99999
col username format a20
col osuser format a10
col owner format a10
col object_name format a30
col machine format a15
col program format a35
col lockmode format a10
prompt ----Sessions and objects involved in the locks

Select distinct s.sid,s.serial#,
s.username,
s.status,
s.osuser,
p.spid "OS Pid",
o.object_name,
decode(l.locked_mode,
0, 'None',
1, 'Null',
2, 'Row-S',
3, 'Row-X',
4, 'Share',
5, 'S/Row-X',
6, 'Exclusive',
to_char(l.locked_mode)) "LockMode",
s.lockwait,
s.program,s.taddr
from dba_objects o ,
v$locked_object l,
v$session s,
v$process p,
v$sqltext t
where l.object_id=o.object_id
and l.session_id = s.sid
and s.paddr = p.addr
and t.address = s.sql_address
and t.hash_value = s.sql_hash_value
order by sid,serial#;

prompt ----SQL statements sessions currently executing

Select distinct s.sid,
s.serial#,
p.spid "O.S|Id",
t.piece,
t.sql_text
from dba_objects o ,
v$locked_object l,
v$session s,
v$process p,
v$sqltext t
where l.object_id=o.object_id
and l.session_id = s.sid
and s.paddr = p.addr
and t.address = s.sql_address
and t.hash_value = s.sql_hash_value
order by sid,serial#;

Agora vamos entender alguns procedimentos de resolução de bloqueios (lock’s), vejamos:

1. Identificar as sessões que estão em Lock
2. Eliminar a sessão que mantem o lock
3. Verificar se ha algum processo background ou amarrado ao S.O
4. Eliminar o processo background aliado a sessão em lock

Ainda podemos contar com alguns artificios a nível de sistema operacional para nos auxiliar na eliminação desses processos Background ligados as sessões em lock, no caso da paltaforma Windos contamos com o ORAKILL um aplicativo externo da Oracle que vem junto com o pacote padrão de instalação, e no caso de ambientes Unix podemos nos valer do poderoso KILL -9 na hora de eliminar esses DAEMON’s, que muitas vezes atrapalham.

Bem , era isso que eu queria compartilhar com vocês, espero que apreciem e comentem, quaisquer dúvidas vocês podem me contactar neste email : drb.ricardo@gmail.com, terei prazer em responder aos questionamentos. Obrigado á todos!

David

Bibliografia utilizada : Gutta, Rajendra
Scripts de Automação Oracle para DBA / Rajendra Gutta; tradução de Kátia Roque. - Rio de Janeiro : Campus, 2002

Trigger’s e seus Eventos

abril 24th, 2009 por David Ricardo

Olá, hoje resolvi escrever um pouco sobre um assunto que particularmente gosto muito, mas que por questões de necessidade nunca usei muito nas empresas por onde passei, porém acho extremamente válido falar sobre este assunto, que é sobre “TRIGGER’S e seus EVENTOS”.

Bom, começarei pelo básico como por exemplo definições, tipos e alguns exemplos de uso e implementações.

Trigger: Um dos inúmeros tipos de objetos utilizados pelo Oracle, onde você pode através destes executar automaticamente determinados comandos DML (SELECT,INSERT,UPDATE e DELETE), de acordo com o evento que esteja sendo contemplado pelo trigger. Então surge a pergunta, “EVENTOS, que eventos são esses?”, pois bem, abaixo citarei alguns exemplos de eventos de Triggers, os mais utilizados no dia-a-dia mesmo.

Evento: After Insert
- Este tipo de evento pode ser utilizado para quando alguma linha for inserida em determinada tabela, então este trigger que possui o evento de AFTER INSERT será “disparado” automaticamente executando um determinado procedimento ou uma determinada instrução que esteja no corpo do Trigger, veja abaixo um exemplo:

CREATE OR REPLACE TRIGGER [owner].[nome_trigger]
AFTER INSERT
ON [owner].[nome_tabela] for each row
begin
[package_name].[procedure_name]( :new.[parametro], :new.[parametro], null, null, :new.[parametro], :new.[parametro], :new.[parametro], ‘[parametro]‘);
end;
/

Como podemos ver esse trigger acima irá para cada linha que foi inserida em uma determinada tabela disparar um Package utilizando um determinado Store Procedure que executará uma funcionalidade de um sistema, que pode ser de caracteristicas diversas, cada ambiente tem sua particularidade.

Evento: Before Insert or Update
- Esse é um tipo composto de funcionalidade de um mesmo trigger, onde antes de ocorrer alguma inserção em determinada Tabela de sistema ou algum tipo de atualização será disparado este Trigger especifico para executar uma funcionalidade , de acordo com a necessidade.

CREATE OR REPLACE TRIGGER [owner].[nome_trigger]
BEFORE INSERT OR UPDATE
ON [owner].[nome_tabela] FOR EACH ROW
begin
[corpo do Trigger]
end;
/

Naturalmente é visivel que contamos com uma gama muito grande de tipos de eventos e formas de combinações desses mesmos eventos para uso do tipo de objeto de banco de dados TRIGGER, e como eu disse anteriormente de acordo com cada tipo de sistema, segmento de atuação, funcionalidades, nós podemos encontrar outros tipos de Triggers, com outros tantos eventos , combinados ou não. Segue mais alguns exemplos de eventos podem ser facilmente encontrados nos corpos das triggers de sistema :
- AFTER DELETE OR INSERT OR UPDATE : Neste evento teremos uma tripla ação por parte do Triggers, onde antes de cada deleção, inserção ou atualização poderá ser executado algum tipo de pré-verificação, ou até mesmo a execução de uma rotina.

- AFTER UPDATE : Como a tradução mesmo sugere ( depois de atualizar), será executada uma rotina de verificação ou até mesmo de atualização de outras tantas tabelas que tenha dependencias com um obejto em comum.

E é isso pessoal, os Triggers são uma ferramenta poderosissima, e se utilizadas com responsabilidade e com objetivos determinados, podem vir a se tornar um trunfo muito bom nas mãos de quem as utiliza, não só para facilitar a execução de rotinas do dia-a-dia como também para automação de processos de verificação e de checklist’s, lembrando sempre que uma boa documentação a respeito do que o Trigger contempla desde a sua necessidade até a construção do seu script de execução são sempre muito bem vindas, e aos olhos de gerentes coordenadores e até mesmo alguns analistas e desenvolvedores isso demonstra que o profissional tem um algo a mais, tem competência, determinação e organização.

Contamos ainda no campo dos TRIGGERS com alguns eventos mais voltados a auditoria, porém isso vai ficar para um próximo Post que virá muito em breve, espero que apreciem este post, fiz com grande prazer e espero que ele elucide ou até mesmo sirva de referencial básico para quem quer que seja.

Obrigado á todos.
Abraço
David Ricardo

1 ° Oracle Open World , primeiro dia.

março 11th, 2009 por David Ricardo

Olá pessoal, bem com é do conhecimento de todos os usuários do nosso Grupo de Profissionais Oracle ( GPO) , esse ano contamos em nosso pais com um dos eventos mais esperados, senão o mais esperado por todos os profissionais e investidores, não é para menos que na parte de exposições encontramos diversos Stand’s de diversas categorias ( Hardware, Software, etc), só para titulo de conhecimento estavam lá empresas como DELL e HP oferecendo o que há de mais novo em termos de equipamentos, na parte de Softwares as empresas de ERP’s marcaram presença, mostrando suas soluções e implementações ligadas a inúmeros segmentos de mercado.
O que mais me fascinou , não só por gostar de linux , mas por trabalhar e ter contado diário com isso, foi ver um stand da RED HAT, mostrando principalmente seu produto o RED HAT Enterprise 5, muito bom também.
Bem, vamos ao ponto alto do OOW, as palestras, eu particularmente assisti a 2 apenas, a primeira foi sobre VIRTUALIZAÇÃO , um show a parte, o indiano (Madhup Gulati, Sênior Product Manager – Oracle Corporation) que veio proporcionar a palestra para os participantes dominava tranqüilamente o assunto, e conseguiu ganhar a confiança de todos e vende muito bem esse novo produto que a Oracle esta apostando e difundindo cada vez mais e mais, e pelo grau de interesse das pessoas que participaram da exposição na palestra ficou nítido para mim que isso se tornará com certeza uma nova tendência cada vez mais crescente no cotidiano das grandes , médias e até porque não dizer, pequenas empresas. A segunda palestra da qual participei foi sobre OPEN SOURCE e OPEN STANDARDS, que foi mais um overview sobre empresas e softwares que contam com esse tipo de tecnologia menos “engessada”, algo mais maleável do que a Microsoft para se trabalhar, não foi uma palestra extensa nem tão pouco gerou tantas dúvidas quanto a palestra sobre virtualização, onde tivemos a duvida mais pertinente talvez sobre o oferecimento deste produto, é grátis o Download porém, não se sabe ainda a forma de cobrança sobre esse produto quando sua utilização se der em ambientes de grande porte, e como isso foi tema de uma das questões levantadas, o expositor disse que de acordo com as necessidades as licenças para concessão de uso deste produto seria nos moldes e critérios já pré adotados pela Oracle.
Por fim me aproximei da área de DEMOGROUNDS, que alias é um conceito muito inteligente e interessante de ver aquilo que todos nós como profissionais desejamos implementar funcionando, eu em particular fui ao demo sobre ACTIVE DATA GUARD, uma nova feature do 11g que possibilita uma nova técnica de DG, onde você tem aplicação do seu redo log em seu ambiente Stand By online, com a base aberta em READ ONLY, o que para muitos seria melhor do que o que temos hoje em termos de base de dados D-1, com isso poderíamos usar este banco em especifico para retirar relatórios grandes, relatórios que tenham uma volumetria enorme de dados , etc e tal.

Bom é isso pessoal , espero que gostem da leiura, um abraço á todos.

ORA-29532

janeiro 26th, 2009 por David Ricardo

Olá pessoal, me deparei com um problema semana passada, um problema bem curioso porém muito chato de se resolver, ao tentar executar qualquer Package de Banco (ex.: DBMS_REPAIR) eu recebia a mensagem de erro ORA-29532, pois bem , resolvi pesquisar e me deparei com um problemão , observem.
Assim que comecei a pesquisar fui da tabela DBA_REGISTRY e para minha surpresa encontrei a seguinte informação :

SQL> /

COMP_NAME STATUS
—————————————- ———–
Oracle Database Java Packages INVALID

Passei então a pesquisar, e consultar alguns colegas sobre o erro que me parecia estranho, até que um deles me disse que em uma pós migração de versão do Oracle 10g, alguns pacotes ficaram invalidos , e esse em especial JAVA também estava, para corrigir tal problema é necessário que sejam REMOVIDO todos os pacotes JAVA do Database e REINSTALA-los conforme manda uma documentação do metalink, o erro que aparece sempre que tentamos utilizar alguma feature ou recurso do Banco, como Export etc e tal é esse :

ORA-29532: Java call terminated by uncaught Java exception: java.lang.ExceptionInInitializerError

Sendo assim, resolvi postar aqui a solução para esse problema. Então vamos lá, caso você note o erro acima em seu DATABASE verifique antes se este erro é ocasionado pelo fato dos pacotes Java estarem INVALIDOS como demonstrado acima, após feito isso e constatado o problema siga os passos a seguir :

spool full_rmjvm.log
set echo on
connect / as sysdba
startup mount
alter system set “_system_trig_enabled” = false scope=memory;
alter system enable restricted session;
alter database open;
@?/rdbms/admin/catnoexf.sql
@?/rdbms/admin/catnojav.sql
@?/xdk/admin/rmxml.sql
@?/javavm/install/rmjvm.sql
truncate table java$jvm$status;
select * from obj$ where obj#=0 and type#=0;
delete from obj$ where obj#=0 and type#=0;
commit;
select owner, count(*) from all_objects
where object_type like ‘%JAVA%’ group by owner;
select obj#, name from obj$
where type#=28 or type#=29 or type#=30 or namespace=32;
select o1.name from obj$ o1,obj$ o2
where o1.type#=5 and o1.owner#=1 and o1.name=o2.name and o2.type#=29;
shutdown immediate
set echo off
spool off
exit

Junte todos esses passos em um único script e o execute logado como SYS, ele fará todos os passos de remoção do JAVA da base de dados, feito isso verifique os logs, e em seguida execute a reinstalação dos pacotes JAVAS como segue abaixo :

spool full_jvminst.log;
set echo on
connect / as sysdba
startup mount
alter system set “_system_trig_enabled” = false scope=memory;
alter database open;
select obj#, name from obj$
where type#=28 or type#=29 or type#=30 or namespace=32;
@?/javavm/install/initjvm.sql
select count(*), object_type from all_objects
where object_type like ‘%JAVA%’ group by object_type;
@?/xdk/admin/initxml.sql
select count(*), object_type from all_objects
where object_type like ‘%JAVA%’ group by object_type;
@?/xdk/admin/xmlja.sql
select count(*), object_type from all_objects
where object_type like ‘%JAVA%’ group by object_type;
@?/rdbms/admin/catjava.sql
select count(*), object_type from all_objects
where object_type like ‘%JAVA%’ group by object_type;
@?/rdbms/admin/catexf.sql
select count(*), object_type from all_objects
where object_type like ‘%JAVA%’ group by object_type;
shutdown immediate
set echo off
spool off
exit

Pronto seus pacotes java estão reinstalados, utilizando o script UTLRP.sql que faz a recompilação dos objetos invalidos, certifique-se de que não tenha sobra nada invalido, este script se encontra no diretório “$ORACLE_HOME/rdbms/admin”, em seguida faça uma query na DBA_REGISTRY para verificar se os pacotes que anteriormente estavam como invalidos retornaram ao status de válidos :

SQL> /

COMP_NAME STATUS
—————————————- ———–
Oracle Database Java Packages VALID

SQL>

Eis que agora todos os recursos que anteriormente não funcionavam pelo fato de classes e procedures que tem chamadas em Java no oracle estavam inválidas, agora você poderá tranquilamente executar export, dbms’s etc.

Abraço á todos!!!
David

Em que Base estou???

janeiro 16th, 2009 por David Ricardo

Olá pessoal , muitas vezes quando gerenciamos diversos databases ao mesmo tempo, ou até mesmo em um mesmo ambiente, nos deparamos com a seguinte questão, “Onde estou conectado???”, ou seja, pra não termos que ficar usando show user toda hora pra sabermos usuário que estamos logado, ou até mesmo fazer aquele pequeno selec básico pra sabermos o nome da instancia em que estamos , pois bem abaixo segue um script só para facilitar a vida, não é nada demais , mas ajuda bastante :

set pause off veri off feed on term on;
set feed off;
undefine cn
undefine us
undefine sn
prompt
prompt
prompt . ………………………………………………..
prompt . . . .
accept cn prompt “. . . . . . Conexao …………. : ”
accept us prompt “. . . . . . . Usuario …………. : ”
accept sn prompt “. . . . . . Senha …………… : ” hide
prompt . . . .
prompt . ………………………………………………..
prompt
conn &us/&sn@&cn

col gn new_value gn noprint
col ur new_value ur noprint

–select INITCAP(replace(global_name,’.WORLD’,”))
– gn from global_name ;
alter session set nls_date_format=’dd/mm/yyyy hh24:mi:ss’;
select INITCAP(user) UR,initcap(’&cn’) gn from dual;

set sqlp “&gn..&ur> ”
set feed on;
undefine ur
undefine gn
clear columns
–clear screen
prompt
prompt
prompt

Bom é isso ai rapaziada, criem os seus scripts e divirtam-se.
Abraços até mais!!!!