O Carnaval do DBA

fevereiro 20th, 2010 por Regis Araujo

Salve Galera.. Tudo bem com vocês??

Desculpem pela demora em postar algo.. eh q esta semana é carnaval neh..!!!
Bom, queria vir aqui cantar uma marchinha de carnaval.. tipo.. “alalaoooo oohohohhhhh.. mas que calor.. ohooo ohhoooooo!”, mas a música que eu cantei esta semana foi.. “Alalaooooo ohoohohoooo.. o banco crashouuu oohooo ohohoooo”..

Eh pessoal, vou fazer um relato de como foi minha semana.. alias.. q semana..

Eu acredito que os responsáveis pela ADM do prédio onde trabalho contrataram um ex-funcionário de angra dos reis.. e ai sabado de carnaval ele viu uma placa na porta do andar.. “O ultimo que sair, desligue tudo”.. é.. ele realmente fez isto.. novamente… e desligou o ar-condicionado do DataCenter.. então imagina.. DataCenter, cheio de servidores.. storage e tal.. sem ar-condicionado.. eh.. foi bem isto q aconteceu.. fez mais calor lá que no Rio de Janeiro.. e conclusão.. máquinas desligadas.. e quando voltaram as bases.. eh.. quando tentaram voltar as bases.. descobrimos que 7 servidores haviam corrompido suas bases.. Ai começa meu martirio.. focando na primeira base.. startado base em modo mount.. verificado arquivos corrompidos.. apenas 1 datafile com problemas.. sussa.. recover datafile X.. recover completo.. banco no ar.. eh.. isto funcionou para 6 bases.. e como Murphy nos ama.. logo a base mais importante não subiu.. total de 78 datafiles corrompidos.. ble.. volta backup dos datafiles.. kd o backup atual? o gato comeu.. de quando eh o ultimo backup.. bom.. de 15 dias atras.. q coisa não.. ble.. volta backup dos datafiles.. kd os archives? ta na fita.. então bora tirar.. opa.. a ferramenta de backup não funciona.. oq? como assim? eh.. não funciona.. bora arrumar primeiro a ferramenta de backup.. opa.. conseguimos baixar archives.. até 5 dias antes do problema.. ainda faltam 5 dias de archive.. bora terminar de baixar..!!
Eh novamente Murphy e a ferramenta de backup novamente não le a fita.. e nesta briga ja foram 3 dias sem dormir.. opa.. finalmente os archives foram baixados.. um total de 1400 archives..
Agora é começar a aplicar.. e isto já eh terça de carnaval..
Eh iniciado a aplicação dos archives, tempo estimado de termino.. 9 horas.. um dia inteiro de aplicação.. bom.. ta acabando.. q felicidade.. !!!! Iuuuupiiiiiiiiiiiiiiii… ta acabandooo..!!!!
1397.. foi… 1398… foooooiiiiii… mais 2.. mais 2.. mais 2…. 1399.. opaaaaaaaaaaaaaa.. vamos la… todos estes dias de trabalho e ta acabando.. q emoção.. q emoção..!!!
1400… opaaaaaaa.. vai.. vai.. vai.. vaaaaaaaaaaaaaaaaaiiiii…..

eh.. isto ai.. na aplicação do ultimo archive.. erro ora-00600… sabe oq eh desespero? bom.. foi oq senti neste momento.. ja estava preparando a festa para comemorar.. mas alegria de DBA dura pouco..
La vou correndo para o metalink.. alias.. Marcão.. valeu mano.. valeu pela ajuda em me mandar os links do MetaLink..
Não havia nada q ajudasse no metalink.. abrir chamado para a oracle.. tempo de resposta.. só eles sabem.. então.. Plano B..
Agora qual o plano B.. bom. plano B é o DBA se F#@#!@# pois agora tem q fazer restore de toda a base.. e ai.. fazer backup da base atual do jeito q esta.. hum.. tem tempo? não.. deleta tudo.. oq? eh.. deleta.. ble..!! apagar cerca de 1.2TB.. ah eh.. esqueci de falar.. esta base tem mais de 1TB.. Então.. voltar backup.. ble.. manda voltar..
Vai demorar quanto tempo? 12 hras..
15 hras depois.. e ai.. ja? ta estranho.. não ta voltando mais nada.. putz… oq? como q é? eh.. a ferramenta de backup não ta tirando da fita.. bora arruma esta “bendita” ferramenta.. oq não voltou? anhnn… cerca de 160 datafiles.. ble.. manda voltar só estes.. ok.. iniciado retirada da fita…. e até ai.. ja estamos na quinta-feira de madrugada.. .
Agora vamos aos procedimentos para verificar quantos archives preciso baixar…

Select * from v$recovery_log; — esta view informa quais os archives vc precisa aplicar na sua base para restaura-la até o ultimo checkpoint que consta no banco..
Select * from v$datafile_header; — esta view mostra as informações sobre os datafiles a serem recuperados..
Select * from v$recover_file; — esta view mostra os datafiles e tem um campo time onde mostra a data que consta do ultimo checkpoint de cada datafile a ser restaurado..

Q coisa estranha.. consta que 80% dos datafiles estão com data de 17/01.. ah.. culpa adivinha de quem? Da ferramenta de backup que restaurou metade dos arquivos do ultimo backup valido e a outra metade do penultimo backup válido.. quantos archives eu preciso aplicar..

Select count(1) from v$recovery_log;

O resultado foi algo assim.. amedrontador.. cerca de 2500 archives para aplicar.. iniciado a aplicação de archive dia 19/02 às 12:00 horas.. ahh.. mas desta vez será um com ultil sequence.. não vou mais aplicar o bendito ultimo archive..

