Create Physical Standby Database with Real-time Apply

1. Documentación en Tahiti -> Oracle Database, 11g Release 2 (11.2) -> Masters Book List -> Data Guard Concepts and Administration -> 3 Creating a Physical Standby Database

2. Podemos crear una BD en Standby a través de SQL + RMAN o a través de OEM. En nuestro caso vamos a utilizar SQL con RMAN ya que es posible que en el examen no tengamos acceso al OEM o nos de problema. Si dispongo de tiempo, hare un manual para hacer la instalación con Enterprise Manager.

3. Vamos a crear la BD de Data Guard en la máquina DG para proteger la BD OCM. Lo primero es configurar la máquina virtual y posteriormente instalar el software de BD.

4. Clonamos la plantilla que hemos guardado durante la instalación de Oracle. Copiamos el directorio G:\Virtual Machines\Template a G:\Virtual Machines\DG

5. Cambiamos el nombre de la máquina virtual. Abrimos el fichero G:\Virtual Machines\DG\OCM.vmx y cambiamos la siguiente linea:

displayName = "OCM"

por la siguiente

displayName = "DG"

6. Modificamos la ubicación del disco del sistema en el mismo fichero. Cambiamos la linea:

scsi0:0.fileName = "G:\Virtual Machines\OCM\OCM.vmdk"

por la siguiente

scsi0:0.fileName = "G:\Virtual Machines\DG\OCM.vmdk"

7. Abrimos la máquina virtual desde VMware. File -> Open -> Seleccionamos “G:\Virtual Machines\DG\OCM.vmx” -> Abrir

8. Validamos que la memoria de la VM DG es como mínimo 1536MB.

Click “Edit virtual machine settings” ->
-> “Memory for this virtual machine” = 1536

9. Generamos una nueva MAC para la tarjeta de red existente

Click “Edit virtual machine settings” ->
-> Click “Network Adapter” ->
-> Click “Advanced” ->
-> Click “Generate”

10. Arrancamos la máquina DG y nos logamos como root para camiar las IPs. Si nos pregunta si hemos movido o copiado la máquina, le decimos que la hemos copiado (I copied it). Abrimos un terminal y escribimos:

system-config-network

11. Borramos la copia antigua de la configuración del interfaz antiguo, “eth0.bak”

Click en el interfaz con nickname “eth0.bak” ->
-> Click “Deactivate” ->
-> Click “Delete” ->
-> Click “Yes”

12. Modificamos las propiedades de “eth0”

Click “eth0” ->
-> Click “Edit” ->
-> Click “Statically set IP addresses” ->
-> Address = “192.168.1.130”, Subnet Mask = “255.255.255.0” y Default gateway address = “192.168.1.1” ->
-> Click “OK” ->
-> Click “Deactivate” ->
-> Click “Activate” ->
-> Click “File” ->
-> Click “Save”

13. Modificamos el archivo “/etc/resolv.conf”. Debe quedar así:

search dbajunior.com
nameserver 192.168.1.100

14. Cambiamos el nombre del HOSTNAME en DG. Editamos el fichero “/etc/sysconfig/network” y modificamos la variable de HOSTNAME de la siguiente forma:

HOSTNAME=dg.dbajunior.com

Además para cambiarlo de forma dinámica ejecutamos, la siguiente instrucción:

hostname dg.dbajunior.com

15. Se modifica el fichero “/etc/hosts” en DG con el siguiente cotenido:

# Do not remove the following line, or various programs
# that require network functionality will fail.
127.0.0.1       localhost.localdomain localhost
::1             localhost6.localdomain6 localhost6
# Oracle Database OCM
192.168.1.100   ocm.dbajunior.com ocm
# Oracle OEM
192.168.1.150   oem.dbajunior.com oem
# Oracle RAC
192.168.1.110   rac1.dbajunior.com rac1
192.168.1.111   rac1-vip.dbajunior.com rac1-vip
192.168.1.120   rac2.dbajunior.com rac2
192.168.1.121   rac2-vip.dbajunior.com rac2-vip
10.10.10.110    rac1-priv.dbajunior.com rac1-priv
10.10.10.120    rac2-priv.dbajunior.com rac2-priv
# Oracle Data Guard
192.168.1.130   dg.dbajunior.com dg

