Mostrando las entradas con la etiqueta dataguard. Mostrar todas las entradas
Mostrando las entradas con la etiqueta dataguard. Mostrar todas las entradas

miércoles, 11 de junio de 2014

Clonación de una BD desde un snapshot de mi base de datos Standby Física

El otro día tuve un cliente que cuando estábamos planeando la solución de sus respaldos, el tenía la necesidad de tomar snapshots de su entorno productivo y de ese snapshot, clonar a sus entornos dev / QA.

Así que a continuación es el resultado del planteamiento de esa solución, probablemente, no es nada que no hayas visto, pero si no , ahí te va.

A pesar de que estoy usando el DG broker, con el propósito de este ejercicio, voy a hacerlo a través de la interfaz de sqlplus, pero quería mostrarte antes el entorno en el DGMGRL.

Para ello, voy a utilizar 2 bases de datos, como mi standby a orclstby  y para el duplicado a orcltest

[oracle@adg12c ~]$ df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/mapper/VolGroup00-LogVol00
                       26G   22G  3.3G  87% /
/dev/sda1              99M   24M   71M  25% /boot
tmpfs                 2.0G  641M  1.4G  33% /dev/shm
/dev/sdb1              12G  159M   12G   2% /u02
[oracle@adg12c ~]$ . oraenv
ORACLE_SID = [oracle] ? orcl
The Oracle base has been set to /u01/app/oracle
[oracle@adg12c ~]$ dgmgrl
DGMGRL for Linux: Version 12.1.0.1.0 - 64bit Production

Copyright (c) 2000, 2012, Oracle. All rights reserved.

Welcome to DGMGRL, type "help" for information.
DGMGRL> connect sys/oracle
Connected as SYSDG.
DGMGRL> show configuration

Configuration - DGCONFIG

  Protection Mode: MaxPerformance
  Databases:
  orcl     - Primary database
    farsync  - Far Sync 
      orclstby - Physical standby database 
    farsync2 - Far Sync (inactive)

Fast-Start Failover: DISABLED

Configuration Status:
SUCCESS

DGMGRL> exit

Para que esto funcione, y no tener ningún problema, hay que asegurarse de que el Standby DB sea consistente, y para ello hay que detener la aplicación de redo en el entorno de DG para la que el snapshot pueda suceder . También detuve la BD standby, a pesar de que eso no es necesario.

[oracle@adg12c ~]$ . oraenv
ORACLE_SID = [orcl] ? orclstby
The Oracle base has been set to /u01/app/oracle

[oracle@adg12c ~]$ sqlplus

SQL*Plus: Release 12.1.0.1.0 Production on Wed Jun 11 17:49:05 2014

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

Enter user-name: /as sysdba

Connected to:
Oracle Database 12c Enterprise Edition Release 12.1.0.1.0 - 64bit Production
With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options

SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL;


Database altered.

SQL> shutdown immediate
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> exit

El snapshot se toma durante este proceso, y para este ejercicio, el resultado del snapshot fue puesto en el siguiente directorio /u02/app/oracle/oradata/orcltest/, en el mismo servidor, pero este se puede poner en otro servidor. Puedes emular esto con un scp (scp -r /u01/app/oracle/oradata/orclstby/ /u02/app/oracle/oradata/orcltest/)

[oracle@adg12c orclstby]$ cd /u02/app/oracle/oradata/orcltest/
[oracle@adg12c orcltest]$ ls
orclstby
[oracle@adg12c orcltest]$ cd orclstby
[oracle@adg12c orclstby]$ ls
control01.ctl  ORCLSTBY  redo01.log  redo03.log  srl02.log  srl04.log     system01.dbf  undotbs01.dbf
orcl_pdb       pdbseed   redo02.log  srl01.log   srl03.log  sysaux01.dbf  temp01.dbf    users01.dbf

También una vez que el snapshot ha terminado, arrancamos la BD Standby orclstby. 

[oracle@adg12c orclstby]$ . oraenv
ORACLE_SID = [farsync2] ? orclstby
The Oracle base remains unchanged with value /u01/app/oracle
[oracle@adg12c orclstby]$ sqlplus

SQL*Plus: Release 12.1.0.1.0 Production on Wed Jun 11 18:43:18 2014

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

Enter user-name: /as sysdba
Connected to an idle instance.

SQL> startup mount
ORACLE instance started.

Total System Global Area  409194496 bytes
Fixed Size                  2288968 bytes
Variable Size             318767800 bytes
Database Buffers           79691776 bytes
Redo Buffers                8445952 bytes
Database mounted.
SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE DISCONNECT FROM SESSION;

Database altered.

Así que ahora el siguiente paso, es crear un pfile para la base de datos orcltest, aquí también hay que cambiar la locación de los archivos correspondientes a la nueva ubicación.

[oracle@adg12c orclstby]$ cat /tmp/initorcltest.ora
*.archive_lag_target=0
*.audit_file_dest='/u02/app/oracle/admin/orcl/adump'
*.audit_trail='db'
*.compatible='12.1.0.0.0'
*.control_files='/u02/app/oracle/oradata/orcltest/orclstby/control01.ctl','/u02/app/oracle/oradata/orcltest/orclstby/control02.ctl'
*.db_block_size=8192
*.db_domain='oracle.com'
*.db_name='orcltest'
*.db_recovery_file_dest='/u02/app/oracle/recovery_area'
*.db_recovery_file_dest_size=5368709120
*.dg_broker_start=TRUE
*.diagnostic_dest='/u02/app/oracle'
*.dispatchers='(PROTOCOL=TCP) (SERVICE=orclXDB)'
*.enable_pluggable_database=true
*.log_archive_dest_1='LOCATION=USE_DB_RECOVERY_FILE_DEST'
orcl.log_archive_format='%t_%s_%r.dbf'
*.log_archive_max_processes=4
*.log_archive_min_succeed_dest=1
orcl.log_archive_trace=0
*.memory_target=390m
*.open_cursors=300
*.processes=300
*.remote_login_passwordfile='EXCLUSIVE'
*.undo_tablespace='UNDOTBS1'


[oracle@adg12c orclstby]$ . oraenv
ORACLE_SID = [orclstby] ? orcltest
ORACLE_HOME = [/home/oracle] ? /u01/app/oracle/product/12.1.0/dbhome_1
The Oracle base remains unchanged with value /u01/app/oracle
[oracle@adg12c orclstby]$ sqlplus

SQL*Plus: Release 12.1.0.1.0 Production on Wed Jun 11 18:30:28 2014

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

Enter user-name: /as sysdba
Connected to an idle instance.

SQL> startup nomount pfile='/tmp/initorcltest.ora';
ORACLE instance started.

Total System Global Area  409194496 bytes
Fixed Size                  2288968 bytes
Variable Size             318767800 bytes
Database Buffers           79691776 bytes
Redo Buffers                8445952 bytes

Ahora, sólo tenemos que crear el controlfile con la ubicación del snapshot de los datafiles y cambiarle el nombre de a la base de datos a orlctest.

SQL> CREATE CONTROLFILE SET DATABASE "orcltest" RESETLOGS
    MAXLOGFILES 16
    MAXLOGMEMBERS 3
    MAXDATAFILES 1024
    MAXINSTANCES 8
    MAXLOGHISTORY 292
LOGFILE
  GROUP 1 '/u02/app/oracle/oradata/orcltest/orclstby/redo01.log'  SIZE 50M BLOCKSIZE 512,
  GROUP 2 '/u02/app/oracle/oradata/orcltest/orclstby/redo02.log'  SIZE 50M BLOCKSIZE 512,
  GROUP 3 '/u02/app/oracle/oradata/orcltest/orclstby/redo03.log'  SIZE 50M BLOCKSIZE 512
