4 de abr. de 2013

Muito boa noite a todos!!

Hoje vou compartilhar com vocês mais um problema que passei, e realmente fiquei preocupado até achar a solução. Foi algo muito interessante e acho que muitos já devem ter passado por problemas parecidos (ao menos em nível de stress).

A história é mais ou menos a seguinte...

Estou realizando um trabalho de padronização de TABLESPACES em todas as bases de dados Oracle da organização onde trabalho. Esse trabalho consiste basicamente em criar as “N” tablespaces, divididas por tamanhos de extents distintos, como por exemplo: TBS50MB, TBS100MB, TBS500MB, etc.

Para alocar as tabelas e índices em uma tablespaces compatível com o tamanho do objeto, foi realizado um cálculo (que não vem ao caso) para que a tabela “residisse” em uma tablespace compatível com seu tamanho. Essa alteração é importante para muitas coisas, inclusive para facilitar o gerenciamento e melhorar performance dos scripts contra esses objetos.

O procedimento que estava realizando, e ainda estou pois são muitas bases, era o seguinte:

        1- Criação das tablespaces “corretas”;
        2- Realização da movimentação das tabelas e índices das tablespaces “antigas” para as novas através dos scripts abaixo:
a.     ALTER TABLE OWNER.TBL_TABELA MOVE TABLESPACE TBS50MB;
b.    ALTER INDEX IDX_TBL_01 REBUILD TABLESPACE TBS50MB;
        3- Após mover todos os objetos da tablespace, realizava o drop da tablespace antiga com o comando:
a.       DROP TABLESPACE TBSOLD INCLUDING CONTENTS AND DATAFILES;
        4- Depois de dropar a tablespace, acessava o servidor da base em questão e realizava a exclusão física do datafile (pois às vezes não eram excluídos pelo comando acima) e às vezes tinha que “derrubar” e iniciar a instância para conseguir excluir o datafile. Fazia isso para liberar espaço em disco gasto desnecessariamente, uma vez que os datafiles não seriam mais utilizados.

Basicamente foi isso que estava fazendo (mas pode acreditar, não é tão simples quanto parece).

Foi então que em uma das execuções, acabei interrompendo o trabalho para fazer alguma outra coisa, e quando retornei para essa atividade, executei o descrito no passo 4 antes do passo 3, ou seja, excluí o datafile antigo (e vazio) fisicamente antes de dropar a tablespace. Resultado, quando tentei “levantar” a instância, não consegui, pois quanto realizei o startup, foi solicitado o datafile excluído acidentalmente.

Na hora que dei conta de que tinha feito uma besteira, fui logo verificar como estava o backup, pois seria o pior dos casos realizar o recovery da base. Obviamente comecei essa tarefa de padronização das tablespaces pelas bases de teste e desenvolvimento, o que me fez respirar mais tranquilo para manter a “estabilidade emocional” (hehe).

Conversei com um colega também DBA sobre o que tinha acontecido e começamos a ver as possibilidades de solução que tínhamos para a situação. Procurei na internet sobre o assunto, foi então que encontrei, em um blog, um artigo com a seguinte chamada: How Drop Tablespace and Recover Oracle Database When Accidentally Delete Datafile.

Pessoal, isso foi um “achado”! (hehehe)

O autor expos uma situação muito parecida com a que vivi e descrevi acima, e a solução que ele apresentou foi mais ou menos a seguinte:

       1- Conectar no SQL*Plus como SYSDBA
a.       SQLPLUS /NOLOG
b.      CONNECT / AS SYSDBA
       2- O banco de dados deve estar no estado mount para conseguirmos executar o comando, então montemos o banco:
a.       STARTUP MOUNT;
        3- Em seguida, o comando que tornará o datafile off-line, e nos permitirá iniciar a instância (abrir o banco):
a.       ALTER DATABASE DATAFILE ' /opt/oracle/oradata/workspace/TBSOLD01.dbf' OFFLINE DROP;
        4- Agora vamos abrir o banco:
