Jak większość z nas wie RMAN (Recovery Manager) pozwala nam w sposób elastyczny oraz automatyzujący zadania wykonywać kopie zapasowe naszych baz. Współpracuje z katalogiem metadanych o wykonanych kopiach , obrazach plików czy też całych baz, oraz kopiach logów powtórzeń.
Katalog RMAN utrzymywany jest w ograniczonej formie w pliku kontrolnym każdej z baz, lub też może być dedykowaną instancją bazy na którą nie potrzebujemy dodatkowej licencji. Zw względu na fakt, że katalog jest niczym innym jak schematem w bazie, częstą praktyką jest “przyklejanie” katalogu RMAN do instancji już działającej bazy.
Wykorzystując RMANa oraz katalog, mamy możliwość wykonywania kopii zapasowych wielu baz. Wraz ze wzrostem ich ilości wzrasta trudność monitorowania polityka backupów.
Informacja o nieudanych backupach zawarta jest w logu z wykonania, i jest prosta do analizy (grep RMAN- *.log) , jak natomiast monitorować wydajność backupu ? W najszybszy i wygodny sposób odpowiedzieć sobie na pytanie “Czy nasza sieć (w przypadku backupu przez LAN) nie staje się wąskim gardłem ?” , “Czy nie mamy problemów z wydajnością storage’u na który wykonujemy kopie ?”…
Dobrym miejscem do znajdowania tego rodzaju informacji jest katalog RMAN. Poniżej przedstawiam gotowe rozwiązanie dające nam możliwość szybkiego przeglądu wydajności. Nie twierdzę, że rozwiązanie to jest najlepsze, czy też dobre, czy też nie można by zrobić tego po prostu lepiej … Powstało ono po porstu AD-HOC w momencie gdy zacząłem podejrzewać, że mamy problemy z czasem backup’ów …
list_backup_rates.sh
#!/bin/bash
# This script list backup rates for rman backups:
#set -x
if [ $# -ne 3 ]; then echo "Usage: list_backup_rates.sh RMAN_USER RMAN_PASS ALIAS" exit 1; fi
# Zebranie przekazanych do skryptu parametrów # schemat katalogu RMAN RMAN_USER=$1 # hasło użytkownika RMAN_PASS=$2 # Alias TNS do katalogu RMAN_ALIAS=$3
# Load usefull functions # Funkcje zaimplementowane przez nas do wykonywania # standardowych czynności takich jak sprawdzanie istnienia # katalogu czy też istnienia lock file w celu wykluczenia # działania jednoczesnego dwóch instancji skryptu if [ ! -f ${HOME}/scripto/bash/bash_library.sh ]; then echo "[error] ${HOME}/scripto/bash/bash_library.sh not found. Exiting. " exit 1 else . ${HOME}/scripto/bash/bash_library.sh fi
RECIPIENTS='recipient@domain.pl'
LOG_DIR=/var/tmp/rman_logs # katalog wystawiony przez WWW w celu łatwego przeglądania # historycznych logów REPORT_DIR=/var/www/html/rman_reports LOG_NAME=list_backup_rates.log #LOCKFILE=/tmp/list_backup_rates.lock
. $HOME/.profile
# standardowe sprawdzenia zmiennych check_variable $ORACLE_HOME check_variable $RMAN_USER check_variable $RMAN_PASS check_variable $RMAN_ALIAS
# sprawdzenie istnienia katalogu z logami mkdir -p $LOG_DIR check_directory $LOG_DIR
LOG=${LOG_DIR}/${LOG_NAME}.`date '+%Y-%m-%d--%H:%M:%S'` #exec > $LOG 2>&1
check_lock $LOCKFILE
# Set lock file touch $LOCKFILE
# kasowanie zbyt starych logów $FIND $LOG_DIR -maxdepth 1 -type f -mtime +30 -name "${LOG_NAME}.*" -print -exec rm {} \; $FIND $REPORT_DIR -maxdepth 1 -type f -mtime +30 -name "${LOG_NAME}.*" -print -exec rm {} \;
# wywołanie skryptu SQL pobierającego dane z katalogu RMAN (Recovery Catalog)
sqlplus -S $RMAN_USER/$RMAN_PASS@$RMAN_ALIAS @list_backup_rates.sql HP_42_OL << EOF 2>&1 >> $LOG EOF echo "Generated by $0 " >> $LOG # przekopiowanie logu do katalogu wystawionego przez WWW cp $LOG $REPORT_DIR # Dodatkowe wysłanie logu na pocztę mail -s "List of RMAN BACKUP RATES" $RECIPIENTS < $LOG
list_backup_rates.sh
set linesize 200 set pagesize 400 set echo off set showmode off set verify off set feedback off set wrap off set SPACE 1 set NULL "Null" set TAB Off set colsep '|' col BS_KEY format A10 col INC_LVL format a10 HEADING 'Inc|Level' justify Center col START_TIME format a14 col INPRATE_BYTES format a15 col BACKUP_TYPE format a16 justify Center
PROMPT ------------- AVERAGE MIN MAX RATES IN BITS PER SECONDS FOR EACH DATABASE --------------;
Select DB_NAME, ROUND(AVG(ROUND( ((OUTPUT_BYTES/ELAPSED_SECONDS)/1024/1024),2) * 8),1) AVG_RATE_WRITTEN_MBITS, ROUND(SUM(ELAPSED_SECONDS)/60,0) SUM_ELAPSED_MINUTES, MIN(ROUND( ((OUTPUT_BYTES/ELAPSED_SECONDS)/1024/1024),1) * 8) MIN_RATE_WRITTEN_MBITS, MAX(ROUND( ((OUTPUT_BYTES/ELAPSED_SECONDS)/1024/1024),1) * 8) MAX_RATE_WRITTEN_MBITS from rc_backup_set_details where BACKUP_TYPE != 'L' and START_TIME > SYSDATE - 2 and ELAPSED_SECONDS != 0 group by DB_NAME order by MAX_RATE_WRITTEN_MBITS;
PROMPT PROMPT PROMPT
PROMPT ------------ BACKUPSET TIMES IN MINUTES BY DATABASE BY BACKUP TYPE LAST 24 H -------------; Select t1.NAME DB_NAME,DECODE(t1.BACKUP_TYPE,'D','FULL OR LEVEL 0','I','INCREMENTAL 1','L','ARCHIVE LOGS') BACKUP_TYPE, ROUND(SUM(t1.ELAPSED_SECONDS)/60,2) MINUTES_ELAPSED from ( Select rcd.NAME, rcbs.BACKUP_TYPE, rcbs.START_TIME,rcbs.ELAPSED_SECONDS from rc_backup_set rcbs, rc_database rcd where rcbs.db_key=rcd.db_key and rcbs.START_TIME > SYSDATE - 1 ) t1 GROUP BY t1.NAME, t1.BACKUP_TYPE order by 1,2;
PROMPT PROMPT PROMPT
PROMPT ------------------------------ BACKUP RATES IN BITS PER SECONDS FOR HP_42_OL --------------; Select DB_NAME, to_char(BS_KEY) "BS_KEY", to_char(INCREMENTAL_LEVEL) "INC_LVL", to_char(START_TIME,'YYYYMMDD HH24:MI') "START_TIME", ROUND(ELAPSED_SECONDS/60,0) "ELA_MIN", to_char(ORIGINAL_INPRATE_BYTES_DISPLAY) "INPRATE_BYTES", ROUND(OUTPUT_BYTES/1024/1024,1) "OUTPUT_MBYTES", ROUND(((OUTPUT_BYTES/ELAPSED_SECONDS)/1024/1024),1)*8 "AVG_WRITE Mbits/s" from rc_backup_set_details where DB_NAME = '&1' and BACKUP_TYPE != 'L' and START_TIME > SYSDATE - 2 order by 4 desc; -- Raport za ostanie 7 dni srednia predkosc backupu set TERMOUT OFF col tdayl1 for a30 new_value tdayl1 select to_char(sysdate-1,'RRRR-MM-DD') as tdayl1 from dual; col tdayl2 for a30 new_value tdayl2 select to_char(sysdate-2,'RRRR-MM-DD') as tdayl2 from dual; col tdayl3 for a30 new_value tdayl3 select to_char(sysdate-3,'RRRR-MM-DD') as tdayl3 from dual; col tdayl4 for a30 new_value tdayl4 select to_char(sysdate-4,'RRRR-MM-DD') as tdayl4 from dual; col tdayl5 for a30 new_value tdayl5 select to_char(sysdate-5,'RRRR-MM-DD') as tdayl5 from dual; col tdayl6 for a30 new_value tdayl6 select to_char(sysdate-6,'RRRR-MM-DD') as tdayl6 from dual; col tdayl7 for a30 new_value tdayl7 select to_char(sysdate-7,'RRRR-MM-DD') as tdayl7 from dual; set TERMOUT ON PROMPT PROMPT PROMPT PROMPT ================================== AVG MBITS LAST 7 DAYS =========================== SELECT db_name, backup_type, ROUND(avg(DECODE(TO_CHAR(START_TIME,'RRRR-MM-DD'),to_char(sysdate-7,'RRRR-MM-DD'),OUTPUT_BYTES/ELAPSED_SECONDS/1024/1024))*8) "&&tdayl7", ROUND(avg(DECODE(TO_CHAR(START_TIME,'RRRR-MM-DD'),to_char(sysdate-6,'RRRR-MM-DD'),OUTPUT_BYTES/ELAPSED_SECONDS/1024/1024))*8) "&&tdayl6", ROUND(avg(DECODE(TO_CHAR(START_TIME,'RRRR-MM-DD'),to_char(sysdate-5,'RRRR-MM-DD'),OUTPUT_BYTES/ELAPSED_SECONDS/1024/1024))*8) "&&tdayl5", ROUND(avg(DECODE(TO_CHAR(START_TIME,'RRRR-MM-DD'),to_char(sysdate-4,'RRRR-MM-DD'),OUTPUT_BYTES/ELAPSED_SECONDS/1024/1024))*8) "&&tdayl4", ROUND(avg(DECODE(TO_CHAR(START_TIME,'RRRR-MM-DD'),to_char(sysdate-3,'RRRR-MM-DD'),OUTPUT_BYTES/ELAPSED_SECONDS/1024/1024))*8) "&&tdayl3", ROUND(avg(DECODE(TO_CHAR(START_TIME,'RRRR-MM-DD'),to_char(sysdate-2,'RRRR-MM-DD'),OUTPUT_BYTES/ELAPSED_SECONDS/1024/1024))*8) "&&tdayl2", ROUND(avg(DECODE(TO_CHAR(START_TIME,'RRRR-MM-DD'),to_char(sysdate-1,'RRRR-MM-DD'),OUTPUT_BYTES/ELAPSED_SECONDS/1024/1024))*8) "&&tdayl1" FROM rman.rc_backup_set_details where elapsed_seconds>0 GROUP BY db_name,backup_type order by db_name;
Mam nadzieje, że podane rozwiązanie przyda wam się choćby jako wzór czy też jako sama idea skąd pobrać takie informacje.