sábado, 25 de abril de 2009

Mercado de banco de dados mais acirrado ...

Olá,

"Um porta-voz da EnterpriseDB declarou que a aplicação da Oracle pode rodar sem mudanças com o seus Postgress Plus. Agora, aplicativos Oracle vão trabalhar "como são" com DB2 Release 9.7, disse Arvind Krishna, VP de servidores de banco de dados da IBM".

Pois bem, estive visitando o canal de notícias do site IT Web e achei esta matéria interessante. Acredito que as empresas de SGBDS estão começando a enxergar que a única forma de competir com a Oracle é fazer com que seus bancos de dados sejam compatíveis com funcionalidades do Oracle, PL/SQL, entre outras. Portanto, acho que isso será uma tendência e, quem tiver suas aplicações baseadas na tecnologia do banco de dados Oracle, poderão ter as mesmas portadas para outro SGBD sem nenhuma alteração de código.

É o caso do PostgreSQL Plus da empresa EnterpriseDB, que lançou anos atrás uma versão de banco de dados "EnterpriseDB" acredito que já baseada no PostgreSQL, mas com algumas funcionalidades compatíveis com o Oracle, e que, agora com o PostgreSQL Plus Advanced Server, mais itens foram adicionados com tais funcionalidades do Oracle PL/SQL, inclusive tendo as mesmas funcionalidades das famosas views de dicionários de banco de dados DBA_*, Public Synonyms, Sequences (CURRVAL, NEXTVAL), functions, packages, triggers, tipos de dados (CHAR, VARCHAR, VARCHAR2, NUMBER, BLOB, CLOB, DATE), pseudo-coluna ROWNUM, a tabela DUAL, entre outras como funções e variáveis embutidas (TO_CHAR, TO_DATE, TO_NUMBER, UPPER, LOWER, CHR, CONCAT, REPLACE, SUBSTR, ADD_MONTHS, NEXT_DAY, MONTHS_BETWEEN, TRUNC, LTRIM, RTRIM, LENGTH, RPAD, LPAD, CEIL, ROUND, FLOOR, NVL, NVL2, INITCAP, LEAST, GREATEST, DECODE, INSTR, LAST_DAY, USER, SYSDATE, SYSTIMESTAMP).


Portanto, acredito que quem possui aplicações baseadas na tecnologia do banco de dados Oracle irá, de alguma forma, se beneficiar destas compatibilidades, inclusive depois da recente aquisição da Sun MicroSystems pela própria Oracle, ou seja, a Oracle agora proprietária do Solaris, MySQL, Java, Virtualbox (software de virtualização), OpenOffice, GlassFish, entre outras ferramentas, ditará algumas regras do mercado.

Além do banco de dados Oracle, utilizo também o PostgreSQL já algum tempo, e estou pensando seriamente em adotar o PostgreSQL Plus Advanced Server como alternativa de negócio, pelo fato de o mesmo vender a idéia de dar suporte ao PL/SQL e outras compatibilidades com o Oracle, então, para as aplicações que utilizam o banco de dados Oracle, tirando o SQL ANSI adotado pela maioria, não seria necessário se preocupar em desenvolver triggers, stored functions/procedures distintas para SGBDS's distintos, ainda mais agora que a IBM está implementando no DB2 versão 9.7 essa tecnologia de compatibilidade com o Oracle, ou seja, seria mais uma opção para os clientes. Em relação a isso, fico imaginando como ficará o Oracle Express Edition, no meio de tantas novidades ...

Para maiores detalhes sobre a matéria, acesse o artigo "IBM adota tecnologia para atrair clientes Oracle" publicada no site da IT Web.

No mais, dia 28 às 14:00 irei participar de um seminário na web (Webinar), ministrado pela empresa EnterpriseDB, que abordará o assunto "Migrating Oracle to Postgres Plus Advanced Server". Meu foco será o de conhecer mais sobre esse pacote de compatibilidade com o Oracle adicionado ao PostgreSQL Plus Advanced Server. Para quem se interessar, bastará apenas fazer o registro no site da EnterpriseDB.

