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:
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
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 ----------------------------------------------------------------