a.       ALTER DATABASE OPEN;
        5- Agora sim! Com a instância iniciada pude finalmente eliminar a tablespace do banco com o comando:
a.       DROP TABLESPACE TBSOLD INCLUDING CONTENTS AND DATAFILES;

É isso aí pessoal!

Realmente foi um susto o que ocorreu, um problema que pode acontecer com qualquer um (ou não... hehehe), mas felizmente foi tudo resolvido de forma tranquila.

Foi um ótimo aprendizado mas espero que vocês não passem por isso, porém caso ocorra, já sabem com solucionar, ok?!?!

Por hoje é só e até a próxima!

Referência:

MY DIGITAL LIFE - How Drop Tablespace and Recover Oracle Database When Accidentally Delete Datafile. Disponível em: http://www.mydigitallife.info/how-drop-tablespace-and-recover-oracle-database-when-accidentally-delete-datafile/. Acessado em: 04/04/2013.

Raphael Fernandes, quinta-feira, abril 04, 2013

1 comentário

2 de abr. de 2013


Olá a todos!

Hoje vou falar sobre particionamento de tabelas e índices no banco de dados Oracle, mas precisamente sobre uma situação que passei recentemente no trabalho.

Para entender a situação que passei, é necessário um conhecimento básico sobre particionamento de tabelas e índices no banco de dados Oracle. Particionamento é alvo de muitos artigos e documentos oficiais da Oracle, portanto não quero entrar nesse mérito, mas recomendo a leitura de Borovina e Legatti que explicam de forma clara e objetiva as definições e conceitos envolvidos. Também tem uma vasta documentação da Oracle disponível em vários artigos, um deles fala sobre: Particionamento no Banco de Dados Oracle 11g. Os links para esses artigos são citados nas referências desse post.

Agora vou apresentar de fato a situação que vivi:

Em uma instância Oracle 10g (na versão 10.2.0.3) tenho uma tabela particionada por lista.

A estrutura da tabela é mais ou menos a seguinte:

CREATE TABLE TBL_TABELA
(
COD NUMBER(9) NOT NULL,
CADASTRO NUMBER(9) NOT NULL,
MES NUMBER(2),
ANO NUMBER(4)
)
TABLESPACE TBS_DEFAULT

PARTITION BY LIST (ANO)
(
PARTITION P_2008 VALUES (2008) TABLESPACE TBS_P_2008,
PARTITION P_2009 VALUES (2009) TABLESPACE TBS_P_2009,
PARTITION P_2010 VALUES (2010) TABLESPACE TBS_P_2010,
PARTITION P_2011 VALUES (2011) TABLESPACE TBS_P_2011,
PARTITION P_DEFAULT VALUES (DEFAULT) TABLESPACE TBS_DEFAULT
);

Meu problema é que os dados dos anos diferentes de 2008,2009,2010 e 2011 cairão, obviamente, na partição default.

O que tenho que fazer, é criar partições para os anos de 2012 e 2013, porém a presença da partição DEFAULT me impede de fazer isso.

É importante saber que a partição default está com muitos dados (2012 e 2013) e não posso simplesmente dropar ela.

Essa era a minha situação problemática, que inclusive tentei ajuda no fórum de Rodrigo Almeida.

No início dessa semana, pesquisando sobre o assunto, achei uma técnica interessante para resolver o assunto.

Para inserir uma nova partição, com a presença de uma partição default, inicialmente criei as tablespaces para os anos de 2012 e 2013, conforme exemplo abaixo:

CREATE TABLESPACE TBS_2012 DATAFILE
  '/opt/oracle/oradata/workspace/tbs_2012.dbf' SIZE 2048M AUTOEXTEND OFF
NOLOGGING
ONLINE
EXTENT MANAGEMENT LOCAL UNIFORM SIZE 100M
BLOCKSIZE 8K
SEGMENT SPACE MANAGEMENT AUTO
FLASHBACK ON;

Em seguida utilizei o comando SPLIT PARTITION para realizer a divisão de uma partição, esse é o ponto crucial da solução do problema.

A sintaxe que utilizei foi mais ou menos a seguinte (para o ano de 2012):