terça-feira, 21 de abril de 2009

Oracle compra Sun Microsystems por US$ 7,4 bilhões

Olá,



Após as negociações da Sun com a IBM terem fracassado há cerca de duas semanas, a Oracle não perdeu tempo
e ofereceu US$ 7,4 bilhões pela Sun Microsystems, que aceitou a proposta. O Conselho de Administração da Sun Microsystems aprovou a transação por unanimidade.

A aquisição da Sun segue a tendência de outras compras realizadas pela Oracle no setor de tecnologia nos últimos anos, como Siebel, PeopleSoft e BEA Systems mas, segundo a Oracle, a aquisição da Sun será mais lucrativa no seu primeiro ano que as compras da BEA, PeopleSoft e Siebel combinadas.


Já o presidente executivo da Oracle, Larry Ellison, mostrou a sua satisfação com o acordo alcançado e afirmou que o Java e o Solaris foram as duas principais razões para a aquisição da Sun. Para o executivo, o movimento está em linha com a estratégia de aquisições da companhia, sempre em busca de produtos líderes de mercado.

A Oracle considera o Solaris como a melhor tecnologia Unix disponível no mercado, o que, segundo Ellison, explica porque há mais bancos de dados da companhia rodando neste sistema operacional do que em qualquer outro. Ele afirmou que os clientes que contam com os dois produtos terão benefícios advindos da integração técnica de ambos.

Com a aquisição da Sun, a Oracle talvez crie problemas para usuários do MySQL, que pregam independência de fornecedores de software proprietário mas, em um comunicado divulgado sobre a aquisição, a Oracle afirma que o MySQL será parte integrante da já existente suíte de bancos de dados Oracle, que inclui produtos como o Database 11g, o TimesTen, o open-source Berkeley DB e o engine de storage transacional, também aberto, InnoDB.

Já em outro comunicado sobre a aquisição, Charls Philips, presidente da Oracle, falou das vantagens da aquisição do Java e do Solaris, sem citar uma palavra sobre o MySQL.

Maiores informações podem ser acessadas no site da Oracle em Oracle e Sun.

No mais, agora é só esperar para ver no que vai dar ....

Fontes: Info plantão, IDG Now, ComputerWorld

quarta-feira, 15 de abril de 2009

Aplicando arquivos de redo log arquivados em um cold backup ...

Olá,

Não é raro vermos em fóruns ou grupos de discussões, questões ou dúvidas relacionadas à aplicação de arquivos de redo log arquivados (archive redo log files) em backups frios (cold backups) de banco de dados Oracle. Apenas para relembrar, um "cold backup" gerenciado por usuário é uma opção de backup na qual o mesmo é realizado no nível de arquivo, onde todos os arquivos de dados, arquivos de controle e opcionalmente os arquivos de redo log on-line são copiados através de comandos do sistema operacional. Nas plataformas Unix/Linux, comandos tais como cp ou tar, normalmente são usados para fazer o backup dos arquivos para um local seguro.

Esta operação de cópia dos arquivos de banco de dados é realizada enquanto o banco de dados está fechado. Por outro lado, para quem utiliza a estratégia de backup gerenciada pelo servidor RMAN, um cold backup para ser realizado necessita que o banco de dados esteja no estado montado (MOUNT), mas não aberto.

"No caso de backups gerenciados pelo usuário, um dos erros mais comuns quando se usa o cold backup é não fechar o banco de dados normalmente com as opções NORMAL, IMMEDIATE ou TRANSACTIONAL do comando SHUTDOWN. Os colds backups executados com o banco de dados aberto ou após ele ter sido fechado de modo anormal são completamente inúteis. Essa situação potencialmente perigosa pode ocorrer quando são usados scripts automatizados que não contêm uma lógica para verificar se o banco de dados foi realmente fechado normalmente antes do início do backup."

