sexta-feira, 28 de dezembro de 2007

O que esperar do novo Oracle 11g

Olá,

Para fechar este ano, e como último artigo de 2007, não poderia deixar de comentar sobre o lançamento do Oracle 11g, e então resolvi postar o comunicado mais esperado pela comunidade Oracle publicado pela imprensa Oracle (Oracle press) no mês de setembro/2007.


Oracle® 11g chega ao mercado brasileiro



Com mais de 400 recursos adicionais, 15 milhões de horas de testes e 36.000 pessoa/meses de desenvolvimento, o banco de dados Oracle 11g destaca-se como o software mais inovador e de mais alta qualidade já lançado pela Oracle. “O banco de dados Oracle 11g oferece aos clientes a capacidade de assumir o controle de suas informações empresariais, ter melhor visão dos negócios e adaptar-se com rapidez e confiança a um ambiente competitivo que passa por grandes mudanças”, afirmou William Hardie, vice-presidente de Marketing de Produto de banco de dados da Oracle. “Trabalhando junto com nossos clientes, incorporamos novas capacidades e recursos aprimorados nessa nova versão, a fim de ajudar a minimizar o risco das mudanças, cumprir as expectativas de nível de serviços dos usuários e regulamentações, além de baixar custos de TI”, completa Hardie.

Com mais de 400 recursos adicionais, 15 milhões de horas de testes e 36.000 pessoa/meses de desenvolvimento, o banco de dados Oracle 11g destaca-se como o software mais inovador e de mais alta qualidade já lançado pela Oracle. “O banco de dados Oracle 11g oferece aos clientes a capacidade de assumir o controle de suas informações empresariais, ter melhor visão dos negócios e adaptar-se com rapidez e confiança a um ambiente competitivo que passa por grandes mudanças”, afirmou William Hardie, vice-presidente de Marketing de Produto de banco de dados da Oracle. “Trabalhando junto com nossos clientes, incorporamos novas capacidades e recursos aprimorados nessa nova versão, a fim de ajudar a minimizar o risco das mudanças, cumprir as expectativas de nível de serviços dos usuários e regulamentações, além de baixar custos de TI”, completa Hardie.

O banco de dados Oracle 11g, construído com 30 anos de experiência em design, oferece recursos de última geração para gerenciamento de informações empresariais", afirma Andy Mendelsohn, vice-presidente sênior de Tecnologias de Servidor de banco de dados da Oracle. "Mais do que nunca, nossos clientes enfrentam desafios, tais como rápido crescimento dos dados, aumento da integração entre eles e pressões no custo da tecnologia para conectividade. O banco de dados Oracle 10g foi pioneiro em grid computing e mais da metade dos clientes Oracle migraram para essa versão. Agora, o banco de dados Oracle 11g oferece os recursos que nossos clientes solicitaram para acelerar a ampla adoção e crescimento dos grids Oracle, representando uma inovação real, que se volta para desafios reais, trazidos até nós por clientes reais", completa Mendelsohn.

Com o banco de dados Oracle 11g, as organizações poderão assumir o controle de suas informações empresariais, ter uma melhor visão dos negócios e adaptar-se com rapidez a um ambiente competitivo que passa por grandes mudanças. A nova versão aumenta a capacidade de cluster de banco de dados, além de acelerar a automação do data center e o gerenciamento da carga de trabalho. Com grids seguros, altamente disponíveis e escaláveis de servidores e armazenamento de baixo custo, os clientes Oracle têm suporte para as aplicações mais exigentes de processamento de transações, data warehousing e gestão de conteúdo.

Testes com aplicativos ajudam a reduzir tempo, risco e custo da mudança

O banco de dados Oracle 11g apresenta recursos avançados de autogerenciamento e automação para ajudar as organizações a cumprir acordos de nível de serviços. Por exemplo, como as organizações precisam fazer atualizações regulares do sistema operacional e do banco de dados, além de alterações no hardware e no sistema, o banco de dados Oracle 11g conta com o Oracle Real Application Testing. Ou seja, trata-se do primeiro banco de dados capaz de ajudar os clientes a testar e gerenciar alterações em seu ambiente de TI rapidamente, de maneira controlada e econômica.

Maior retorno do investimento em soluções de recuperação de catástrofe

No banco de dados Oracle 11g, o Oracle Data Guard permite a utilização do banco de dados em standby para melhorar o desempenho no ambiente de produção, além de fornecer proteção contra falhas do sistema e catástrofes. O Oracle Data Guard possibilita a leitura e a recuperação simultâneas de um único banco de dados de standby, tornando-o disponível para geração de relatórios, backup, testes e atualizações para bancos de dados de produção. Ao aliviar a carga de trabalho de um sistema de produção para um de standby, o Oracle Data Guard ajuda a melhorar o desempenho dos sistemas de produção e fornece uma solução mais econômica para recuperação de catástrofe.

Aprimoramento da gestão do ciclo de vida das informações e do armazenamento

O banco de dados Oracle 11g conta com novos e significativos recursos de particionamento e compactação de dados para as gestões do ciclo de vida das informações e do armazenamento com mais economia. O banco de dados Oracle 11g automatiza muitas operações de particionamento de dados e amplia o particionamento por faixas, por função matemática e por listas (em inglês, range, hash e list), incluindo as novas extensões por intervalo, referência e por coluna virtual (em inglês, interval, REF e virtual columns). Além disso, o banco de dados Oracle 11g oferece um conjunto completo de opções de particionamento composto, permitindo que o gerenciamento do armazenamento seja orientado por regras de negócios.

Complementando recursos já tradicionais de compactação de dados, o Oracle 11g oferece ainda compactação avançada para dados estruturados e não-estruturados (em inglês, large objects ou LOBs) gerenciados em ambientes de processamento de transações, data warehousing e gestão de conteúdo. É possível atingir índices de compactação de 2x a 3x ou até mais para todos os dados, com os novos recursos avançados presentes no banco de dados Oracle 11g.

Registro total de todas as alterações nos dados 

A nova versão também apresenta o "Oracle Total Recall", que possibilita a consulta de dados em tabelas designadas a partir de pontos no passado. O recurso é uma maneira fácil e prática de acrescentar uma dimensão de tempo aos dados para acompanhamento de alterações, auditoria e cumprimento de regulamentações.

