Monitorowanie wydajności backupów RMAN

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.

 

This entry was posted in Oracle, Oracle DBA, Oracle DBA Advanced and tagged , , , , . Bookmark the permalink.

Leave a Reply