Dependendo da política de backup implementada e do tipo de desastre ocorrido no servidor do banco de dados, talvez sempre existirá a possibilidade de contar com pelo menos um "cold backup" do banco de dados e um backup de todos os arquivos de redo log gerados após a realização do cold backup.

No mais, neste artigo irei simular a aplicação de todos os arquivos de redo log arquivados criados após a realização de um cold backup, nos arquivos de banco de dados restaurados do próprio cold backup. Não precisa nem dizer que o banco de dados deverá estar configurado para operar no modo de arquivamento (ARCHIVELOG) ...

[oracle@linux1 oracle]$ sqlplus / as sysdba

SQL*Plus: Release 10.2.0.4.0 - Production on Qua Abr 15 13:28:52 2009

Copyright (c) 1982, 2007, Oracle. All Rights Reserved.

Conectado a uma instância inativa.

SQL> startup
Instância ORACLE iniciada.

Total System Global Area 155189248 bytes
Fixed Size 1266320 bytes
Variable Size 100666736 bytes
Database Buffers 50331648 bytes
Redo Buffers 2924544 bytes
Banco de dados montado.
Banco de dados aberto.

-- Confirmando o formato dos archive logs
SQL> show parameter log_archive_format

NAME TYPE VALUE
---------------------------------- ----------- ------------------------------
log_archive_format string %t_%s_%r.dbf

-- Confirmando o destino para os archive redo logs gerados
SQL> show parameter log_archive_dest_1

NAME TYPE VALUE
------------------------- ----------- ---------------------------------------
log_archive_dest_1 string LOCATION=/u01/archive/ MANDATORY REOPEN

-- Confirmando que o banco de dados está no modo de arquivamento
SQL> archive log list
Modo log de banco de dados Modo de Arquivamento
Arquivamento automático Ativado
Destino de arquivamento /u01/archive/
A seqüência de log on-line mais antiga 1
Próxima seqüência de log a arquivar 1
Seqüência de log atual 1

-- Confirmando a seqüencia do arquivo de redo log-online corrente
SQL> select group#,thread#,sequence#,bytes,members,archived,status from v$log;

GROUP# THREAD# SEQUENCE# BYTES MEMBERS ARC STATUS
---------- ---------- ---------- ---------- ---------- --- ----------------
1 1 1 4194304 1 NO CURRENT
2 1 0 4194304 1 YES UNUSED
3 1 0 4194304 1 YES UNUSED

-- Fechando o banco de dados
SQL> shutdown immediate
Banco de dados fechado.
Banco de dados desmontado.
Instância ORACLE desativada.

SQL> exit
Desconectado de Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

Irei abaixo realizar uma cópia de todos os arquivos de banco de dados para um outro local.

[oracle@linux1 oracle]$ cp -a /u01/app/oracle/oradata /backup

Após a realização do cold backup, irei reiniciar o banco de dados para simular algumas transações.

[oracle@linux1 oracle]$ sqlplus / as sysdba

SQL*Plus: Release 10.2.0.4.0 - Production on Qua Abr 15 13:28:52 2009

Copyright (c) 1982, 2007, Oracle. All Rights Reserved.

Conectado a uma instância inativa.

SQL> startup
Instância ORACLE iniciada.

Total System Global Area 155189248 bytes
Fixed Size 1266320 bytes
Variable Size 100666736 bytes
Database Buffers 50331648 bytes
Redo Buffers 2924544 bytes
Banco de dados montado.
Banco de dados aberto.

-- Criando um usuário de teste
SQL> create user scott identified by tiger default tablespace users;

Usuário criado.

-- Concedendo atribuições padrão
SQL> grant connect,resource to scott;

Concessão bem-sucedida.

-- Conectando com o usuário SCOTT
SQL> connect scott/tiger
Conectado.

-- Criando uma tabela de teste
SCOTT> create table t1 (id number);