DATAFILE
  '/u02/app/oracle/oradata/orcltest/orclstby/system01.dbf',
  '/u02/app/oracle/oradata/orcltest/orclstby/sysaux01.dbf',
  '/u02/app/oracle/oradata/orcltest/orclstby/undotbs01.dbf',
  '/u02/app/oracle/oradata/orcltest/orclstby/pdbseed/system01.dbf',
  '/u02/app/oracle/oradata/orcltest/orclstby/users01.dbf',
  '/u02/app/oracle/oradata/orcltest/orclstby/pdbseed/sysaux01.dbf',
  '/u02/app/oracle/oradata/orcltest/orclstby/orcl_pdb/system01.dbf',
  '/u02/app/oracle/oradata/orcltest/orclstby/orcl_pdb/sysaux01.dbf',
  '/u02/app/oracle/oradata/orcltest/orclstby/orcl_pdb/SAMPLE_SCHEMA_users01.dbf',
  '/u02/app/oracle/oradata/orcltest/orclstby/orcl_pdb/example01.dbf'
CHARACTER SET WE8MSWIN1252
;
  2    3    4    5    6    7    8    9   10   11   12   13   14   15   16   17   18   19   20   21   22   23  
Control file created.

SQL> RECOVER DATABASE
ORA-00283: recovery session canceled due to errors
ORA-01610: recovery using the BACKUP CONTROLFILE option must be done


SQL> ALTER DATABASE OPEN RESETLOGS;

Database altered.

SQL> ALTER PLUGGABLE DATABASE ALL OPEN;

Pluggable database altered.

SQL> ALTER TABLESPACE TEMP ADD TEMPFILE '/u02/app/oracle/oradata/orcltest/orclstby/temp01.dbf'
     SIZE 62914560  REUSE AUTOEXTEND ON NEXT 655360  MAXSIZE 32767M;
ALTER SESSION SET CONTAINER = PDB$SEED;
ALTER TABLESPACE TEMP ADD TEMPFILE '/u02/app/oracle/oradata/orcltest/orclstby/pdbseed/pdbseed_temp01.dbf'
     SIZE 20971520  REUSE AUTOEXTEND ON NEXT 655360  MAXSIZE 32767M;
ALTER SESSION SET CONTAINER = ORCL_PDB;
ALTER TABLESPACE TEMP ADD TEMPFILE '/u02/app/oracle/oradata/orcltest/orclstby/orcl_pdb/orcl_pdb_temp01.dbf'
     SIZE 20971520  REUSE AUTOEXTEND ON NEXT 655360  MAXSIZE 32767M;
ALTER SESSION SET CONTAINER = CDB$ROOT;
  2  
Tablespace altered.

SQL> 
Session altered.

SQL>   2  
Tablespace altered.

SQL> 
Session altered.

SQL>   2  

Tablespace altered.

SQL> 
Session altered.

Y como puedes ver, la nueva BD está en corriendo y funcionando de un snapshot de la base de datos standby.

SQL> set lines 200 pages 9999
SQL>SELECT NAME,OPEN_MODE,PROTECTION_MODE,
       PROTECTION_LEVEL,
       DATABASE_ROLE ROLE,
       SWITCHOVER_STATUS
FROM V$DATABASE;
  
NAME      OPEN_MODE            PROTECTION_MODE      PROTECTION_LEVEL     ROLE             SWITCHOVER_STATUS
--------- -------------------- -------------------- -------------------- ---------------- --------------------
ORCLTEST  READ WRITE           MAXIMUM PERFORMANCE  UNPROTECTED          PRIMARY          NOT ALLOWED

SQL> select host_name,instance_name from gv$instance;

HOST_NAME                                                        INSTANCE_NAME
---------------------------------------------------------------- ----------------
adg12c.oracle.com                                                orcltest

Conclusión

Esta no es la forma recomendada de hacerlo, pero eso no quiere decir que no se puede hacer. También puedes tener pérdida de datos, ya que si la BD primaria no esta totalmente sincronizada con la BD standby, vas a tener un hueco, así que tienes que estar seguro de el último redo log haya sido aplicado. De igual manera, asegurate de que esto no tenga un impacto en tu ambiente de alta disponibilidad, ya que aunque sea por pocos minutos , la replicación de tu ambiente DG estará inactivo para que puedas tener un snapshot de una base de datos consistente.




lunes, 26 de mayo de 2014

Oracle 12cR1 : Como configurar una BD Standby en cascada con la propiedad RedoRoutes

En una de las entradas pasadas, vimos como crear una instancia Far Sync, que lo que realmente es,
es una instancia que en cascada manda los Redologs a las instancias que configuramos.

Algo que se podia hacer en 11g, es tener Standby's en cascada, pero no a través del broker. En Oracle 12c te permite hacer las configuraciones de las rutas de hacia donde quieres que se direccionen tus Redologs a través de la propiedad RedoRoutes del broker de 12c .

Para entender un poco de que es lo que queremos hacer , voy a hacer un dibujo de que es lo que queremos hacer.


Para este ejercicio, vamos a tener 3 bases de datos , una primaria, y dos Physical Standbys , asi como dos instancias FarSync, una local y otra remota.

  • Primaria: orcl
  • Remote Standby:orclstby
  • Remote Local Standby:orclrep

Aquí no te voy a decir como crear una Physical Standby, eso lo puedes ver en la entrada Como crear un Standby Fisico con RMAN Active Duplicate en 11.2.0.3 , aunque es para 11.2.0.3, aplica para 12cR1.

Lo primero que vamos a hacer, es deshabilitar la aplicación de los redologs en nuestras Base de Datos Standbys.

[oracle@adg12c ~]$ . oraenv
ORACLE_SID = [orcl] ? orcl
The Oracle base remains unchanged with value /u01/app/oracle
[oracle@adg12c ~]$ dgmgrl
DGMGRL for Linux: Version 12.1.0.1.0 - 64bit Production

Copyright (c) 2000, 2012, Oracle. All rights reserved.

Welcome to DGMGRL, type "help" for information.
DGMGRL> connect sys/oracle
Connected as SYSDG.
DGMGRL> edit database 'orclstby' set state='apply-off';
Succeeded.
DGMGRL> edit database 'orclrep' set state='apply-off';
Succeeded.

La propiedad de RedoRoutes, esta definida por reglas, y estas reglas se definen por el origen y el destino de los RedoLogs

(origen de los redologs : destino de los redo )

Si el redo source se define como LOCAL, se entiende que es la Base de Datos de donde se esta definiendo la propiedad.

Ahora vamos a definir las rutas de los Redologs, con la propiedad RedoRoutes del broker de Dataguard de 12c.

DGMGRL> edit database 'orclstby' set state='apply-off';
Succeeded.
DGMGRL> edit database 'orclrep' set state='apply-off';
Succeeded.
DGMGRL> edit database 'orcl' set property 'redoroutes'='( LOCAL : farsync SYNC)';
Succeeded.
DGMGRL> edit database 'orclstby' set property 'redoroutes'='(orcl : orclrep ASYNC)(orclrep : orcl ASYNC)(LOCAL : farsync2 SYNC)';
Succeeded.
DGMGRL> edit database 'orclrep' set property 'redoroutes'= '(orclrep : orclstby SYNC)';
Succeeded.
DGMGRL> edit far_sync 'farsync' set property 'redoroutes' = '(orcl : orclstby ASYNC )';
Succeeded.
DGMGRL> edit far_sync 'farsync2' set property 'redoroutes' ='(orclstby : orcl ASYNC, orclrep )';
Succeeded.
DGMGRL> edit database 'orclstby' set state='apply-on';
Succeeded.
DGMGRL> edit database 'orclrep' set state='apply-on';
Succeeded.