16. Modificamos los límites del usuario oracle

vi /etc/security/limits.conf

# Añadimos las siguientes lineas al final de archivo
oracle              soft    nproc   2047
oracle              hard    nproc   16384
oracle              soft    nofile  1024
oracle              hard    nofile  65536
oracle              soft    stack   10240

17. Modificar los parámetros del SO

vi /etc/sysctl.conf
# Comentamos las siguientes lineas
#kernel.shmmax = 68719476736
#kernel.shmall = 4294967296
# Añadimos las siguientes lineas
# Valores recomendados
fs.aio-max-nr = 1048576
fs.file-max = 6815744
# Shmall es el numero de paginas de memoria compartida que puede usar el sistema
# El valor recomendado de 2097152 nos permite cubrir = 2097152 * 4096K (pagesize) = 8GB
kernel.shmall = 2097152
# Valor recomendado de shmmax = (4GB * 1024^3) - 1
kernel.shmmax = 4294967295
# Shmmni es el numero de identificadores de segmentos en la memoria compartida. Valor recomendado.
kernel.shmmni = 4096
# Valores tipicos de semaforos en Instalaciones de Oracle
kernel.sem = 250 32000 100 128
# Valores recomendados
net.ipv4.ip_local_port_range = 9000 65500
net.core.rmem_default = 262144
net.core.rmem_max = 4194304
net.core.wmem_default = 262144
net.core.wmem_max = 1048576

17. Activamos los nuevos parámetros de SO.

sysctl -p

19. Creamos los directorios base de Oracle ($ORACLE_BASE), Inventario, FRA y ORACLE_HOME.

mkdir -p /u01/app/oracle
mkdir -p /u01/app/oraInventory
mkdir -p /u01/app/11.2.0/grid
chown -R oracle:oinstall /u01/app/oracle
chown -R oracle:oinstall /u01/app/oraInventory
chown -R oracle:oinstall /u01/app/11.2.0/grid
chmod -R 775 /u01/app/oracle
chmod -R 775 /u01/app/oraInventory
chmod -R 775 /u01/app/11.2.0/grid
mkdir -p /u01/app/oracle/oradata
mkdir -p /u01/app/oracle/fast_recovery_area
chown -R oracle:oinstall /u01/app/oracle/oradata
chown -R oracle:oinstall /u01/app/oracle/fast_recovery_area
chmod -R 775 /u01/app/oracle/oradata
chmod -R 775 /u01/app/oracle/fast_recovery_area

20. Aprovechamos para crear un directorio para el software de Oracle

mkdir -p /u01/stage
chown -R oracle:oinstall /u01/stage
chmod -R 775 /u01/stage

21. Modificamos los grupos secundarios del usuario oracle. Ejecutamos como root

usermod -G dba,oper,asmadmin,asmdba,asmoper oracle

22. Activamos el modo slewing del demonio NTP. Editamos el fichero /etc/sysconfig/ntpd como root y cambiamos la linea:

OPTIONS="-u ntp:ntp -p /var/run/ntpd.pid"

por

OPTIONS="-x -u ntp:ntp -p /var/run/ntpd.pid"

Guardamos y reiniciamos el demonio NTP:

service ntpd restart

23. El siguiente paso es instalar el software de BD. Antes de nada comprobaremos que estamos listo para instalar el software de Oracle en la VM DG. Copiamos los siguientes ficheros descargados desde nuestro equipo a la máquina virtual DG1. Podemos usar cualquier programa gratuito (WinSCP o FileZilla).

· p10404530_112030_LINUX_1of7.zip -> /u01/stage
· p10404530_112030_LINUX_2of7.zip -> /u01/stage

24. Descomprimimos el software con el usuario oracle y borramos los archivos comprimidos

su - oracle
cd /u01/stage
unzip p10404530_112030_LINUX_1of7.zip
unzip p10404530_112030_LINUX_2of7.zip
rm p10404530_112030_LINUX_1of7.zip
rm p10404530_112030_LINUX_2of7.zip

25. Creamos un profile con las variables de entorno.