Tabela criada.

Realizado a etapa acima, abaixo irei simular algumas operações DML no banco de dados de forma a gerar registros de redo suficientes para a criação de arquivos de redo log arquivados:

SCOTT> insert into t1 select level from dual connect by level <= 100000;

100000 linhas criadas.

SCOTT> commit;

Commit concluído.

SCOTT> update t1 set id=1000;

100000 linhas atualizadas.

SCOTT> rollback;

Rollback concluído.

SCOTT> drop table t1 purge;

Tabela eliminada.

SCOTT> create table t2 (data timestamp);

Tabela criada.

-- Inserindo a data e horário atual
SCOTT> insert into t2 select localtimestamp from dual;

1 linha criada.

SCOTT> commit;

Commit concluído.

SCOTT> select * from t2;

DATA
--------------------------
15/04/2009 13:34:36,883986

SQL> connect / as sysdba;
Conectado.

-- Forçando o arquivamento do arquivo de redo log on-line corrente
SQL> alter system archive log current;

Sistema alterado.

Após a simulação das operações acima, podemos ver abaixo que foram gerados 12 arquivos de redo log arquivados.

SQL> select recid,name from v$archived_log;

RECID NAME
---------- -----------------------------------------
1 /u01/archive/1_1_684148997.dbf
2 /u01/archive/1_2_684148997.dbf
3 /u01/archive/1_3_684148997.dbf
4 /u01/archive/1_4_684148997.dbf
5 /u01/archive/1_5_684148997.dbf
6 /u01/archive/1_6_684148997.dbf
7 /u01/archive/1_7_684148997.dbf
8 /u01/archive/1_8_684148997.dbf
9 /u01/archive/1_9_684148997.dbf
10 /u01/archive/1_10_684148997.dbf
11 /u01/archive/1_11_684148997.dbf
12 /u01/archive/1_12_684148997.dbf

12 linhas selecionadas.

-- Fechando o banco de dados
SQL> shutdown immediate
Banco de dados fechado.
Banco de dados desmontado.
Instância ORACLE desativada.

SQL> exit
Desconectado de Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

-- Confirmando os registros de redo log criados no destino de arquivamento
[oracle@linux1 archive]$ ls -lhatr
total 46M
drwxrwxr-x 4 oracle dba 4,0K Abr 15 13:31 ..
-rw-r----- 1 oracle oinstall 4,0M Abr 15 13:34 1_1_684148997.dbf
-rw-r----- 1 oracle oinstall 4,0M Abr 15 13:34 1_2_684148997.dbf
-rw-r----- 1 oracle oinstall 4,0M Abr 15 13:34 1_3_684148997.dbf
-rw-r----- 1 oracle oinstall 4,0M Abr 15 13:34 1_4_684148997.dbf
-rw-r----- 1 oracle oinstall 4,0M Abr 15 13:34 1_5_684148997.dbf
-rw-r----- 1 oracle oinstall 4,0M Abr 15 13:34 1_6_684148997.dbf
-rw-r----- 1 oracle oinstall 4,0M Abr 15 13:34 1_7_684148997.dbf
-rw-r----- 1 oracle oinstall 4,0M Abr 15 13:34 1_8_684148997.dbf
-rw-r----- 1 oracle oinstall 4,0M Abr 15 13:34 1_9_684148997.dbf
-rw-r----- 1 oracle oinstall 4,0M Abr 15 13:34 1_10_684148997.dbf
-rw-r----- 1 oracle oinstall 4,0M Abr 15 13:34 1_11_684148997.dbf
-rw-r----- 1 oracle oinstall 1,5M Abr 15 13:35 1_12_684148997.dbf
drwxr-xr-x 2 oracle oinstall 20K Abr 15 13:35 .


-- Simulando a perda de todos os arquivos de banco de dados
[oracle@linux1 oracle]$ rm -rf /u01/app/oracle/oradata