Como podemos ver en la configuración de nuestro dataguard, la BD orclrep, ahora esta recibiendo en cascada los RedoLogs de la standby orclstby , que ese era nuestro objetivo aqui, para asi poder liberar los recursos de la instancia FarSync, y se hiciera a través de la BD orclstby.


DGMGRL> show configuration;

Configuration - DGCONFIG

  Protection Mode: MaxPerformance
  Databases:
  orcl     - Primary database
    farsync  - Far Sync 
      orclstby - Physical standby database 
        orclrep  - Physical standby database (receiving current redo)
    farsync2 - Far Sync (inactive)

Fast-Start Failover: DISABLED

Configuration Status:
SUCCESS

Conclusion
Ahora Oracle 12cR1 te permite a través de su DG broker hacer configuraciones mas complejas para tu topología de DR con dataguard. De la misma manera, puedes jugar con tus configuraciones para ver que es lo que se acomoda a tus necesidades y poder validar la configuración antes de hacer un switchover.

miércoles, 30 de abril de 2014

Oracle 12cR1 : Como crear una instancia Far Sync para Active Data Guard

En Oracle 12c , se introduce el concepto de Far Sync Instance para Active Data Guard (ADG), esta instancia acepta redo de la base de datos principal en Standby Redo Logs (SRLs), y luego envia estos a los miembros de la configuración de ADG. Una instancia Far Sync, no tiene datafiles de usuario, no se puede abrir accederla, no se puede ejecutar Redo Apply, y nunca puede funcionar como BD principal o convertir en cualquier tipo de BD standby.

Lo que vamos a hacer aqui es configurar 2 instancias de Far Sync (farsync y farsync2), una que pertenezca a la Principal (orcl) y otra que pertenezca a la Standby (orclstby).

Primero en la BD orcl, vamos a crear el controlfile y el password file  para la instancia Far Sync

SQL> alter database create far sync instance controlfile as '/u01/app/oracle/oradata/farsync/control01.ctl'

Database altered.

SQL> !cp /u01/app/oracle/product/12.1.0/dbhome_1/dbs/orapworcl /u01/app/oracle/product/12.1.0/dbhome_1/dbs/orapwfarsync

Ahora vamos a crear los Standby Redo Logs para la instancia Far Sync

SQL> alter database add standby logfile '/u01/app/oracle/oradata/farsync/farsync01.log' size 50M;
 
Database altered.

SQL> alter database add standby logfile '/u01/app/oracle/oradata/farsync/farsync02.log' size 50M;
 
Database altered.

SQL> alter database add standby logfile '/u01/app/oracle/oradata/farsync/farsync03.log' size 50M;
 
Database altered.

SQL> alter database add standby logfile '/u01/app/oracle/oradata/farsync/farsync04.log' size 50M;
 
Database altered.

Vamos ahora a crear un archivo de parámetros (pfile) para la instancia Far Sync, y la vamos a subir

[oracle@adg12c ~]$ export ORACLE_SID=farsync

[oracle@adg12c ~]$ cat /u01/pfile.ora
*.archive_lag_target=0
*.audit_file_dest='/u01/app/oracle/admin/orcl/adump'
*.audit_trail='db'
*.compatible='12.1.0.0.0'
*.control_files='/u01/app/oracle/oradata/farsync/control01.ctl'
*.db_block_size=8192
*.db_domain='oracle.com'
*.db_name='orcl'
*.db_recovery_file_dest='/u01/app/oracle/recovery_area'
*.db_recovery_file_dest_size=5368709120
*.dg_broker_start=TRUE
*.diagnostic_dest='/u01/app/oracle'
*.dispatchers='(PROTOCOL=TCP) (SERVICE=orclXDB)'
*.enable_pluggable_database=true
*.log_archive_config='dg_config=(orcl,farsync,orclstby)'
*.log_archive_dest_1='LOCATION=USE_DB_RECOVERY_FILE_DEST VALID_FOR=(all_logfiles,all_roles) db_unique_name=farsync'
*.log_archive_dest_2='SERVICE=orclstby ASYNC VALID_FOR=(STANDBY_LOGFILES,STANDBY_ROLE) DB_UNIQUE_NAME=orclstby'
*.log_archive_dest_state_2='ENABLE'
*.log_archive_dest_state_3='ENABLE'
farsync.log_archive_format='%t_%s_%r.dbf'
*.log_archive_max_processes=4
*.log_archive_min_succeed_dest=1
farsync.log_archive_trace=0
*.open_cursors=300
*.processes=300
*.remote_login_passwordfile='EXCLUSIVE'
*.standby_file_management='MANUAL'
*.undo_tablespace='UNDOTBS1'
LOG_FILE_NAME_CONVERT='orcl',farsync'
DB_UNIQUE_NAME=farsync
FAL_SERVER=orcl

[oracle@adg12c ~]$ sqlplus

Enter user-name: /as sysdba

Connected to an idle instance.

SQL> startup nomount pfile=/u01/pfile.ora
SQL> ORACLE instance started.

Total System Global Area  246386688 bytes
Fixed Size                  2286992 bytes
Variable Size             188746352 bytes
Database Buffers           50331648 bytes
Redo Buffers                5021696 bytes
SQL> alter database mount

Database altered.

A continuación lo que vamos a hacer es agregar la configuración de la instancia Far Sync , al DG broker

[oracle@adg12c ~] export ORACLE_SID=orcl
[oracle@adg12c ~] sqlplus "/ as sysdba"
SQL> alter system set log_archive_dest_2='';

System altered.

SQL> exit

[oracle@adg12c ~] export ORACLE_SID=farsync
[oracle@adg12c ~] sqlplus "/ as sysdba" 
SQL> alter system set log_archive_dest_2='';

System altered.

SQL> exit

[oracle@adg12c ~] export ORACLE_SID=orcl
[oracle@adg12c ~] dgmgrl
DGMGRL> connect sys/oracle
Connected as SYSDG.
DGMGRL> add far_sync farsync as connect identifier is farsync;

far sync instance "farsync" added

DGMGRL> enable far_sync farsync;

Enabled.

DGMGRL> exit

[oracle@adg12c ~] export ORACLE_SID=orcl
[oracle@adg12c ~] sqlplus "/ as sysdba" 
SQL> alter system set log_archive_dest_2='service="orclstby"','ASYNC NOAFFIRM delay=0 optional compression=disable max_failure=0 max_connections=1 reopen=300 db_unique_name="orclstby" net_timeout=30','valid_for=(online_logfile,all_roles)';

System altered.

SQL> exit

[oracle@adg12c ~] export ORACLE_SID=farsync
[oracle@adg12c ~] sqlplus "/ as sysdba" 
SQL> alter system set log_archive_dest_2='SERVICE=orclstby ASYNC VALID_FOR=(STANDBY_LOGFILES,STANDBY_ROLE) DB_UNIQUE_NAME=orclstby';

System altered.

SQL> create spfile from pfile='/u01/pfile.ora';

File created.

SQL> shutdown immediate;

ORA-01109: database not open

Database dismounted.
ORACLE instance shut down.

SQL> startup mount;

ORACLE instance started.

Total System Global Area  246386688 bytes
Fixed Size                  2286992 bytes
Variable Size             188746352 bytes
Database Buffers           50331648 bytes
Redo Buffers                5021696 bytes
Database mounted.

SQL> exit

Una vez que completamos estos pasos, vamos a hacer los mismos , reemplazando la instancia farsync (ORACLE_SID=farsync) , por farsync2 (ORACLE_SID=farsync2) , y así tenemos nuestras dos instancias Far Sync.

