MigraTI - Soluções em banco de dados

terça-feira, 16 de junho de 2009

Movendo Datafiles

Muitas vezes, você precisará mover algum datafile menos importante de seu ambiente para algum filesystem com mais expaço em disco. Porem a pergunta, preciso parar o banco inteiro para efetuar este processo?
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

Bom dia.

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

Este. é uma excelente procedure criada pela própria Oracle para descobrir quem esta utilizando o objeto no momento.

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

Quem trabalha a tempo com bancos sabe que este é um problema constante em base de dados onde não há nenhum DBA constantemente efetuando manutenções.

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

Esta dica é bem útil para efetuar export/import de um banco de dados.

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

Precisa pegar ddl de alguns objetos de seu banco?

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 ;)