-- Restaurando o cold backup para o local de origem
[oracle@linux1 oracle]$ cp -a /backup/oradata /u01/app/oracle/oradata

[oracle@linux1 oracle]$ sqlplus / as sysdba

SQL*Plus: Release 10.2.0.4.0 - Production on Qua Abr 15 13:47:19 2009

Copyright (c) 1982, 2007, Oracle. All Rights Reserved.

Conectado a uma instância inativa.

SQL> startup mount
Instância ORACLE iniciada.

Total System Global Area 155189248 bytes
Fixed Size 1266320 bytes
Variable Size 100666736 bytes
Database Buffers 50331648 bytes
Redo Buffers 2924544 bytes
Banco de dados montado.

SQL> recover database;
ORA-00283: sessão de recuperação cancelada devido a erros
ORA-00264: nenhuma recuperação necessária

Apenas para validar o cold backup, podemos perceber acima como era de se esperar, que o comando RECOVER DATABASE falhou, pelo fato de os arquivos de banco de dados já estarem consistentes e, portanto, não haveria nenhuma necessidade de qualquer tipo de recuperação.

Como poderemos então aplicar os arquivos de redo log arquivados sobre este banco de dados de modo a reconstruir todas as transações realizadas anteriormente? A chave para isso é utilizar o comando RECOVER DATABASE em conjunto com a cláusula USING BACKUP CONTROLFILE sendo que, a cláusula UNTIL CANCEL poderá ser utilizada agora ou depois, como demonstrarei mais a frente. Neste caso, podemos dizer que os arquivos de controle restaurados, na verdade, são realmente backups dos arquivos de controle. Selecionarei a opção AUTO para que eu não precise confirmar os arquivos de redo log arquivados um a um.

SQL> recover database using backup controlfile;
ORA-00279: alterar 187046 gerado em 04/15/2009 13:31:13 necessário para o thread 1
ORA-00289: sugestão : /u01/archive/1_1_684148997.dbf
ORA-00280: alterar 187046 para o thread 1 está na seqüência #1

Especificar log: {=nome de arquivo | sugerido | AUTO | CANCEL}
AUTO
ORA-00279: alterar 187315 gerado em 04/15/2009 13:34:12 necessário para o thread 1
ORA-00289: sugestão : /u01/archive/1_2_684148997.dbf
ORA-00280: alterar 187315 para o thread 1 está na seqüência #2
ORA-00278: o arquivo de log '/u01/archive/1_1_684148997.dbf' não é mais
necessário para esta recuperação

ORA-00279: alterar 187390 gerado em 04/15/2009 13:34:13 necessário para o thread 1
ORA-00289: sugestão : /u01/archive/1_3_684148997.dbf
ORA-00280: alterar 187390 para o thread 1 está na seqüência #3
ORA-00278: o arquivo de log '/u01/archive/1_2_684148997.dbf' não é mais
necessário para esta recuperação

ORA-00279: alterar 187467 gerado em 04/15/2009 13:34:15 necessário para o thread 1
ORA-00289: sugestão : /u01/archive/1_4_684148997.dbf
ORA-00280: alterar 187467 para o thread 1 está na seqüência #4
ORA-00278: o arquivo de log '/u01/archive/1_3_684148997.dbf' não é mais
necessário para esta recuperação

ORA-00279: alterar 187541 gerado em 04/15/2009 13:34:16 necessário para o thread 1
ORA-00289: sugestão : /u01/archive/1_5_684148997.dbf
ORA-00280: alterar 187541 para o thread 1 está na seqüência #5
ORA-00278: o arquivo de log '/u01/archive/1_4_684148997.dbf' não é mais
necessário para esta recuperação

ORA-00279: alterar 187617 gerado em 04/15/2009 13:34:20 necessário para o thread 1
ORA-00289: sugestão : /u01/archive/1_6_684148997.dbf
ORA-00280: alterar 187617 para o thread 1 está na seqüência #6
ORA-00278: o arquivo de log '/u01/archive/1_5_684148997.dbf' não é mais
necessário para esta recuperação