Lo que sigue es que tenemos que configurar las rutas con la propiedad de RedoRoutes conectandonos a la BD orcl.

[oracle@adg12c ~]$ . oraenv
ORACLE_SID = [orcl] ? orcl
The Oracle base remains unchanged with value /u01/app/oracle

[oracle@adg12c ~]$ dgmgrl
DGMGRL> connect sys/oracle
Connected as SYSDG.
DGMGRL> EDIT DATABASE orcl SET PROPERTY 'RedoRoutes' = '( LOCAL : farsync SYNC)';

Property "RedoRoutes" updated
DGMGRL> EDIT FAR_SYNC farsync SET PROPERTY 'RedoRoutes' = '(orcl : orclstby ASYNC)';

Property "RedoRoutes" updated
DGMGRL> EDIT FAR_SYNC farsync2 SET PROPERTY 'RedoRoutes' = '(orclstby : orcl ASYNC)';

Property "RedoRoutes" updated
DGMGRL> EDIT DATABASE orclstby SET PROPERTY 'RedoRoutes' = '(LOCAL : farsync2 FASTSYNC)';
Property "RedoRoutes" updated


Ahora vamos a configurar los umbrales de aplicación y transporte en el retraso y de desconexión

DGMGRL> edit database orclstby set property TransportDisconnectedThreshold=0;

Property "transportdisconnectedthreshold" updated
DGMGRL> edit database orclstby set property transportlagthreshold=0;

Property "transportlagthreshold" updated
DGMGRL> edit database orcl set property TransportDisconnectedThreshold=0;

Property "transportdisconnectedthreshold" updated
DGMGRL> edit database orcl set property transportlagthreshold=0;

Property "transportlagthreshold" updated
DGMGRL> edit far_sync farsync set property TransportDisconnectedThreshold=0;

Property "transportdisconnectedthreshold" updated
DGMGRL> edit far_sync farsync set property transportlagthreshold=0;

Property "transportlagthreshold" updated
DGMGRL> edit far_sync farsync2 set property TransportDisconnectedThreshold=0;

Property "transportdisconnectedthreshold" updated
DGMGRL> edit far_sync farsync2 set property transportlagthreshold=0;

Property "transportlagthreshold" updated
DGMGRL> edit database orcl set property ApplyLagThreshold=0;

Property "applylagthreshold" updated
DGMGRL> edit database orclstby set property ApplyLagThreshold=0;

Property "applylagthreshold" updated
DGMGRL> edit database orclstby set property logxptmode=sync;

Property "logxptmode" updated

Vamos a ver como quedo nuestra configuración de nuestras instancias de Far Sync

DGMGRL> show configuration;

Configuration - DGCONFIG

  Protection Mode: MaxPerformance
  Databases:
  orcl     - Primary database
    farsync  - Far Sync 
      orclstby - Physical standby database 
    farsync2 - Far Sync (inactive)

Fast-Start Failover: DISABLED

Configuration Status:
SUCCESS

Si te fijas, la instancia farsync2 esta inactiva, ya que esta le pertenece a la BD standby  (orclstby),de igual manera ahora verificamos que la BD orcl este lista para un switchover

DGMGRL> validate database orcl;
  Database Role:    Primary database

  Ready for Switchover:  Yes

Ya que verificamos que si esta lista para el switchover, vamos a proceder a hacerlo hacia orclstby

DGMGRL> switchover to orclstby;
Performing switchover NOW, please wait...
Operation requires a connection to instance "orclstby" on database "orclstby"
Connecting to instance "orclstby"...
Connected as SYSDBA.
New primary database "orclstby" is opening...
Operation requires startup of instance "orcl" on database "orcl"
Starting instance "orcl"...
ORACLE instance started.
Database mounted.
Database opened.
Switchover succeeded, new primary is "orclstby"

Ahora que la BD orclstby es la primaria, y orcl es la BD es la standby , vamos a checar la configuración de nuevo, y veras que la instancia farsync2 es la instancia Far Sync activa, y la instancia farsync2 va a estar inactiva


DGMGRL> show configuration;
Configuration - DGCONFIG

  Protection Mode: MaxPerformance
  Databases:
  orclstby - Primary database
    farsync2 - Far Sync 
      orcl     - Physical standby database 
    farsync  - Far Sync (inactive)

Fast-Start Failover: DISABLED

Configuration Status:
SUCCESS

Conclusión

Este tipo de configuración te va a permitir tener "casi cero" perdida de datos, sin perjudicar tu BD primaria por los estados latentes de tu red. Así como tener la misma configuración cuando hagas un switchover de tus BDs.






sábado, 18 de mayo de 2013

Como crear un Standby Fisico con RMAN Active Duplicate en 11.2.0.3

Este tema ha sido escrito por otros administradores de bases de datos, pero quería que estuviera disponible en español, y sobre todo porque en los sitios que he buscado de cómo se hizo esto, o bien no son muy claros los pasos que se hicieron y asume que ya sabes lo que estás haciendo, o en realidad ejecutan los pasos demasiado rápido sin dar alguna explicación.

Antes de continuar, sólo te quiero decir de que se trata de una entrada larga, y no digas que no te lo advertí :)

Así que para continuar y antes de entrar en cualquiera de los pasos en la creación de tu base de datos Standby Fisica, hay algunos términos que necesitas saber de antemano, que te ayudará a entender mejor el entorno y lo que DataGuard está haciendo, en lugar de copiar una serie de pasos. Estas son sólo las definiciones en la documentación de Oracle, pero te evitarás de ir a buscar por todas partes para entenderlas.

LOG_ARCHIVE_DEST_n .- Controla diferente aspectos de como los servicios de transporte de los Redo, transfiere los datos de redo de la base de datos primaria
a su destino de standby. Este parámetro tiene varios atributos que son necesarios para configurar tu ambiente de Dataguard, aquí nada mas voy a mencionar
los que son críticos para esto:

  • ASYNC (Default) .- Los datos generados de redo por transacción no tienen que haber sido recibidos en cada uno de los destinos habilitados antes de cometerse ésta.
    o
  • SYNC .-Los datos generados de redo por transacción tienen que haber sido recibidos en cada uno de los destinos habilitados antes de cometerse ésta.
  • AFFIRM y NOAFFIRM .- Controla si un destino de transporte de redo acusa de recibo los datos de redo antes o despues de escribir estos al standby redo log.
  • DB_UNIQUE_NAME .-  Especifica un nombre unico para la base de datos que va a recibir los datos de redo. Tienes que especificar este nombre, no hay un valor por default.
  • VALID_FOR .- Identifica cuando el servicio de transporte de redo puede transmitir datos de redo a los destinos, esto se basa en los siguiente factores:
    • redo_log_type .-Si los archivos de Online Redo Log, Standby Redo log o ambos este siendo archivados en la base de datos destinada.
    • database_role .-Si el rol de la base de datos es la Primaria o la base de datos en Stanby.

FAL_SERVER .- Especifica el servidor FAL (Fetch Archive Log) para un base de datos en Standby. Este valor es un nombre de servicio de Oracle Net.
FAL_CLIENT .- Especifica el nombre del cliente FAL (Fetch Archive Log) que es usado por el servicio FAL, que este es configurado a través del parametro FAL_SERVER para referir al cliente.Este valor es un nombre de servicio de Oracle Net.

LOG_ARCHIVE_CONFIG .- Este parámetro habilita o deshabilita el envió de redo los a destinos remotos y el recipiente de estos. Este parámetro tiene varios atributos, aquí te menciono el mas importante para este ejercicio:

  • DG_CONFIG .- Especifica hasta 30 nombres de bases de datos únicas (Definidas con el parámetro DB_UNIQUE_NAME) para todas las bases de datos en tu configuración de Data Guard.

