Criando um Standby manual no Oracle

As vezes precisamos realizar a replicação de um banco de dados muito grande para outro servidor, nesse tipo de cenário uma das melhores ferramentas seria o uso do Data Guard mas como pode ser visto, essa opção não contempla a versão Standard:

enter image description here

Uma opção seria realizar um backup e de forma manual realizar o recover de tempos em tempos para manter os ambientes sincronizados, esse script que compartilho agora serve para facilitar um pouco esse trabalho.

Nota: Nesse artigo não vou cobrir a criação e restauração do backup, vamos supor que isso já tenha sido realizado.

Preparação do ambiente

Pacotes

Você vai precisar instalar em ambos os servidores o programa rsync caso ele não esteja instalado, nas distribuições baseadas em Red Hat (CentOS, Oracle Linux..) você pode usar o seguinte comando:

yum install rsync -y

Estabelecer confiança entre as máquinas

O ideal é que a relação de confiança ssh entre as máquina seja configurada para que você não precise digitar a senha do usuário do sistema operacional toda vez que o script executar.

Na máquina de destino executar os seguintes comandos

Caso você já possua uma chave publica criada, não execute esse comando pois ele vai sobrescrever a que você já possui

ssh-keygen -t rsa   
enter image description here

Copiar a chave para o servidor de origem:

ssh-copy-id oracle@ip-producao  A partir desse momento você pode se conectar do servidor de destino para o de origem sem precisar de senha.

tnsnames.ora

Após isso, devemos configurar duas entradas no tnsnames.ora para que seja possível verificar se os ambientes estão sincronizados:

DB_PRD =
 (DESCRIPTION = 
    (ADDRESS_LIST =
         (ADDRESS = (PROTOCOL = TCP)(HOST = db-orig)(PORT = 1521))
	    )
	     (CONNECT_DATA =
	        (SERVICE_NAME = dborcl)
		 )
		 )
		 
DB_STBY =
  (DESCRIPTION = 
     (ADDRESS_LIST =
          (ADDRESS = (PROTOCOL = TCP)(HOST = db-dest)(PORT = 1521))
	     )
	      (CONNECT_DATA =
	         (SERVICE_NAME = dborcl)
		  )
		  )

Variáveis de ambiente

Você precisa criar um arquivo com as seguintes variáveis de ambiente:

export DIR_PRD=/backup/oracle/archive #Diretório de origem
export DIR_STD=/backup/oracle/archive #Diretório de destino
export CLIENTE="XXXX"
export IP_PRD=192.168.10.180  #IP do servidor de origem
export IP_STD=192.168.10.183  #IP do servidor de destino
export DATA=$(date +"%Y%m%d")
export HORA=$(date +"%T")
export LOG_DIR=/home/oracle/$CLIENTE/logs
export LOG_FILE=standby-$ORACLE_SID-$DATA
export SYS_PASSWD=SENHA_DO_USUARIO_SYS

Recomendo que ele seja criado no diretório /home/oracle/scripts/ com o nome env$ORACLE_SID, caso crie em outro diretório você precisa ajustar a linha 51 do script.

Execução do script

O script deve ser executado na máquina de destino passando o $ORACLE_SID do banco que você deseja sincronizar.

O Script

#!/bin/bash

#####################################
#Manual Standby
#First setup ssh trust between the two hosts
#You will need rsync installed on both servers
#Create an file on /home/oracle/scripts/ with the name env$ORACLE_SID.sh with enviroinment variables (ORACLE_HOME, ORACLE_SID,PATH)
#Create two tnsnames.ora entry:

#DB_PRD =
# (DESCRIPTION =
#    (ADDRESS_LIST =
#         (ADDRESS = (PROTOCOL = TCP)(HOST = db-orig)(PORT = 1521))
#           )
#            (CONNECT_DATA =
#               (SERVICE_NAME = dborcl)
#                )
#                )


#DB_STBY =
#  (DESCRIPTION =
#     (ADDRESS_LIST =
#          (ADDRESS = (PROTOCOL = TCP)(HOST = db-dest)(PORT = 1521))
#            )
#             (CONNECT_DATA =
#                (SERVICE_NAME = dborcl)
#                 )
#                 )