ORA-00279: alterar 187693 gerado em 04/15/2009 13:34:21 necessário para o thread 1
ORA-00289: sugestão : /u01/archive/1_7_684148997.dbf
ORA-00280: alterar 187693 para o thread 1 está na seqüência #7
ORA-00278: o arquivo de log '/u01/archive/1_6_684148997.dbf' não é mais
necessário para esta recuperação

ORA-00279: alterar 187769 gerado em 04/15/2009 13:34:22 necessário para o thread 1
ORA-00289: sugestão : /u01/archive/1_8_684148997.dbf
ORA-00280: alterar 187769 para o thread 1 está na seqüência #8
ORA-00278: o arquivo de log '/u01/archive/1_7_684148997.dbf' não é mais
necessário para esta recuperação

ORA-00279: alterar 187909 gerado em 04/15/2009 13:34:26 necessário para o thread 1
ORA-00289: sugestão : /u01/archive/1_9_684148997.dbf
ORA-00280: alterar 187909 para o thread 1 está na seqüência #9
ORA-00278: o arquivo de log '/u01/archive/1_8_684148997.dbf' não é mais
necessário para esta recuperação

ORA-00279: alterar 187982 gerado em 04/15/2009 13:34:27 necessário para o thread 1
ORA-00289: sugestão : /u01/archive/1_10_684148997.dbf
ORA-00280: alterar 187982 para o thread 1 está na seqüência #10
ORA-00278: o arquivo de log '/u01/archive/1_9_684148997.dbf' não é mais
necessário para esta recuperação

ORA-00279: alterar 188055 gerado em 04/15/2009 13:34:28 necessário para o thread 1
ORA-00289: sugestão : /u01/archive/1_11_684148997.dbf
ORA-00280: alterar 188055 para o thread 1 está na seqüência #11
ORA-00278: o arquivo de log '/u01/archive/1_10_684148997.dbf' não é mais
necessário para esta recuperação

ORA-00279: alterar 188127 gerado em 04/15/2009 13:34:32 necessário para o thread 1
ORA-00289: sugestão : /u01/archive/1_12_684148997.dbf
ORA-00280: alterar 188127 para o thread 1 está na seqüência #12
ORA-00278: o arquivo de log '/u01/archive/1_11_684148997.dbf' não é mais
necessário para esta recuperação

ORA-00279: alterar 188197 gerado em 04/15/2009 13:35:05 necessário para o thread 1
ORA-00289: sugestão : /u01/archive/1_13_684148997.dbf
ORA-00280: alterar 188197 para o thread 1 está na seqüência #13
ORA-00278: o arquivo de log '/u01/archive/1_12_684148997.dbf' não é mais
necessário para esta recuperação

ORA-00308: não é possível abrir o log '/u01/archive/1_13_684148997.dbf arquivado'
ORA-27037: não é possível obter status do arquivo
Linux Error: 2: No such file or directory
Additional information: 3

Agora a pergunta que não quer calar: Como é possível o arquivo de controle saber da existência dos arquivos de redo log arquivados sendo que os mesmos não foram gerados anteriormente (antes do cold backup)? Na verdade, ele não sabe e nem teria como saber, então podemos chegar a conclusão de que este é um comportamento padrão quando utilizamos a cláusula USING BACKUP CONTROLFILE do comando RECOVER DATABASE, ou seja, o processo de recuperação irá perguntar automaticamente e de forma seqüencial por arquivos de redo log arquivados e, caso o processo localize o arquivo de redo log arquivado, o mesmo será fornecido como opção para ser aplicado até o momento em que desejarmos cancelar a operação (CANCEL).

SQL> alter database open resetlogs;
alter database open resetlogs
*
ERRO na linha 1:
ORA-01113: o arquivo 1 precisa da recuperação de mídia
ORA-01110: 1 do arquivo de dados: '/u01/app/oracle/oradata/BD01/system01.dbf'

