Blog criado para ajudar profissionais a resolver problemas diversos com Banco de dados
terça-feira, 14 de julho de 2009
Que tipo de DBA é você?
Bom eu sou o DBA "moda foka"!
É meio que uma expressão minha. Mas não sabia que alguém havia criado classes de DBA´s.
Sou obrigado a concordar com o que o Rodrigo passou sobre esta função.
Gostaria apenas de defender um pouco mais "Tipo que sou de DBA".
Ao ler o artigo. Defino-me como DBA Google.
Pelo simples fato que falta experiência para me denominar outro tipo de DBA.
Trabalho em uma empresa de Consultoria em TI e provavelmente com muito estudo me tornarei um DBA de infra ou de projetos, logicamente se eu quiser seguir estes passos.
Acho que poderia ter uma classe para DBA´s com pouca experiência.
Achei muito interessante este artigo segue abaixo o link para que vocês possam ler e tirar suas conclusões.
Artigo Rodrigo Almeida
quinta-feira, 9 de julho de 2009
Gerenciando Objetos de Usuários II
Dia 4/06/2009 postei alguns scripts para gerenciar objetos de usuários.
Como mover de uma tablespace para outra etc...
Existia uma duvida em minha cabeça.
Será que o oracle 10G ainda não havia um modo de mover os campos LOB para outro local sem ser pelo famoso EXPDP?
Bom Pesquisando um pouco no metalink e no santo google da vida encontrei alguns procedimentos bem úteis.
Porem fiquei com a impressão de que não seria fácil.
No metalink eu encontrei o Doc ID: 386341.1, ele tem vários passos para efetuar a manutenção destes objetos.
Porem se você é contratado por uma empresa e você nunca nem olhou para os objetos daquela empresa você vai ficar na mão quanto a descobrir informações sobre o LOBSEGMENT.
então vou postar aqui alguns "passos" a mais que para quem não conhece a estrutura das tabelas possa se virar.
Este Select lhe mostrará quais os segmentos de lob estão na tablespace.
SELECT OWNER,SEGMENT_NAME,
SEGMENT_TYPE,TABLESPACE_NAME,BYTES/1024/1024
from dba_segments
where SEGMENT_TYPE='LOBSEGMENT'
and TABLESPACE_NAME='<>';
Pegando o nome do segmento vc inclui no select abaixo para descobrir qual tabela e qual coluna tem o campo lob.
SELECT TABLE_NAME,COLUMN_NAME,
SEGMENT_NAME,INDEX_NAME
FROM DBA_LOBS
WHERE SEGMENT_NAME='<>';
Após receber os dados deste dois select é só você alterar a tabela com o campo lob.
ALTER TABLE <>
MOVE LOB( <>) STORE AS (
TABLESPACE <> )
/
exemplo.
SQL> CREATE TABLE LANA_LOB (
id NUMBER
, xml_file CLOB
, image BLOB
);
Tabela criada.
SQL> select OWNER,SEGMENT_NAME,SEGMENT_TYPE,
TABLESPACE_NAME,BYTES/1024/1024
from dba_segments
where SEGMENT_TYPE='LOBSEGMENT'
and TABLESPACE_NAME='LANA';
OWNER SEGMENT_NAME SEGMENT_TYPE TABLESPACE_NAME BYTES/1024/1024
------------- ---------------------------- ------------------ ------------------ ----------------
LANA SYS_LOB0000016287C00003$$ LOBSEGMENT LANA ,0625
LANA SYS_LOB0000016287C00002$$ LOBSEGMENT LANA ,0625
LANA SYS_LOB0000016282C00003$$ LOBSEGMENT LANA ,0625
LANA SYS_LOB0000016282C00002$$ LOBSEGMENT LANA ,0625
SQL> SELECT TABLE_NAME,COLUMN_NAME,
SEGMENT_NAME,INDEX_NAME
FROM DBA_LOBS
WHERE SEGMENT_NAME='SYS_LOB0000016287C00003$$';
TABLE_NAME COLUMN_NAME SEGMENT_NAME INDEX_NAME
------------- -------------- ------------------------------ ------------------------------
LANA_LOB IMAGE SYS_LOB0000016287C00003$$ SYS_IL0000016287C00003$$
SQL> CREATE TABLESPACE LANA_LOB
DATAFILE '/u01/app/oracle/oradata/lana/lana_LOB.DBF'
size 50m autoextend on next 50m maxsize 500m;
Tablespace criado.
SQL> ALTER TABLE LANA_LOB
MOVE LOB(image) STORE AS (
TABLESPACE LANA_LOB )
/
Tabela alterada.
SQL> select OWNER,SEGMENT_NAME,SEGMENT_TYPE,
TABLESPACE_NAME,BYTES/1024/1024
from dba_segments
where SEGMENT_TYPE='LOBSEGMENT'
and TABLESPACE_NAME='LANA';
OWNER SEGMENT_NAME SEGMENT_TYPE TABLESPACE_NAME BYTES/1024/1024
--------- ----------------------------- ------------------ ------------------ ---------------
LANA SYS_LOB0000016287C00002$$ LOBSEGMENT LANA ,0625
LANA SYS_LOB0000016282C00003$$ LOBSEGMENT LANA ,0625
LANA SYS_LOB0000016282C00002$$ LOBSEGMENT LANA ,0625
SQL> select OWNER,SEGMENT_NAME,SEGMENT_TYPE,
TABLESPACE_NAME,BYTES/1024/1024
from dba_segments
where SEGMENT_TYPE='LOBSEGMENT'
and TABLESPACE_NAME='LANA_LOB';
OWNER SEGMENT_NAME SEGMENT_TYPE TABLESPACE_NAME BYTES/1024/1024
---------- ----------------------------- ------------------ ------------------ ----------------
LANA SYS_LOB0000016287C00003$$ LOBSEGMENT LANA_LOB ,0625
SQL>
sexta-feira, 3 de julho de 2009
Ausência
Não vou dizer que foi fácil, pois nas dez primeiras questões eu fiquei com vontade de pegar o rascunho que a

