segunda-feira, 14 de novembro de 2011

Oracle Standby Database 1/2


Neste artigo descreverei os procedimentos para a criação, ativação e gerenciamento de uma configuração do “standby database”.

Oracle Standby Database Conceito - O “standby database” é uma “feature” do Oracle, utilizada como plano de contingência do banco de dados. Sua arquitetura é constituída por um banco primário e um ou mais bancos secundários, versões mais recentes do Oracle são conhecidas também como Oracle Data Guard.

A principal diferença entre o “Standby” é o “Data Guard” é que o Data Guard possuí níveis maiores de configuração para a segurança da base de dados principal. Na prática alguns parâmetros podem ser ajustados para melhorar a verificação da base principal e em caso de queda ou interrupção o banco de dados secundário assume automaticamente como base principal.

Neste artigo irei descrever os passos para a criação de um banco em modo “standby”.  Este artigo será dividido em duas partes a primeira será apresentado a criação do banco e na segunda parte será apresentado gerenciamento e administração.

Segue abaixo os passos necessários para a criação de um “Standby Database”.

1.   Habilitar o banco de dados primário em FORCE LOGGING.
Executar: alter database force logging;

2.   Configurar o redo log para o “standby” no banco primário.
Executar: alter database add standby logfile group 4 size 50m;

Nota: Adicionar a quantidade de “redo logs” conforme a quantidade de “redo logs” do banco de dados primário, o comando acima serve como exemplo.


3.   Gerar o arquivo de “pfile”.
Executar: create pfile='+.ora’ from spfile;

E editar o “init.ora” e incluir os parâmetros no “init.ora” do banco primário.

*.LOG_ARCHIVE_CONFIG='DG_CONFIG=(base,basestd)'
*.LOG_ARCHIVE_DEST_1='LOCATION=/u03/oradata/base/arch/ VALID_FOR=(ALL_LOGFILES,ALL_ROLES) DB_UNIQUE_NAME=base'
*.LOG_ARCHIVE_DEST_2='SERVICE=basestd LGWR ASYNC VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=basestd'
*.LOG_ARCHIVE_DEST_STATE_1=ENABLE
*.LOG_ARCHIVE_DEST_STATE_2=ENABLE
*.LOG_ARCHIVE_FORMAT=arch_%r_%t_%s.arc
*.LOG_ARCHIVE_MAX_PROCESSES=30
*.fal_server=BASE
*.fal_client=BASESTD
*.standby_file_management=auto

4.   Recriar o arquivo “spfile” do banco de dados primário.
Executar: create spfile  from pfile='+.ora’;

5.   Verificar o “archives” antes da cópia.
Executar: Archive log list;

6.   Colocar o banco de dados primário em “begin backup”.
Executar : alter database begin backup;

7.   Copiar os datafiles e tempfiles para o servidor DESTINO.

Executar a query abaixo, para gerar o comando que irá realizar a cópia dos datafiles:

select 'scp '||substr(file_name,1,43)||' 100.107.10.153:'||substr(file_name,1,43)
  from dba_data_files
 order by 1;

Executar a query abaixo, para gerar o comando que irá realizar a cópia dos tempfiles:

select 'scp '||substr(file_name,1,43)||' 100.107.10.153:'||substr(file_name,1,43)
  from dba_temp_files

Nota: Substituir o endereço IP para o endereço do seu servidor (endereço meramente ilustrativo).

8.   Ao término das cópias dos datafiles e tempfiles retirar o banco de dados primário do status de  “end backup”.
Executar : alter database end backup;

9.   Verificar o “archives” depois da cópia.
Executar : archive log list;

10. Gerar um “control file standby” no banco de primário.
Executar: alter database create standby controlfile as '/';

11. Copiar o “control file” do servidor primário para o servidor do “standby” .
Executar:
 scp /home/oracle/control_stdby.ctl 100.107.10.153:/home/oracle/control_stdby.ctl

Nota: Após a cópia do “control file” de STANDBY copiar os “control files” para as cópias existentes, abaixo segue um exemplo:

copy control_stdby.ctl contro01.ctl
copy control_stdby.ctl contro02.ctl
copy control_stdby.ctl contro03.ctl