ALTER TABLE TBL_TABELA
   SPLIT PARTITION P_DEFAULT  VALUES (2012)
   INTO  ( PARTITION P_2012 TABLESPACE    TBS_2012,PARTITION P_DEFAULT);


O resultado após a execução desse comando é uma partição P_2012 (que estará na tablespace TBS_2012) contendo os dados da tabela do ano de 2012 e os dados dos outros anos ficarão na partição P_DEFAULT (exceto para os anos que existem partições referentes), no meu caso apenas os dados de 2013.

Depois fiz a mesma coisa para a partição do ano de 2013, e pronto. Resolvida a situação!

Bom pessoal, por enquanto é isso.

Grande abraço e até a próxima!

Referências:

LEGATTI, EDUARDO - Oracle Blog - Um pouco sobre índices particionados no Oracle. Disponível em: http://eduardolegatti.blogspot.com.br/2011/12/um-pouco-sobre-indices-particionados-no.html. Acessado em: 02/04/2013.

BOROVINA, JOÃO MARCELO - Particionamento de Dados: Uma introdução aos conceitos e aplicação. Disponível em: http://www.devmedia.com.br/particionamento-de-dados-uma-introducao-aos-conceitos-e-aplicacao/7299. Acessado em 02/04/2013.

ALMEIDA, RODRIGO - Fórum: Problema com tabela particionada no Oracle 10g. Disponível em: http://www.rodrigoalmeida.net/forum/viewtopic.php?f=3&t=891&sid=2642261a63b71d2453109f92000e0a96 Acessado em: 01/04/2013.

Oracle Corporation - Particionamento no Banco de Dados Oracle 11g -Um artigo técnico da Oracle. Junho de 2007. Disponível em: http://www.oracle.com/technetwork/pt/database/enterprise-edition/documentation/particionamento-banco-de-dados-11g-432098-ptb.pdf. Acessado em: 31/03/2013.

Oracle Corporation - Maintaining Partitions. Disponível em: http://docs.oracle.com/cd/E11882_01/server.112/e25523/part_admin002.htm. Acessado em: 01/04/2013.

Raphael Fernandes, terça-feira, abril 02, 2013

Sem comentários

1 de abr. de 2013


Bom dia a todos!

Ontem estava lendo umas notícias, quando me deparei com uma que foge um pouco o assunto de banco de dados, mas é interessante por se tratar de tecnologia.

A notícia foi publicada 23/02/2013, e fala sobre ataques cibernéticos diante da “vulnerabilidade” da tecnologia JAVA. Na reportagem fala da ocorrências de ataques em empresas bastante conhecidas tais como: Apple, Facebook e Twitter; e que os criminosos que tentam invadir sistemas focaram na linguagem Java pois julgam que atualmente possui pontos de ataque mais fáceis.

A Oracle, que é a proprietária da linguagem Java (após a aquisição da Sun Microsystems) desde o ano de 2010, vem corrigindo os furos na linguagem, mas assim que as falhas são reparadas, novas são expostas, segundo a reportagem.

Confiram a matéria completa no site: http://www.advivo.com.br/blog/luisnassif/ataques-ciberneticos-expoem-oracle

É uma matéria interessante!

Fica a dica, e até a próxima!

Raphael Fernandes, segunda-feira, abril 01, 2013

Sem comentários

25 de mar. de 2013

Olá pessoal!

Tive uma semana conturbada e não deu para postar nada, mas comecei a escrever algo e terminei há pouco.

Bom...

Hoje vou falar sobre duas funções de linha simples: round e trunc.

Só relembrando as primeiras aulas de banco de dados da faculdade, funções de linha simples são as que operam com uma linha de conjunto de dados por vez. Se uma instrução SQL seleciona 20 linhas (registros), a função será executada 20 vezes, uma para cada linha.

As funções round e trunc podem ser usadas em campos do tipo numérico e data, mas minha abordagem será apenas sobre número.

A função ROUND
Essa função realiza uma operação de arredondamento de um valor com base em uma precisão especificada.