Ufff , esto estuvo largo, y si te interesa saber mas, lo puedes encontrar en la documentación oficial de Oracle 11gR2 . Pero ahora que quitamos las definiciones de encima,  vamos a empezar con la configuracion de nuestra Base de Datos Standby Fisica.

Para este ejercicio tengo lo siguiente :

Primary : testgg1   Server : dlabvm13
Standby : testgg2   Server : dlabvm14
DB_NAME: testgg1

Lo primero que tienes que hacer, es encontrar la ubicación en donde tienes los Online Redo Logs, Datafiles que residen en la base de datos primaria y donde van a residir  estos en la base de datos Standby para que puedas establecer los parámetros LOG_FILE_NAME_CONVERT y DB_FILE_NAME_CONVERT correctamente. Asegúrate de que estos directorios y que tienes el espacio necesario para contener la base de datos primaria, si no tienes este espacio en el servidor de la Standby, entonces ¿cuál es el caso de continuar? :)

A continuación, asegúrate de que estás en modo archivelog y que force logging está activado en tu base de datos primaria.

Si tu base de datos no está en modo archivelog, haz lo siguiente:

SQL> shutdown immediate
Database closed.
Database dismounted.
ORACLE instance shut down.

SQL> startup mount
ORACLE instance started.

Total System Global Area 534462464 bytes
Fixed Size 2230072 bytes
Variable Size 163580104 bytes
Database Buffers 364904448 bytes
Redo Buffers 3747840 bytes
Database mounted.

SQL> alter database archivelog;

Database altered.

SQL> alter database open;

Database altered.

SQL> alter database force logging;

Database altered.

SQL> select log_mode,force_logging from v$database;

LOG_MODE FOR
------------ ---
ARCHIVELOG YES


Ahora que estamos en modo archivelog y establecida force logging para la base de datos primaria, asegúrate de que las entradas del  Listener/Tns están configurados correctamente y que puedes hacer un  tnsping ambos desde el servidor de la Primaria / Standby.

En esto si no voy a entrar a detalle pero puedes checar la entrada de Kamran en el blog de Pythian (Paso 2) para ver como se hace esto. Si tienes una pregunta de como se hace esto, no dudes en hacermela.

Pero el resultado en ambos servidores debe de ser algo similar a esto:


oracle@dlabvm13.dlab.pythian.com [testgg1] /home/oracle/bin
oracle $ tnsping testgg1

TNS Ping Utility for Linux: Version 11.2.0.3.0 - Production on 14-MAY-2013 09:44:34
Copyright (c) 1997, 2011, Oracle. All rights reserved.
Used parameter files:
/u01/app/oracle/product/11.2.0/dbhome_1/network/admin/sqlnet.ora

Used TNSNAMES adapter to resolve the alias

Attempting to contact (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = dlabvm13.dlab.pythian.com)(PORT = 1521))) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = testgg1)))

OK (0 msec)

oracle@dlabvm13.dlab.pythian.com [testgg1] /home/oracle/bin
oracle $ tnsping testgg2
TNS Ping Utility for Linux: Version 11.2.0.3.0 - Production on 14-MAY-2013 09:44:40
Copyright (c) 1997, 2011, Oracle. All rights reserved.

Used parameter files:
/u01/app/oracle/product/11.2.0/dbhome_1/network/admin/sqlnet.ora

Used TNSNAMES adapter to resolve the alias

Attempting to contact (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = dlabvm14.dlab.pythian.com)(PORT = 1521))) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = testgg2)))

OK (10 msec)

A continuación, debes crear y replicar el archivo de contraseñas de la base de datos primaria que se encuentra en $ORACLE_HOME/dbs y cambiarle el nombre para que refleje el nombre de la Standby. El nombre del archivo de la contraseña de la Standby debe coincidir con el ORACLE_SID utilizado, no el DB_NAME.


oracle@dlabvm13.dlab.pythian.com [testgg1] /u01/app/oracle/product/11.2.0/dbhome_1/dbs
oracle $ orapwd file=orapwtestgg1 password=test entries=5

oracle@dlabvm13.dlab.pythian.com [testgg1] /u01/app/oracle/product/11.2.0/dbhome_1/dbs
oracle $ scp orapwtestgg1 dlabvm14:/u01/app/oracle/product/11.2.0/dbhome_1/dbs/orapwtestgg2

orapwtestgg1 100% 2048 2.0KB/s 00:00

Ahora que has creado el archivo de contraseñas, vamos a configurar el archivo de parámetros init para la base de datos Primaria, como se puede ver al final de este ejemplo, son los parámetros que explicamos y definimos al principio de esta entrada.

SQL> !cat dg.ora
*.audit_file_dest='/u01/app/oracle/oradata/dump/testgg1/adump'
*.audit_trail='db'
*.compatible='11.2.0'
*.control_files='/u01/app/oracle/oradata/testgg1/control/control01.ctl','/u01/app/oracle/oradata/testgg1/control/control02.ctl'
*.db_block_size=8192
*.db_cache_size=128M
*.db_domain=''
*.db_name='testgg1'
*.db_recovery_file_dest='/u01/app/oracle/fast_recovery_area'
*.db_recovery_file_dest_size=2G
*.db_unique_name='testgg1'
*.diagnostic_dest='/u01/app/oracle/oradata/dump/testgg1'
*.log_archive_dest_1='location=use_db_recovery_file_dest valid_for=(ALL_LOGFILES,ALL_ROLES) DB_UNIQUE_NAME=testgg1'
*.log_archive_dest_2='SERVICE=testgg2 ASYNC valid_for=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=testgg2'
*.log_archive_dest_state_1='enable'
*.log_archive_dest_state_2='enable'
*.open_cursors=300
*.pga_aggregate_target=128M
*.processes=150
*.remote_login_passwordfile='EXCLUSIVE'
*.sga_target=512M
testgg11.UNDO_TABLESPACE='UNDOTBS1'
FAL_SERVER=testgg2;
FAL_CLIENT=testgg1;
DB_FILE_NAME_CONVERT='/u01/app/oracle/oradata/testgg2/TESTGG2/datafile/','/u01/app/oracle/oradata/testgg1/TESTGG1/datafile/'
LOG_FILE_NAME_CONVERT='/u01/app/oracle/oradata/testgg2/TESTGG2/onlinelog/','/u01/app/oracle/oradata/testgg1/TESTGG1/onlinelog/'
LOG_ARCHIVE_CONFIG='DG_CONFIG=(testgg1,testgg2)'

Una de las cosas mas padres o cheveres acerca de este método, es que casi todo el trabajo que haré será en el servidor de base de datos Primaria,  lo único que tengo que hacer en el servidor de la base de datos Standby es crear las ubicaciones en donde van a residir mis archivos de diagnóstico / redo / datafiles / control files y verificar la conectividad entre el servidor Primario y el Standby y solamente arrancar la instancia de nuestra base de datos Standby, que es nuestro siguiente paso.

Lo que voy a hacer ahora es establecer el ORACLE_SID, ORACLE_HOME y ORACLE_BASE para la instancia Standby y abrirla con las mínimas  opciones posibles:


oracle@dlabvm14.dlab.pythian.com [testgg2] /home/oracle/bin
oracle $ export ORACLE_HOME="/u01/app/oracle/product/11.2.0/dbhome_1"

oracle@dlabvm14.dlab.pythian.com [testgg2] /home/oracle/bin
oracle $ export ORACLE_BASE=/u01/app/oracle

oracle@dlabvm14.dlab.pythian.com [testgg2] /home/oracle/bin
oracle $ export ORACLE_SID=testgg2