Podemos ver acima que após a aplicação de todos os arquivos de redo log arquivados possíveis (logs de 1 até 12), mesmo assim ainda não foi possível abrir o banco de dados, isso porque será necessário sinalizar o final do processo de recuperação utilizando a cláusula UNTIL CANCEL, pois o arquivo de redo log arquivado 1_13_684148997.dbf apesar de não existir, realmente não seria necessário como demonstrado abaixo:

SQL> recover database using backup controlfile until cancel;
ORA-00279: alterar 188197 gerado em 04/15/2009 13:35:05 necessário para o thread 1
ORA-00289: sugestão : /u01/archive/1_13_684148997.dbf
ORA-00280: alterar 188197 para o thread 1 está na seqüência #13


Especificar log: {=nome de arquivo | sugerido | AUTO | CANCEL}
CANCEL

recuperação de mídia cancelada.

Pronto. Após aplicados todos os arquivos de redo log arquivados possíveis, poderemos então abrir o banco de dados com a opção RESETLOGS.

SQL> alter database open resetlogs;

Banco de dados alterado.

Apenas para certificar que o banco de dados foi realmente recuperado até a última transação, selecionarei o registro da tabela SCOTT.T2 criada antes da realização do cold backup, para verificar se o registro inserido foi recuperado com sucesso.

SQL> connect scott/tiger
Conectado.

SQL> select * from t2;

DATA
--------------------------
15/04/2009 13:34:36,883986


segunda-feira, 6 de abril de 2009

E assim se passaram 3 anos ... CPU - Critical Patch Updates

Olá,

Para quem não se lembra, hoje, em 6 de Abril de 2009, faz exatamente 3 anos que a Oracle lançou uma nota (Note 363848.1) no Oracle Metalink, atualmente conhecido como My Oracle Support, sobre uma vulnerabilidade de segurança que afeta todas as versões do Oracle 9i (9.2.0.1) até o Oracle 10g (10.2.0.3), mas que na verdade afeta todas as versões do seu banco de dados Oracle desde a versão 7.3. Essa vulnerabilidade permite que um usuário com o privilégio de SELECT nas tabelas base de outro usuário execute operações (UPDATE, DELETE e INSERT) à partir de uma VIEW. Há inclusive quem diga que não seja nem mesmo necessário criar uma view de banco de dados para executar estas operações DML's ...

Atualmente esta nota não está mais acessível ao público por razões de segurança. No mais, quero apenas salientar que minha intenção com este artigo não é a de ressuscitar um assunto do passado, mas a de ALERTAR todos os DBA's que ainda insistem em não aplicar as correções críticas (Critical Patche Updates) recomendadas pela Oracle nas versões de seus bancos de dados de produção. Digo isso porque tenho visto muitos bancos de dados Oracle por aí (8i/9i/10g) nas quais jamais foram atualizados ou tiveram quaisquer correções aplicadas em seu software.

Como primeira solução (workaround) para este problema, foi sugerido revogar da role CONNECT os privilégios de sistema CREATE VIEW e CREATE DATABASE LINK, assim como revogar das contas de todos os usuários de banco de dados o privilégio CREATE VIEW porventura concedida de forma desnecessária. Felizmente a correção definitiva para o problema veio através do Oracle Critical Patch Update - October 2006.

Para demonstrar tal vulnerabilidade, irei demonstrar abaixo utilizando o Oracle 10g release 2 (10.2.0.1), como é possível executar tais operações DML's em uma tabela de outro usuário através de uma view, tendo este usuário apenas os privilégios CREATE VIEW e CREATE SESSION. Por questões de ética, bom senso e segurança, não irei disponibilizar o código de criação da view:


C:\>sqlplus system/manager

SQL*Plus: Release 10.2.0.1.0 - Production on Seg Abr 6 08:13:12 2009

