Olá pessoal,

Espero que todos estejam bem durante a pandemia.

Esse post pode parecer bastante simples para algumas pessoas, mas, para outras pode ser um tanto quanto útil.

Há algum tempo atrás um cliente solicitou suporte para o nosso time informando que um dos nodes do cluster sofreu um problema e ficou desativado por 3 semanas, e, acreditem, o cliente percebeu apenas depois de 3 semanas que o banco de dados não tinha mais backups sendo gerados pois o node que ficou indisponível era aquele que possuía o script agendado na Cron para fazer backup do banco de dados.

Em muitos clientes é comum haver ferramentas de backup que controlam todo o ciclo de backup incluindo o agendamento, como o Data Protector, SnapCenter, TSM, NetWorker, etc. Essas ferramentas são úteis pois, geralmente são instalados agentes e as chamadas de backup partem do servidor de backup, portanto, caso um agente (node) esteja indisponível, a ferramenta consegue disparar o backup através de outro agente (node).

Mas, esse ambiente nem sempre é uma realidade em todos os clientes. Muitos clientes utilizam agendamento na Cron realizando a chamada de shell scripts, e, estes chamando o RMAN com os comandos de backup.

Voltando ao cliente que citei, ele ficou com o node desativado por 3 semanas sem backup do banco de dados. Alguém consegue imaginar isso?

Pois bem, para estes clientes, como podemos resolver a questão de chamada do script de backup num único servidor?

Para alguns clientes que ainda usam Cron, o desafio é: como podemos garantir que o script seja armazenado em todos os servidores e que o agendamento também possa ficar ativo em todos os servidores?

Para armazenar um arquivo em todos os servidores, talvez um ponto de montagem NFS possa ajudar, mas, alguns clientes não possuem essa tecnologia. Alguns clientes inclusive proibem o uso de NFS, incluindo bloqueando no firewall as portas que o NFS usa.

Nesse caso, uma solução viável é manter uma cópia do script em todos os nodes , e, tenha certeza que caso você altere o script no primeiro node, você copie o script para todos os outros nós.

Talvez você não tenha visto, mas, em março de 2019 eu criei um post no blog sobre a cópia do backup de OCR para o filesystem, naquele post eu mostrei a estrutura do meu script sempre executando os comandos APENAS no Master Node do Cluster. Desta forma, você pode deixar o shell script em todos os nodes, bem como o agendamento na Cron ativado em todos os nodes, porém, o único node que chamará o script será o Master Node. E, sempre haverá apenas um Master Node no Cluster. Você pode ler o post aqui.

Portanto, a ideia é utilizar um shell script cujo arquivo exista em todos os nodes do cluster, e com o agendamento na Cron ativo em todos os nodes. Esse shell script verificará qual node é o Master Node, e, caso o node de execução seja o Master Node, o script disparará o RMAN com a chamada para o script de backup.

O script backup_full.sh segue abaixo:

#!/bin/bash

export GRID_HOME=/u01/app/193/grid
export ORACLE_HOME=/u01/app/oracle/product/19.3.0/dbhome_1
export PATH=${GRID_HOME}/bin:${ORACLE_HOME}/bin:${PATH}
export DT=`date +%m_%d_%Y`
export MASTER_NODE=`oclumon manage -get master | grep Master | awk '{print $3}' | cut -d "." -f1 | sed -e 's/\(.*\)/\U\1/'`
export HOST=`echo ${HOSTNAME} | cut -d "." -f1 |sed -e 's/\(.*\)/\U\1/'`
export WORK_DIR=/u01/app/oracle/scripts
export LOG_DIR=${WORK_DIR}/log


if [ "${HOST} == "${MASTER_NODE}" ]; then
$ORACLE_HOME/bin/rman cmdfile=${WORK_DIR}/backup_full.rman log=${LOG_DIR}/backup_full_${DT}.log
else
exit
fi

Supondo que o script fique em /u01/app/oracle/scripts com o nome de backup_full.sh, a chamada na Cron pode ser criada da seguinte forma, por exemplo:

0 0 * * 6 /u01/app/oracle/scripts/backup_full.sh 1>/dev/null 2>/dev/null

O script /u01/app/oracle/scripts/backup_full.sh será executado todo sábado à meia-noite.

O objetivo do post não é mostrar as opções de backup de um banco de dados em RAC, mas, o arquivo backup_full.rman poderia ter o seguinte conteúdo (é apenas uma ideia):

connect target / 
backup as compressed backupset database plus archivelog delete input;
exit

Espero que seja útil.

Um abraço

Vinicius