run {
set ultil sequence 2499;
restore database;
}
la se vai mais um dia.. sexta-feira o dia todo.. agora vou dormir (1 da manhã).. e as 2 da manhã.. o cel toca.. o coração dispara.. oq houve? algum problema? as lagrimas correndo pelo rosto.. =(
Ufa… não era problema.. só queriam saber em que archive estava.. la vai eu olhar.. bom.. aplicado cerca de 40% dos archives.. e quem disse q eu consegui dormr de novo.. heheeh..
7 hras da manhã.. la vai eu para o curso de SqlServer (ai.. não to traindo o oracle não heim.. eh q a função exige..)..

Inicio do curso.. 40 minutos depois.. o cel toca.. =D… iupiii… la vai eu correr para um local com wirelles.. bora acessar a empresa.. cerca de 90% ja aplicado.. opa.. agora bora as movimentações de archive.. pq mais de 2000 archives é pesado pakas.. e a área de archive tava abarrotada.. bora fazer gambiarra.. renomear a área de archive e criar outra..

Aguardando o termino da aplicação de archive.. e quando foi umas 2 da tarde.. faltavam 4 archives.. olha o coração batendo forte de novo.. o suor escorrendo pela testa.. as mãos tremulas.. a boca seca.. faltam 3.. faltam 3.. mais 1.. mais 1.. mais 1.. agora faltam 2…. as lagrimas correndo pelo rosto.. a aflição tomando conta.. falta 1.. .. falta 1.. o coração ta na garganta agora.. e a mensagem enfim aparece…

RECOVERY MEDIA COMPLETE!!!!

Eh uma alegria tremenda.. mas ainda falta abrir o banco.. engole a saliva.. um silencio no corredor da instituição onde curso.. as secretárias no telefone..

la vai o tão esperado comando….

alter database open resetlogs; — a opção resetlogs faz com que seu banco sofra uma nova incarnação.. isto mesmo.. incarnação.. digamos que ele tenha morrido e renascido em outro corpo.. tudo zera.. o proximo archive gerado terá sequence 1…

E a mensagem aparece…

Database Altered;

Lanço um sonoro e alto.. CARA#$@!!#$# TA NO AR!!!!!!!!!!!

Bom.. só que neste exato momento passa pela minha frente uma das secretárias da instituição.. coitada.. hauah.. hauha.. nunca vi alguem dar um pulo tão grande quanto ela.. naquele momento ela deve ter chigado até a ultima geração da minha familia.. huaha.. hauha..!!

Enfim.. 2:40 da tarde deste sabado (20/02) a base estava no ar e integra..

Gostaria de agradecer ao Portilho por tirar algumas dúvidas que eu tinha.. hhheehe.. como sempre me ajudando.. e agradecer a todos que tem me auxiliado nestas minhas empreitadas… Rodrigo Almeida que to sempre enchendo para tirar dúvidas e ao David Ricardo que é outro que sofre com minhas perguntas.. hauh.. hauah.. Abraços manos.. !! E bora marcar um dia para tomar aquela gelada..!!

Bom pessoal.. fiz um relato bem curto de como foi minha semana de carnaval.. e quando o banco ficou no ar.. ufa.. senti como se um peso tivesse saido das minhas costas.. cheguei em casa por volta das 17 hras e apaguei.. acordei as 22 hras.. estava precisando.. caraca.. mas valeu a pena.. aprendi muito nesta semana… e uma coisa que é deveras importante em nossa carreira.. backup.. algo que meu Diretor falou.. “Em uma empresa muitas vezes não importa a base de produção, ou outra coisa.. muitas vezes o que importa realmente é o backup.”…

Que luta.. q luta.. mas foi vencida.. bom.. espero que tenha sido.. só iremos saber se a base realmente ta completa na segunda-feira quando o pessoal for utiliza-la.. ahh.. e sim.. eu ja mandei fazer backup FULL desta base.. e esta fazendo..!!!

Abraços galera.. espero que no proximo post eu fale de coisas melhoras.. não me adentrei muito aos detalhes do que foi feito pois ai o post teria mais de 100 partes.. foi trampo pra caramba.. coloquei aqui apenas o necessário..!!

Até a proxima..!!

Entendendo a ultilização de Indices - Parte III

janeiro 29th, 2010 por Regis Araujo

PARTE I
PARTE II

Fala Galera….!!!

Demorou mas enfim.. aqui está a terceira parte do post.. hehehe.. coisas da vida né.. correria faz parte.. no ultimo post falamos sobre TIPOS de JOIN e neste post iremos falar de HINTS.. é HINTS.. existem varios tipos de HINTS para melhorar ou ate mesmo prejudicar uma consulta.. dependendo de como cada hint será utilizado… Como tudo tem seus prós e contras..! Mas vamos a uma melhor explicação de HINT´s e suas utilizações.. espero que aproveitem e que possam utilizar HINT´s corretos em suas instruções SQL.. Nós DBA´s agradecemos.. e muitoooooo!!!

3. Hints

Hint é um comentário padronizado que se inclui no meio do comando para modificar o plano de execução. Geralmente ele é utilizado nos casos em que o Oracle não consegue definir uma boa estratégia.

Sintaxe:


select /*+ Hint... */
colunas ...
from tabelas ...

Abaixo segue a listagem dos hints para consultas:

3.1 Tipo de Otimizador

All_rows – força o cost-based optimizer(CBO) a otimizar o comando para retornar todos registros com o menor tempo possível (maior throughput)

First_rows – força o CBO a otimizar o comando para obter o melhor tempo de resposta

Rule – força a utilização do rule-based optimizer(RBO)

Choose – deixa para o Oracle optar por CBO ou RBO. Se pelo menos uma das tabelas possuir estatísticas coletadas então CBO é optado, senão é considerado o RBO.

3.2 Subquery / View

Push_Subq – executa as subqueries antes. Normalmente são executadas por último.

Exemplo:

select /*+ push_subq */
count(*)
from tabela_teste
where codigo in (select codigo
from tabela_teste2
where tipo = ‘T’);

Merge(v) – força o merge da view com a query principal

Exemplo:

select /*+ merge(v) */
count(*)
from view_teste v,
tabela_teste t
where v.codigo = t.codigo;

No_Merge(v) – previne o merge da view com a query principal

Exemplo:

select /*+ no_merge(v) */
count(*)
from view_teste v,
tabela_teste t
where v.codigo = t.codigo;

Merge_Aj – transforma o NOT IN subquery em sort-merge anti-join

Merge_Aj

Hash_Aj – transforma o NOT IN subquery em hash anti-join

Merge_Sj - transforma o EXISTS em sort-merge semi-join mantendo a semântica. O default do EXISTS é usar o algoritmo nested loops.

Obs: nos casos em que a tabela que está sendo verificada (tabela dentro do EXISTS) não possuir índice nas colunas do join, haverá um ganho de performance se o sort-merge semi-join for usado.

Hash_Sj – transforma o EXISTS em hash semi-join mantendo a semântica. O default do EXISTS é usar o algoritmo nested loops.

Obs: nos casos em que a tabela que está sendo verificada (tabela dentro do EXISTS) não possuir índice nas colunas do join, haverá um ganho de performance se o hash semi-join for usado.

Push_Join_Pred(v) – força a view usar o join predicate da query principal

3.3 Acesso

Full(tab) – força o full table scan para tabela ‘tab’

Cache(tab) – força que blocos retornados da consulta sejam colocados na lista LRU do buffer cache quando o full table scan for executado, se o tamanho da tabela for menor ou igual ao valor do parâmetro CACHE_SIZE_THRESHOLD.

Nocache(tab) – força que os blocos retornados da consulta não sejam colocados na cache, mesmo que a tabela tenha o parâmetro cache habilitado.

Rowid(tab) – força o acesso a tabela ‘tab’ pelo rowid

Index(tab index) – força o acesso a tabela ‘tab’ pelo índice ‘index’

Index_Asc(tab index) – induz o Oracle a acessar o índice ‘index’ da tabela ‘tab’ com um range scan

Index_Desc(tab index) – induz o Oracle a acessar o índice ‘index’ da tabela ‘tab’ na ordem decrescente

Ndex_Ffs(tab index) – opta pelo fast full scan ao invés do full table scan

Index_Combine(tab i1.. i5) – realiza a combinação booleana de índices bitmap com melhor custo.

Index_join(tab i1.. i5) – induz a utilização index join

And_Equal(tab i1.. i5) – realiza o merge de 2 a 5 índices com apenas 1 coluna.

Use_Concat – transforma a combinação de ORs/IN na cláusula WHERE em uma query composta com operador de conjunto UNION ALL.

No_Expand – não permite a concatenação

Driving_Site(tab) – a query é executada no site que a tabela ‘tab’ se encontra

3.4 Join

Use_Nl(tab) – induz o Oracle a optar a tabela ‘tab’ como sendo a inner table.

Use_Merge(tab) – induz o Oracle a realizar o join da tabela ‘tab’ com o método sort-merge.

Use_Hash(tab) – induz o Oracle a realizar o join da tabela ‘tab’ com o método hash join.

Star – induz o Oracle a realizar o start query

Star_Transformation – induz o Oracle a optar pelo melhor plano com Star Transformation. A transformação só é realizada se for benéfico.

Ordered – induz o Oracle a executar o join na ordem em que as tabelas se encontram na cláusula FROM (da esquerda para direita e de cima para baixo).

Leading(tab) - induz o Oracle iniciar o join com a tabela ‘tab’.

3.5 Parallel Query (PQ)

Parallel (tab,degree[,inst]) – induz o Oracle a paralelizar a consulta a tabela ‘tab’ pelo grau de paralelismo ‘degree’ com ‘inst’ instâncias.

Parallel_Index(table,[index,[degree[,inst]]]) - induz o oracle a paralelizar o acesso de índice particionado.

Pq_Distribute(tab,out,in)- indica como distribuir os registros da tabela ‘tab’ em uma PQ entre produtores e consumidores. Os valors para ‘out’ (outer table) e ‘in’ (inner table) podem ser: hash, none, broadcast ou partition.

Noparallel(tab) – evita a paralelização do acesso a tabela ‘tab’

Noparallel_Index(tab) – evita o parallel index scan

3.7 Variados

Rewrite(v1[,v2]) – permite que uma query compatível com a consulta de uma materialized view (v1,v2,…) seja reescrita de forma que aproveite os dados pré processados da materialized view.

Obs: Isto somente funciona caso o seu banco seja superior à 8.1

Norewrite – não permite que a query seja reescrita

Bom pessoal.. este post é realmente curtinho.. Espero que tenham aproveitado.. e caso queiram entender mais de HINT´s.. podem dar uma olhada neste link.. HINTS 11g.. Muita coisa pode ser melhorada em uma instrução Sql com a inclusão de apenas um HINT.. e algo que eu digo sempre para os analistas.. “P… meu.. q m… q vc fez desta vez?” …. Brincadeira.. Brincadeira heim.. mas agora é serio.. Algo que eu sempre pensava quando programava.. é.. programava.. isto mesmo.. ja fui programador.. em DELPHI+ORACLE.. e quando eu desenvolvia uma instrução Sql, eu sempre procurava ver se a maneira que eu havia escrito a mesma era a mais correta… procurando sempre melhorar e obter a informação que eu queria o mais rapido possível e sem prejudicar o banco…!!!

“Melhor uma query gigante bem escrita no banco do que duas pequenas derrubando o meu banco”

Abraços Galera.. até o proximo post..!!

Entendendo a ultilização de Indices - Parte II

janeiro 15th, 2010 por Regis Araujo

PARTE I

Salve Galera..

Vou continuar a falar sobre a ultilização de indices, no primeiro post foi falado sobre metodos de acesso.. e neste post será falado sobre TIPOS DE JOIN… Espero q tenham gostado da primeira parte e que também gostem da segunda.. Desculpa a demora em colocar todo o conteudo, é que o dia esta sendo corrido e somente monto este post a noite… Tudo culpa do ASM no 11gR2… “benditos” pacotes adicionais.. Grid Infrastructure e De-Install Utility (muito bom).. Ainda vou colocar um Post falando sobre ASM (RAC e Single) no 11gR2 com Grid Infrastructure e o pacote De-Install Utility.. Mas vamos voltar ao assunto do Post…!

2. Tipos de Join

O join é uma operação que permite combinar o resultado de duas ou mais tabelas baseando se nos valores das colunas em comum. O Oracle utiliza os seguintes algoritmos

2.1 Nested Loops

• O otimizador escolhe uma tabela para ser a outer table (driving table) e outra para ser a inner table
• Para cada registro da outer table, o Oracle acha todos registros da inner table que satisfazem o join condition
• O Oracle combina os dados de cada par de registros que satisfazem o join condition e então retorna os registros resultantes


select *
from tab_loc l,
tab_loc_peq p
where l.codigo = p.codigo;

2.2 Sort-Merge

• Os registros de cada tabela são ordenados pelas colunas do join condition
• É feito um merge das duas ordenações e os registros que satisfizerem o join condition são retornados


select /*+ use_merge(l p) */ *
from tab_loc l,
tab_loc_peq p
where l.codigo = p.codigo;

Obs: a etapa 2 não precisou realizar o sort porque o range scan já retornou os dados ordenados.

2.3 Hash Join

• O Oracle escolhe uma tabela menor para construir a tabela hash e o maior para verificar a tabela hash
• Geralmente o Hash Join é mais rápido que o Sort-Merge


select /*+ use_hash(l) */ *
from tab_loc l,
tab_loc_peq p
where l.codigo = p.codigo;

2.4 Star Join

• Join realizado entre uma tabela fato e algumas dimensões (tabelas lookup com informações dos atributos da tabela fato)
• Geralmente é usado quando o schema tem tabelas fato grandes e dimensões bem pequenas
• Cada tabela lookup possui um join com a tabela fato (PK_Lookup = FK_Fato_Lookup), mas as tabelas lookups não têm join entre si.
• Os joins são realizados nas seguintes etapas:
1. produto cartesiano entre as dimensões
2. join com a tabela fato usando um índice concatenado por nested loops

Exemplo de um star join

• Não confunfir o start join com o star transformation

2.5 Star transformation

• Transformação de uma consulta realizada entre uma tabela fato e algumas dimensões
• É realizado apenas se houver redução no custo
• Não há necessidade de criar índices concatenados para atender a combinação de tabelas referenciadas, pois combina índices bitmap da tabela fato
• Pré-requisitos
- Deve existir um índice bitmap para cada FK
- STAR_TRANSFORMATION_ENABLED = TRUE
- CBO deve estar sendo usado

• A consulta é realizada da em 2 fases:

1. O Oracle transforma a consulta e utiliza os índices bitmap das colunas FKs da tabela fato para obter o result set (conjunto exato dos registros necessários para avaliar a consulta). Em seguida os registros da tabela fato são obtidos.
2. O join entre a tabela fato e as dimensões é realizado. Geralmente o hash join é o mais eficiente.

Exemplo:

Comando original

Tabela fato: sales
Dimensões : store, time e product

SELECT store.sales_district,
time.fiscal_period,
SUM(sales.dollar_sales) revenue,
SUM(dollar_sales) - SUM(dollar_cost) income
FROM sales, store, time, product
WHERE sales.store_key = store.store_key
AND sales.time_key = time.time_key
AND sales.product_key = product.product_key
AND time.fiscal_period IN ('3Q95', '4Q95', '1Q96')
AND product.department = 'Grocery'
AND store.sales_district IN ('San Francisco', 'Los Angeles')
GROUP BY store.sales_district, time.fiscal_period;

Transformação

1ª parte: obtenção do result set


SELECT ...
FROM sales
WHERE store_key IN (SELECT store_key FROM store
WHERE sales_district IN ('WEST','SOUTHWEST'))
AND time_key IN (SELECT time_key FROM time
WHERE quarter IN ('3Q96', '4Q96', '1Q97'))
AND product_key IN (SELECT product_key FROM product
WHERE department = 'GROCERY');

2ª parte: join entre o result set e as dimensões

Plano de execução

Bom pessoal.. por enquanto é só.. logo venho com mais uma parte do material sobre utilização de indices.. espero que tenham gostado…!!!!
Qualquer coisa é só postar ai…!!

Abraços…!!!!

Insert - Update imagem em campo BLOB

janeiro 14th, 2010 por Regis Araujo

Salve Galera..
Vou interromper a sequencia de Posts sobre Indice Entendendo a ultilizaçao de indices para postar apenas algumas linhas sobre Update e Insert de imagens em campos BLOB dentro do banco ORACLE.. Percebi que existe muito pouco material falando sobre udate, vc encontra 1 ou 2 sobre insert.. mas vamos la… é algo bem basico.. apenas um script…

–Primeiro Passo:
Devemos acessar o servidor onde será realizado a alteração, criar um diretório e salvar a imagem dentro do mesmo.

[oracle@DBARegis temp]$ mkdir fotos
[oracle@DBARegis temp]$ ll
total 28
drwxr-xr-x 2 oracle oinstall 4096 Jan 14 11:12 fotos
drwxr-xr-x 2 oracle oinstall 825 Jan 14 11:00 SheilaMeloPlayBoy1.jpb
drwxr-xr-x 2 oracle oinstall 954 Jan 14 11:15 SheilaMeloPlayBoy2.jpb
drwxrwxr-x 2 oracle oinstall 16384 Ago 27 14:48 lost+found
[oracle@DBARegis temp]$ cp SheilaMeloPlayBoy1.jpb fotos
[oracle@DBARegis temp]$ cp SheilaMeloPlayBoy2.jpb fotos
[oracle@DBARegis temp]$ cd fotos/
[oracle@DBARegis fotos]$ ll
drwxr-xr-x 2 oracle oinstall 825 Jan 14 11:15 SheilaMeloPlayBoy1.jpb
drwxr-xr-x 2 oracle oinstall 954 Jan 14 11:15 SheilaMeloPlayBoy2.jpb
[oracle@DBARegis fotos]$ pwd
/temp/fotos/
[oracle@DBARegis fotos]$

Obs.: Estou utilizando linux, então dei o comando PWD para saber qual o caminho completo do diretório em que esta a minha sessão.. ou seja.. o diretório da imagem…

– Segundo Passo

Precisamos agora criar um diretório dentro do banco de dados oracle apontando para o nosso diretório “fotos”..

SQL> CREATE DIRECTORY FOTO_UPLOAD as '/temp/fotos/';

Diretório criado.

Obs.: Eu não dei permissão dentro deste diretório pois estou utilizando o usuário “MASTER” dentro do Sql*Plus.. mas caso vc esteja utilizando outro usuário .. basta rodar o comando..


SQL> GRANT READ, WRITE ON DIRECTORY FOTO_UPLOAD TO REGIS;

Concessão bem-sucedida.

Hehehe.. até agora esta bem tranquilo..!! Vamos agora a parte do insert.. basta rodar o script abaixo..

SQL> DECLARE
2 L_BLOB BLOB;
3 L_BFILE BFILE;
4 BEGIN
5 INSERT INTO TB_IMAGENSREGIS (ID_IMAGENSREGIS, DESCRICAO, FOTOS)
6 VALUES (17, 'Uma bela Imagem, belissima imagem', EMPTY_BLOB())
7 RETURN FOTOS INTO L_BLOB;
8 L_BFILE := BFILENAME('FOTO_UPLOAD','SheilaMeloPlayBoy1.jpb');
9 DBMS_LOB.FILEOPEN(L_BFILE);
10 DBMS_LOB.loadfromfile(L_BLOB,L_BFILE,DBMS_LOB.GETLENGTH(L_BFILE));
11 DBMS_LOB.fileclose(L_BFILE);
12 COMMIT;
13 END;
14 /

Procedimento PL/SQL concluído com sucesso.

Pronto.. insert Realizado..!!

Agora vamos a vizualização da imagem, e para isto vou utilizar o Pl/Sql Developer que é mais rapido..!

Resultado do Select

Agora a imagem né…!!! Que todos esperavam..!! Ahh.. para ver a imagem.. basta clicar no “quadrado” ao lado da descrição dentro do resultado do select…

Sheila PlayBoy 1

hehehe..!!

Agora o passo do Update..!!! Albo bem simples tbm..!

SQL> DECLARE
2 L_BLOB BLOB;
3 L_BFILE BFILE;
4 BEGIN
5 UPDATE TB_IMAGENSREGIS SET FOTOS = EMPTY_BLOB()
6 WHERE IMAGENSREGIS = 17
7 RETURN FOTOS INTO L_BLOB;
8 L_BFILE := BFILENAME('FOTO_UPLOAD','SheilaMeloPlayBoy2.jpb');
9 DBMS_LOB.FILEOPEN(L_BFILE);
10 DBMS_LOB.loadfromfile(L_BLOB,L_BFILE,DBMS_LOB.GETLENGTH(L_BFILE));
11 DBMS_LOB.fileclose(L_BFILE);
12 COMMIT;
13 END;
14 /

Procedimento PL/SQL concluído com sucesso.

É.. bem isto mesmo.. só muda o insert para update.. mas agora novamente aos resultados.. hehehe..!!

Resultado do Select 2

Agora a imagem novamente….Ta.. ta.. sei q agora ninguem mais ta com vontade de ver a imagem..! Mas la vai.. Para ver a imagem.. basta clicar no “quadrado” ao lado da descrição dentro do resultado do select…

Sheila PlayBoy 2

Bom.. então é isto.. Um passo a passo bem simples sobre insert e update de imagem em tabela dentro do ORACLE..!

Corrido hj… Culpa do “BENDITO” GRID INFRASTRUCTURE do oracle 11gR2.. fiquei sabendo que agora para criar ASM tem q ser por este pacote.. ¬.¬.. internet lenta devido ao download deste pacote.. bom.. isto é assunto para outro POST…

Espero que este post seja ultil…!!

Abraços Galera..!!!

Entendendo a ultilização de Indices - Parte I

janeiro 13th, 2010 por Regis Araujo

Salve Galera do Bem..!!!!

A um tempo atras eu estava procurando uma “apostila” de Sql Básico para passar a uma pessoa que me pediu, dentre os arquivos encontrados me deparei com um que me chamou muito a atenção pela didática com a qual ele foi escrito e o detalhamento de informações, então resolvi compartilhar o conteudo deste documento com vocês.. Mas devido ao conteudo ser um pouco extenso, vou faze-lo em partes.

Espero que desfrutem deste material…

——————————————————————-
1. Método de Acesso

Representa o tipo de acesso para obter os dados de uma determinada tabela. O Oracle possui os seguintes métodos:

1.1 Full Table Scan

• Realiza a leitura direta da tabela para determinar os registros que satisfazem a cláusula Where
• Permite o uso do multiblock I/O (leitura de vários blocos seqüenciais com um simples I/O)
• Permite a paralelização
• Nem sempre representa um método de acesso ruim

1.2 Table Access by Rowid

• Realiza o acesso a tabela pelo Rowid
• É a maneira mais rápida de acessar um registro

1.3 Index Scan

• Realiza o acesso aos dados através de um índice
• A maioria é do tipo b*-tree (padrão)

Estrutura interna da B*-tree

Arvore B*Tree

Full Scan: é usado quando a query usa pelo menos uma coluna do índice. Também é usado quando a consulta não possui predicado e se deseja evitar a operação de sort.

Fast Full Scan: é um Full Table Scan alternativo usado quando o índice possui todas colunas necessárias para a query. Para ler todos dados do índice, é mais rápido que o Index Scan por possibilitar o Multiblock I/O e a paralelização.
Obs: não pode ser usado para evitar a operação de sort (os dados não são retornados de forma ordenada).

Bitmap: utiliza um bitmap como chave para cada valor distinto da coluna e uma função de mapeamento que converte cada bit para um rowid. Se a coluna indexada tiver baixa cardinalidade, são rápidos e ocupam pouco espaço.

Obs: uma coluna é considerada de baixa cardinalidade se o número de valores distintos for menor ou igual a 1% do total de registros.

Exemplo: tabela Customer com 6 registros

Índice Bitmap sobre a coluna Region

Consulta de clientes casados e da região central e oeste.


SELECT COUNT(*) FROM customer
WHERE STATUS = 'married'
AND REGION IN ('central','west');

Bom.. espero q tenham gostado desta primeira parte, o documento possui um total de 4 partes.. caso tenham alguma dúvida.. basta postarem que irei fazer o máximo para auxiliar..!

Abraços Galera.. Otimo dia a todos..!!

Estimativa de Crescimento - Banco Oracle (ou qualquer outro)

dezembro 22nd, 2009 por Regis Araujo

Salve Galera..!

Depois de um bom tempo, resolvi abrir meu e-mail do hotmail e havia um e-mail com um questionamento, “Como estimar o crescimento de um banco de dados Oracle”, bom, pensei por um bom tempo como responder a aquela pergunta, mas ai percebi que já havia passado muito tempo que o e-mail havia sido enviado a mim, mas então resolvi pensar mais ainda e colocar a minha opinião sobre isto.

Estimar o crescimento de um banco de dados é tarefa de todo e qualquer DBA, independente se ele é DBA Oracle, SqlServer, DB2, MySql, PostGre, Access, etc.. Mas a dúvida é como estimar este crescimento, pois em um futuro proximo ou não, você terá que apresentar para a diretoria um plano de crescimento e aquisição de hardwares e também terá que “provar” que aquele novo HD é necessário, que você precisa de mais processador, memória etc..

Mas esta é uma tarefa ardua, pois vai ser necessário alguns dias ou até mesmo meses para poder montar um bom plano de estimativa, vou tentar ser mais específico e dar alguns exemplos…!!

Neste Post vou falar de estimativa de crescimento de DISCO.
Vamos a um ambiente onde haja um servidor “XPTO” com 12GB de RAM, Storage de 3T e 8 Processadores.
Neste ambiente você tenha um banco de dados para armazenar todas as informações de uma empresa, desde estoque à folha de pagamento, nesta instância atualmente existem 200 aplicativos conectados simultânemente e uma carga diária é em torno de 10.000 registros/aplicativo (apenas texto*), gerando uma carga diária de 2.000.000 de registros, contabilizando em aproximadamente 22 dias úteis são 44.000.000 de registros.
O que precisamos fazer é determinar quando será iniciado nossa coleta de informações, eu estou levando em consideração o dia 01 do mês, onde vou verificar as seguintes informações:
Quantidade de Tablespaces, espaço total da tablespace, espaço utilizado, espaço disponivel nos FileSystens e vou alimentar uma planilha excell mesmo com estas informações no primeiro dia. Digamos que fique assim:

Primeiro Dia

Ai iremos determinar de quanto em quanto tempo eu iremos captar novamente estas informações, eu vou utilizar como padrão 7 dias, então temos o 7º dia a informação abaixo:

Setimo Dia

Podemos perceber que houve um aumento de 100% de utilização, tanto na tablespace quanto nos FileSystens.
Agora vamos verificar no 14º dia:

Décimo Quarto Dia

Avaliando, identificamos que alem de um crescimento de 50% no espaço usado e nos FileSystem, houve a necessidade de crescer a Tablespace em 100%.

Com estas informações de apenas 3 verificações, já podemos montar algo para um período pequeno, mas é aconselhavel que se utilize um período maior para avaliar o crescimento e assim estimar um crescimento a longo prazo.
Bom, vamos ao ponto cruscial, que é a estimativa de crescimento em um período de 2 meses, contando de 7 em 7 dias conforme abaixo:

Estimativa de Crescimento Próximos 2 meses

Olhando a planilha de controle, podemos teóricamente antecipar que em um pouco mais de 56 dias o FileSystem “u03″ poderá estourar seu espaço total, assim poderemos solicitar a área de Storage que adicione mais um disco a este “FileSystem” e assim justificar a diretória qual da aquisição de mais um disco para o storage, iremos mostrar o levantamento realizado e a estimativa de crescimento.

Claro que isto é apenas uma explanação bem, mas bem básica de como planejar uma estimativa de crescimento, pois isto depende também de outros fatores, como espaço para BackUp, Archive, Clob, External Table, etc.. Esta demostração é de apenas inserção de linhas, apenas caracteres e números, mas é uma idéia de como começar um planejamento de “Estimativa de Crescimento”.

Bom, esta é a minha explanação sobre este assunto, ficarei muito grato se os amigos deixarem também suas idérias de como fazer isto e de outros fatores que devemos levar em consideração quando iniciar um projeto de crescimento.

Em um outro Posto, iremos falar de RAM, PGA e SGA…

Abraços.. Espero que tenham gostado..!!

Como dar Comprimido a um Gato

agosto 6th, 2009 por Regis Araujo

Salve Galera..

Lembrei que a um tempo atras eu li no blog do David um texto do Luis Fernando Verissimo “Um dia de Merda” (não achei o link no blog dele..).. Então resolvi postar tbm um outro Texto…!!

Espero que gostem..!!

Veja aqui um facílimo passo a passo de como dar remédio ao seu querido e amado bichano. Grrr.

1. Pegue o amável gatinho e coloque-o em seu braço esquerdo como se estivesse segurando um bebê. Posicione o dedo indicador e o polegar da mão esquerda em cada canto da boca do bichano, com cuidado para não ferir o bichinho. Pressione levemente para que ele abra a boca. Tão logo isto aconteça, coloque o comprimido em sua boca. Permita que o animalzinho feche a boca e engula a pílula.
2. Pegue a pílula do chão e o assustado gato atrás do sofá. Encaixe-o no seu braço esquerdo e repita o processo.
3. Apanhe o gato no quarto e jogue fora o comprimido encharcado.
4. Pegue um novo comprimido, coloque o gato em seu braço esquerdo e segure as patas traseiras com a sua mão esquerda. Force-o a abrir a boca e empurre o comprimido até a garganta com o indicador. Feche a sua boca imediatamente e conte até 10 antes de soltá-lo.
5. Apanhe o comprimido dentro do aquário e o gato de cima do guarda-roupa. Peça ajuda a um amigo.
6. Ajoelhe-se no chão com o gato preso firmemente entre os joelhos, segurando suas quatro patas. Ignore os grunhidos emitidos pelo querido bichano. Peça ao amigo que segure com força a cabeça dele enquanto você abre a boca. Coloque uma espátula de madeira o mais fundo que puder. Deixe o comprimido escorregar pela espátula e esfregue a garganta vigorosamente.
7. Apanhe o gato que está grudado no trilho da cortina e pegue outro comprimido. Lembre-se de comprar uma nova espátula e remendar a cortina. Cuidadosamente enrole o gato numa toalha de modo que apenas sua cabeça fique de fora. Peça para o amigo mantê-lo assim. Dissolva o comprimido em um pouco de água, abra a boca do gato com o auxílio de um lápis e despeje o líquido em sua boca.
8. Veja na bula do remédio se ele tem alguma contra-indicação para seres humanos. Beba um pouco de água para se acalmar. Faça um curativo no braço do amigo e limpe o sangue do tapete com água morna e sabão.
9. Busque o desgraçado do gato no vizinho. Pegue um novo comprimido. Bote o gato dentro do armário da cozinha e feche a porta, mantendo a cabeça do gato para o lado de fora. Abra a boca com o auxílio de uma colher de sobremesa. Jogue o comprimido para dentro da boca com o auxílio de um estilingue.
10. Vá até a garagem e apanhe uma chave de fenda para colocar a porta do armário no lugar. Coloque uma compressa fria nos arranhões do seu rosto e cheque quando tomou pela última vez a vacina antitetânica. Jogue a camiseta fora e apanhe outra em seu quarto.
11. Chame o corpo de bombeiros para apanhar o fdp do gato do outro lado da rua. Peça desculpas ao vizinho que se machucou tentando desviar-se do animal. Pegue o último comprimido do frasco.
12. Amarre as patas dianteiras nas traseiras com uma corda do varal e prenda o gato no pé da mesa de jantar. Coloque luvas de jardinagem. Abra a boca do gato com uma pequena chave inglesa. Coloque o comprimido seguido de um pedaço de filé mignon. Segure a cabeça dele na vertical e derrame meio copo d’água para ajudá-lo a engolir o comprimido.
13. Peça ao seu amigo para levá-lo ao pronto-socorro mais próximo. Sente-se tranqüilamente enquanto o médico sutura seus dedos e braços e remove partes do comprimido que ficaram encravadas no seu olho direito. Pare na primeira loja de móveis no caminho de casa e encomende uma nova mesa de jantar.
14. Procure um veterinário que faça atendimento a domicílio, pois a essa altura do campeonato você não tem mais condições físicas de ir até a clínica!

Abraços..!!

Minha Nova CPU

julho 29th, 2009 por Regis Araujo

Salve Galera..

Acabo de adquirir esta incrivel máquina….

MINHA NOVA CPU

Agora sim uma máquina potente…!!

Abraços..!!

Scripts Práticos - Oracle

julho 28th, 2009 por Regis Araujo

Salve Galera…

Ontem eu estava lendo o blog do Flavio Isidoro sobre indices e ele postou um script de rebuild que eu já utilizo aqui.. ai pensei que poderia também compartilhar os meus com o pessoal..
Então ta ai.. Estou postando 1 script de consulta SHARED_POOL das intâncias, porém só funciona para versões abaixo do 10g, já que no 10G esta “memória” é “auto-gerenciável” de acordo com sua SGA.. mas vamos la..

Ahh… estes scripts são todos para serem utilizados no SQL*PLUS..

Obs.: Lilian.. ta vendo.. eu falei que estava ultilizando na maioria das vezes o SQL*PLUS e não ferramentas gráficas.. huahauha..!!!

Script 1 - Consulta Shared Pool


COL TAMANHO_SHARED_POOL FORMAT 999,990.00 HEADING “TAMANHO_SHARED_POOL(MB)”
COL PERCENTAGEM_USADO_SHARED_POOL FORMAT 990.00 HEADING “%USADO”
COL USADO_SHARED_POOL FORMAT 999,990.00 HEADING “USADO_SHARED_POOL(MB)”
COL LIVRE_SHARED_POOL FORMAT 999,990.00 HEADING “LIVRE_SHARED_POOL(MB)”

set heading off
set feedback off

SET PAGESIZE 100 LINES 130 HEADING on FEED OFF NULL ” break on report ON contents SKIP 1

SELECT
MAX(B.VALUE)/(1024*1024) TAMANHO_SHARED_POOL,
SUM(A.BYTES)/(1024*1024) USADO_SHARED_POOL,
(MAX(B.VALUE)/(1024*1024)) - (SUM(A.BYTES)/(1024*1024)) LIVRE_SHARED_POOL,
((SUM(A.BYTES)/(1024*1024))/(MAX(B.VALUE)/(1024*1024)))*100 PERCENTAGEM_USADO_SHARED_POOL
FROM V$SGASTAT A, V$PARAMETER B
WHERE A.POOL= ’shared pool’
AND A.NAME NOT IN (’free memory’)
AND B.NAME=’shared_pool_size’
/

set heading on
set feedback on
PROMPT

No scrips acima, eu já pré-formatei algumas colunas, para melhorar a visualização dentro do Sql*Plus.. assim evitando que haja quebra de linhas quando eu rodar o script…

Script 2 - Rebuild de Indice para outra Tablespace

Obs2.: Houve um assunto no forum falando sobre a criação de tablespaces para cada “situação”, uma para dados, outra para indices, outra para tmp.. etc.. Bom.. eu sou adepto desta prática, criar uma tablespace para armazenar cada grupo de dados.. Pode ser por performance, mas eu prefiro por estética e melhor pratica de controle, pois assim consigo mensurar melhor a ultilização de uma determinada tablespace…


set heading off
set feedback off
set time off
set timing off
set lines 100
set pages 3000
spool C:\SCRIPTS\temp\Rebuild_indexes_tablespaces.sql
SELECT ‘alter index ‘|| a.owner ||’.'||a.index_name || ‘ rebuild tablespace TBS’||UPPER(TRIM(d.NAME))||’IND;’ FROM ALL_INDEXES a, v$database d
WHERE a.OWNER = ‘&OWNER’
AND TABLESPACE_NAME = ‘TBS’||UPPER(TRIM(d.NAME))||’DAT’
/
spool off
set heading on
set feedback on
set time on
set timing on
@C:\SCRIPTS\temp\Rebuild_indexes_tablespaces.sql

Neste script acima eu fiz para ter praticidade, eu costumo determinar o nome das tablespaces colocando TBS+INSTANCIA+GRUPO, ou seja.. TBSBANCODAT (tablespace de dados puros), TBSBANCOIND (Tablespace de Indices) e TBSBANCOTMP (tablespace Temporary).. por este motivo existe a concatenação com a view V$database..
Quando este script for executado, vc vai precisar apenas passar o OWNER que vc quer fazer o rebuild, não precisará editar o script para cada OWNER que vc for fazer..

Script 3 - Rebuild de Indice para ajustar tamanho de INITIAL e NEXT.


set heading off
set feedback off
set time off
set timing off
set lines 100
set pages 3000
spool C:\SCRIPTS\temp\Rebuild_indexes_storage_initial.sql
SELECT ‘ALTER INDEX ‘ || a.OWNER || ‘.’ || INDEX_NAME || ‘ REBUILD STORAGE (INITIAL 128K NEXT 128K);’ FROM ALL_INDEXES
WHERE OWNER = ‘&OWNER’
/
spool off
set heading on
set feedback on
set time on
set timing on
@C:\SCRIPTS\temp\Rebuild_indexes_storage_initial.sql

Bom, já peguei varios casos onde o indice é criado pelo desenvolvedor e por muitas vezes sem parametros de intial e next corretos.. indices com initial de 80MB e next de 48k.. então para ajustar isto, eu decidi adotar 128k para o initial e next de todos os indices.. Sei que existem indices que precisam ser reavaliados, mas 99% dos que utilizo eu padronizei com estes tamanhos por ser o mais adequado a situação deles… tenho indices também com 1mb de initial e 1mb de next.. mas depende de cada caso.. que deve ser muito bem analisado…

Script 4 - Analyze Tables…


set heading off
set feedback off
set time off
set timing off
set lines 100
set pages 3000
spool C:\SCRIPTS\temp\Analyze_Tables.sql
SELECT ‘ANALYZE TABLE ‘|| OWNER ||’.'||TABLE_NAME || ‘ COMPUTE STATISTICS FOR TABLE FOR ALL INDEXES FOR ALL INDEXED COLUMNS;’ FROM ALL_TABLES
WHERE NUM_ROWS IS NOT NULL
AND OWNER = ‘&OWNER’
/
spool off
set heading on
set feedback on
set time on
set timing on
@C:\SCRIPTS\temp\Analyze_Tables.sql

Este é um script de Analyze.. simples.. onde também vai solicitar qual o Owner que vc gostaria de fazer o Analyze..

MAIS 2 SCRIPTS QUE TENHO A CERTEZA QUE SERÃO DE BOM PROVEITO…

Script 5 - Move Tables para outra Tablespace…


set heading off
set feedback off
set time off
set timing off
set lines 100
set pages 3000
spool C:\SCRIPTS\temp\Move_Tables_tablespaces.sql
select 'ALTER TABLE '||owner||'."'||table_name||'" move tablespace ' || '&TABLESPACEDESTINO'|| ';' from dba_tables
WHERE owner = '&OWNER'
AND TABLESPACE_NAME = '&TABLESPACEORIGEM'
/
spool off
set heading on
set feedback on
set time on
set timing on
@C:\SCRIPTS\temp\Move_Tables_tablespaces.sql

O script de Move Table ao ser executado irá solicitar a Tablespace de Destino das tabelas, o Owner da tabela e a Tablespace de Origem das tabelas..

Script 6 - Move LOB para outra Tablespace…

set heading off
set feedback off
set time off
set timing off
set lines 100
set pages 3000
spool C:\SCRIPTS\temp\Move_Lob_tablespaces.sql

SELECT 'ALTER TABLE '|| OWNER ||'.'|| TABLE_NAME || ' MOVE LOB (' || COLUMN_NAME || ') store as (TABLESPACE &TABLESPACEDESTINO);'
from dba_tab_columns
WHERE owner='&OWNER'
and data_type like '%LOB'
/
spool off
set heading on
set feedback on
set time on
set timing on
@C:\SCRIPTS\temp\Move_Lob_tablespaces.sql

O script 6 é um complemento do Script 5, mas somente quando existem campos do tipo BLOB e CLOB, pois por muitas vezes temos types CLOB e BLOB que são referenciados a uma determinada Tablespace e ao mover as Tabelas, também temos que mover estes types..

Estes scripts podem ser adaptados conforme a necessidade de cada um..

Bom pessoal, é isto, conforme eu for precisando de mais scripts eu vou disponibilizando aqui para vocês… Espero que sejam uteis para vocês assim como estão sendo para mim…

Abraços….

PQ inventaram o Telefone??

julho 2nd, 2009 por Regis Araujo

Salve..

O que seria de nós sem o telefone? Como poderiamos conversar com pessoas que estão muito longe de nós? Por sinal de fumaça? Pombo correio? Carta? Telegrama? Bom, não sei realmente o que seria da raça humana sem a invenção do telefone. Hoje agradecemos muito ao “Alexander Graham Bell” pela invenção do telefone ou pelo roubo da invenção.. De acordo com o congresso dos EUA quem inventou o telefone foi o Italiano Antonio Meucci .. vai lá saber..

Mas imaginem a cena..

Domingo.. 23:40 minutos.. vc preparado para dormir.. de pijaminha.. tomando um leite com biscoitos.. e derrepente esta maravilhosa invenção toca.. Vc começa a se perguntar.. Quem será a esta hora da noite? Será que aconteceu algo com algum familiar? Ao atender a “maravilhosa invenção” ouve-se a frase: “Boa noite, é Fulano da Empresa você pode verificar se ta com algum problema o servidor X”?
Logo vc começa a perguntar o real motivo pelo qual esta “maravilhosa invenção” foi inventada..
Ligando a máquina.. acessando a VPN.. tentando conectar ao servidor via Putty.. mensagem “Lost Connection”.. Pingando servidor.. “Esgotado o tempo limite do pedido.”
Através do telefone questiona o funcionário.. “Fulano.. vê se tem alguma mensagem na tela do servidor” e a resposta..”Ahhh.. tem uma mensagem em inglês.. assim.. Linux Error: FileSystem A,B,C corrupted”.. coração já ta na boca.. outra pergunta.. “Ve no nágios as mensagens de erro e qual o tempo em DURATION”.. resposta..” Ah.. ta tudo vermelho.. o duration ta com 16 horas..” .. outra pergunta.. “Vc consegiu falar com mais alguem?”.. resposta..”Ninguem atendeu o telefone.. só vc.”..

Conclusão.. Servidor com HD´s corrompidos e muito trabalho noturno para restaurar as bases “perdidas” neste servidor…

Agora vcs entendem o pq inventaram o telefone.. para alguem te ligar em pleno domingo.. 23:40, falando de um problema na empresa.. que vc vai precisar arrumar pois as 6:00 da segunda-feira todo mundo começa a trabalhar…
Tenho certeza que o Graham Bell e o Meucci estão dando muita risada dentro de seus túmulos…

Quem nunca passou por esta situação.. que atire o primeiro HD…

Abraços…