cd $HOME
vi profile_dg
# Añadimos las siguientes variables de entorno
export ORACLE_BASE=/u01/app/oracle
export ORACLE_HOME=$ORACLE_BASE/product/11.2.0/dbhome_1
export ORACLE_SID=DG
export ORA_DUMP=/u01/app/oracle/diag/rdbms/dg/DG/trace
export PATH=$ORACLE_HOME/bin:$PATH

# Damos permisos de ejecución al profile
chmod u+x profile_dg

26. Cargamos el profile de DG y ejecutamos el asistente runInstaller

cd $HOME
. profile_dg
/u01/stage/database/runInstaller

27. Como es un proceso sencillo iré rapidito sin screenshots.

Desactivamos “I wish to receive…” ->
-> Click “Next” ->
-> Click “Yes” ->
-> Seleccionamos “Install database software only” ->
-> Click “Next” ->
-> Deben aparecer los nodos seleccionados “dg1” y “dg2” ->
-> Click “Next” ->
-> Idioma “English” ->
-> Click “Next” ->
-> Seleccionamos “Enterprise Edition (4.22GB)” ->
-> Click “Next” ->
-> Oracle Base = “/u01/app/oracle y Software Location = “/u01/app/oracle/product/11.2.0/dbhome_1” ->
-> Click “Next” ->
-> Database Administrator (OSDBA) Group = “dba” y Database Operator (OSOPER) Group = “oper” ->
-> Click “Next” ->
-> Click “Finish”

Ejecutamos como root los scripts “/u01/app/oraInventory/orainstRoot.sh” y “/u01/app/oracle/product/11.2.0/dbhome_1/root.sh”

Click “OK” ->
-> Click “Close”

28. Tenemos todo listo para comenzar la instalación de Data Guard. Luego es un buen momento para guardar una copia de las máquinas virtuales para poder hacer varias pruebas de instalación sin tener que perder tiempo con los preparativos. Para ellos pararemos las dos máquinas virtuales OCM y DG y haremos una copia de los siguientes dos directorios a otra ubicación. Una vez terminado. levantamos las máquinas virtuales.

G:\Virtual Machines\DG
G:\Virtual Machines\OCM

29. Necesitamos realizar una serie de modificaciones en la BD primaria. En nuestro caso es la BD de OCM.

-- La BD primaria (Primary) debe tener los modos ARCHIVELOG, FORCE_LOGGING y FLASHBACK activados
-- En caso de no tener FORCE_LOGGING activado => ALTER DATABASE FORCE LOGGING;
-- En caso de no tener FLASHBACK activado => ALTER DATABASE FLASHBACK ON;
SELECT LOG_MODE, FORCE_LOGGING, FLASHBACK_ON FROM V$DATABASE;

-- Se recomienda que la BD primaria tenga creados los Redo Logfile de Standby
-- En la BD primaria hay 3 grupos de Redo Log
-- Se recomienda que hay al menos un grupo más que en la primaria
ALTER DATABASE ADD STANDBY LOGFILE ('/u01/app/oracle/oradata/OCM/sdbylog01.log') SIZE 200M;
ALTER DATABASE ADD STANDBY LOGFILE ('/u01/app/oracle/oradata/OCM/sdbylog02.log') SIZE 200M;
ALTER DATABASE ADD STANDBY LOGFILE ('/u02/app/oracle/oradata/OCM/sdbylog03.log') SIZE 200M;
ALTER DATABASE ADD STANDBY LOGFILE ('/u02/app/oracle/oradata/OCM/sdbylog04.log') SIZE 200M;

-- Revisamos la configuración de los Redo Log
SELECT * FROM V$STANDBY_LOG;
SELECT * FROM V$LOGFILE WHERE TYPE='STANDBY';

-- Modificamos los parámetros de archivados
ALTER SYSTEM SET LOG_ARCHIVE_DEST_1='LOCATION=USE_DB_RECOVERY_FILE_DEST';
ALTER SYSTEM SET LOG_ARCHIVE_CONFIG='DG_CONFIG=(OCM,DG)';
ALTER SYSTEM SET LOG_ARCHIVE_DEST_2='SERVICE=DG ASYNC VALID_FOR=(ONLINE_LOGFILE,PRIMARY_ROLE) DB_UNIQUE_NAME=DG';

Añadimos la siguiente entrada al fichero tnsnames.ora en la VM OCM.