oracle@dlabvm14.dlab.pythian.com [testgg2] /home/oracle/bin
oracle $ cat dg.ora

DB_NAME=testgg1
DB_UNIQUE_NAME=testgg2
DB_BLOCK_SIZE=8192

oracle@dlabvm14.dlab.pythian.com [testgg2] /home/oracle/bin
oracle $ sqlplus
SQL*Plus: Release 11.2.0.3.0 Production on Tue May 14 09:53:30 2013
Copyright (c) 1982, 2011, Oracle.  All rights reserved.
Enter user-name: /as sysdba

Connected to an idle instance.

SQL> startup nomount pfile='/home/oracle/bin/dg.ora';
ORACLE instance started.
Total System Global Area  238034944 bytes
Fixed Size              2227136 bytes
Variable Size            180356160 bytes
Database Buffers        50331648 bytes
Redo Buffers              5120000 bytes

SQL> exit

Disconnected from Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production

With the Partitioning, OLAP, Data Mining and Real Application Testing options

Ahora vamos a volver al servidor de la base de datos Primaria, donde lo siguiente que voy a hacer es agregar los Standby Redo Logs, en mi caso he creado dos con el mismo tamaño que los Online Redo Logs que tengo en la Primaria.


SQL> select instance_name,host_name from v$instance;

INSTANCE_NAME HOST_NAME
---------------- ----------------------------------------------------------------
testgg1 dlabvm13.dlab.pythian.com

SQL> select name from v$database;

NAME
---------
TESTGG1

SQL> select GROUP#,THREAD#,MEMBERS,BYTES FROM V$LOG;

GROUP# THREAD# MEMBERS BYTES
---------- ---------- ---------- ----------
1 1 1 104857600
2 1 1 104857600

SQL> ALTER DATABASE ADD STANDBY LOGFILE SIZE 104857600;

Database altered.

SQL> ALTER DATABASE ADD STANDBY LOGFILE SIZE 104857600;

Database altered.

SQL> SELECT GROUP#, BYTES FROM V$STANDBY_LOG;

GROUP# BYTES
---------- ----------
 3 104857600
 4 104857600

Una vez que he creado los Standby Redo Logs en mi base de datos Primaria, creo los siguientes comandos de RMAN y también los cambios que se van a hacer en spfile de la Standby en este bloque de RMAN.

oracle@dlabvm13.dlab.pythian.com [testgg1] /home/oracle/bin
oracle $ cat duplicate.rmn

run {
allocate channel prmy1 type disk;
allocate channel prmy2 type disk;
allocate channel prmy3 type disk;
allocate channel prmy4 type disk;
allocate auxiliary channel stby type disk;
duplicate target database for standby from active database
spfile
 parameter_value_convert 'testgg1','testgg2'
 set db_unique_name='testgg2'
 set db_file_name_convert='/u01/app/oracle/oradata/testgg1/TESTGG1/datafile/','/u01/app/oracle/oradata/testgg2/TESTGG2/datafile/'
 set log_file_name_convert='/u01/app/oracle/oradata/testgg1/TESTGG1/onlinelog/','/u01/app/oracle/oradata/testgg2/TESTGG2/onlinelog/'
 set control_files='/u01/app/oracle/oradata/testgg2/control/control01.ctl','/u01/app/oracle/oradata/testgg2/control/control02.ctl'
 set log_archive_max_processes='10'
 set fal_client='testgg2'
 set fal_server='testgg1'
 set standby_file_management='AUTO'
 set log_archive_config='dg_config=(testgg1,testgg2)'
 set log_archive_dest_2='service=testgg1 ASYNC valid_for=(ONLINE_LOGFILE,PRIMARY_ROLE) db_unique_name=testgg1'
;
}

Ahora que  he creado el archivo de comandos de RMAN, sólo necesito ejecutar este comando en la base de datos target, que es la base de datos Primaria, que se conectara a la Standby que en este caso es la auxiliary.


oracle@dlabvm13.dlab.pythian.com [testgg1] /home/oracle/bin
oracle $ rman target sys/test@testgg1 auxiliary sys/test@testgg2

Recovery Manager: Release 11.2.0.3.0 - Production on Thu May 16 08:42:46 2013
Copyright (c) 1982, 2011, Oracle and/or its affiliates. All rights reserved.

connected to target database: TESTGG1 (DBID=839852638)
connected to auxiliary database: TESTGG1 (not mounted)

RMAN> @duplicate.rmn

RMAN>
RMAN> run {
2> allocate channel prmy1 type disk;
3> allocate channel prmy2 type disk;
4> allocate channel prmy3 type disk;
5> allocate channel prmy4 type disk;
6> allocate auxiliary channel stby type disk;
7> duplicate target database for standby from active database
8> spfile
9> parameter_value_convert 'testgg1','testgg2'
10> set db_unique_name='testgg2'
11> set db_file_name_convert='/u01/app/oracle/oradata/testgg1/TESTGG1/datafile/','/u01/app/oracle/oradata/testgg2/TESTGG2/datafile/'
12> set log_file_name_convert='/u01/app/oracle/oradata/testgg1/TESTGG1/onlinelog/','/u01/app/oracle/oradata/testgg2/TESTGG2/onlinelog/'
13> set control_files='/u01/app/oracle/oradata/testgg2/control/control01.ctl','/u01/app/oracle/oradata/testgg2/control/control02.ctl'
14> set log_archive_max_processes='10'
15> set fal_client='testgg2'
16> set fal_server='testgg1'
17> set standby_file_management='AUTO'
18> set log_archive_config='dg_config=(testgg1,testgg2)'
19> set log_archive_dest_2='service=testgg1 ASYNC valid_for=(ONLINE_LOGFILE,PRIMARY_ROLE) db_unique_name=testgg1'
20> ;
21> }
using target database control file instead of recovery catalog
allocated channel: prmy1
channel prmy1: SID=32 device type=DISK

allocated channel: prmy2
channel prmy2: SID=33 device type=DISK

allocated channel: prmy3
channel prmy3: SID=34 device type=DISK

allocated channel: prmy4
channel prmy4: SID=35 device type=DISK

allocated channel: stby
channel stby: SID=19 device type=DISK

Starting Duplicate Db at 16-MAY-13

contents of Memory Script:
{
 backup as copy reuse
 targetfile '/u01/app/oracle/product/11.2.0/dbhome_1/dbs/orapwtestgg1' auxiliary format
 '/u01/app/oracle/product/11.2.0/dbhome_1/dbs/orapwtestgg2' targetfile
 '/u01/app/oracle/product/11.2.0/dbhome_1/dbs/spfiletestgg1.ora' auxiliary format
 '/u01/app/oracle/product/11.2.0/dbhome_1/dbs/spfiletestgg2.ora' ;
 sql clone "alter system set spfile= ''/u01/app/oracle/product/11.2.0/dbhome_1/dbs/spfiletestgg2.ora''";
}
executing Memory Script

Starting backup at 16-MAY-13
Finished backup at 16-MAY-13

sql statement: alter system set spfile= ''/u01/app/oracle/product/11.2.0/dbhome_1/dbs/spfiletestgg2.ora''

