zOs/REXX.O08/DB2RCEST
/*---------------------REXX-------------------------------------------*/
/* DB2RCEST DB2 Recovey Estimator */
/* Dises Programm gibt eine Schätzung, wie lange der Recovery eines */
/* Pagesets etwa laufen wird. */
/* */
/* Für die folgenen Spaces sind die ermittelten Zeiten sicher falsch */
/* (zu kurz): */
/* DSNDB01.DBD01, DSNDB01.SPT01, DSNDB01.SCT02, DSNDB01.SYSLGRNX, */
/* DSNDB01.SYSUTILX, DSNDB06.SYSCOPY, DSNDB06.SYSGROUPS */
/* Diese Spaces müssen alle Logs in ihrer ganzen Länge seit der */
/* letzten Image Copy lesen. */
/* */
/* Input: -Output aus dem DB2 REPORT Utility */
/* -BSDS aller Group Members (StartRBA Activlog, highest */
/* written RBA) */
/* */
/* Output: approximative Recoveryzeit */
/* */
/* 04.08.2004 erstellt durch B.Dudle */
/* 13.08.2004 BDU div. Anpassungen */
/* 18.10.2005 BDU Anpassung an PT/A */
/* 21.02.2006 BDU total überarbeitet */
/*--------------------------------------------------------------------*/
/*--- initialisieren -------------------------------------------------*/
numeric digits 15;
z1=0; z2=0; z3=0;
cc=0;
out.=""; out.0=0; o=0;
group=left("",4);
dat=translate(date('E'),".","/");
dat=insert("20",dat,pos(".",dat,4));
tim=time('N');
rz=sysvar(sysnode);
select;
when (rz = 'RZ0'); then do;
mount=150; /* tape mount: Sek. */
resto=2.00E+05; /* restore: Pages / 60 Sek. */
logap=8.00E+08; /* logappl: Bytes / 60 Sek. */
end;
when (rz = 'RZ1'); then do;
mount=150; /* tape mount: Sek. */
resto=2.00E+05; /* restore: Pages / 60 Sek. */
logap=8.00E+08; /* logappl: Bytes / 60 Sek. */
end;
when (rz = 'RZ2'); then do;
mount=90; /* tape mount: Sek. */
resto=2.00E+05; /* restore: Pages / 60 Sek. */
logap=8.00E+08; /* logappl: Bytes / 60 Sek. */
end;
when (rz = 'RZ4'); then do;
mount=90; /* tape mount: Sek. */
resto=2.00E+05; /* restore: Pages / 60 Sek. */
logap=8.00E+08; /* logappl: Bytes / 60 Sek. */
end;
when (rz = 'RR2'); then do;
rz='RZ2'; /* change für PT/A */
mount=90; /* tape mount: Sek. */
resto=2.00E+05; /* restore: Pages / 60 Sek. */
logap=8.00E+08; /* logappl: Bytes / 60 Sek. */
end;
when (rz = 'RR4'); then do;
rz='RZ4'; /* change für PT/A */
mount=90; /* tape mount: Sek. */
resto=2.00E+05; /* restore: Pages / 60 Sek. */
logap=8.00E+08; /* logappl: Bytes / 60 Sek. */
end;
otherwise; nop;
end;
/*--- Output aus Report Utility einlesen und in Tablellen speichern --*/
address tso "execio * diskr REPORT (stem rpt. open finis";
do r=1 to rpt.0;
select;
when (pos("DSNU050I",rpt.r) > 0); then do; /* DSNUM request */
p=pos("REPORT RECOVERY TABLESPACE",rpt.r)+26;
do while (substr(rpt.r,p,1) = " "); p=p+1; end;
p1=p;
do while (substr(rpt.r,p1,1) <> " "); p1=p1+1; end;
space=substr(rpt.r,p,p1-p);
p=pos("DSNUM",rpt.r); part=0;
if (p > 0); then do;
p=p+5;
do while (substr(rpt.r,p,1) = " "); p=p+1; end;
do while (substr(rpt.r,p,1) <> " ");
part=part*10+substr(rpt.r,p,1); p=p+1;
end;
end;
else nop;
end;
when ((pos("DSNU054I",rpt.r)>0) | (pos("DSNU007I",rpt.r)>0));
then do; /* TS not found */
o=o+1; out.o=group right(dat tim,75);
o=o+1; out.o=left("",80,"-");
o=o+1; out.o=" "; out.0=o;
address tso "execio * diskw PRINT (stem out. open";
address tso "execio * diskw PRINT (stem rpt. finis";
cc=8;
exit cc;
end;
when (pos("IC TYPE =",rpt.r) > 0); then do; /* image copies */
r1=r; z1=z1+1;
p=pos("IC TYPE =",rpt.r1);
ictype.z1=substr(rpt.r1,p+11,1);
if (ictype.z1 = "F" | ictype.z1 = "I"); then do;
p=pos("DSNUM =",rpt.r1);
p=p+10; dsnum.z1=0;
do while (substr(rpt.r,p,1) = " "); p=p+1; end;
do while (substr(rpt.r,p,1) <> ",");
dsnum.z1=dsnum.z1*10+substr(rpt.r,p,1); p=p+1;
end;
if (dsnum.z1 = part | dsnum.z1 = 0); then do;
p=pos("START LRSN =",rpt.r1);
slrsn.z1=x2d(substr(rpt.r1,p+12,12));
r1=r1+1;
p=pos("IC BACK =",rpt.r1);
icback.z1=substr(rpt.r1,p+10,2);
p=pos("DEV TYPE =",rpt.r1);
devtyp.z1=substr(rpt.r1,p+12,4);
r1=r1+2;
p=pos("COPYPAGESF =",rpt.r1);
copypage.z1=0;
copypage.z1=trunc(strip(substr(rpt.r1,p+13,14)));
r1=r1+2;
p=pos("DSNAME =",rpt.r1);
group=strip(substr(rpt.r1,p+12,4)); /* group name */
p=pos("MEMBER NAME =",rpt.r1);
memb=strip(substr(rpt.r1,p+14,4)); /* member name */
end;
else do;
z1=z1-1;
end;
end;
else do;
z1=z1-1;
end;
end;
when (pos("UCDATE ",rpt.r) > 0); then do; /* log ranges */
r2=r+1;
do while (substr(rpt.r2,24,12) <> " ");
z2=z2+1;
srba.z2=x2d(substr(rpt.r2,24,12),14);
erba.z2=x2d(substr(rpt.r2,39,12),14);
slrsns.z2=x2d(substr(rpt.r2,54,12),14);
elrsns.z2=x2d(substr(rpt.r2,69,12),14);
mbid.z2=x2d(substr(rpt.r2,99,4),4);
if (srba.z2 = erba.z2); then do; /* not a range */
z2=z2-1;
end;
else nop;
r2=r2+1;
end;
end;
otherwise nop;
end;
end;
slrsn.0=z1; srba.0=z2;
/* say "---copy table";
do z1=1 to slrsn.0;
say right(d2x(slrsn.z1),12) devtyp.z1 copypage.z1;
end;
say "---syslgrnx table";
do z2=1 to srba.0;
say right(d2x(srba.z2),12),
right(d2x(erba.z2),12),
right(d2x(slrsns.z2),12),
right(d2x(elrsns.z2),12),
right(d2x(mbid.z2),12);
end;
*/
/*--- Image Copies Set selektieren -----------------------------------*/
do z1=1 to slrsn.0-1; /* sortieren */
do z11=z1+1 to slrsn.0;
select;
when (slrsn.z1 > slrsn.z11); then do;
sl=slrsn.z1; slrsn.z1=slrsn.z11; slrsn.z11=sl;
it=ictype.z1; ictype.z1=ictype.z11; ictype.z11=it;
ib=icback.z1; icback.z1=icback.z11; icback.z11=ib;
dv=devtyp.z1; devtyp.z1=devtyp.z11; devtyp.z11=dv;
ds=dsnum.z1; dsnum.z1=devtyp.z11; dsnum.z11=dv;
cp=copypage.z1; copypage.z1=copypage.z11; copypage.z11=cp;
end;
when (slrsn.z1 = slrsn.z11); then do;
if (icback.z1 <> " "); then do;
sl=slrsn.z1; slrsn.z1=slrsn.z11; slrsn.z11=sl;
it=ictype.z1; ictype.z1=ictype.z11; ictype.z11=it;
ib=icback.z1; icback.z1=icback.z11; icback.z11=ib;
dv=devtyp.z1; devtyp.z1=devtyp.z11; devtyp.z11=dv;
ds=dsnum.z1; dsnum.z1=devtyp.z11; dsnum.z11=dv;
cp=copypage.z1; copypage.z1=copypage.z11;
copypage.z11=cp;
end;
else nop;
end;
otherwise nop;
end;
end;
end;
z1=1; /* Duplikat eliminieren */
do z11=z1+1 to slrsn.0;
if (slrsn.z1 <> slrsn.z11); then do;
z1=z1+1;
slrsn.z1=slrsn.z11;
ictype.z1=ictype.z11;
icback.z1=icback.z11;
devtyp.z1=devtyp.z11;
dsnum.z1=devtyp.z11;
copypage.z1=copypage.z11;
end;
else nop;
end;
slrsn.0=z1;
/* say "---copy table sortiert";
do z1=1 to slrsn.0;
say right(d2x(slrsn.z1),12),
devtyp.z1,
copypage.z1;
end;
*/
/*--- highest written RBAs, oldest RBAs Active Log ermitteln ---------*/
loadlib="DB2@."rz".P0.DSNLOAD";
callmod="call '"loadlib"(DSNJU004)'"; upper callmod;
cntl.1="MEMBER *"; cntl.0=1; upper cntl.1;
bsds="'"group"."memb".BSDS01'"; upper bsds;
address tso "alloc dd(SYSIN) new space(1,1) tracks
unit(VIO) dsorg(PS) blksize(800) lrecl(80) recfm(F B) reuse";
address tso "execio * diskw SYSIN (stem cntl. open finis";
address tso "alloc dd(SYSPRINT) new space(15,15) tracks
unit(VIO) dsorg(PS) blksize(27875) lrecl(125) recfm(F B A) reuse";
allcbsds="alloc f(GROUP) da("bsds") shr";
address tso allcbsds;
address tso callmod;
address tso "free f(GROUP)";
address tso "free f(SYSIN)";
address tso "execio * diskr SYSPRINT (stem bsdslst. open finis";
address tso "free f(SYSPRINT)";
h2=0; z3=0; z1=slrsn.0; highlrsn=0;
do h1=1 to bsdslst.0;
select;
when (pos("HIGHEST RBA WRITTEN",bsdslst.h1) > 0); then do;
p=pos("HIGHEST RBA WRITTEN",bsdslst.h1);
h2=h2+1; highrba.h2=x2d(substr(bsdslst.h1,p+26,12),14);
end;
when (pos("HOST MEMBER NAME:",bsdslst.h1) > 0); then do;
h3=h1+1; p=pos("MEMBER ID:",bsdslst.h3);
do h4=p+10 to 133 while (substr(bsdslst.h3,h4,1) = " ");
end;
himemb.h2=0;
do while (substr(bsdslst.h3,h4,1) <> " ");
himemb.h2=himemb.h2*10+substr(bsdslst.h3,h4,1);
h4=h4+1;
end;
end;
when (pos("ACTIVE LOG COPY 1",bsdslst.h1) > 0); then do;
p=pos("ACTIVE LOG COPY 1",bsdslst.h1); h3=h1+3;
do while (pos("EMPTY DATA SET",bsdslst.h3) > 0);
h3=h3+3;
end;
h4=h3+1; z1=slrsn.0;
activrba.h2=x2d(substr(bsdslst.h3,p+3,12),14);
activlrsn.h2=x2d(substr(bsdslst.h4,p+5,12),14);
do while(substr(bsdslst.h4,p+28,12) <> "............");
elrsn=x2d(substr(bsdslst.h4,p+28,12),14);
if (elrsn >= slrsn.z1);
then do;
z3=z3+1;
srbalog.z3=x2d(substr(bsdslst.h3,p+3,12),14);
erbalog.z3=x2d(substr(bsdslst.h3,p+26,12),14);
slrsnlog.z3=x2d(substr(bsdslst.h4,p+5,12),14);
elrsnlog.z3=elrsn;
unitlog.z3="DISK";
memblog.z3=himemb.h2;
logtyp.z3="ACTIV";
end;
h3=h3+3; h4=h3+1;
end;
z3=z3+1;
srbalog.z3=x2d(substr(bsdslst.h3,p+3,12),14);
erbalog.z3=x2d(substr(bsdslst.h3,p+26,12),14);
slrsnlog.z3=x2d(substr(bsdslst.h4,p+5,12),14);
elrsnlog.z3=max(slrsnlog.z3+1,slrsn.z1);
unitlog.z3="DISK";
memblog.z3=himemb.h2;
logtyp.z3="ACTIV";
highlrsn=max(highlrsn,elrsnlog.z3);
h3=h3+3; h4=h3+1;
end;
when (pos("ARCHIVE LOG COPY 1",bsdslst.h1) > 0); then do;
h0=h1+1; z1=slrsn.0;
if (pos("NO ARCHIVE DATA SETS",bsdslst.h0) = 0); then do;
p=pos("ARCHIVE LOG COPY 1",bsdslst.h1); h3=h1+3;
do while(pos("ACTIVE LOG COPY",bsdslst.h3) = 0);
h4=h3+1;
elrsn=x2d(substr(bsdslst.h4,p+28,12),14);
if (elrsn >= slrsn.z1 & elrsn <= activlrsn.h2);
then do;
z3=z3+1;
srbalog.z3=x2d(substr(bsdslst.h3,p+3,12),14);
erbalog.z3=x2d(substr(bsdslst.h3,p+26,12),14);
slrsnlog.z3=x2d(substr(bsdslst.h4,p+5,12),14);
elrsnlog.z3=x2d(substr(bsdslst.h4,p+28,12),14);
u=pos("UNIT=",bsdslst.h4);
unitlog.z3=strip(substr(bsdslst.h4,u+5,6));
memblog.z3=himemb.h2;
logtyp.z3="ARCHIV";
end;
h3=h3+4;
end;
end;
else nop;
end;
otherwise nop;
end;
end;
highrba.0=h2; srbalog.0=z3;
/* say "---Logs";
do z3=1 to srbalog.0
say right(d2x(srbalog.z3),12) right(d2x(erbalog.z3),12),
right(d2x(slrsnlog.z3),12) right(d2x(elrsnlog.z3),12),
unitlog.z3 right(memblog.z3,2) logtyp.z3;
end;
say "---highest LRSN:" d2x(highlrsn,12);
say "---highest written RBA";
do h2=1 to highrba.0;
say "highest:" right(d2x(highrba.h2,12),12) right(himemb.h2,2);
end;
*/
/*--- highest written RBAs nachführen in Logapply Ranges -------------*/
z1=slrsn.0;
do z2=1 to srba.0;
if (erba.z2 = 0); then do; /* SYSLGRNX open ? */
do h2=1 to highrba.0;
if (mbid.z2 = himemb.h2); then do;
erba.z2=highrba.h2;
elrsns.z2=max(slrsns.z2+1,highlrsn,slrsn.z1);
end;
else nop;
end;
end;
else nop;
end;
/* say "---syslgrnx table ergänzt";
do z2=1 to srba.0;
say right(d2x(srba.z2),12),
right(d2x(erba.z2),12),
right(d2x(slrsns.z2),12),
right(d2x(elrsns.z2),12),
right(d2x(mbid.z2),12);
end;
*/
/*--- Logapply Ranges ermitteln --------------------------------------*/
do z3=1 to srbalog.0; /* archlog ranges berechnen */
range.z3=0;
do z2=1 to srba.0;
if (mbid.z2 = memblog.z3); then do;
select;
when (elrsnlog.z3 < slrsns.z2);
then nop;
when (slrsnlog.z3 < slrsns.z2 & ,
elrsnlog.z3 <= elrsns.z2);
then do;
if (unitlog.z3 = "DISK"); then do;
range.z3=range.z3 + erbalog.z3 - srba.z2;
end;
else do;
range.z3=range.z3 + erbalog.z3 - srbalog.z3;
end;
end;
when (slrsnlog.z3 < slrsns.z2 & ,
elrsnlog.z3 > elrsns.z2);
then do;
if (unitlog.z3 = "DISK"); then do;
range.z3=range.z3 + erba.z2 - srba.z2;
end;
else do;
range.z3=range.z3 + erba.z2 - srbalog.z3;
end;
end;
when (slrsnlog.z3 >= slrsns.z2 & ,
elrsnlog.z3 <= elrsns.z2);
then do;
range.z3=range.z3 + erbalog.z3 - srbalog.z3;
end;
when (slrsnlog.z3 >= slrsns.z2 & ,
slrsnlog.z3 <= elrsns.z2 & ,
elrsnlog.z3 > elrsns.z2);
then do;
range.z3=range.z3 + erba.z2 - srbalog.z3;
end;
otherwise; nop;
end;
end;
end;
end;
/* say "---LOGS mit Ranges";
do z4=1 to srbalog.0;
say "srbalog:" d2x(srbalog.z4,12) ,
"erbalog:" d2x(erbalog.z4,12) ,
memblog.z4 unitlog.z4 logtyp.z4 range.z4;
end;
*/
z4=0; /* Reduktion no ranges */
do z3=1 to srbalog.0;
if (range.z3 > 0); then do;
z4=z4+1;
srbalog.z4=srbalog.z3; erbalog.z4=erbalog.z3;
slrsnlog.z4=slrsnlog.z3; elrsnlog.z4=elrsnlog.z3;
memblog.z4=memblog.z3; unitlog.z4=unitlog.z3;
logtyp.z4=logtyp.z3; range.z4=range.z3;
end;
else nop;
end;
srbalog.0=z4;
/* say "---benötigte Logs";
do z3=1 to srbalog.0
say right(d2x(srbalog.z3),12) right(d2x(erbalog.z3),12),
right(d2x(slrsnlog.z3),12) right(d2x(elrsnlog.z3),12),
unitlog.z3 right(memblog.z3,2) logtyp.z3 range.z3;
end;
*/
/*--- Bestimmen erforderliche Anzahl Cart Units ----------------------*/
icunit=0; lgunit=0;
do z1=1 to slrsn.0;
if (devtyp.z1 <> 3390); then do;
icunit=icunit+1;
end;
end;
do z3=1 to srbalog.0;
if (unitlog.z3 <> "DISK"); then do;
lgunit=lgunit+1;
end;
end;
lgvts=lgunit;
lgunit=min(2,lgunit);
cartunit=max(icunit,lgunit);
/*--- Berechnung der Recoverytime ------------------------------------*/
icmount=icunit*mount;
pages=0;
do z1=1 to slrsn.0;
pages=pages+copypage.z1;
end;
tmresto=icmount+trunc(pages*60/resto,0);
apply=0;
lgmount=min(1,lgunit)*mount;
do z3=1 to srbalog.0;
if (unitlog.z3 = "DISK"); then do;
apply=apply+range.z3*60/logap;
end;
else do;
apply=apply+max(mount,range.z3*60/logap);
end;
end;
tmlgapp=trunc(apply,0);
tmtot=tmresto+tmlgapp;
tmtotmm=trunc(tmtot/60,0);
tmtotss=tmtot-tmtotmm*60;
/*--- Print Resultate ------------------------------------------------*/
z1=slrsn.0;
o=o+1; out.o=group right(dat tim,75);
o=o+1; out.o=left("",80,"-");
o=o+1; out.o=" ";
o=o+1; out.o="Annahmen:";
o=o+1; out.o=left(" mounts:",20) mount "Sek. / mount";
o=o+1; out.o=left(" restore:",20) format(resto,,,,2) ,
"Pages / Min.";
o=o+1; out.o=left(" logapply:",20) format(logap,,,,2) ,
"Bytes / Min.";
o=o+1; out.o=" ";
o=o+1; out.o="Pageset: " space", PART/DSNUM:" part;
o=o+1; out.o="benötige Card Units:" format(cartunit,12,0);
o=o+1; out.o="Imagecopies: " format(slrsn.0,12,0);
o=o+1; out.o=" Pages: " format(pages,12,0);
o=o+1; out.o=" LRSN: " right(d2x(slrsn.z1,12),12);
o=o+1; out.o="SYSLGRNX: " format(srba.0,12,0);
o=o+1; out.o="Arch- und Activlogs:" format(srbalog.0,12,0);
o=o+1; out.o="Archlogs auf VTS: " format(lgvts,12,0);
o=o+1; out.o="Recovery:";
o=o+1; out.o=" Restore: " format(tmresto,17) "Sek.";
o=o+1; out.o=" Logapply: " format(tmlgapp,17) "Sek.";
o=o+1; out.o=left(" ",36,"-");
o=o+1; out.o=" total: " ,
right(tmtotmm,16)":"right(tmtotss,2,"0") "Min.";
o=o+1; out.o=copies("-",80);
o=o+1; out.o=" ";
o=o+1; out.o="SYSLGRNX Tabelle";
o=o+1; out.o="MEMBER" left("STARTRBA",12) left("ENDRBA",12) ,
left("STARTLRSN",12) left("ENDLRSN",12);
do z2=1 to srba.0;
o=o+1; out.o=right(mbid.z2,6) ,
d2x(srba.z2,12) d2x(erba.z2,12) ,
d2x(slrsns.z2,12) d2x(elrsns.z2,12);,
end;
o=o+1; out.o=" ";
o=o+1; out.o="Log Tabelle";
o=o+1; out.o="MEMBER" left("STARTRBA",12) left("ENDRBA",12) ,
left("STARTLRSN",12) left("ENDLRSN",12) ,
left("UNIT",4) left("LOGTYP",6);
do z3=1 to srbalog.0;
o=o+1; out.o=right(memblog.z3,6) ,
d2x(srbalog.z3,12) d2x(erbalog.z3,12) ,
d2x(slrsnlog.z3,12) d2x(elrsnlog.z3,12) ,
unitlog.z3 logtyp.z3;
end;
o=o+1; out.o=left("",80,"=");
out.0=o;
address tso "execio * diskw PRINT (stem out. open";
/* address tso "execio * diskw PRINT (stem rpt.";
address tso "execio * diskw PRINT (stem bsdslst.";
*/ address tso "execio * diskw PRINT ( finis";
exit cc;