vi $ORACLE_HOME/network/admin/tnsnames.ora
# Añadimos las siguientes lineas
DG =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = dg.dbajunior.com)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = DG)
    )
  )

30. Realizamos los siguientes cambios en la VM DG.

# Añadimos la siguiente linea al fichero $ORACLE_HOME/dbs/initDG.ora en la máquina DG
DB_NAME=DG

# Creamos los siguientes directorios
mkdir -p /u01/app/oracle/admin/DG/adump
mkdir -p /u01/app/oracle/admin/DG/dpdump
mkdir -p /u01/app/oracle/admin/DG/hdump
mkdir -p /u01/app/oracle/admin/DG/pfile

# También necesitamos este directorio para crear el Controlfile con el comando DUPLICATE
mkdir -p /u01/app/oracle/oradata/DG

# Creamos el fichero de Password en el nodo DG
cd $ORACLE_HOME/dbs
orapwd file=orapwDG password=**********

31. Tenemos que crear el Listener en la máquina DG y además, añadir el servicio de forma estática.

Ejecutamos el comando netca en DG ->
-> Seleccionamos “Listener configuration” ->
-> Click “Next” ->
-> Seleccionamos “Add” ->
-> Click “Next” ->
-> Listener Name = “LISTENER” ->
-> Click “Next” ->
-> Añadismos “IPC” a la lista ->
-> Click “Next” ->
-> Dejamos el puerto por defecto 1521 ->
-> Click “Next” ->
-> IPC Key value = “extproc” ->
-> Click “Next” ->
-> Seleccionamos “No” ->
-> Click “Next” ->
-> Click “Next” ->
-> Click “Finish”

Ejecutamos el comando netmgr en DG ->
-> Expandimos “Local” ->
-> Expandimos “Listeners” ->
-> Abrimos el desplegable y seleccionamos “Database Services” ->
-> Click “Add Database” ->
-> Global Database Name = “DG” ->
-> Oracle Home Directory = “/u01/app/oracle/product/11.2.0/dbhome_1” ->
-> SID = DG ->
-> Click “Add Database” ->
-> Global Database Name = “DG_DGMGRL” ->
-> Oracle Home Directory = “/u01/app/oracle/product/11.2.0/dbhome_1” ->
-> SID = DG ->
-> Click “File” ->
-> Click “Save Network Configuration” ->
-> Cerramos el asistente

# Reiniciamos el Listener
lsnrctl stop
lsnrctl start

32. Añadimos el servicio estático a la BD de OCM para que funcione correctamente el Broker.

Ejecutamos el comando netmgr en OCM ->
-> Expandimos “Local” ->
-> Expandimos “Listeners” ->
-> Abrimos el desplegable y seleccionamos “Database Services” ->
-> Click “Add Database” ->
-> Global Database Name = “OCM_DGMGRL” ->
-> Oracle Home Directory = “/u01/app/oracle/product/11.2.0/dbhome_1” ->
-> SID = “OCM” ->
-> Click “File” ->
-> Click “Save Network Configuration” ->
-> Cerramos el asistente

# Reiniciamos el Listener
lsnrctl stop
lsnrctl start

33. Configuramos el fichero tnsnames.ora en la MV DG.

# Añadimos las siguientes lineas al fichero $ORACLE_HOME/network/admin/tnsnames.ora
OCM=
(DESCRIPTION=
  (ADDRESS=(PROTOCOL=tcp)(HOST=ocm.dbajunior.com)(PORT=1521))
  (CONNECT_DATA=
     (SERVICE_NAME=OCM)))

OEM =
  (DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = TCP)(HOST = oem.dbajunior.com)(PORT = 1521))
    )
    (CONNECT_DATA =
      (SERVICE_NAME = OEM)
    )
  )

DG =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = dg.dbajunior.com)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = DG)
    )
  )

34. Lanzamos el script de duplicación de la BD Primary para Standby. Para ello realizamos las siguientes operaciones en el nodo DG.

-- Ponemos la instancia DG en modo NOMOUNT
STARTUP NOMOUNT PFILE=$ORACLE_HOME/dbs/initDG.ora