A sintaxe da função ROUND pode ser observada na Figura 1.

Figura 1 - Sintaxe da função ROUND. (Fonte: Oracle Corporation)

O grau de arredondamento ou precisão é opcional e caso exista, deve ser um valor decimal, e para o caso desse valor ser “n”, onde n > 0, o dígito significante ao arredondamento é encontrado (n+1) do lado direito do ponto decimal, ou seja:
SELECT ROUND (1.259, 2) valor FROM DUAL;

A precisão é igual a 2 nesse exemplo, portanto o dígito de arredondamento nesse caso será o de posição 2 após (lado direito) o ponto, nesse caso o valor “5”.

Para o caso do valor da precisão ser um número negativo, o dígito significante ao arredondamento é “n” colocado do lado esquerdo do ponto:
SELECT ROUND (136.479, -1) valor FROM DUAL;

Nesse caso a precisão é -1, então o arredondamento será feito no primeiro dígito após o ponto decimal, nesse caso o valor “6”.

Se o valor numérico do dígito significante for maior ou igual a 5, um arredondamento para cima ocorrerá, caso contrário será um arredondamento para baixo. Se não for informada a precisão de arredondamento para a função round, o grau padrão de arredondamento é zero, significando que a origem será arredondada para o número inteiro mais próximo (lado esquerdo do ponto decimal).

Vou dar uns exemplos para facilitar o entendimento:

SELECT ROUND (1652.479, 2) AS valor FROM DUAL
UNION ALL
SELECT ROUND (1652.479, 1) AS valor FROM DUAL
UNION ALL
SELECT ROUND (1652.479) AS valor FROM DUAL
UNION ALL
SELECT ROUND (1652.479, -1) AS valor FROM DUAL
UNION ALL
SELECT ROUND (1652.479, -2) AS valor FROM DUAL;

O resultado para as consultas do exemplo pode ser conferido na Figura 2.

Figura 2 - Resultado de consultas utilizando o comando round. (Fonte: autoria própria)

A função TRUNC
A função trunc realiza uma operação de truncamento em um valor numérico com base em uma precisão decimal especificada, que assim como a função round, é opcional. A diferença entre as funções round e trunc é que a segunda função “quebra” o resultado na precisão decimal especificada e não tenta arredondar para cima ou para baixo.

A sintaxe do comando trunc pode ser configurada na Figura 3.

Figura 3 - Sintaxe da função TRUNC. (Fonte: Oracle Corporation)

Como os conceitos entre as funções round e trunc são bem parecidos, vou partir para exemplos do comando TRUNC para facilitar o entendimento:

SELECT TRUNC (1652.479123, 3) AS valor FROM DUAL
UNION ALL
SELECT TRUNC (1652.479123, 2) AS valor FROM DUAL
UNION ALL
SELECT TRUNC (1652.479123, 1) AS valor FROM DUAL
UNION ALL
SELECT TRUNC (1652.479123) AS valor FROM DUAL
UNION ALL
SELECT TRUNC (1652.479123, -1) AS valor FROM DUAL
UNION ALL
SELECT TRUNC (1652.479123, -2) AS valor FROM DUAL
UNION ALL
SELECT TRUNC (1652.479123, -3) AS valor FROM DUAL;


Figura 4 - Resultado de consultas utilizando o comando trunc. (Fonte: autoria própria)

Esses comandos de linhas simples são bastante eficientes e muito útil quando se precisa trabalhar com precisões.

Espero ter conseguido passar o entendimento sobre as funções.

Grande abraço e até a próxima!

Referências:

WATSON, JOHN – Ramklass, Roopesh (2010) – OCA Oracle Database 11g – Fundamentos I SQL – Manual do Exame 1z0-051. Editora: ALTABOOKS.

ORACLE CORPORATION – ROUND (number). Disponível em: http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions135.htm. Acessado em 24/03/2013.              

ORACLE CORPORATION – TRUNC (number). Disponível em: http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions200.htm. Acessado em 24/03/2013.

Raphael Fernandes, segunda-feira, março 25, 2013

9 comentários