atendente da prometric entrega, levantar e sair da sala. Nem mesmo vou dizer que foi tranquila devido ao atraso de trinta minutos para iniciar a minha prova, pois ocorreu um problema no computador do teste e quase fui impossibilitado de fazer a prova.
Mas enfim após dois anos me envolvendo com a tecnologia da Oracle consigo o Certificado Profissional da área. Como dizem os meus colegas de trabalho agora só falta aprender Oracle. ;)
terça-feira, 16 de junho de 2009
Movendo Datafiles
Não não. você apenas irá colocar a tablespace em offline para poder mover os datafiles.
Segue abaixo ospassos corretos.
Primeiro você passa a Tablespace para modo offline
SQL> alter tablespace TABLESPACE offline;
Segundo você copia/mover o datafile para o novo local.
Terceiro você efetua o processo de rename
SQL> alter database rename file 'CAMINHO_ANTIGO' TO 'CAMINHO_NOVO';
Opcional: Eu costumo a copiar o datafile para o novo local e o datafile antigo eu renomeio ele para "_old" ou como vocês preferirem. caso o prcesso execute com algum erro o tempo de recuperação eh mais rapido.
Quarto passo é colocar novamente a tablespace em on line.
SQL> alter tablespace TABLESPACE online;
Procedimento concluido.
[]´s
sábado, 13 de junho de 2009
Restaurando Tablespace Temporario
Os tablespaces temporarios juntamente com seus arquivos de dados não podem ser incuidos no backup, pois não há como colocar estes arquivos de dados em BEGIN BACKUP devido a estes dados não serem importantes para um banco de dados.
Então como faremos para recuperar esta tablespace ou algum tempfile desta tablespace?
A resposta é oviamente facil se analizarmos que os datafiles temp não contem dados propriamente dito.
Esta tablespace serve exclusivamente para armazenar dados temporarios cuja desaparecerão quando a sessão que o utilizou desconectar.
Como eu utilizo esta tablespace?
Bom isto esta implicito no banco. Você utilizará esta tablespace quando for fazer alguma ordenação (ORDER BY) em sua query em que seja muito grande para a memória poder ordenar, neste caso você utilizará a tablespace temporaria para efetuar a ordenação.
Ou então se você criar uma tabela "global temporary" esta tabela é utilizada para armazenar dados temporarios de uma seção, infelizmente este recurso é muito pouco utilizado aqui no Brasil, pois os programadores insistem em criar tabelas normais para fazer este serviço gerando assim redo e undo.
Bom não vamos fujir do assunto.
Depois de toda esta ladainha da importancia da temp vem a pergunta.
Como recupero a temp se nem backup eu posso fazer dela?
Na verdade você não recupera a temp, você recria ela. Abaixo vou postar os passos para efetuar este processo.
1 Adicione um tempfile ao tablespace temporario com problema.
SQL> alter tablespace temp add tempfile ' CAMINHO ' size 200m;
2 Retire o tempfile danificado do ar.
SQL> alter tablespace tempfile ' CAMINHO ' offline;
3 Exclua o arquivo danificado.
SQL> alter tablespace tempfile ' CAMINHO ' drop;
Você também poderá efetuar estes procedimentos incluindo uma nova tablespace temporaria.
Neste caso você deve lembrar de transformar a nova temporary tablespace como padrão do oracle caso a danificada seja.
1 Crie um novo tablespace
SQL> create temporary tablespace temp1 tempfile ' CAMINHO ' size 200m;
2 Altere esta tablespace para ser a default do banco.
SQL> alter database default temporary tablespace temp1;
3 Eclua a tablespace danificada.
SQL> drop tablespace temp including contents and datafile;
Resolvido.
Lembrando que um usuário comun de seu ambiente não irá perceber problemas no banco de imediato mas você deverá perceber e corrigir o mesmo afim de não causar problemas maiores.
[]'s
segunda-feira, 8 de junho de 2009
WHO_IS_USING
Digamos que você queira recompilar algum objeto, mas quando vc faz isto o banco trava sua seção.
Obviamente o objeto esta sendo utilizado.
Então você utiliza esta procedure com o comando abaixo.
SQL> exec who_is_using('NOME_DO_OBJETO');
(140) - TS
PL/SQL procedure successfully completed
Onde 140 é o sid da sessão.
Simples rapido e rasteiro.
para você instalar o who_is_using vc precisa instalar ele no seu banco, e abaixo vão os passos.
-- conectar com senha de sys
conn / as sysdba
-- e rodar o codigo wrap da procedure!
prompt The following procedure MUST be created in the SYS schema.
create or replace procedure who_is_using wrapped
0
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
7
200f000
1
4
0
1e
c WHO_IS_USING:
8 OBJ_NAME:
8 VARCHAR2:
b DBMS_OUTPUT:
6 ENABLE:
7 1000000:
1 I:
1 B:
8 USERNAME:
3 SID:
3 SYS:
7 X$KGLPN:
1 A:
9 V$SESSION:
7 X$KGLOB:
1 C:
8 KGLPNUSE:
1 =:
5 SADDR:
5 UPPER:
8 KGLNAOBJ:
4 LIKE:
8 KGLPNHDL:
8 KGLHDADR:
4 LOOP:
8 PUT_LINE:
1 (:
2 ||:
7 TO_CHAR:
4 ) - :
0
0
0
74
2
0 1d 9a 8f a0 b0 3d b4
55 6a :2 a0 6b 51 a5 57 91
:2 a0 6b :2 a0 6b ac :2 a0 6b a0
b9 :2 a0 b9 :2 a0 6b a0 b9 b2
ee :2 a0 6b a0 7e a0 6b b4
2e :3 a0 6b a5 b 7e :2 a0 a5
b b4 2e a 10 :2 a0 6b a0
7e a0 6b b4 2e a 10 ac
d0 e5 e9 37 :3 a0 6b 6e 7e
:3 a0 6b a5 b b4 2e 7e 6e
b4 2e 7e :2 a0 6b b4 2e a5
57 b7 a0 47 b7 a4 b1 11
68 4f 17 b5
74
2
0 3 4 19 15 14 20 13
25 29 2d 31 35 38 3b 3c
41 45 49 4d 50 54 58 5b
5c 60 64 67 11 6b 6f 73
75 79 7d 80 84 86 87 8e
92 96 99 9d a0 a4 a7 a8
ad b1 b5 b9 bc bd bf c2
c6 ca cb cd ce 1 d3 d8
dc e0 e3 e7 ea ee f1 f2
1 f7 fc fd 101 106 10b 10d
111 115 119 11c 120 123 127 12b
12f 132 133 135 136 13b 13e 142
143 148 14b 14f 153 156 157 15c
15d 162 164 168 16f 171 175 177
182 186 188 18f
74
2
0 1 b 18 21 :2 18 17 :2 1
2 :2 e 15 :2 2 6 1c :2 1e 27
:2 29 1c 11 15 11 1d 11 1f
29 1f 2b 2f 2b 37 2b c
11 12 :2 14 1f 1d :2 21 :2 1d 12
18 :2 1a :3 12 2a 30 :2 2a :5 12 :2 14
1f 1d :2 21 :2 1d :2 12 :4 c 2 2b
3 :2 f 18 1b 1d 25 :2 27 :2 1d
:2 18 2b 2d :2 18 33 35 :2 37 :2 18
:2 3 2b 6 2 :8 1
74
2
0 :9 1 :6 3 :8 4 :f 5 :9 6 :d 7 :2 6
:9 8 :2 6 5 :4 4 8 :19 9 8 a
4 :2 2 :6 1
191
2
:4 0 1 :a 0 70 1 1a 1b 5
:2 3 :3 0 2 :6 0 5 4 :3 0 7
:2 0 70 2 8 :2 0 4 :3 0 5
:3 0 a b 0 6 :2 0 7 c
e :2 0 6c 7 :3 0 8 :3 0 9
:3 0 11 12 0 8 :3 0 a :3 0
14 15 0 9 b :3 0 c :3 0
18 19 0 d :3 0 e :3 0 8
:3 0 1d 1e b :3 0 f :3 0 20
21 0 10 :3 0 22 23 c 25
49 0 4a :3 0 d :3 0 11 :3 0
27 28 0 8 :3 0 12 :2 0 13
:3 0 2a 2c 0 12 2b 2e :3 0
14 :3 0 10 :3 0 15 :3 0 31 32
0 10 30 34 16 :2 0 14 :3 0
2 :3 0 15 37 39 17 36 3b
:3 0 2f 3d 3c :2 0 d :3 0 17
:3 0 3f 40 0 10 :3 0 12 :2 0
18 :3 0 42 44 0 1c 43 46
:3 0 3e 48 47 :3 0 2 17 26
0 4b :5 0 4c :2 0 4e 10 4d
19 :3 0 4 :3 0 1a :3 0 50 51
0 1b :3 0 1c :2 0 1d :3 0 7
:3 0 a :3 0 56 57 0 1a 55
59 1f 54 5b :3 0 1c :2 0 1e
:3 0 22 5d 5f :3 0 1c :2 0 7
:3 0 9 :3 0 62 63 0 25 61
65 :3 0 28 52 67 :2 0 69 2a
6b 19 :3 0 4e 69 :4 0 6c 2c
6f :3 0 6f 0 6f 6e 6c 6d
:6 0 70 0 2 8 6f 72 :2 0
1 70 73 :6 0
2f
2
:3 0 1 3 1 6 1 d 2
13 16 3 1c 1f 24 1 33
2 29 2d 1 38 2 35 3a
1 58 2 41 45 2 53 5a
2 5c 5e 2 60 64 1 66
1 68 2 f 6b
1
4
0
72
0
1
14
2
3
0 1 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0
2 0 1
3 1 0
10 2 0
0
/
Prontinho você já instalou a procedure agora é soh testar.
quinta-feira, 4 de junho de 2009
Gerenciando Objetos de Usuários
Varias vezes eu detectei em muitos clientes owners gravando seus objetos em varios tablespaces.
Isto alem de desorganizado degride a performance do banco, pois como você poderá criar metricas de I/O sendo que você não sabe onde seus dados estão gravando?
Então para você reorganizar novamente e colocar os objetos nos locais devidos abaixo vai uma solução bem simples para você transferir os dados necessários de uma tablespace para outra.
OBS: Para indicces com lob segments aconselho a usar export Datapump!
Com este select você descobre o que esta sendo gravado na tablespace!
select owner,segment_type,segment_name,bytes from dba_segments where tablespace_NAME = 'TABLESPACE_NAME' ORDER BY BYTES;
Você pode efetuar o mesmo select com varias outras clausulas where que poderão lhe auxiliar EX:
select owner,tablespace_name,segment_type,segment_name,bytes from dba_segments where owner like '%OWNER%' ORDER BY BYTES;
Para Mover os indices
select 'alter index ' || owner || '.' || segment_name || ' rebuild tablespace TABLESPACE_NOVA;'
from dba_segments where owner = 'USER' and tablespace_name = 'TABLESPACE_ANTIGA';
Para Mover as tabelas
select 'alter table ' || owner || '.' || segment_name || ' move tablespace TABLESPACE_NOVA'
from dba_segments where owner = 'USER' and tablespace_name = 'TABLESPACE_ANTIGA';
Para Mudar a tablespace padrão do Owner
alter user USUARIO default tablespace TABLESPACE NOVA
Pronto Manutenção efetuada.
Lembrando que poderão ocorrer erros em indices e tabelas que estão sendo utilizadas então recomendo a fazer este processo com o minimo de conexões o possivel no banco.
Este processo irá gerar archives caso seu banco esteja em ARCHIVELOG, caso a manutenção seja muito grande desabilite esta opção.
quarta-feira, 3 de junho de 2009
Lendo arquivos em Memória
Digamos que você esteja enfrentando problemas de espaço em disco, você tem míseros 10G de espaço livre sobrando e por sorte seu arquivo DUMP compactado ficou com pouco abaixo disto vamos suport 9G de dump o que não é considerado um arquivo grande para este tipo de situação.
Como iremos importar a base de dados? Bom vamos lhe apresentar o comando mknod no Linux.
Est comano cria um arquivo especial no linux.
Primeiro você precisa criar um arquivo para ser o apontamento da memória.
# mknod pipe1 p
Depois você precisa descompactar o arquivo e aqui é que entra a grande mágica deste post.
# gunzip < arquivocompactado.dmp.gz > pipe1 &
Este comando irá descompactar o arquivo para dentro do arquivo pipe1, porem se você listar o arquivo ele estará vazio.
OBS: você não poderá tentar editar o arquivo, caso você faça isto você terá de refazer todos estes passos novamente.
Após isto você deverá efetuar o processo de import.
Imp user/senha@banco file=pipe1 log=import.log parâmetros...
Basicamente o que fizemos foi colocar o arquivo de dump para descompactar em memória sendo assim ele vai ser descompactado no arquivo pipe1 conforme o import vai precisando, e com isso o mesmo não ocupa espaço em disco.
Um teste que eu acabei não realizando seria a questão de performance dos imports.
Ai vai minha dica. ;)
terça-feira, 2 de junho de 2009
Pegar DDL de objetos
Simples conheça o "dbms_metadata.get_ddl"
Muito simples de usar
select dbms_metadata.get_ddl('TIPO_OBJETO','NOME_OBJETO','USER') from dual;
Utilize spool para salver o memso em disco.
"set heading off;
set echo off;
Set pages 999;
set long 90000;
spool ddl_list.sql
select dbms_metadata.get_ddl('TABLE','DEPT','SCOTT') from dual;"
Ou então se mate com a dba_source ;)
quinta-feira, 28 de maio de 2009
EXP-00008: ORACLE error 6550 encountered
ORA-06550: line 1, column 18:
ORA-06550: line 1, column 7:
ORA-06512: at SYS.DBMS_SYS_SQL, line 1204
ORA-06512: at SYS.DBMS_SQL, line 323
ORA-06512: at SYS.DBMS_EXPORT_EXTENSION, line 97
ORA-06512: at SYS.DBMS_EXPORT_EXTENSION, line 126
Este erro pode ocorrer em varios casos, os que eu conheço são.
Nova instalação
Upgrade de versão para 10.2.0.4
Normalmente este erro ocorre apenas no backup full e no oracle 10.2.0.4, pois o oracle 10.2.0.4 existem algumas permisões de seguranças a mais que o 10.2.0.3.
Erro facilmente resolvido com apenas doid grants.
GRANT EXECUTE ON SYS.DBMS_DEFER_IMPORT_INTERNAL TO OWNER;
GRANT EXECUTE ON SYS.DBMS_EXPORT_EXTENSION TO OWNER;
Este erro esta referenciado no Note: 464672.1