12. Copiar os “redo logs” do servidor primário para o servidor secundário.
Executar:
select 'scp '||substr(member,1,33)||' 100.107.10.153:'||substr(member,1,33)
  from v$logfile order by 1;

13. Copiar os arquivos de “init.ora”, “spfiles”, “orapwd”,”listener”, “tnsnames”, “sqlnet”.
Executar:
scp /u01/app/oracle/ora11/dbs/initbase.ora 
100.107.10.153:/u01/app/oracle/ora11/dbs/initbase.ora

scp /u01/app/oracle/ora11/dbs/spfilebase.ora 
100.107.10.153:/u01/app/oracle/ora11/dbs/spfilebase.ora

scp /u01/app/oracle/ora11/dbs/orapwbase
100.107.10.153:/u01/app/oracle/ora11/dbs/orapwbase

scp /u01/app/oracle/ora11/network/admin/listener.ora
100.107.10.153:/u01/app/oracle/ora11/network/admin/listener.ora

scp /u01/app/oracle/ora11/network/admin/tnsnames.ora 100.107.10.153:/u01/app/oracle/ora11/network/admin/tnsnames.ora

scp /u01/app/oracle/ora11/network/admin/sqlnet.ora
100.107.10.153:/u01/app/oracle/ora11/network/admin/sqlnet.ora

14. Verificar os caminhos dos parâmetros, control_files, log_archive_dest(n) no banco “standby”.

15. Criar o arquivo “pfile” para o “standby” a partir do banco de dados primário.
Executar: create pfile='+.ora’ from spfile;

16.  Ajustar os arquivos TNSNAMES.ora nos servidores primários e “standby”.
Incluir as entradas abaixo:

base  =
(description =
   (address_list =
      (address=(protocol=tcp)(host=100.117.20.143)(port=1521))
      (ADDRESS = (PROTOCOL = TCP)(HOST = 100.117.20.143)(PORT = 1525))
      (ADDRESS = (PROTOCOL = TCP)(HOST = 100.117.20.143)(PORT = 1526))
      (ADDRESS = (PROTOCOL = TCP)(HOST = 100.117.20.143)(PORT = 1527))
      (ADDRESS = (PROTOCOL = TCP)(HOST = 100.117.20.143)(PORT = 1528))
      )
   (connect_data=(sid=base)))

basestd  =
(description =
   (address_list =
      (address=(protocol=tcp)(host=100.107.10.153)(port=1521))
      (ADDRESS = (PROTOCOL = TCP)(HOST = 100.107.10.153)(PORT = 1525))
      (ADDRESS = (PROTOCOL = TCP)(HOST = 100.107.10.153)(PORT = 1526))
      (ADDRESS = (PROTOCOL = TCP)(HOST = 100.107.10.153)(PORT = 1527))
      (ADDRESS = (PROTOCOL = TCP)(HOST = 100.107.10.153)(PORT = 1528))    
      )
   (connect_data=(sid=base)))

17.  Ajustar o arquivo LISTENER.ora, incluir a entrada do banco de dados “standby”.

SID_LIST_LISTENER =
  (SID_LIST =
    (SID_DESC =
      (SID_NAME = PLSExtProc)
      (ORACLE_HOME = /u01/app/oracle/ora11)
      (PROGRAM = extproc)
    )

    (SID_DESC =
      (SID_NAME = base)
      (GLOBAL_DBNAME = basestd)
      (ORACLE_HOME = /u01/app/oracle/ora11)
    )
  )

LISTENER =
  (DESCRIPTION_LIST =
    (DESCRIPTION =
      (ADDRESS = (PROTOCOL = TCP)(HOST = 100.107.10.153)(PORT = 1521))
      (ADDRESS = (PROTOCOL = TCP)(HOST = 100.107.10.153)(PORT = 1525))
      (ADDRESS = (PROTOCOL = TCP)(HOST = 100.107.10.153)(PORT = 1526))
      (ADDRESS = (PROTOCOL = TCP)(HOST = 100.107.10.153)(PORT = 1527))
      (ADDRESS = (PROTOCOL = TCP)(HOST = 100.107.10.153)(PORT = 1528))
    )
  )