Máxima disponibilidade de informações

A Oracle tem sido líder no mercado em proteção para aplicativos de banco de dados contra indisponibilidade planejada ou imprevista. O Oracle 11g mantém essa liderança, pois facilita o atendimento das expectativas de disponibilidade de seus usuários. Dentre os novos recursos estão o Oracle Flashback Transaction, que facilita a reversão de uma transação efetuada com erro, bem como de qualquer transação dependente; Parallel Backup and Restore, que ajuda a melhorar o desempenho do backup e restauração de bancos de dados grandes; e 'hot patching', que melhora a disponibilidade do sistema ao permitir que correções sejam aplicadas sem a necessidade de interromper a operação do banco de dados. Além disso, um novo recurso de aconselhamento – Data Recovery Advisor – ajuda os administradores a reduzir significativamente a parada para recuperação, o que permite automatizar investigação de falhas, determinar planos de recuperação e lidar com várias situações de crise.

Oracle Secure Files

Esse recurso de última geração tem a função de armazenar grandes objetos como imagens, textos ou tipos de dados avançados – incluindo XML, imagens médicas e objetos tridimensionais – dentro do banco de dados. O Oracle Secure Files oferece desempenho dos aplicativos de banco de dados plenamente comparável aos sistemas de arquivos. Ao armazenar uma variedade mais ampla de informações empresariais e recuperá-las com rapidez e facilidade, as empresas podem saber mais sobre seus negócios e adaptar-se com agilidade.

XML mais rápido

O banco de dados Oracle 11g inclui aprimoramentos significativos de desempenho no XML DB, um recurso que permite armazenar nativamente e manipular dados em XML. Acrescentou-se o suporte para XML binário, oferecendo aos clientes várias opções de armazenamento de XML que atendem aos seus requisitos específicos de aplicação e desempenho. O XML DB também possibilita manipulação de dados em XML usando interfaces padrão de mercado com suporte para XQuery, Java Specification Requests (JSR)-170 e padrões SQL/XML.

Criptografia transparente

O banco de dados Oracle 11g complementa seus imbatíveis recursos de segurança com a adição de outros significativos. A nova versão apresenta um aprimoramento dos recursos do Oracle Transparent Data Encryption, além da criptografia no nível das colunas. O banco de dados Oracle 11g oferece criptografia de tablespaces, que pode ser utilizada para criptografar tabelas inteiras, índices e outros armazenamentos de dados.

 
Cubos OLAP incorporados

O banco de dados Oracle 11g também oferece inovações em data warehousing. Os cubos OLAP foram aprimorados para se comportar como visualizações materializadas no banco de dados. Com isso, os desenvolvedores podem usar SQL padrão de mercado para consultas de dados, além de beneficiarem-se com a alta performance proporcionada por um cubo OLAP. Os novos recursos de notificação contínua de consultas permitem que os aplicativos sejam notificados imediatamente, sempre que forem feitas alterações importantes nas informações contidas no banco de dados, sem sobrecarregá-lo com pesquisas constantes.

Pool de conexões e caches de resultados das consultas

Os recursos de desempenho e escalabilidade do banco de dados Oracle 11g possibilitam às empresas manter uma infra-estrutura de serviços de alta qualidade. O novo produto consolida ainda mais a posição da Oracle como líder em desempenho e escalabilidade do mercado, com novos recursos como Query Result Caches, que melhoram o desempenho e a escalabilidade do aplicativo com o armazenamento em cache e a reutilização dos resultados de consultas acessadas com freqüência e as funções das camadas do banco de dados e do aplicativo. Oferece ainda o Database Resident Connection Pooling, que melhora a escalabilidade dos sistemas baseados na web ao fornecer pools de conexões para aplicativos que não são multithread, ou seja, quando diferentes partes de um código são executadas concorrentemente ou simultaneamente.

Desenvolvimento de aplicativos

O banco de dados Oracle 11g oferece várias ferramentas e um processo rápido de desenvolvimento de aplicativos, que aproveita plenamente os principais recursos dessa nova versão. Dentre eles, estão os novos recursos como cache no cliente, XML binário para melhor desempenho dos aplicativos, processamento de XML e armazenamento e recuperação de arquivos. Além disso, o Oracle 11g também inclui um novo compilador Java just-in-time para executar procedimentos Java no banco de dados mais rapidamente, sem a necessidade de um compilador de outro fornecedor; integração nativa com o Visual Studio 2005 para desenvolvimento de aplicativos .NET no Oracle; ferramentas de migração de Access com Oracle Application Express; e um recurso para fácil criação de consultas do SQL Developer e rápida codificação de rotinas SQL e PL/SQL.

Aprimoramentos no auto-gerenciamento e na automação

Os recursos de gerenciamento do banco de dados Oracle 11g foram desenvolvidos para facilitar o gerenciamento dos grids empresariais, atendendo às expectativas dos usuários quanto ao nível dos serviços. O banco de dados Oracle 11g conta com mais recursos de auto-gerenciamento e automação, que contribuem para a redução dos custos de gerenciamento dos sistemas e o aumento do desempenho, da escalabilidade, da disponibilidade e da segurança de seus aplicativos do banco de dados. Entre os novos recursos de gerenciamento presentes no Oracle 11g, destacam-se o ajuste automático de SQL e memória; o novo Partitioning Advisor que sugere aos administradores automaticamente como particionar tabelas e índices para melhorar o desempenho; e diagnóstico aprimorado do desempenho para clusters de banco de dados. Além disso, o banco de dados Oracle 11g inclui um novo Support Workbench que fornece uma interface fácil de usar, além de apresentar incidentes relacionados à integridade do banco de dados aos administradores, junto com informações para conduzir a resolução rapidamente."


Meu Comentário:


De acordo com o comunicado acima e dentre os vários recursos mencionados, o que eu mais esperava e achava inclusive que já estaria disponível na versão do Oracle 10g é a possibilidade de criar colunas virtuais, ou seja, os valores destas colunas não são armazenados fisicamente. Estas colunas são conhecidas entre os desenvolvedores de aplicações como "campos calculados". No Oracle 11g, teremos a opção de criar os campos calculados diretamente em uma tabela e assim, não ficar precisando mais gerar estas informações de forma codificada em nossas aplicações. Em resumo, o Oracle fará automaticamente para nós o cálculo baseado em uma expressão definida na coluna em questão:

SQL> CREATE TABLE emp (
  2  cod         NUMBER,
  3  nome        VARCHAR2(60),
  4  sobrenome   VARCHAR2(60),
  5  salario     NUMBER(9,2),
  6  comissao1   NUMBER(3),
  7  comissao2   NUMBER(3),
  8  salario1    AS (ROUND(salario*(1+commissao1/100),2)),
  9  salario2    NUMBER GENERATED ALWAYS AS (ROUND(salario*(1+comissao2/100),2)) VIRTUAL,
 10  CONSTRAINT pk_emp PRIMARY KEY (cod)
);

SQL> INSERT INTO emp (cod,nome,sobrenome,salario,comissao1,comissao2)
  2  VALUES (1,'EDUARDO','LEGATTI',100,5,10);

SQL> INSERT INTO emp (cod,nome,sobrenome,salario,comissao1,comissao2)
  2  VALUES (2, 'ELIZA', 'A. MENDES', 200, 10, 20);

SQL> SELECT * FROM emp;

 COD  NOME      SOBRENOME  SALARIO  COMISSAO1 COMMISSAO2  SALARIO1  SALARIO2
------ --------- ---------- ------- ---------- ---------- --------- ---------
     1 EDUARDO   LEGATTI        100          5         10       105       110
     2 ELIZA     A. MENDES      200         10         20       220       240

2 linhas selecionadas. 
 

quarta-feira, 26 de dezembro de 2007

Restauração do ORACLE BASE e ORACLE HOME: É possível?

Olá,

Sim, é possível. Recentemente, tive um problema em um de nossos servidores de desenvolvimento utilizando o Oracle 10g release 1 (120 GB de dados) sobre o Suse Linux 9.2. O problema ocorreu após uma queda de energia elétrica na rede, o que ocasionou o desligamento abrupto da máquina sem o processo de shutdown apropriado. De fato, isto não teria acontecido se o nobreak na qual o equipamento estava ligado estivesse funcionando corretamente. Entretanto, por algum defeito técnico o mesmo não forneceu carga elétrica de emergência para manter o equipamento ligado até que fosse realizado o procedimento correto de shutdown do banco de dados e do servidor.

Devido a este fato, foi diagnosticado danos no sistema de arquivos da partição "/u01" (device /dev/hda6) – partição onde fica armazenada o software do banco de dados (ORACLE BASE e ORACLE_HOME) e, após constatar a inconsistência no sistema de arquivos da referida partição, foram executadas as ferramentas e2fsck e dd para tentar corrigir o sistema de arquivos com o objetivo de tentar gerar uma cópia da partição para outro disco. Como a operação não teve o sucesso esperado, a corrupção da partição "/u01" (/dev/hda6) deixou a mesma inutilizada. Por fim, foi decretada a perda completa e irrecuperável da partição onde o software Oracle estava instalado, e como conseqüência, a mesma foi removida do sistema operacional.

Em resumo, a perda da partição "/u01" ocasionou a perda do arquivo de inicialização spfile do banco de dados, o arquivo listener.ora, o arquivo de senha orapwd.ora e os diretórios contendo as informações do OEM Database Console entre outros diretórios (bdump, udump, cdump ...).

Como demonstrado abaixo, a instalação do software Oracle estava separada dos demais arquivos de banco de dados:

DISCO 1


/
/swap
/home
/boot
/u01 (Oracle Base / Oracle Home)

 
DISCO 2
 
/u02 (arquivos de banco de dados como data files, control files e redo log files)

DISCO 3

/u03 (arquivos de banco de dados como data files, control files e redo log files multiplexados)

DISCO 4

/u04 (arquivos de banco de dados como data files, control files e redo log files multiplexados)


Então, realizei as seguintes tarefas para re-configurar o ORACLE BASE e ORACLE HOME:
  • Criei o diretório /u01 na partição raiz do DISCO 1
Como root:

$ mkdir /u01 
$ chown -R oracle.dba /u01
$ chmod 775 /u01
  • Instalei o software Oracle (apenas o software) no diretório /u01
$ ./runinstaller –ignoresysprereqs
  • Após a instalação do software, utilizei o utilitário DBCA para gerar um script de criação do banco de dados (BD01.sh), para aproveitar os comandos gerados pelo mesmo:
$ mkdir -p /u01/app/oracle/admin/BD01/bdump 
$ mkdir -p /u01/app/oracle/admin/BD01/cdump
$ mkdir -p /u01/app/oracle/admin/BD01/create 
$ mkdir -p /u01/app/oracle/admin/BD01/pfile
$ mkdir -p /u01/app/oracle/admin/BD01/udump 
$ mkdir -p /u01/app/oracle/oradata/BD01
$ mkdir -p /u01/app/oracle/product/10.1.0/bd01/dbs
  • Após a execução dos comandos acima, aproveitei do script (BD01.sql) a linha abaixo para criar o arquivo de senhas
$ orapwd file=/u01/app/oracle/product/10.1.0/bd01/dbs/orapwBD01

Após isso, copiei o arquivo init.ora para o diretório /u01/app/oracle/product/10.1.0/bd01/dbs com o nome de initBD01.ora e realizei as seguintes alterações:
  • Alterei o parâmetro control_files para refletir o caminho atual dos arquivos de controle presentes nas partições u02, u03 e u04
  • alterei o parâmetro db_recovery_file_dest para refletir o caminho atual em /u03/oradata/BD01/flash_recovery_area
  • Para gerar o spfile, tive apenas que abrir o SQL*PLUS e executar o comando abaixo na qual retirei do script postDBCreation.sql:
SQL> create spfile='/u01/app/oracle/product/10.1.0/bd01/dbs/spfileBD01.ora'
  2  FROM
  3  pfile='/u01/app/oracle/product/10.1.0/bd01/dbs/initBD01.ora';
  • Para recriar o arquivo listener.ora, utilizei o utilitário Oracle Net Manager
  • Com relação aos diretórios do OEM Database Console tive apenas que recriá-lo utilizando o comando emca –r pelo fato de o repositório já estar criado.
Pronto. Ao executar o SQL*PLUS e digitar startup, o banco de dados abriu normalmente após o processo background SMON realizar a recuperação de instância, pelo fato de o banco de dados não ter sido fechado normalmente (devido a queda de energia). Com o banco de dados funcionando normalmente, apenas realizei algumas alterações no spfile (utilizando ALTER SYSTEM ...) para ajustar alguns parâmetros de configuração.

quarta-feira, 19 de dezembro de 2007

JOBS no Oracle não são executados automaticamente. O que fazer?

Olá,
Recentemente um membro do forum OTN postou um estranho problema (ver a thread Jobs don't running automatically) relacionado à execução de tarefas usando o pacote DBMS_JOB no Oracle 9i. Apesar do parâmetro job_queue_processes estar setado corretamente com um valor maior que zero, os novos JOBS criados não eram executados automaticamente. De acordo com o Note:313102.1 do Oracle Metalink que mostra algumas ações que devem realizadas para poder solucionar o problema, e segundo note, este problema foi reportado na versão Oracle Server - Enterprise Edition - Version: 9.2.0.4.0.

No caso do problema referente à thread, o problema só foi resolvido quando o servidor foi reiniciado e isso porque segundo o note, se o servidor estiver no ar ininterruptamente por mais de 497 dias (UPTIME > 497 days), então haverá a possibilidade de que os JOBS não sejam executados automaticamente (bug 3427424).

A novidade é que me deparei com este problema também na versão Oracle Database 10g Enterprise Edition Release 10.1.0.2.0, e apesar de o banco de dados estar funcionando perfeitamente e os JOBS agendados estarem automaticamente sendo executados, novos JOBS que fossem JOBS criados não eram executados automaticamente. Além do mais, mesmo que executasse o procedimento DBMS_JOB.RUN para executar o JOB, o mesmo era agendado para a próximo horário, mas não era executado automaticamente.


Em resumo, o problema somente foi resolvido quando eu reinicializei o parâmetro JOB_QUEUE_PROCESSES como mostrado abaixo:
  • alter system set job_queue_processes=0;
  • aguardei por 1 minuto ...
  • alter system set job_queue_processes=10;

Após executado o procedimento acima, os novos JOBS criados foram agendados e executados normalmente. Pelo fato deste problema ter ocorrido também na release 1 do Oracle 10g, achei importante relatar o ocorrido e enviei um e-mail para a equipe do Oracle Metalink reportando o problema.

Após o envio, obtive a resposta abaixo:


"Thank you for the feedback.

We have sent your comments to the support team that
created this document. They will review the information
and update the Note as necessary.

Regards
"

No mais, se alguém tiver esse mesmo problema, eu sugiro tentar primeiro reinicializar o parâmetro JOB_QUEUE_PROCESSES, antes de tentar uma outra solução como por exemplo, efetuar um shutdown no banco de dados e inclusive no servidor.

quarta-feira, 12 de dezembro de 2007

Removendo registros duplicados de uma tabela usando o ROWID

Olá,

Antes de demonstrar como remover linhas duplicadas de uma tabela, irei comentar um pouco sobre o que é ROWID (estendido) no Oracle. Na verdade, os ROWIDS não são endereços na memória ou em disco; em vez disso, eles são identificadores que o Oracle pode utilizar para calcular o local de uma linha em uma tabela. Então, localizar uma linha de uma tabela fazendo o uso do ROWID é a maneira mais rápida de encontra-la. Um ROWID não é armazenado explicitamente como um valor de coluna e, quando uma linha é adicionada a uma tabela, o mesmo é gerado para identificar o local exclusivo dessa linha no banco de dados. Um ROWID estendido precisa de 10 bytes de armazenamento em disco, é exibido com 18 caracteres e consiste nos seguintes componentes:
  • Data Object number: É designado a cada objeto de dados, como uma tabela ou um índice, quando criado e é exclusivo no banco de dados.
  • Relative file number: É exclusivo para cada arquivo de um tablespace.
  • Block Number: Representa a posição do bloco que contém a linha no arquivo de dados.
  • Row number: Identifica a posição do slot de diretório de linha no cabeçalho do bloco.
Internamente, o número do objeto de dados precisa de 32 bits, o número do arquivo relativo precisa de 10 bits, o número do bloco precisa de 22 bits e o número da linha precisa de 16 bits que totalizam 80 bits ou 10 bytes.

Podemos perceber que um ROWID estendido é exibido por meio de um schema de codificação de base 64, que usa seis posições para o número do objeto de dados, três posições para o número do arquivo relativo, seis posições para o número do bloco e três posições para o número da linha. Este schema de codificação de base 64 usa caracteres de A-Z, a-z, 0-9, +, e / como mostrado no exemplo abaixo:

Irei criar um tabela para exemplificar.
 
SQL> create table t1 (id number);

Tabela criada.

SQL> insert into t1 select rownum rn from dual connect by rownum <=10;

SQL> commit;

Validação completa.

SQL> select rowid,id from t1;

ROWID                      ID
------------------ ----------
AAOifoAAIAAAPhPAAA          1
AAOifoAAIAAAPhPAAB          2
AAOifoAAIAAAPhPAAC          3
AAOifoAAIAAAPhPAAD          4
AAOifoAAIAAAPhPAAE          5
AAOifoAAIAAAPhPAAF          6
AAOifoAAIAAAPhPAAG          7
AAOifoAAIAAAPhPAAH          8
AAOifoAAIAAAPhPAAI          9
AAOifoAAIAAAPhPAAJ         10

10 linhas selecionadas.
 

Selecionarei o registro de id=1 para ver o valor da pseudo-coluna ROWID.
 
SQL> select substr(rowid,1,6) "OBJECT",
  2         substr(rowid,7,3) "FILE",
  3         substr(rowid,10,6) "BLOCK",
  4         substr(rowid,16,3) "ROW"
  5  from t1 where id = 1;

OBJECT FIL BLOCK  ROW
------ --- ------ ---
AAOifo AAI AAAPhP AAA

No resultado do SQL acima podemos ver que:

  • AAOifo é o número do objeto de dados
  • AAI é o número do arquivo relativo
  • AAAPhP é o número do bloco
  • AAA é o número da linha para o ID = 1

OBS: As versões anteriores ao Oracle 8 usavam o formato ROWID restrito na qual usava internamente apenas seis bytes e não continha o número do objeto de dados.

Concluindo, como um segmento pode residir apenas em um tablespace, o servidor Oracle pode determinar o tablespace que contém uma linha usando o número do objeto de dados, o número do arquivo relativo no tablespace é usado para localizar o arquivo, o número do bloco é usado para localizar o bloco que contém a linha e o número da linha é usado para localizar a entrada de diretório da linha.

O pacote DBMS_ROWID está disponível a partir do Oracle 8 e fornece os procedimentos para criar e interpretar os ROWIDS permitindo que as informações de ROWID sejam decodificadas em informações de arquivo/bloco/identificador de objeto. Abaixo, irei exemplificar algumas das funções deste pacote:

Selecionarei o registro de id=1 para ver o valor da pseudo-coluna ROWID.
 
SQL> select rowid,id from t1 where id = 1;

ROWID                      ID
------------------ ----------
AAOifoAAIAAAPhPAAA          1




Abaixo, DBMS_ROWID.ROWID_TYPE retorna o tipo de um ROWID (0 significa restrito e 1 significa estendido).

SQL> select dbms_rowid.rowid_type('AAOifoAAIAAAPhPAAA') from dual;

DBMS_ROWID.ROWID_TYPE('AAOIFOAAIAAAPHPAAA')
-------------------------------------------
                                          1

Abaixo, DBMS_ROWID.ROWID_OBJECT extrai o número do objeto de dados de um ROWID.

SQL> select dbms_rowid.rowid_object('AAOifoAAIAAAPhPAAA') from dual;

DBMS_ROWID.ROWID_OBJECT('AAOIFOAAIAAAPHPAAA')
---------------------------------------------
                                      3811304

Através do número do objeto retornado, podemos ver que objeto é esse. 

SQL> select object_name,object_type from user_objects where object_id = 3811304;

OBJECT_NAME        OBJECT_TYPE
------------------ -------------------
T1                 TABLE
 
Abaixo, DBMS_ROWID.ROWID_RELATIVE_FNO extrai o número do arquivo relativo de um ROWID. 

SQL> select dbms_rowid.rowid_relative_fno('AAOifoAAIAAAPhPAAA') from dual;

DBMS_ROWID.ROWID_RELATIVE_FNO('AAOIFOAAIAAAPHPAAA')
---------------------------------------------------
                                                  8

Através do número retornado, podemos ver em que arquivo de dados o objeto está armazenado.
 
SQL> select tablespace_name,file_name,file_id from dba_data_files where relative_fno=8;

TABLESPACE_NAME             FILE_NAME                             FILE_ID
--------------------------- ---------------------------------- ----------
USERS                       /u02/oradata/BD1/users01.dbf                8


Abaixo, DBMS_ROWID.ROWID_BLOCK_NUMBER é usado para extrair o número de bloco de determinado ROWID.
 
SQL> select dbms_rowid.rowid_block_number('AAOifoAAIAAAPhPAAA') from dual;

DBMS_ROWID.ROWID_BLOCK_NUMBER('AAOIFOAAIAAAPHPAAA')
---------------------------------------------------
                                              63567

Através do número do bloco retornado, podemos também encontrar o objeto.
 
SQL> select segment_type,owner||'.'||segment_name
  2  from dba_extents
  3  where file_id = 8 and 63567 between block_id
  4  and block_id+blocks -1;

SEGMENT_TYPE       OWNER||'.'||SEGMENT_NAME
------------------ ----------------------------------------
TABLE              LEGATTI.T1


Abaixo, DBMS_ROWID.ROWID_ROW_NUMBER extrai o número de linha de um ROWID (0 significa a primeira linha da tabela).

SQL> select dbms_rowid.rowid_row_number('AAOifoAAIAAAPhPAAA') from dual;

DBMS_ROWID.ROWID_ROW_NUMBER('AAOIFOAAIAAAPHPAAA')
-------------------------------------------------
                                                0




Podemos extrair também da view DBA_SEGMENTS informações de armazenamento (storage) de um segmento.
 
SQL> select s.owner,t.ts#,s.header_file,s.header_block
  2  from v$tablespace t, dba_segments s
  3  where s.segment_name='T1'
  4  and t.name = s.tablespace_name;

OWNER                       TS# HEADER_FILE HEADER_BLOCK
-------------------- ---------- ----------- ------------
LEGATTI                       8           8        63563


Agora irei inserir alguns registros na minha tabela criada anteriormente e adicionar alguns registros que já existem atualmente na tabela.
 
SQL> insert into t1 values (1);

1 linha criada.

SQL> insert into t1 values (10);

1 linha criada.

SQL> insert into t1 values (10);

1 linha criada.

SQL> insert into t1 values (10);

1 linha criada.

SQL> commit;

Validação completa. 

Podemos ver abaixo os registros duplicados.
 
SQL> select rowid,id from t1;

ROWID                      ID
------------------ ----------
AAOifoAAIAAAPhPAAA          1
AAOifoAAIAAAPhPAAB          2
AAOifoAAIAAAPhPAAC          3
AAOifoAAIAAAPhPAAD          4
AAOifoAAIAAAPhPAAE          5
AAOifoAAIAAAPhPAAF          6
AAOifoAAIAAAPhPAAG          7
AAOifoAAIAAAPhPAAH          8
AAOifoAAIAAAPhPAAI          9
AAOifoAAIAAAPhPAAJ         10
AAOifoAAIAAAPhPAAK          1
AAOifoAAIAAAPhPAAL         10
AAOifoAAIAAAPhPAAM         10
AAOifoAAIAAAPhPAAN         10

14 linhas selecionadas.


Podemos perceber que os registros com id's 1 e 10 estão duplicados.
 
SQL> select id,count(*) from t1 group by id having count(*) > 1;

      ID   COUNT(*)
---------- ----------
         1          2
        10          4

A query abaixo irá retornar todos os registros da tabela sem nenhuma duplicação, isso porque irei fazer um subselect na qual será retornado sempre as linhas com menor ROWID encontrado para cada coluna ID da minha tabela.
 
SQL> select rowid,id from t1 A where rowid = (select min(rowid) from t1 B where a.id = b.id);

ROWID                      ID
------------------ ----------
AAOifoAAIAAAPhPAAA          1
AAOifoAAIAAAPhPAAB          2
AAOifoAAIAAAPhPAAC          3
AAOifoAAIAAAPhPAAD          4
AAOifoAAIAAAPhPAAE          5
AAOifoAAIAAAPhPAAF          6
AAOifoAAIAAAPhPAAG          7
AAOifoAAIAAAPhPAAH          8
AAOifoAAIAAAPhPAAI          9
AAOifoAAIAAAPhPAAJ         10

10 linhas selecionadas.

Agora é só usar o mesmo SQL apenas trocando o comando SELECT pelo DELETE, e o operador de = para >.

SQL> delete from t1 A where rowid > (select min(rowid) from t1 B where a.id = b.id);

4 linhas deletadas.

SQL> commit;

Validação completa.

Pronto. Não há mais registros duplicados na tabela.

SQL> select rowid,id from t1;

ROWID                      ID
------------------ ----------
AAOifoAAIAAAPhPAAA          1
AAOifoAAIAAAPhPAAB          2
AAOifoAAIAAAPhPAAC          3
AAOifoAAIAAAPhPAAD          4
AAOifoAAIAAAPhPAAE          5
AAOifoAAIAAAPhPAAF          6
AAOifoAAIAAAPhPAAG          7
AAOifoAAIAAAPhPAAH          8
AAOifoAAIAAAPhPAAI          9
AAOifoAAIAAAPhPAAJ         10

10 linhas selecionadas.


domingo, 25 de novembro de 2007

Recuperação no modo NOARCHIVELOG

Olá,

Se você leu e entendeu a diferença entre os dois modos de operação do Oracle descritas no artigo de Agosto/2007 à respeito dos modos ARCHIVELOG e NOARCHIVELOG, então você verá como será possível recuperar um banco de dados no modo NOARCHIVELOG. Devido às chances de recuperação de um banco de dados operando sem o modo de arquivamento ativado serem mínimas ou quase nulas (em um ambiente real), trate este artigo apenas como fonte didática. Por favor, não confunda recuperação com restauração, porque são coisas diferentes.

Agora, em caso de uma falha de mídia, porque as chances de recuperação de um banco de dados operando no modo NOARCHIVELOG são mínimas ou quase nulas? Simples. Pelo fato dos arquivos de registro de redo log online terem uma natureza cíclica, os mesmos não são arquivados durante a operação de alternância de log (log switch). Neste caso, os dados de redo contidos em um grupo podem ser sobregravados a cada operação de alternância de log ocasionando, assim, a perda de dados importantes necessários para recuperação completa do banco de dados. Então, lembre-se de que os registros de redo log online não são arquivados (copiados) e o processo de segundo plano log writer process (LGWR) recicla os registros de redo log online, sobregravando os grupos de registro de redo preenchidos.

Em resumo, quando uma falha de mídia ocorrer, será necessário restaurar um backup de banco de dados fechado (cold backup) válido. No modo NOARCHIVELOG, todos os arquivos deverão ser restaurados, mesmo que apenas um arquivo de dados tenha sido danificado ou perdido. É necessário certificar de ter restaurado todos os arquivos de dados (datafiles) e arquivos de controle (controlfiles). Você poderá restaurar os arquivos de redo log online também, caso tenha feito o backup junto com os controlfiles e datafiles. Lembre-se de que todos os arquivos de banco de dados Oracle deverão estar sincronizados para que o mesmo possa ser aberto.

No caso de um banco de dados operando no modo NOARCHIVELOG, na qual sofreu uma falha de mídia, e que acarretou na perda de um ou mais arquivos de dados, será necessário restaurar apenas os arquivos de dados afetados, isso se nenhum arquivo de redo log online tiver sido sobre-gravado desde o último backup. Neste artigo abordarei especificamente este caso.

Cenário:

  • Existem três grupos de redo log online.
  • Foi feito um backup frio (cold backup) na seqüência de log 3.
  • Foi feita uma carga de dados em um segmento (tabela) pertencente ao tablespace formado pelo arquivo de dados 10.
  • Enquanto o banco de dados estava na seqüência de log 5, o arquivo de dados 10 foi perdido.
Resultado:
  • Como a seqüência de log 3 não foi sobre-gravada, então apenas o arquivo de dados número 10 precisará ser restaurado do backup e recuperado manualmente.
Pronto, então agora vamos ao que interessa.

Irei abrir o banco de dados com a opção de resetlogs apenas para reiniciar novamente a seqüência de logs. Para isso simularei uma recuperação incompleta.

oracle@linux:~> sqlplus "/ as sysdba"

SQL*Plus: Release 9.2.0.4.0 - Production on Qui Nov 22 11:18:29 2007

Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.

Conectado a uma instância inativa.

SQL> startup mount
Instância ORACLE iniciada.

Total System Global Area  114365800 bytes
Fixed Size                   451944 bytes
Variable Size              92274688 bytes
Database Buffers           20971520 bytes
Redo Buffers                 667648 bytes
Banco de dados montado.

SQL> recover database until cancel;

Recuperação de mídia concluída.

SQL> alter database open resetlogs;

Banco de dados alterado.

Confirmando que o banco está operando no modo NOARCHIVELOG.


SQL> archive log list
Modo log de banco de dados   Modo Sem Arquivamento
Arquivamento automático      Desativado
Destino de arquivamento      /archive
A seqüência de log on-line mais antiga     0
Seqüência de log atual           1

SQL> select log_mode from v$database;

LOG_MODE
------------
NOARCHIVELOG 

Irei criar um tablespace chamado TBS_RECOVER que será usado para a simulação da recuperação.

SQL> create tablespace tbs_recover
 2 logging
 3 datafile '/u01/oradata/BD1/tbsrecover01.dbf' size 100m
 4 extent management local
 5 segment space management auto;
 6 /

Tablespace criado.
Irei criar um schema de banco de dados que será usado para criar uma tabela com alguns registros.

SQL> create user legatti identified by legatti
 2 default tablespace tbs_recover
 3 quota unlimited on tbs_recover;
 4 /

Usuário criado.

SQL> grant connect,resource to legatti;

Concessão bem-sucedida.
Confirmando o grupo e a seqüência atual de redo log nos arquivos de controle.

SQL> set linesize 1000
SQL> select * from v$log;

    GROUP#    THREAD#  SEQUENCE#      BYTES    MEMBERS ARC STATUS   FIRST_CHANGE# FIRST_TIME
---------- ---------- ---------- ---------- ---------- --- -------- ------------- ----------
         1          1          1    1048576          1 NO  CURRENT        5065706 22/11/2007
         2          1          0    1048576          1 YES UNUSED               0
         3          1          0    1048576          1 YES UNUSED               0

Devido ao fato de eu ter resetado a seqüência de log, irei forçar 2 alternâncias de log afim de se chegar na seqüência 3 como descrito no cenário.

SQL> alter system switch logfile;

Sistema alterado.

SQL> /

Sistema alterado.
Novamente irei confirmar o grupo e a seqüência atual de redo log registrada nos arquivos de controle.

SQL> select * from v$log;

    GROUP#    THREAD#  SEQUENCE#      BYTES    MEMBERS ARC STATUS   FIRST_CHANGE# FIRST_TIME
---------- ---------- ---------- ---------- ---------- --- -------- ------------- ----------
         1          1          1    1048576          1 NO  INACTIVE       5065706 22/11/2007
         2          1          2    1048576          1 NO  INACTIVE       5065883 22/11/2007
         3          1          3    1048576          1 NO  CURRENT        5065885 22/11/2007

SQL> select current_group#,sequence#,checkpoint_change# from v$thread;

CURRENT_GROUP#  SEQUENCE# CHECKPOINT_CHANGE#
-------------- ---------- ------------------
             3          3            5065885

Irei fechar o banco de dados para realizar um backup de todos os arquivos (controlfiles, datafiles e redo log files). Então neste caso, o backup será realizado na seqüência de log 3.

SQL> shutdown
Banco de dados fechado.
Banco de dados desmontado.
Instância ORACLE desativada.
SQL> exit

Desconectado de Oracle9i Enterprise Edition Release 9.2.0.4.0 - Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release 9.2.0.4.0 - Production

oracle@linux:~> cp -a /u01/oradata /u01/bkp
Irei abrir o banco de dados para realizar a simulação de uma carga de dados no schema criado anteriormente.

oracle@linux:~> sqlplus "/ as sysdba"

SQL*Plus: Release 9.2.0.4.0 - Production on Qui Nov 22 11:25:52 2007

Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.

Conectado a uma instância inativa.

SQL> startup
Instância ORACLE iniciada.

Total System Global Area  114365800 bytes
Fixed Size                   451944 bytes
Variable Size              92274688 bytes
Database Buffers           20971520 bytes
Redo Buffers                 667648 bytes
Banco de dados montado.
Banco de dados aberto.

SQL> connect legatti/legatti;
Conectado.

SQL> create table emp (id number);

Tabela criada.

SQL> begin
 2  for i in 1..100000
 3  loop
 4   insert into emp values (i);
 5  end loop;
 6 end;
/

Procedimento PL/SQL concluído com sucesso.

SQL> commit;

Validação completa.

SQL> select count(*) from emp;

   COUNT(*)
-----------
     100000
Podemos perceber abaixo, realizando uma consulta na view V$LOG, que ocorreu uma alternância de log (log switch) devido à carga de dados realizada na tabela EMP. Agora, o grupo de redo número 2 é o grupo atual e contém a seqüência 5. Neste caso, a seqüências 1 e 2 foram sobregravadas.OBS: apenas aproveitando a oportunidade, vocês podem notar que o STATUS do grupo de redo 1 está definido como ACTIVE o que significa que, em caso de falha de instância, o mesmo será utilizado no processo de recuperação.

SQL> connect "/ as sysdba"
Conectado.

SQL> select * from v$log;

    GROUP#    THREAD#  SEQUENCE#      BYTES    MEMBERS ARC STATUS   FIRST_CHANGE# FIRST_TIME
---------- ---------- ---------- ---------- ---------- --- -------- ------------- ----------
         1          1          4    1048576          1 NO  ACTIVE         5066130 22/11/2007
         2          1          5    1048576          1 NO  CURRENT        5066375 22/11/2007
         3          1          3    1048576          1 NO  INACTIVE       5065885 22/11/2007

SQL> shutdown
Banco de dados fechado.
Banco de dados desmontado.
Instância ORACLE desativada.

SQL> exit

Desconectado de Oracle9i Enterprise Edition Release 9.2.0.4.0 - Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release 9.2.0.4.0 - Production
Irei simular uma falha de disco deletando fisicamente o arquivo de dados número 10 que é o datafile pertencente ao tablespace TBS_RECOVER.

oracle@linux:~> rm /u01/oradata/BD1/tbsrecover01.dbf
Após realizar o procedimento acima, vou tentar abrir o banco de dados novamente e você verá que o banco de dados não abrirá porque o arquivo de dados 10 não foi encontrado.

oracle@linux:~> sqlplus "/ as sysdba"

SQL*Plus: Release 9.2.0.4.0 - Production on Qui Nov 22 11:36:13 2007

Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.

Conectado a uma instância inativa.

SQL> startup
Instância ORACLE iniciada.

Total System Global Area  114365800 bytes
Fixed Size                   451944 bytes
Variable Size              92274688 bytes
Database Buffers           20971520 bytes
Redo Buffers                 667648 bytes
Banco de dados montado.

ORA-01157: não é possível identificar/bloquear arquivo de dados 10 - consulte
arquivo de análise DBWR
ORA-01110: 10 do arquivo de dados: '/u01/oradata/BD1/tbsrecover01.dbf'

SQL> select * from v$recover_file;

     FILE# ONLINE  ONLINE_ ERROR                               CHANGE# TIME
---------- ------- ------- -------------------------------- ---------- ----------
        10 ONLINE  ONLINE  FILE NOT FOUND                            0 22/11/2007
Neste caso, o banco de dados ficou no estado MOUNT, então para exemplificar, fecharei novamente o banco de dados e restaurarei o arquivo de dados 10 (tbsrecover01.dbf) do backup.

SQL> shutdown
ORA-01109: banco de dados não aberto
Banco de dados desmontado.
Instância ORACLE desativada.

SQL> exit

Desconectado de Oracle9i Enterprise Edition Release 9.2.0.4.0 - Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release 9.2.0.4.0 - Production

oracle@linux:~> cp -a /u01/bkp/BD1/tbsrecover01.dbf /u01/oradata/BD1/
Agora com o arquivo de dados restaurado do backup, irei tentar abrir novamente o banco de dados. Você irá perceber que a mensagem de erro mudou de ORA-01157 para ORA-01113, o que significa que ao tentar abrir o banco de dados, o Oracle detectou que as informações de checkpoint contidas no o arquivo de dados 10 não estão sincronizadas com os arquivos de controle.

oracle@linux:~> sqlplus "/ as sysdba"

SQL*Plus: Release 9.2.0.4.0 - Production on Qui Nov 22 11:40:42 2007

Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.

Conectado a uma instância inativa.

SQL> startup
Instância ORACLE iniciada.

Total System Global Area  114365800 bytes
Fixed Size                   451944 bytes
Variable Size              92274688 bytes
Database Buffers           20971520 bytes
Redo Buffers                 667648 bytes
Banco de dados montado.

ORA-01113: o arquivo 10 precisa da recuperação de mídia
ORA-01110: 10 do arquivo de dados: '/u01/oradata/BD1/tbsrecover01.dbf'
Verificando a view v$recover_file, que nos mostra quais arquivos precisam de recuperação, podemos ver no campo CHANGE# o número 5065885 que significa o SCN à partir do qual a recuperação deve ser iniciada. Podemos notar também que o número SCN é bem próximo do SCN contido no campo FIRST_CHANGE# da view V$LOG pertencente ao grupo de redo 3 no qual não foi sobregravado durante a carga de dados.

SQL> select * from v$recover_file;

     FILE# ONLINE  ONLINE_ ERROR                               CHANGE# TIME
---------- ------- ------- -------------------------------- ---------- ----------
        10 ONLINE  ONLINE                                      5065889 22/11/2007

Agora irei proceder com a recuperação do arquivo de dados e abrir o banco de dados normalmente.

SQL> recover datafile 10;
Recuperação de mídia concluída.

SQL> alter database open;

Banco de dados alterado.

Irei conectar com o usuário criado anteriormente e verificar se a tabela EMP e os dados inseridos nela foram recuperados com sucesso.

SQL> connect legatti/legatti
Conectado.

SQL> select count(*) from emp;

   COUNT(*)
-----------
     100000

Abaixo, estou mostrando o que foi gravado no arquivo de alerta (alert log file) durante a fase de recuperação.

Thu Nov 22 11:44:29 2007
ALTER DATABASE RECOVER  datafile 10
Thu Nov 22 11:44:29 2007
Media Recovery Datafile: 10
Media Recovery Start
Starting datafile 10 recovery in thread 1 sequence 3
Datafile 10: '/u01/oradata/BD1/tbsrecover01.dbf'
Media Recovery Log
Recovery of Online Redo Log: Thread 1 Group 3 Seq 3 Reading mem 0
  Mem# 0 errs 0: /u01/oradata/BD1/redo02.log
Recovery of Online Redo Log: Thread 1 Group 1 Seq 4 Reading mem 0
  Mem# 0 errs 0: /u01/oradata/BD1/redo03.log
Recovery of Online Redo Log: Thread 1 Group 2 Seq 5 Reading mem 0
  Mem# 0 errs 0: /u01/oradata/BD1/redo01.log
Media Recovery Complete
Completed: ALTER DATABASE RECOVER  datafile 10
Thu Nov 22 11:44:37 2007
alter database open
Thu Nov 22 11:44:37 2007
Thread 1 opened at log sequence 5
  Current log# 1 seq# 5 mem# 0: /u01/oradata/BD1/redo02.log
Successful open of redo thread 1.
Thu Nov 22 11:44:38 2007
SMON: enabling cache recovery
Thu Nov 22 11:44:38 2007
Undo Segment 1 Onlined
Undo Segment 2 Onlined
Undo Segment 3 Onlined
Undo Segment 4 Onlined
Undo Segment 5 Onlined
Undo Segment 6 Onlined
Undo Segment 7 Onlined
Undo Segment 8 Onlined
Undo Segment 9 Onlined
Undo Segment 10 Onlined
Successfully onlined Undo Tablespace 1.
Thu Nov 22 11:44:38 2007
SMON: enabling tx recovery
Thu Nov 22 11:44:38 2007
Database Characterset is WE8ISO8859P1
replication_dependency_tracking turned off (no async multimaster replication found)
Completed: alter database open

Em resumo, diferentemente do que foi demonstrado acima, se você decidir operar um banco de dados no modo NOARCHIVELOG, considere as seguintes vantagens e desvantagens em relação à recuperação:

Vantagens

  • Fácil de executar, pois é necessária apenas uma restauração de todos os arquivos de um backup válido. Os únicos riscos são de natureza operacional como restauração do backup incorreto, sobregravação do backup, não desativação do banco de dados antes da restauração ou criação de backups inválidos (como copiar os arquivos de banco de dados estando com o banco de dados aberto).
  • O tempo necessário para a recuperação é simplesmente o tempo para restaurar todos os arquivos, o que depende do seu hardware e do sistema operacional.
Desvantagens
  • Todos os dados informados pelos usuários desde o último backup serão perdidos e será necessário informá-los manualmente.
  • O banco de dados inteiro precisa ser restaurado à partir do último backup fechado completo (cold backup), mesmo que apenas um arquivo de dados esteja perdido.