Copyright (c) 1982, 2005, Oracle.  All rights reserved.

Conectado a:
Oracle Database 10g Release 10.2.0.1.0 - Production

-- Criação do usuário USUARIO1
SYSTEM> create user usuario1 identified by usuario1 default tablespace users;

Usuário criado.

-- Criação do usuário USUARIO2
SYSTEM> create user usuario2 identified by usuario2 default tablespace users;

Usuário criado.

-- Concessão padrão para o USUARIO1
SYSTEM> grant connect,resource to usuario1;

Concessão bem-sucedida.

-- Concessão dos privilégios CREATE VIEW e CREATE SESSION para o USUARIO2
SYSTEM> grant create view, create session to usuario2;

Concessão bem-sucedida.

-- Conectando com o USUARIO1
SYSTEM> connect usuario1/usuario1
Conectado.

-- Criação de uma tabela para teste
USUARIO1> create table t1 (id number constraint pk_t1 primary key);

Tabela criada.

-- Criação de 10 registros na tabela T1 para realização da simulação
USUARIO1> insert into t1 select level from dual connect by level <= 10;

10 linhas criadas.

USUARIO1> commit;

Validação completa.

USUARIO1> select * from t1;

        ID
----------
         1
         2
         3
         4
         5
         6
         7
         8
         9
        10

10 linhas selecionadas.

-- Concessão de privilégio SELECT na tabela T1 para o USUARIO2
USUARIO1> grant select on t1 to usuario2;

Concessão bem-sucedida.

-- Conectando com o USUARIO2
USUARIO1> connect usuario2/usuario2
Conectado.

USUARIO2> select * from usuario1.t1;

        ID
----------
         1
         2
         3
         4
         5
         6
         7
         8
         9
        10

10 linhas selecionadas.

USUARIO2> delete from usuario1.t1;
delete from usuario1.t1
                     *
ERRO na linha 1:
ORA-01031: privilégios insuficientes


Podemos perceber acima que o usuário USUARIO2 realmente terá apenas o privilégio de SELECT na tabela T1 de propriedade do usuário USUARIO1. Portanto, qualquer comando (DELETE, INSERT, UPDATE) executado contra a tabela T1 falhará ocasionando assim o erro [ORA-01031: privilégios insuficientes]. A questão muda de figura à partir do momento em que o usuário USUARIO2 criar uma view um pouco maliciosa ...


USUARIO2> create view v_t1 as ([censurado]);

View criada.

USUARIO2> select * from v_t1;

        ID
----------
         1
         2
         3
         4
         5
         6
         7
         8
         9
        10

10 linhas selecionadas.

-- Deletando registros da tabela T1 à partir da view V_T1
USUARIO2> delete from v_t1;

10 linhas deletadas.

USUARIO2> commit;

Validação completa.

USUARIO2> select * from usuario1.t1;

não há linhas selecionadas


Podemos ver acima que o usuário USUARIO2 conseguiu deletar todos os registros da tabela T1 à partir da view V_T1, mesmo não tendo privilégios de DELETE na tabela T1 de propriedade do usuário USUARIO1.


USUARIO2> insert into usuario1.t1 values (1);
insert into usuario1.t1 values (1)
                     *
ERRO na linha 1:
ORA-01031: privilégios insuficientes

USUARIO2> insert into v_t1 values (1);

1 linha criada.

USUARIO2> update usuario1.t1 set id=2;
update usuario1.t1 set id=2
                *
ERRO na linha 1:
ORA-01031: privilégios insuficientes

USUARIO2> update v_t1 set id=2;

1 linha atualizada.

USUARIO2> commit;

Validação completa.

USUARIO2> select * from usuario1.t1;

        ID
----------
         2


Acima podemos perceber que o usuário USUARIO2 também conseguiu inserir e atualizar registros na tabela T1 à partir da view V_T1 mesmo não tendo privilégios de UPDATE e INSERT.