18.  Validar as conexões do banco primário para o “standby”, via sistema operacional executar:
 tnsping basestd

19.  Validar as conexões do banco “standby” para o primário, via sistema operacional executar:
tnsping base

20.  Levantar e montar o banco de dados “standby”.
Executar:
startup nomount;
alter database mount standby database;

21.  Ativar a atualização automática do “standby”.
Executar:
alter database recover managed standby database disconnect from session;


A partir desse comando o banco de dados “standby”está configurado, no próximo artigo estarei demonstrando como gerenciar um banco “standby”.



Rubens Oliveira
DBA Oracle Consultor
olivert.dba@consultant.com

terça-feira, 1 de novembro de 2011

Tabelas em modo de leitura (read-only) no Oracle 11g


Em versões anteriores do Oracle ao 11g, não existia a possibilidade de ter tabelas em modo de leitura (read-only). Para que os usuários do banco de dados pudessem somente ler as informações das tabelas, o DBA tinha que conceder somente o privilégio de SELECT na tabela desejada, não permitindo mais operações. A partir da versão 11g o banco de dados permite que as tabelas sejam configuradas somente em modo de leitura (read-only) usando o comando ALTER TABLE.

Deve-se utilizar:

Para habilitar o modo de leitura:

ALTER TABLE table_name READ ONLY;
  
Para habilitar o modo de gravação:

ALTER TABLE table_name READ WRITE;

A seguir será demonstrada a criação de uma tabela, a inserção de uma linha, na sequência a tabela será colocada em modo de leitura (read-only).

Criando a tabela:

CREATE TABLE TABELA_LEITURA (id NUMBER);

Inserindo uma linha na tabela criada:

INSERT INTO TABELA_LEITURA VALUES (1);
  
Alterando a tabela para o modo de leitura (read-only):

ALTER TABLE TABELA_LEITURA READ ONLY;

Depois de alterar a tabela para o modo de leitura. Qualquer comando DML executado pelo banco de dados que afete os dados da tabela e o comando “SELECT...FOR UPDATE” apresentarão a mensagem de erro ORA-12081, indicando que a operação não é permitida.


ORA-12081: update operation not allowed on table "string"."string"

SQL> INSERT INTO TABELA_LEITURA VALUES (2);
INSERT INTO TABELA_LEITURA VALUES (2)
            *
ERROR at line 1:
ORA-12081: update operation not allowed on table "DEMO"."TABELA_LEITURA"

SQL> UPDATE TABELA_LEITURA SET id = 2;
UPDATE TABELA_LEITURA SET id = 2
       *
ERROR at line 1:
ORA-12081: update operation not allowed on table "DEMO"."TABELA_LEITURA"

SQL> DELETE FROM TABELA_LEITURA;
DELETE FROM TABELA_LEITURA
            *
ERROR at line 1:
ORA-12081: update operation not allowed on table "DEMO"."TABELA_LEITURA"

Declarações DDL que também afetam os dados da tabela serão restringidas.

SQL> TRUNCATE TABLE TABELA_LEITURA;
TRUNCATE TABLE TABELA_LEITURA
               *
ERROR at line 1:
ORA-12081: update operation not allowed on table "DEMO"."TABELA_LEITURA"

SQL> ALTER TABLE TABELA_LEITURA ADD (description VARCHAR2(50));
ALTER TABLE TABELA_LEITURA ADD (description VARCHAR2(50))
*
ERROR at line 1:
ORA-12081: update operation not allowed on table "DEMO"."TABELA_LEITURA"

As operações de criação de índices associados à tabela NÃO são afetadas pela restrição de leitura.

Após a alteração da tabela para o modo de gravação (read-write) as operações de DML e DDL voltarão ao normal, conforme demonstrado.

Alterando a tabela para o modo de gravação (read-write):


SQL> ALTER TABLE TABELA_LEITURA READ WRITE;
Table altered.

Removendo as linhas da tabela:

SQL> DELETE FROM TABELA_LEITURA;
1 row deleted.

O status de leitura das tabelas é exibido através da coluna READ_ONLY nas visões [DBA ​​| ALL | USER]_TABLES.



Rubens Oliveira
DBA Oracle Consultor
olivert.dba@consultant.com