#After that, fill the variaveis() function with the correct information for your enviroinment
#Give execute permission: chmod +x standby.sh
#How to run the script: standby.sh ORACLE_SID
#Created by Adriano Tanaka 12/15/2019 adriano.tanakaa@gmail.com


script_name=$(basename -- "$0")

if pidof -x "$script_name" -o $$ >/dev/null;then
   echo "An another instance of this script is already running!"
   exit 1
fi


export ORACLE_SID=$1
variaveis(){

        . /home/oracle/accerte/env$ORACLE_SID.sh

        echo "### Variaveis carregadas: "
        echo "### SID: " $ORACLE_SID
        echo "### ORIGEM: " $DIR_PRD
        echo "### DESTINO: " $DIR_STD
        echo "### IP PRD: " $IP_PRD
        echo "### IP STD: " $IP_STD
        echo "### RETENCAO: " $RETENCAO
}

rsync_prd(){

        rsync  -azvh $IP_PRD:$DIR_PRD/ $DIR_STD/ --partial-dir=$DIR_STD/partial/ --progress --ignore-existing  

}

cataloga() {

rman target=/ << EOF
RUN {
  catalog start with '\$DIR_STD' noprompt;
}
EXIT;
EOF


}


recupera_se(){

rman target=/ << EOF
RUN {
  recover database;
  }
EXIT;
EOF
}


recupera_ee(){

rman target=/ << EOF
RUN {
  allocate CHANNEL c1 DEVICE TYPE DISK;
  allocate CHANNEL c2 DEVICE TYPE DISK;
  allocate CHANNEL c3 DEVICE TYPE DISK;
  allocate CHANNEL c4 DEVICE TYPE DISK;
  recover database;
  }
EXIT;
EOF
}

runsql () {
sqlplus -S /nolog << EOF
CONNECT $1 as sysdba;
whenever sqlerror exit sql.sqlcode;
SET      pagesize 0
SET      heading OFF
SET      feedback OFF
SET      verify OFF
set     echo off
$2
exit;
EOF
}


compara () {
ULT_STBY=$(runsql sys/$SYS_PASSWD@DB_STBY  "select max (sequence#) from v\$archived_log where APPLIED='YES' ;")
ULT_PRD=$(runsql sys/$SYS_PASSWD@DB_PRD  "select max (sequence#) from v\$log_history;")

diferenca=$(($ULT_PRD-$ULT_STBY))
echo $diferenca


}


variaveis

echo ----------------------------------------------------------------
echo "### Iniciando recuperacao do do banco " $ORACLE_SID " " $DATA $HORA
echo "### Iniciando recuperacao do do banco " $ORACLE_SID " " $DATA $HORA >> $LOG_DIR/$LOG_FILE.log
echo ----------------------------------------------------------------
echo "### Copiando archives de " $IP_PRD:$DIR_PRD " "  $DATA $HORA
echo "### Copiando archives de " $IP_PRD:$DIR_PRD " "  $DATA $HORA >> $LOG_DIR/$LOG_FILE.log
rsync_prd >> $LOG_DIR/$LOG_FILE.log
echo ----------------------------------------------------------------
echo "### Catalogando archives copiados" " "  $DATA $HORA
echo "### Catalogando archives copiados" " "  $DATA $HORA >> $LOG_DIR/$LOG_FILE.log
echo ----------------------------------------------------------------
cataloga >> $LOG_DIR/$LOG_FILE.log
echo "### Aplicando archives " " "  $DATA $HORA
echo "### Aplicando archives " " "  $DATA $HORA  >> $LOG_DIR/$LOG_FILE.log
echo ----------------------------------------------------------------
recupera_se >> $LOG_DIR/$LOG_FILE.log
#recupera_ee >> $LOG_DIR/$LOG_FILE.log
echo "### Archives aplicados " " "  $DATA $HORA
echo "### Archives aplicados " " "  $DATA $HORA >> $LOG_DIR/$LOG_FILE.log
echo ----------------------------------------------------------------
echo "### Diferenca " $compara  " "  $DATA $HORA >> $LOG_DIR/$LOG_FILE.log
echo "### Diferenca " $compara  #" -- "  $DATA $HORA >> $LOG_DIR/$LOG_FILE.log
echo ----------------------------------------------------------------
compara >>  $LOG_DIR/$LOG_FILE.log
compara
echo ----------------------------------------------------------------
chevron_left
chevron_right