contents of Memory Script:
{
 sql clone "alter system set audit_file_dest =
 ''/u01/app/oracle/oradata/dump/testgg2/adump'' comment=
 '''' scope=spfile";
 sql clone "alter system set diagnostic_dest =
 ''/u01/app/oracle/oradata/dump/testgg2'' comment=
 '''' scope=spfile";
 sql clone "alter system set log_archive_dest_1 =
 ''location=use_db_recovery_file_dest valid_for=(ALL_LOGFILES,ALL_ROLES) DB_UNIQUE_NAME=testgg2'' comment=
 '''' scope=spfile";
 sql clone "alter system set db_unique_name =
 ''testgg2'' comment=
 '''' scope=spfile";
 sql clone "alter system set db_file_name_convert =
 ''/u01/app/oracle/oradata/testgg1/TESTGG1/datafile/'', ''/u01/app/oracle/oradata/testgg2/TESTGG2/datafile/'' comment=
 '''' scope=spfile";
 sql clone "alter system set log_file_name_convert =
 ''/u01/app/oracle/oradata/testgg1/TESTGG1/onlinelog/'', ''/u01/app/oracle/oradata/testgg2/TESTGG2/onlinelog/'' comment=
 '''' scope=spfile";
 sql clone "alter system set control_files =
 ''/u01/app/oracle/oradata/testgg2/control/control01.ctl'', ''/u01/app/oracle/oradata/testgg2/control/control02.ctl'' comment=
 '''' scope=spfile";
 sql clone "alter system set log_archive_max_processes =
 10 comment=
 '''' scope=spfile";
 sql clone "alter system set fal_client =
 ''testgg2'' comment=
 '''' scope=spfile";
 sql clone "alter system set fal_server =
 ''testgg1'' comment=
 '''' scope=spfile";
 sql clone "alter system set standby_file_management =
 ''AUTO'' comment=
 '''' scope=spfile";
 sql clone "alter system set log_archive_config =
 ''dg_config=(testgg1,testgg2)'' comment=
 '''' scope=spfile";
 sql clone "alter system set log_archive_dest_2 =
 ''service=testgg1 ASYNC valid_for=(ONLINE_LOGFILE,PRIMARY_ROLE) db_unique_name=testgg1'' comment=
 '''' scope=spfile";
 shutdown clone immediate;
 startup clone nomount;
}
executing Memory Script

sql statement: alter system set audit_file_dest = ''/u01/app/oracle/oradata/dump/testgg2/adump'' comment= '''' scope=spfile

sql statement: alter system set diagnostic_dest = ''/u01/app/oracle/oradata/dump/testgg2'' comment= '''' scope=spfile

sql statement: alter system set log_archive_dest_1 = ''location=use_db_recovery_file_dest valid_for=(ALL_LOGFILES,ALL_ROLES) DB_UNIQUE_NAME=testgg2'' comment= '''' scope=spfile

sql statement: alter system set db_unique_name = ''testgg2'' comment= '''' scope=spfile

sql statement: alter system set db_file_name_convert = ''/u01/app/oracle/oradata/testgg1/TESTGG1/datafile/'', ''/u01/app/oracle/oradata/testgg2/TESTGG2/datafile/'' comment= '''' scope=spfile

sql statement: alter system set log_file_name_convert = ''/u01/app/oracle/oradata/testgg1/TESTGG1/onlinelog/'', ''/u01/app/oracle/oradata/testgg2/TESTGG2/onlinelog/'' comment= '''' scope=spfile

sql statement: alter system set control_files = ''/u01/app/oracle/oradata/testgg2/control/control01.ctl'', ''/u01/app/oracle/oradata/testgg2/control/control02.ctl'' comment= '''' scope=spfile

sql statement: alter system set log_archive_max_processes = 10 comment= '''' scope=spfile

sql statement: alter system set fal_client = ''testgg2'' comment= '''' scope=spfile

sql statement: alter system set fal_server = ''testgg1'' comment= '''' scope=spfile

sql statement: alter system set standby_file_management = ''AUTO'' comment= '''' scope=spfile

sql statement: alter system set log_archive_config = ''dg_config=(testgg1,testgg2)'' comment= '''' scope=spfile

sql statement: alter system set log_archive_dest_2 = ''service=testgg1 ASYNC valid_for=(ONLINE_LOGFILE,PRIMARY_ROLE) db_unique_name=testgg1'' comment= '''' scope=spfile

Oracle instance shut down

connected to auxiliary database (not started)
Oracle instance started

Total System Global Area 534462464 bytes

Fixed Size 2230072 bytes
Variable Size 163580104 bytes
Database Buffers 364904448 bytes
Redo Buffers 3747840 bytes
allocated channel: stby
channel stby: SID=18 device type=DISK

contents of Memory Script:
{
 backup as copy current controlfile for standby auxiliary format '/u01/app/oracle/oradata/testgg2/control/control01.ctl';
 restore clone controlfile to '/u01/app/oracle/oradata/testgg2/control/control02.ctl' from
 '/u01/app/oracle/oradata/testgg2/control/control01.ctl';
}
executing Memory Script

Starting backup at 16-MAY-13
channel prmy1: starting datafile copy
copying standby control file
output file name=/u01/app/oracle/product/11.2.0/dbhome_1/dbs/snapcf_testgg1.f tag=TAG20130516T084319 RECID=7 STAMP=815561001
channel prmy1: datafile copy complete, elapsed time: 00:00:07
Finished backup at 16-MAY-13

Starting restore at 16-MAY-13

channel stby: copied control file copy
Finished restore at 16-MAY-13

contents of Memory Script:
{
 sql clone 'alter database mount standby database';
}
executing Memory Script

sql statement: alter database mount standby database

contents of Memory Script:
{
 set newname for tempfile 1 to
 "/u01/app/oracle/oradata/testgg2/TESTGG2/datafile/o1_mf_temp_8qbok7fk_.tmp";
 switch clone tempfile all;
 set newname for datafile 1 to
 "/u01/app/oracle/oradata/testgg2/TESTGG2/datafile/o1_mf_system_8ocl7bho_.dbf";
 set newname for datafile 2 to
 "/u01/app/oracle/oradata/testgg2/TESTGG2/datafile/o1_mf_sysaux_8ocl7k6n_.dbf";
 set newname for datafile 3 to
 "/u01/app/oracle/oradata/testgg2/TESTGG2/datafile/o1_mf_sys_undo_8ocl7q6c_.dbf";
 set newname for datafile 4 to
 "/u01/app/oracle/oradata/testgg2/TESTGG2/datafile/o1_mf_users_8qbolh3g_.dbf";
 backup as copy reuse
 datafile 1 auxiliary format
 "/u01/app/oracle/oradata/testgg2/TESTGG2/datafile/o1_mf_system_8ocl7bho_.dbf" datafile
 2 auxiliary format
 "/u01/app/oracle/oradata/testgg2/TESTGG2/datafile/o1_mf_sysaux_8ocl7k6n_.dbf" datafile
 3 auxiliary format
 "/u01/app/oracle/oradata/testgg2/TESTGG2/datafile/o1_mf_sys_undo_8ocl7q6c_.dbf" datafile
 4 auxiliary format
 "/u01/app/oracle/oradata/testgg2/TESTGG2/datafile/o1_mf_users_8qbolh3g_.dbf" ;
 sql 'alter system archive log current';
}
executing Memory Script

executing command: SET NEWNAME

renamed tempfile 1 to /u01/app/oracle/oradata/testgg2/TESTGG2/datafile/o1_mf_temp_8qbok7fk_.tmp in control file

executing command: SET NEWNAME

executing command: SET NEWNAME

executing command: SET NEWNAME

executing command: SET NEWNAME

Starting backup at 16-MAY-13
channel prmy1: starting datafile copy
input datafile file number=00001 name=/u01/app/oracle/oradata/testgg1/TESTGG1/datafile/o1_mf_system_8ocl7bho_.dbf
channel prmy2: starting datafile copy
input datafile file number=00002 name=/u01/app/oracle/oradata/testgg1/TESTGG1/datafile/o1_mf_sysaux_8ocl7k6n_.dbf
channel prmy3: starting datafile copy
input datafile file number=00003 name=/u01/app/oracle/oradata/testgg1/TESTGG1/datafile/o1_mf_sys_undo_8ocl7q6c_.dbf
channel prmy4: starting datafile copy
input datafile file number=00004 name=/u01/app/oracle/oradata/testgg1/TESTGG1/datafile/o1_mf_users_8qbolh3g_.dbf
output file name=/u01/app/oracle/oradata/testgg2/TESTGG2/datafile/o1_mf_sys_undo_8ocl7q6c_.dbf tag=TAG20130516T084335
channel prmy3: datafile copy complete, elapsed time: 00:00:45
output file name=/u01/app/oracle/oradata/testgg2/TESTGG2/datafile/o1_mf_users_8qbolh3g_.dbf tag=TAG20130516T084335
channel prmy4: datafile copy complete, elapsed time: 00:00:55
output file name=/u01/app/oracle/oradata/testgg2/TESTGG2/datafile/o1_mf_system_8ocl7bho_.dbf tag=TAG20130516T084335
channel prmy1: datafile copy complete, elapsed time: 00:01:05
output file name=/u01/app/oracle/oradata/testgg2/TESTGG2/datafile/o1_mf_sysaux_8ocl7k6n_.dbf tag=TAG20130516T084335
channel prmy2: datafile copy complete, elapsed time: 00:01:05
Finished backup at 16-MAY-13

sql statement: alter system archive log current

contents of Memory Script:
{
 switch clone datafile all;
}
executing Memory Script

datafile 1 switched to datafile copy
input datafile copy RECID=7 STAMP=815561103 file name=/u01/app/oracle/oradata/testgg2/TESTGG2/datafile/o1_mf_system_8ocl7bho_.dbf
datafile 2 switched to datafile copy
input datafile copy RECID=8 STAMP=815561104 file name=/u01/app/oracle/oradata/testgg2/TESTGG2/datafile/o1_mf_sysaux_8ocl7k6n_.dbf
datafile 3 switched to datafile copy
input datafile copy RECID=9 STAMP=815561104 file name=/u01/app/oracle/oradata/testgg2/TESTGG2/datafile/o1_mf_sys_undo_8ocl7q6c_.dbf
datafile 4 switched to datafile copy
input datafile copy RECID=10 STAMP=815561104 file name=/u01/app/oracle/oradata/testgg2/TESTGG2/datafile/o1_mf_users_8qbolh3g_.dbf
Finished Duplicate Db at 16-MAY-13
released channel: prmy1
released channel: prmy2
released channel: prmy3
released channel: prmy4
released channel: stby

RMAN> **end-of-file**

RMAN> exit

Como puedes ver, es pan comido, ahora sólo inicio el proceso de recuperación de la base de datos Standby, en mi caso he usado la opción de Active Dataguard para que te pueda demostrar que realmente funciona, pero ten cuidado que es un Opción Licenciable.


SQL> alter database open;

Database altered.

SQL> alter database recover managed standby database disconnect;

Database altered.

SQL> select protection_mode,protection_level,database_role,name from v$database;

PROTECTION_MODE PROTECTION_LEVEL DATABASE_ROLE NAME
-------------------- -------------------- ---------------- ---------
MAXIMUM PERFORMANCE MAXIMUM PERFORMANCE PHYSICAL STANDBY TESTGG1

SQL> select instance_name,host_name from v$instance;

INSTANCE_NAME HOST_NAME
---------------- ----------------------------------------------------------------
testgg2 dlabvm14.dlab.pythian.com

SQL> select * from sender.test;
select * from sender.test
 *
ERROR at line 1:
ORA-00942: table or view does not exist


Ahora me regreso a la base de datos Primaria, y creo una tabla llamada test en el esquema sender, y como se puede ver arriba, esta tabla no existe en la base de datos Standby.


SQL> select instance_name,host_name from v$instance;

INSTANCE_NAME HOST_NAME
---------------- ----------------------------------------------------------------
testgg1 dlabvm13.dlab.pythian.com

SQL> select protection_mode,protection_level,database_role,name from v$database;

PROTECTION_MODE PROTECTION_LEVEL DATABASE_ROLE NAME
-------------------- -------------------- ---------------- ---------
MAXIMUM PERFORMANCE MAXIMUM PERFORMANCE PRIMARY TESTGG1

SQL> create table sender.test(id number);

Table created.

SQL> insert into sender.test values(1);

1 row created.

SQL> commit;

Commit complete.

SQL> alter system switch logfile;

System altered.

De nuevo me regreso a la base de datos Standby y podemos ver que tenemos nuestra tabla test que acabamos de crear en la primaria.


SQL> select protection_mode,protection_level,database_role,name from v$database;

PROTECTION_MODE PROTECTION_LEVEL DATABASE_ROLE NAME
-------------------- -------------------- ---------------- ---------
MAXIMUM PERFORMANCE MAXIMUM PERFORMANCE PHYSICAL STANDBY TESTGG1

SQL> select instance_name,host_name from v$instance;

INSTANCE_NAME HOST_NAME
---------------- ----------------------------------------------------------------
testgg2 dlabvm14.dlab.pythian.com

SQL> select * from sender.test;

ID
----------
 1

Ahora bien, hay varias manera de ver si esto funciona o no, puedes utilizar el siguiente query para ver cual fue el último archivo recibido/se aplico en la base de datos Standby.


SQL> SELECT 'Last Applied : ' Logs,
TO_CHAR(next_time,'DD-MON-YY:HH24:MI:SS') TIME,thread#,sequence#
FROM v$archived_log
WHERE sequence# =
(SELECT MAX(sequence#) FROM v$archived_log WHERE applied='YES'
)
UNION
SELECT 'Last Received : ' Logs,
TO_CHAR(next_time,'DD-MON-YY:HH24:MI:SS') TIME,thread#,sequence#
FROM v$archived_log
WHERE sequence# =
(SELECT MAX(sequence#) FROM v$archived_log );

LOGS TIME THREAD# SEQUENCE#
---------------- ------------------ ---------- ----------
Last Applied : 16-MAY-13:11:42:52 1 65
Last Received : 16-MAY-13:11:42:52 1 65

Mientras que en la base de datos Primaria, se puede comprobar cuál es la secuencia actual y cuál es la secuencia en espera de ser aplicada.


SQL> SELECT
 (SELECT name FROM V$DATABASE
 ) name,
 (SELECT MAX (sequence#) FROM v$archived_log WHERE dest_id = 1
 ) Current_primary_seq,
 (SELECT MAX (sequence#)
 FROM v$archived_log
 WHERE TRUNC(next_time) > SYSDATE - 1
 AND dest_id = 2
 ) max_stby,
 (SELECT NVL (
 (SELECT MAX (sequence#) - MIN (sequence#)
 FROM v$archived_log
 WHERE TRUNC(next_time) > SYSDATE - 1
 AND dest_id = 2
 AND applied = 'NO'
 ), 0)
 FROM DUAL
 ) "To be applied",
 (
 (SELECT MAX (sequence#) FROM v$archived_log WHERE dest_id = 1
 ) -
 (SELECT MAX (sequence#) FROM v$archived_log WHERE dest_id = 2
 )) "To be Shipped"
FROM DUAL;

NAME CURRENT_PRIMARY_SEQ MAX_STBY To be applied To be Shipped
--------- ------------------- ---------- ------------- -------------
TESTGG1 65 65 0 0

Espero que esta pequeña guía te pueda ayudar cuando estés tratando de construir una base de datos Standby Fisica con RMAN Active Duplicate, y como siempre,  prueba todo lo ,que he dicho o se ha mencionado,  antes de ejecutarlo en un entorno de producción y sobre todo para que puedas entender lo que está sucediendo .