Lanzamos RMAN en el nodo OCM y ejecutamos el script de duplicación. Si nos da un error ORA-00845 se debe a que la instancia auxiliar no tiene suficiente memoria temporale (tmpfs) para poder lanzar la operación. Se puede subir temporalmente con el comando “mount -t tmpfs shmfs -o size=1536m /dev/shm”.

CONNECT TARGET SYS/*******
CONNECT AUXILIARY  SYS/********@DG
RUN {
  ALLOCATE CHANNEL D1 TYPE DISK;
  ALLOCATE CHANNEL D2 TYPE DISK;
  ALLOCATE CHANNEL D3 TYPE DISK;
  ALLOCATE CHANNEL D4 TYPE DISK;
  ALLOCATE AUXILIARY CHANNEL AUX1 TYPE DISK;
  DUPLICATE TARGET DATABASE FOR STANDBY FROM ACTIVE DATABASE
    SPFILE
      PARAMETER_VALUE_CONVERT 'OCM','DG'
      SET DB_UNIQUE_NAME='DG'
      SET DB_CREATE_FILE_DEST='/u01/app/oracle/oradata'
      SET DB_RECOVERY_FILE_DEST='/u01/app/oracle/fast_recovery_area'
      SET DB_RECOVERY_FILE_DEST_SIZE='4500M'
      SET CONTROL_FILES='/u01/app/oracle/oradata/DG/control01.ctl','/u01/app/oracle/fast_recovery_area/OCM/control02.ctl'
      SET LOG_ARCHIVE_MAX_PROCESSES='5'
      SET FAL_CLIENT='DG'
      SET FAL_SERVER='OCM'
      SET STANDBY_FILE_MANAGEMENT='AUTO'
      SET LOG_ARCHIVE_CONFIG='DG_CONFIG=(OCM,DG)'
      SET LOG_ARCHIVE_DEST_2='SERVICE=OCM ASYNC VALID_FOR=(ONLINE_LOGFILE,PRIMARY_ROLE) DB_UNIQUE_NAME=OCM';
}

35. Realizamos las siguientes tareas para finalizar la instalación.

-- Forzamos la generación de un Log Switch en la primaria (instancia OCM)
ALTER SYSTEM SWITCH LOGFILE;
# Añadimos la siguiente linea al archivo /etc/oratab en el nodo DG
DG:/u01/app/oracle/product/11.2.0/dbhome_1:N

36. Activamos el modo Real-Time Apply.

-- Ejecutamos la siguiente linea en SQL*Plus en la instancia DG
-- "RECOVER MANAGED STANDBY DATABASE" activa el Recovery de la BD Standby
-- "USING CURRENT LOGFILE" activa la función Real-Time Apply (el redo se aplica desde los Redo Logfile)
-- "DISCONNECT FROM SESSION" nos permite utilizar Redo Apply de una sesión Backgroud
ALTER DATABASE
  RECOVER MANAGED STANDBY DATABASE
  USING CURRENT LOGFILE
  DISCONNECT FROM SESSION;

-- Para parar Redo Apply se utiliza el siguiente comando aunque no lo vamos a hacer
--   · ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL;

37. Verificamos que la BD Standby está funcionando correctamente.

-- Revisamos los archivelogs recibidos en DG
SELECT THREAD#, SEQUENCE#, APPLIED, FIRST_TIME, NEXT_TIME
FROM V$ARCHIVED_LOG ORDER BY 1,2;

-- Forzamos la generación de varios Archivelog en la primaria (OCM)
ALTER SYSTEM SWITCH LOGFILE;
ALTER SYSTEM SWITCH LOGFILE;
ALTER SYSTEM SWITCH LOGFILE;

-- Volvemos a revisar los archivelogs recibidos en DG (debemos haber recibido varios)
SELECT THREAD#, SEQUENCE#, APPLIED, FIRST_TIME, NEXT_TIME
FROM V$ARCHIVED_LOG ORDER BY 1,2;

-- Podemos ver la actividad de los procesos relaciones con Data Guard con la siguiente consulta
-- Normalmente el proceso MRP0 debe tener el estado "APPLYING_LOG"
SELECT PROCESS, STATUS, THREAD#, SEQUENCE#, BLOCK#, BLOCKS FROM V$MANAGED_STANDBY;