Update 18/01/2017 : More field for Workfile BufferPool usage and alerts
Merge pass degraded ..., check Sequential Prefetch Quantity
Update 12/10/2017 : Track Workfile usage and others enhancements
Counters are checked and reports are sent to a dataset (which is then sent to our DB2 team e-mail account).
update : 11/5/2017
This Rexx allows to aggregate the detailed stats in value corresponding to 1 hour interval : this allows me to have a quick view / analysis , and it is enough light to be loaded to a DB2 database on Windows, SQLlite ...for a quick report (Note : after testing several free database on Windows, i am satisfied with DB2 because it allows a one click export to Excel from any SQL query )
I submit this Rexx daily on every Production LPAR and get the files sent to my PC where i load it to the DB2 table ...
I do this for the accounting and the statistics.
/*REXX*/
/****************************************************************/
/* DB2 STATS AGGREGATED BY HOUR */
/****************************************************************/
numeric digits 15
arg OPT OPT2
if OPT = '' then lpar = MVSVAR(SYSNAME)
else lpar = OPT
clnt=''
temX=0 /* just open new one time */
temR=0 /* Report in LOGW */
Call SetSmfDs
hlq='SYSTMP.DBDC.DB2'
vsm='Y' /*virtual storage monitoring Yes/No*/
/* Start processing unit for one SSID */
Start_Pgm:
nbGBP=0
nbBP=0
Hour='00'
Max_QISTW4K=0
Max_QISTW32K=0
bp0_vpsize=0
ifcid1_seen=0
Max_SUD2_gp=0
SumBP_SUD2=0
SumBP_SUD2_all=0
SUD2_BpInact=0
tsaylocal=0
ope =0
rupture=0
rec.0 =1
recw =0
RFlush =0
/* init compteurs divers */
call init_var
/* START PROCESSING */
DO FOREVER
/* read SMF record one by one */
"EXECIO 1 DISKR INP"
IF RC > 0 THEN DO
if rc = 2 then
do
SAY 'End of input SMF file rc=' RC
rcalloc = rc
end
else do
SAY 'Error while reading SMF file rc=' RC
rcalloc = 8
end
leave
END
PARSE PULL INPUT_REC
reci=reci+1
OFFSET = 1
/* Decode SMF header */
CALL DSNDQWST
/* process only smf100 */
IF (SM100RTY = 100 ) THEN
DO
if ope = 0 then call CrOutput /* do the first time only */
if sm100ssi <> ssid then iterate
/* record SMF records period */
if min_time > run_fmt_time then min_time=run_fmt_time
if Max_time < run_fmt_time then Max_time=run_fmt_time
if min_date > sm100dte then min_date=sm100dte
if Max_date < sm100dte then Max_date=sm100dte
/*sauvegarde offset_self car on le reutilise */
offset_selfdef= offset
/* on va sur le self def. section pour aller vers prod section*/
offset = C2D(SUBSTR(INPUT_REC,OFFSET,4))
offset = offset - 4 + 1
/* traitement product section*/
CALL DSNDQWHS
offset=offset_selfdef
/* ifcid 1 must start the stats group */
if ifcid = 1 then ifcid1_seen = 1
else if ifcid <> 1 & ifcid1_seen = 0 then
do
iterate
say 'bypass' ifcid
end
recs=recs+1
Select
When ifcid = 1 Then do
CALL DSNDQWS0
OFFSET = QWS00PSO - 4 + 1
end
When ifcid = 2 Then do
CALL DSNDQWS1
OFFSET = QWS10PSO - 4 + 1
end
When ifcid = 225 Then do
CALL QW0225
OFFSET = QWS10PSO - 4 + 1
end
Otherwise do
/* add line here to avoid excessive displays */
if ifcid = 202 then nop
else
if ifcid = 230 then nop
else
say 'ifcid ' ifcid ' not processed'
end
end /* select */
/*write report quand on a fait le tour des ifcids */
if ifcid = 1 & recs > 1 then
do
call ifcid_diff
/* on bypass le 1er record qui comprend les totaux*/
if reco > 0 then Call write_report
else reco = 1
end
else
do
if ifcid = 1 & recs = 1 then
do
Old_Mstrtcb = Mstrtcb
Old_MstrSrb = MstrSrb
Old_MstrpSRB= MstrpSRB
Old_MstrpSRB_Ziip = MstrpSRB_Ziip
Old_dbm1Tcb = dbm1Tcb
Old_dbm1srb = dbm1srb
Old_dbm1pSRB= dbm1pSRB
Old_dbm1pSRB_Ziip = dbm1pSRB_Ziip
Old_irlmTcb = irlmTcb
Old_irlmsrb = irlmsrb
Old_irlmpSRB= irlmpSRB
Old_irlmpSRB_Ziip = irlmpSRB_Ziip
Old_distTcb = distTcb
Old_distsrb = distsrb
Old_distpSRB= distpSRB
Old_distpSRB_Ziip = distpSRB_Ziip
end
end
END /* IF SM100RTY = 100 */
END
/* flush pending report (only at eof ) */
RFlush=1
call write_summary
"EXECIO" queued() "DISKW OUFL ( FINIS"
rcwrite = rc
if rcwrite<> 0 then Do
say "**********************************************"
say " Error writting OUFL file: " rcwrite
say " Abnormal end "
say "**********************************************"
Exit 8
end
"EXECIO 0 DISKR INP (STEM INL. FINIS"
/* Free REPORTS dataset */
"FREE DD(OUFL)"
rec.1= " "
call LOGW
call DisplayPref
rec.1= " "
call LOGW
rec.1= "Input records =" reci
call LOGW
rec.1= "Output records=" reco
call LOGW
rec.1= 'SMF period : ' min_date "/" Max_date min_time "/" Max_time
call LOGW
/*-------------------------------------------------*/
/* F20 End of program display counters and figures */
/*-------------------------------------------------*/
call DisplayVStor
if lpar = 'SUD2' then
call SUD2_report_bp_usage
"EXECIO 0 DISKW OUFw (FINIS"
/* Free REPORTSW dataset */
"FREE DD(OUFW)"
if lpar = 'IPO4' then
do
/* process DSNI now */
if ssid = 'DSNI' then /* avoid forever loop */
do
say 'End processing for IPO4'
end
else
do
ssid = 'DSNI'
signal start_pgm
end
end
if lpar = 'SUD2' then
do
if ssid = 'DBAP' then
do
ssid = 'DB2A'
signal start_pgm
end
if ssid = 'DB2A' then
do
ssid = 'DB2C'
signal start_pgm
end
if ssid = 'DB2C' then
do
ssid = 'DB2D'
signal start_pgm
end
if ssid = 'DB2D' then
do
ssid = 'DB2G'
signal start_pgm
end
if ssid = 'DB2G' then
do
ssid = 'DB2I'
signal start_pgm
end
if ssid = 'DB2I' then
do
ssid = 'DB2P'
signal start_pgm
end
if ssid = 'DB2P' then
do
ssid = 'DB2R'
signal start_pgm
end
if ssid = 'DB2R' then
do
ssid = 'DFEI'
signal start_pgm
end
if ssid = 'DFEI' then
do
ssid = 'DFLI'
signal start_pgm
end
if ssid = 'DFLI' then
do
ssid = 'DPEI'
signal start_pgm
end
if ssid = 'DPEI' then
do
ssid = 'DPLI'
signal start_pgm
end
if ssid = 'DPLI' then
do
ssid = 'DQE3'
signal start_pgm
end
if ssid = 'DQE3' then
do
ssid = 'DRC2'
signal start_pgm
end
if ssid = 'DRC2' then
do
say 'All DB2 of SUD2 processed - Ending'
end
end
if lpar = 'ZPR1' then
do
/* process DSNH now */
if ssid = 'DB2E' then /* avoid forever loop */
do
ssid = 'DB2H'
signal start_pgm
end
else
do
if ssid = 'DB2H' then
do
ssid = 'DB2I'
signal start_pgm
end
else
do
/* je suis la parce que ssid = 'DB2I'*/
say 'Tous les DB2 de ZPR1 sont traités'
end
end
end
"FREE DD(INP)"
if lpar = 'SUD2' then
do
"EXECIO 0 DISKW OUFs2 (FINIS"
"FREE DD(OUFs2)"
end
EXIT rcalloc
/*---------------------------------------*/
/* End of program body- Routines section */
/*---------------------------------------*/
/* MAP SELF-DEFINING SECT IFCID 001 LG = 112 */
DSNDQWS0:
/* OFFSET TO THE PRODUCT SECTION */
QWS00PSO = C2D(SUBSTR(INPUT_REC,OFFSET,4))
OFFSET = OFFSET + 4
QWS00PSL = C2D(SUBSTR(INPUT_REC,OFFSET,2))
OFFSET = OFFSET + 2
QWS00PSN = C2D(SUBSTR(INPUT_REC,OFFSET,2))
OFFSET = OFFSET + 2
/* OFFSET TO THE DATA SECTION MAPPED BY DSNDQWSA CPU TIME */
QWS00R1O = C2D(SUBSTR(INPUT_REC,OFFSET,4))
OFFSET = OFFSET + 4
QWS00R1L = C2D(SUBSTR(INPUT_REC,OFFSET,2))
OFFSET = OFFSET + 2
QWS00R1N = C2D(SUBSTR(INPUT_REC,OFFSET,2))
OFFSET = OFFSET + 2
save_offset = offset
/* controle de coherence */
if QWS00R1N > 4 then
do
say 'QWS00R1N is not equal to 4, abnormal end ' QWS00R1N
exit 8
end
/* Load offset to DSNDQWSA section - decode db2 stc cpu section */
OFFSET= QWS00R1O - 4 + 1
/* init DIST pas toujours pr§sent */
DISTTcb = 0
DISTSrb = 0
DISTpSRB = 0
DISTpSRB_Ziip= 0
i=0
do until i= QWS00R1N
i = i+ 1
call DSNDQWSA
end
/*restore offset */
offset = save_offset
/* OFFSET TO THE DATA SECTION MAPPED BY DSNDQWSB STATS COUNTERS*/
/* INSTRUMENTATION STATISTICS DATA ABOUT OUTPUT DESTINATION */
QWS00R2O = C2D(SUBSTR(INPUT_REC,OFFSET,4))
OFFSET = OFFSET + 8
/* OFFSET TO THE DATA SECTION MAPPED BY DSNDQWSC */
/* IFCIDS RECORDED TO STATISTICS */
QWS00R3O = C2D(SUBSTR(INPUT_REC,OFFSET,4))
OFFSET = OFFSET + 8
/* OFFSET TO THE DATA SECTION MAPPED BY DSNDQ3ST */
/* Subsytem services fields */
/* SIGNON, IDEN, COMMITS, ABORTS ...*/
QWS00R4O = C2D(SUBSTR(INPUT_REC,OFFSET,4))
OFFSET = OFFSET + 8
save_offset = offset
offset = QWS00R4O - 4 + 1
call DSNDQ3ST
offset = save_offset
/* OFFSET TO THE DATA SECTION MAPPED BY DSNDQ9ST */
QWS00R5O = C2D(SUBSTR(INPUT_REC,OFFSET,4))
OFFSET = OFFSET + 8
/* OFFSET TO THE DATA SECTION MAPPED BY DSNDQWSD */
/* CHECKPOINT INFO, IFI COUNT ...*/
QWS00R6O = C2D(SUBSTR(INPUT_REC,OFFSET,4))
OFFSET = OFFSET + 8
save_offset = offset
offset = QWS00R6O - 4 + 1
call DSNDQWSD
offset = save_offset
/* OFFSET TO THE DATA SECTION MAPPED BY DSNDQVLS */
/* LATCH COUNTS ...*/
QWS00R7O = C2D(SUBSTR(INPUT_REC,OFFSET,4))
OFFSET = OFFSET + 8
/* OFFSET TO THE DATA SECTION MAPPED BY DSNDQVAS */
/* ASMC STATS NBRE DE SUSPENSIONS ..*/
QWS00R8O = C2D(SUBSTR(INPUT_REC,OFFSET,4))
OFFSET = OFFSET + 8
/* OFFSET TO THE DATA SECTION MAPPED BY DSNDQSST */
/* STORAGE MANAGER */
QWS00R9O = C2D(SUBSTR(INPUT_REC,OFFSET,4))
OFFSET = OFFSET + 8
save_offset = offset
offset = QWS00R9O - 4 + 1
call DSNDQSST
offset = save_offset
/* OFFSET TO THE DATA SECTION MAPPED BY DSNDQLST */
/* DDF STATS BY LOCATION */
QWS00RAO = C2D(SUBSTR(INPUT_REC,OFFSET,4))
OFFSET = OFFSET + 8
/* OFFSET TO THE DATA SECTION MAPPED BY DSNDQJST */
/* LOG MANAGER */
QWS00RAO = C2D(SUBSTR(INPUT_REC,OFFSET,4))
OFFSET = OFFSET + 8
save_offset = offset
offset = QWS00RAO - 4 + 1
call DSNDQJST
offset = save_offset
/* OFFSET TO THE DATA SECTION MAPPED BY DSNDQDST */
/* DBAT STATS */
QWS00RCO = C2D(SUBSTR(INPUT_REC,OFFSET,4))
OFFSET = OFFSET + 8
save_offset = offset
offset = QWS00RCO - 4 + 1
call DSNDQDST
offset = save_offset
/* OFFSET TO THE DATA SECTION MAPPED BY DSNDQWOS */
/* ZOS STATS */
QWS00RCO = C2D(SUBSTR(INPUT_REC,OFFSET,4))
OFFSET = OFFSET + 8
/* LG = 112 = 14 SECTIONS * 8 */
Return
QW0225:
numeric digits 15
offset_save=offset /* sauvergarde offset debut data section*/
/* offset= offset of self definition section*/
/* offset= offset + 8 : bypass pointer to Product Section*/
/* offset_d = offset de la data section */
offset=offset+4+2+2 /*pointer to data section 1*/
/*take the contents pointed by the offset */
offset_d= C2D(SUBSTR(INPUT_REC,OFFSET,4))
/* -------------- */
/* data section 1 */
/* -------------- */
/* Data section 1 = 2 parts, DBM1 and DIST */
/* offset to dbm1 */
offset_d=offset_d -4+1
offset=offset+4
/* say 'offs sect1' offset_d */
/* len of data section 1 : it will be repeated :*/
/* One for DBM1 and one for DIST */
len= C2D(SUBSTR(INPUT_REC,OFFSET,2))
offset=offset+2
rep= C2D(SUBSTR(INPUT_REC,OFFSET,2))
offset=offset+2
/* say 'len' len
say 'rep' rep */
/* offset to DIST */
offset_d2=offset_d+len
/* say 'offs sect2' offset_d2 */
QW0225AN =(SUBSTR(INPUT_REC,OFFSET_d,4))
if QW0225AN <> 'DBM1' then
do
say 'W0225 - Mapping error'
exit 8
end
/***********************************/
/* Processing DBM1 storage section */
/***********************************/
if QW0225AN = 'DBM1' & vsm ='Y' then
do
offset_d=offset_d+4
/* extended region size */
QW0225RG = C2D(SUBSTR(INPUT_REC,OFFSET_d,4))
offset_d=offset_d+4+4+4
QW0225EL = C2D(SUBSTR(INPUT_REC,OFFSET_d,4))
offset_d=offset_d+4
QW0225EH = C2D(SUBSTR(INPUT_REC,OFFSET_d,4))
offset_d=offset_d+4 +4+4
/* storage reserved fo must complete */
/* before V10 depends on CTHREAD and MaxDBAT zparm*/
QW0225CR = C2D(SUBSTR(INPUT_REC,OFFSET_d,4))
offset_d=offset_d+4
/* storage reserved for open/close datasets */
/* depends on DSMax value */
QW0225MV = C2D(SUBSTR(INPUT_REC,OFFSET_d,4))
offset_d=offset_d+4
QW0225SO = C2D(SUBSTR(INPUT_REC,OFFSET_d,4))
offset_d=offset_d+4
QW0225GS = C2D(SUBSTR(INPUT_REC,OFFSET_d,4))
offset_d=offset_d+4+4
QW0225VR = C2D(SUBSTR(INPUT_REC,OFFSET_d,4))
offset_d=offset_d+4
QW0225FX = C2D(SUBSTR(INPUT_REC,OFFSET_d,4))
offset_d=offset_d+4
QW0225GM = C2D(SUBSTR(INPUT_REC,OFFSET_d,4))
offset_d=offset_d+4
/* 31 bit storage available */
QW0225AV = C2D(SUBSTR(INPUT_REC,OFFSET_d,4))
offset_d=offset_d+4+4+8+8+8+8
QW0225RL_dbm1 = C2D(SUBSTR(INPUT_REC,OFFSET_d,8))
/* 225RL = Real stor. frame used by the Address Space*/
/* this includes bufferpools storage qw0225bb */
offset_d=offset_d+8
QW0225AX_dbm1 = C2D(SUBSTR(INPUT_REC,OFFSET_d,8))
offset_d=offset_d+8
/* QW0225HVPagesInReal 64 bits private Real */
QW0225HVPagesInReal = C2D(SUBSTR(INPUT_REC,OFFSET_d,8))
offset_d=offset_d+8
/* QW0225HVAuxSlots 64 bits private Aux */
QW0225HVAuxSlots = C2D(SUBSTR(INPUT_REC,OFFSET_d,8))
offset_d=offset_d+24
/* /* QW0225HWM 64 bits private Real*/
QW0225HVGPagesInReal = C2D(SUBSTR(INPUT_REC,OFFSET_d,8))
offset_d=offset_d+8
/* QW0225HWM 64 bits private Aux */
QW0225HVGAuxSlots= C2D(SUBSTR(INPUT_REC,OFFSET_d,8))
offset_d=offset_d+8 */
/* QW0225PagesInReal 64 bits private Real without BP */
QW0225PriStg_Real= C2D(SUBSTR(INPUT_REC,OFFSET_d,8))
offset_d=offset_d+8
/* QW0225PagesInAux 64 bits private Aux without BP */
QW0225PriStg_Aux= C2D(SUBSTR(INPUT_REC,OFFSET_d,8))
offset_d=offset_d+8
TotalRealUsedBP = QW0225HVPagesInReal - QW0225PriStg_Real
TotalAuxUsedBP = QW0225HVAuxSlots - QW0225PriStg_Aux
end /* if QW0225AN = 'DBM1' & vsm = 'Y' then */
/* rep = 2 : there is 2 parts , DBM1 and DDF */
if rep = 2 then
do
/* partie DIST */
QW0225AN =(SUBSTR(INPUT_REC,OFFSET_d2,4))
if QW0225AN <> 'DIST' then
do
say 'W0225 - Mapping error DIST not found'
say 'input_rec' input_rec
say 'offset' offset_d2
exit 8
end
if QW0225AN = 'DIST' & vsm='Y' then
do
offset_d2=offset_d2+4
offset_d2=offset_d2+4+4+4
offset_d2=offset_d2+4
offset_d2=offset_d2+4 +4+4
offset_d2=offset_d2+4
offset_d2=offset_d2+4
offset_d2=offset_d2+4
offset_d2=offset_d2+4+4
offset_d2=offset_d2+4
offset_d2=offset_d2+4
offset_d2=offset_d2+4+4+4+8+8+8+8
QW0225RL_dist = C2D(SUBSTR(INPUT_REC,offset_d2,8))
offset_d2=offset_d2+8
QW0225AX_dist = C2D(SUBSTR(INPUT_REC,offset_d2,8))
end /* if QW0225AN = 'DIST' & vsm = 'Y' then */
end
else /*if rep = 2 then*/
do
QW0225RL_dist = 0
QW0225AX_dist = 0
end
/*pointer to data section 2*/
offset_d= C2D(SUBSTR(INPUT_REC,OFFSET,4))
offset_d=offset_d -4+1
QW0225AT =C2D(SUBSTR(INPUT_REC,OFFSET_d,4))
offset_d=offset_d+4 /*pointer on data section 2*/
QW0225DB =C2D(SUBSTR(INPUT_REC,OFFSET_d,4))
if (QW0225AT + qw0225DB) < MinThdSee then
do
MinThdSee = QW0225AT + qw0225DB
MinThdSeeTime= run_fmt_time
MinThdSeeDate= sm100dte
end
if (QW0225AT + qw0225DB) > MaxThdSee then
do
MaxThdSee = QW0225AT + qw0225DB
MaxThdSeeTime= run_fmt_time
MaxThdSeeDate= sm100dte
end
/* say 'threads allied=' QW0225AT
say 'threads dbat=' QW0225DB */
/*pointer to data section 3 : Shared and Common Storage */
offset=offset+8 /* go to next pointer*/
if vsm = 'Y' then
do
/* load address of section 3*/
offset_d= C2D(SUBSTR(INPUT_REC,OFFSET,4))
offset_d=offset_d -4+1
offset_d=offset_d +136
QW0225SHRINREAL =C2D(SUBSTR(INPUT_REC,OFFSET_d,8))
offset_d=offset_d + 32
QW0225ShrStg_Real=C2D(SUBSTR(INPUT_REC,OFFSET_d,8))
offset_d=offset_d + 8
QW0225ShrStg_Aux =C2D(SUBSTR(INPUT_REC,OFFSET_d,8))
offset_d=offset_d + 8
QW0225ShrStkStg_Real=C2D(SUBSTR(INPUT_REC,OFFSET_d,8))
offset_d=offset_d + 8
QW0225ShrStkStg_Aux =C2D(SUBSTR(INPUT_REC,OFFSET_d,8))
offset_d=offset_d + 8
QW0225ComStg_Real=C2D(SUBSTR(INPUT_REC,OFFSET_d,8))
offset_d=offset_d + 8
QW0225ComStg_Aux =C2D(SUBSTR(INPUT_REC,OFFSET_d,8))
/* formula from Redbook V11 Monitoring */
/* table 13-1 13-2 */
/* Calculation to be updated when V11 + Log Mgr control */
/* in Real, Log. write buffers */
TotalRealUsedByDB2 = qw0225rl_dbm1+ qw0225rl_dist +,
QW0225ShrStg_Real + QW0225ShrStkStg_Real +,
QW0225ComStg_Real
/* TotalRealUsedByLPAR meaning not clear - value does not */
/* corresponds with others z/OS monitoring tool */
/* TotalRealUsedByLPAR= qw0225rl_dbm1+ qw0225rl_dist +, */
/* QW0225ComStg_Real + -- in redbook but no where else*/
/* QW0225SHRINREAL */
/* QW0225ComStg_Real Real in use 64 bit shared */
/* QW0225SHRINREAL Real in use 64 bit common */
/* if MaxRealLPAR < TotalRealUsedByLPAR then */
/* do */
/* MaxRealLPAR = TotalRealUsedByLPAR */
/* time_MaxRealLPAR = run_fmt_time */
/* end */
offset_d=offset_d + 32
/* QW0225_WARN =C2D(SUBSTR(INPUT_REC,OFFSET_d,4)) */
offset_d=offset_d + 8
QW0225_REALAVAIL =C2D(SUBSTR(INPUT_REC,OFFSET_d,4))
if MinQW0225_REALAVAIL > QW0225_REALAVAIL then
do
MinQW0225_REALAVAIL = QW0225_REALAVAIL
time_MinQW0225_REALAVAIL = run_fmt_time
date_MinQW0225_REALAVAIL = sm100dte
end
end
/*-------------------------*/
/*pointer to data section 4*/
/*-------------------------*/
offset=offset+8
/*-------------------------------------------------*/
/*pointer to data section 5 : Pool storage details */
/*-------------------------------------------------*/
offset=offset+8
if vsm = 'Y' then
do
offset_d= C2D(SUBSTR(INPUT_REC,OFFSET,4))
offset_d= offset_d+4
/* QW0225AS Total system agent storage 31 bits*/
QW0225AS =C2D(SUBSTR(INPUT_REC,OFFSET_d,4))
/* QW0225BB Total buffer manager storage blocks */
/*-------------------------------*/
/* Calculate Max threads allowed */
/*-------------------------------*/
/*Ici on a eu tous les infos on peut donc calculer le */
/* nombre de threads Max theoriques*/
/* Source : IBM formula */
/* (Redbook V11 subsystem monitoring Chap. Virtual Stor*/
/* Min and Max is used in a very defensive way */
/* The excel proposed with MEMU deoesn't use min Max */
/* I also caculate this value (thdcomp2) */
/* Thread footprint calculation : */
/* Basic Storage Cushion */
BC = QW0225CR + QW0225MV + QW0225SO
/* Non DB2 storage, retains Max value for final calculation*/
ND = QW0225EH-QW0225GM-QW0225GS-QW0225FX-QW0225VR
if ND > MaxND then MaxND=ND
/* Max Allowable storage */
AS = QW0225RG-BC-MaxND
AS2= QW0225RG-BC-ND
if AS < MinAS then MinAS=AS
/* Max Allowable storage for thread use*/
TS = MinAS-(QW0225AS + QW0225FX + QW0225GM+ QW0225EL)
TS2= AS2-(QW0225AS + QW0225FX + QW0225GM+ QW0225EL)
if TS < MinTS then MinTS=TS
/* Average thread footprint */
if (QW0225AT + qdstcnat) = 0 then
/* if threads in system = 0 then 1 */
TF = QW0225VR- QW0225AS + QW0225GS
else
TF = (QW0225VR-QW0225AS+QW0225GS)/(QW0225AT+qdstcnat)
if TF > MaxTF then MaxTF=TF
/* Max threads supported */
ThdComp=MinTS/MaxTF
ThdComp2=TS2/TF
StorBefContract=qw0225AV-(qw0225cr+qw0225SO+qw0225MV)
/* Storage contraction ?*/
if qw0225AV < qw0225cr then
do
say ' Storage critical condition',
'@ ' run_fmt_time
end
else do
if qw0225AV < (qw0225cr+ qw0225SO+qw0225MV) then
do
say ' Full system contraction should happen',
'@ ' run_fmt_time
end
end /* else */
if ThdComp < MinThdComp then do
MinThdComp =ThdComp
MinThdCompTime=run_fmt_time
MinThdCompDate=sm100dte
end
if ThdComp2 < MinThdComp2 then do
MinThdComp2 =ThdComp2
MinThdComp2Time=run_fmt_time
MinThdComp2Date=sm100dte
end
if ThdComp > MaxThdComp then do
MaxThdComp =ThdComp
MaxThdCompTime =run_fmt_time
MaxThdCompDate =sm100dte
end
if ThdComp2 > MaxThdComp2 then do
MaxThdComp2 =ThdComp2
MaxThdComp2Time =run_fmt_time
MaxThdComp2Date =sm100dte
end
Real4K_dbm1=(QW0225RL_dbm1 *4096)/ 1048576 /*1MB*/
Real4K_dist=(QW0225RL_dist *4096)/ 1048576 /*1MB*/
If MinReal4K_dbm1 > Real4K_dbm1 then
do
MinReal4K_dbm1=Real4K_dbm1
time_MinReal4K_dbm1=run_fmt_time
Date_MinReal4K_dbm1=sm100dte
end
If MaxReal4K_dbm1 < Real4K_dbm1 then
do
MaxReal4K_dbm1=Real4K_dbm1
time_MaxReal4K_dbm1=run_fmt_time
Date_MaxReal4K_dbm1=sm100dte
end
If MinReal4K_dist > Real4K_dist then
do
MinReal4K_dist=Real4K_dist
time_MinReal4K_dist=run_fmt_time
Date_MinReal4K_dist=sm100dte
end
If MaxReal4K_dist < Real4K_dist then
do
MaxReal4K_dist=Real4K_dist
time_MaxReal4K_dist=run_fmt_time
Date_MaxReal4K_dist=sm100dte
end
/* calculation to be updated when V11 + Log Mgr control */
/* in aux - check IBM excel provided with memu */
TotalAuxlUsedByDB2 = qw0225ax_dbm1+ qw0225ax_dist +,
QW0225ComStg_Aux + QW0225ShrStg_Aux + ,
QW0225ShrStkStg_Aux
If MaxDB2AuxUse < TotalAuxlUsedByDB2 then
do
MaxDB2AuxUse=TotalAuxlUsedByDB2
timeMaxDB2AuxUse=run_fmt_time
DateMaxDB2AuxUse=sm100dte
end
end /* if vsm ... */
return
/* MAP SELF-DEFINING SECT IFCID 002 LG = 12X8 = 96 */
DSNDQWS1:
/* OFFSET TO THE PRODUCT SECTION */
QWS10PSO = C2D(SUBSTR(INPUT_REC,OFFSET,4))
OFFSET = OFFSET + 8
/* OFFSET TO THE DATA SECTION MAPPED BY DSNDQXST */
/* RDS stats block */
QWS10R1O = C2D(SUBSTR(INPUT_REC,OFFSET,4))
OFFSET = OFFSET + 8
if QWS10R1O > 0 then
do
save_offset = offset
offset = QWS10R1O - 4 + 1
call DSNDQXST
offset = save_offset
end
else
do
call DSNDQXST0
end
/* OFFSET TO THE DATA SECTION MAPPED BY DSNDQTST */
/* nbre de bind, nbre de plan allocated succ ... */
QWS10R2O = C2D(SUBSTR(INPUT_REC,OFFSET,4))
OFFSET = OFFSET + 8
save_offset = offset
offset = QWS10R2O - 4 + 1
call DSNDQTST
offset = save_offset
/* OFFSET TO THE DATA SECTION MAPPED BY DSNDQBST */
/* Buffer manager stats */
QWS10R3O = C2D(SUBSTR(INPUT_REC,OFFSET,4))
OFFSET = OFFSET + 6
QWS10r3N = C2D(SUBSTR(INPUT_REC,OFFSET,2))
OFFSET = OFFSET + 2
/* decode dsndqbst to have buffer stats */
Sum_QBSTGET = 0
Sum_QBSTRIO = 0
Sum_QBSTIMW = 0
Sum_QBSTDSO = 0
Sum_QBSTWIO = 0
Sum_QBSTRPI = 0
Sum_QBSTWPI = 0
Sum_QBSTPIO = 0
Sum_QBSTMAX = 0
Sum_QBSTWFD = 0
Sum_QBSTWFF = 0
Sum_QBSTCIO = 0
Sum_QBSTDIO = 0
Sum_QBSTLIO = 0
Sum_QBSTSIO = 0
if QWS10R3O > 0 then
do
saveoffset= offset
offset=QWS10R3O - 4 + 1
/*add code here if need figures by bufferpool ID */
m=0
do until m= QWS10r3N
m = m+ 1
call dsndqbst
Sum_QBSTGET = Sum_QBSTGET + QBSTGET
Sum_QBSTRIO = Sum_QBSTRIO + QBSTRIO
Sum_QBSTIMW = Sum_QBSTIMW + QBSTIMW
Sum_QBSTDSO = Sum_QBSTDSO + QBSTDSO
Sum_QBSTWIO = Sum_QBSTWIO + QBSTWIO
Sum_QBSTRPI = Sum_QBSTRPI + QBSTRPI
Sum_QBSTWPI = Sum_QBSTWPI + QBSTWPI
Sum_QBSTPIO = Sum_QBSTPIO + QBSTPIO
Sum_QBSTMAX = Sum_QBSTMAX + QBSTMAX
Sum_QBSTWFD = Sum_QBSTWFD + QBSTWFD
Sum_QBSTWFF = Sum_QBSTWFF + QBSTWFF
Sum_QBSTCIO = Sum_QBSTCIO + QBSTCIO
Sum_QBSTDIO = Sum_QBSTDIO + QBSTDIO
Sum_QBSTLIO = Sum_QBSTLIO + QBSTLIO
Sum_QBSTSIO = Sum_QBSTSIO + QBSTSIO
end
offset=saveoffset
end
/* OFFSET TO THE DATA SECTION MAPPED BY DSNDQIST */
/* Data manager stats */
QWS10R4O = C2D(SUBSTR(INPUT_REC,OFFSET,4))
OFFSET = OFFSET + 8
/* decode dsnDQIST to have to Data manager stats */
saveoffset= offset
offset=QWS10R4O - 4 + 1
call dsndqist
offset=saveoffset
/* OFFSET TO THE DATA SECTION MAPPED BY DSNDQTXA */
/* Lock manager stats */
OFFSET = OFFSET + 8
/* OFFSET TO THE DATA SECTION MAPPED BY DSNDQISE */
OFFSET = OFFSET + 8
/* OFFSET TO THE DATA SECTION MAPPED BY DSNDQBGL */
/* GBP Stats */
QWS10R7O = C2D(SUBSTR(INPUT_REC,OFFSET,4))
OFFSET = OFFSET + 6
QWS10R7N = C2D(SUBSTR(INPUT_REC,OFFSET,2))
OFFSET = OFFSET + 2
if QWS10R7O > 0 then
do
save_offset = offset
offset = QWS10R7O - 4 + 1
m=0
do until m= QWS10r7N
m = m+ 1
call DSNDQBGL
end /* do until */
offset = save_offset
end /* QWS10R7O > 0 */
/* (...) */
/* Others sections - Check Rex100 */
return
dsndqist:
numeric digits 15
offset = offset +4
/* Fields of these macro seems to be all cumulative */
/* calculate difference between interval */
/* check QIEYE */
if SUBSTR(INPUT_REC,OFFSET,4) <> 'QIST' then
do
say 'Mapping error QIST eye catcher not found'
exit(8)
end
offset = offset + 4
/* RID Term RDS Limit */
QISTRLLM = C2D(SUBSTR(INPUT_REC,offset,4))
offset = offset + 4
/* RID Term DM Limit */
QISTRPDM = C2D(SUBSTR(INPUT_REC,OFFSET,4))
offset = offset + 20
/* not optimal column proc Invalid Sproc */
QISTCOLS = C2D(SUBSTR(INPUT_REC,OFFSET,4))
offset = offset + 40
/* 32KB Wrkfile used instead of 4KB */
QISTWFP1 = C2D(SUBSTR(INPUT_REC,OFFSET,4))
offset = offset + 4
/* 4 KB Wrkfile used instead of 32 KB */
QISTWFP2 = C2D(SUBSTR(INPUT_REC,OFFSET,4))
offset = offset + 28
/* hwm storage used by workfiles in KB */
offset = offset + 8
/* Current all workfile usage in KB : DGTT and Sort */
offset = offset + 8
/* Current 4K wrkfile storage usage in KB*/
QISTW4K = C2D(SUBSTR(INPUT_REC,OFFSET,8))
if QISTW4K > Max_QISTW4K then
Max_QISTW4K = QISTW4K
offset = offset + 8
/* Current 32K wrkfile storage usage in KB*/
QISTW32K = C2D(SUBSTR(INPUT_REC,OFFSET,8))
if QISTW32K > Max_QISTW32K then
Max_QISTW32K = QISTW32K
offset = offset + 8
/* Nb DM in memory wrkfiles active currently */
offset = offset + 8
/* Space DM in memory active currently in KB*/
offset = offset + 24
/* Nb SRT in memory wrkfiles active currently */
offset = offset + 8
/* Space SRT in memory active currently in bytes */
offset = offset + 32
/* Current RID blocks overflowed (stored) in wrkfiles*/
offset = offset + 8
/* Current NON Sort related workfiles active */
offset = offset + 16
/* Physical workfiles created */
offset = offset + 24
/* HWM wkfile storage used by an agent */
QISTAMXU = C2D(SUBSTR(INPUT_REC,OFFSET,8))
offset = offset + 8
/* Current storage configured for wkfiles*/
offset = offset + 8
/* Current DGTT configured for wkfile KB*/
offset = offset + 8
/* Current DGTT used KB*/
offset = offset + 8
/* HWM DGTT used KB*/
QISTDGTTMXU = C2D(SUBSTR(INPUT_REC,OFFSET,8))
offset = offset + 8
/* Current others configured for wkfile KB*/
offset = offset + 8
/* Current others used KB*/
offset = offset + 8
/* HWM others used KB*/
QISTWFMXU = C2D(SUBSTR(INPUT_REC,OFFSET,8))
return
/* MAP STANDARD HEADER PRODUCT SECTION */
DSNDQWHS:
OFFSET = OFFSET + 2
QWHSTYP = C2D(SUBSTR(INPUT_REC,OFFSET,1))
OFFSET = OFFSET + 2
/* QWHSIID DS XL2 IFCID */
QWHSIID = C2D(SUBSTR(INPUT_REC,OFFSET,2))
IFCID=QWHSIID
OFFSET = OFFSET + 2
QWHSNSDA =C2D(SUBSTR(INPUT_REC,OFFSET,1))
OFFSET = OFFSET + 6
/* QWHSSSID DS CL4 SUBSYSTEM NAME */
QWHSSSID = SUBSTR(INPUT_REC,OFFSET,4)
OFFSET = OFFSET + 64
/* TOTAL LENGTH = 76 */
RETURN
/* STATISTICS CPU TIME MAPPING MACRO LG = 52*4*/
DSNDQWSA:
numeric digits 15
QWSAPROC =(SUBSTR(INPUT_REC,OFFSET,4))
OFFSET = OFFSET + 4
/*CONVERT INTO HEX VALUE*/
QWSAEJST = C2X(SUBSTR(INPUT_REC,OFFSET,8))
/*ELIMINATE 1.5 BYTES */
QWSAEJST = X2D(SUBSTR(QWSAEJST,1,13))
QWSAEJST = QWSAEJST/1000000
OFFSET = OFFSET + 8
QWSASRBT = C2X(SUBSTR(INPUT_REC,OFFSET,8))
QWSASRBT = X2D(SUBSTR(QWSASRBT,1,13))
QWSASRBT = QWSASRBT/1000000
OFFSET = OFFSET + 16
QWSAPSRB = C2X(SUBSTR(INPUT_REC,OFFSET,8))
QWSAPSRB = X2D(SUBSTR(QWSAPSRB,1,13))
QWSAPSRB = QWSAPSRB/1000000
OFFSET = OFFSET + 8
QWSAPSRB_Ziip = C2X(SUBSTR(INPUT_REC,OFFSET,8))
QWSAPSRB_Ziip = X2D(SUBSTR(QWSAPSRB_Ziip,1,13))
QWSAPSRB_Ziip = QWSAPSRB_Ziip/1000000
OFFSET = OFFSET + 16
Select
When qwsaproc = 'MSTR' Then do
MstrTcb =QWSAEJST
MstrSrb =QWSAsrbt
MstrpSRB =QWSApsrb
MstrpSRB_Ziip=QWSApsrb_Ziip
end
When qwsaproc = 'DBM1' Then do
DBM1Tcb =QWSAEJST
DBM1Srb =QWSAsrbt
DBM1pSRB =QWSApsrb
DBM1pSRB_Ziip=QWSApsrb_Ziip
end
When qwsaproc = 'DIST' Then do
DISTTcb =QWSAEJST
DISTSrb =QWSAsrbt
DISTpSRB =QWSApsrb
DISTpSRB_Ziip=QWSApsrb_Ziip
end
When qwsaproc = 'IRLM' Then do
IRLMTcb =QWSAEJST
IRLMSrb =QWSAsrbt
IRLMpSRB =QWSApsrb
IRLMpSRB_Ziip=QWSApsrb_Ziip
end
Otherwise do
say 'qwsaproc NOT correct' qwsaproc
exit 8
end
end /* select */
RETURN
DSNDQISE:
/* EDMPOOL STATS */
numeric digits 15
/* Fields from IFCID002 : all cumulative */
/* calculate difference between interval */
/*# OF REQ FOR CT SECTIONS*/
offset = offset + 8
QISECTG = C2D(SUBSTR(INPUT_REC,offset,4))
/*# OF LOAD CT SECT FROM DASD*/
offset = offset + 4
QISECTL = C2D(SUBSTR(INPUT_REC,offset,4))
/*# OF REQUESTS FOR DBD*/
offset = offset + 20
QISEDBDG = C2D(SUBSTR(INPUT_REC,offset,4))
/*# OF LOAD DBD FROM DASD*/
offset = offset + 4
QISEDBDL = C2D(SUBSTR(INPUT_REC,offset,4))
/*# OF REQ FOR PT SECTIONS*/
offset = offset + 4
QISEKTG = C2D(SUBSTR(INPUT_REC,offset,4))
/*# OF LOAD PT SECT FROM DASD*/
offset = offset + 4
QISEKTL = C2D(SUBSTR(INPUT_REC,offset,4))
offset = offset + 12
/*# OF Inserts FOR DYN CACHE*/
QISEDSI = C2D(SUBSTR(INPUT_REC,offset,4))
/*# OF REQUESTS FOR DYN CACHE*/
offset = offset + 4
QISEDSG = C2D(SUBSTR(INPUT_REC,offset,4))
/*NUMBER OF PAGES IN DBD POOL*/
offset = offset + 12
QISEDPGE = C2D(SUBSTR(INPUT_REC,offset,4))
/*# OF FREE PG IN DBD FREE CHAIN*/
offset = offset + 4
QISEDFRE = C2D(SUBSTR(INPUT_REC,offset,4))
/*# OF FAIL DUE TO DBD POOL FULL*/
offset = offset - 8
QISEDFAL = C2D(SUBSTR(INPUT_REC,offset,4))
/*# OF PGS IN STMT POOL*/
offset = offset + 20
QISECPGE = C2D(SUBSTR(INPUT_REC,offset,4))
/*# OF FREE PG IN STMT FREE CHAIN*/
offset = offset + 4
QISECFRE = C2D(SUBSTR(INPUT_REC,offset,4))
/*# OF FAIL DUE TO STMT POOL FULL*/
offset = offset - 8
QISECFAL = C2D(SUBSTR(INPUT_REC,offset,4))
/*# OF PAGES IN SKEL EDM POOL*/
offset = offset + 24
QISEKPGE = C2D(SUBSTR(INPUT_REC,offset,4))
/*# OF FREE PG IN SKEL EDM POOL FREE CHAIN */
offset = offset + 4
QISEKFRE = C2D(SUBSTR(INPUT_REC,offset,4))
/*# OF FAIL DUE TO STMT SKEL POOL FULL*/
offset = offset - 8
QISEKFAL = C2D(SUBSTR(INPUT_REC,offset,4))
return
DSNDQSST:
offset= offset+4
/* eye catcher */
eyec = SUBSTR(INPUT_REC,OFFSET,4)
if ( eyec <> 'QSST' ) then
do
say 'DSNDQSST eye catcher not met, error'
exit(8)
end
offset= offset+4*14
/* full storage contraction*/
QSSTCONT = C2D(SUBSTR(INPUT_REC,OFFSET,4))
offset = offset + 4
QSSTCRIT = C2D(SUBSTR(INPUT_REC,OFFSET,4))
offset = offset + 4
QSSTABND = C2D(SUBSTR(INPUT_REC,OFFSET,4))
offset = offset + 4
return
DSNDQTST:
/* Service Controler Stats */
offset= offset+4
/* eye catcher */
eyec = SUBSTR(INPUT_REC,OFFSET,4)
if ( eyec <> 'QTST' ) then
do
say 'DSNDQTST eye catcher not met, error'
exit(8)
end
offset= offset+4*18
/* Datasets opened */
QTDSOPN = C2D(SUBSTR(INPUT_REC,OFFSET,4))
offset = offset + 4*12
/* DS closed by drain DSMax reached */
QTDSDRN = C2D(SUBSTR(INPUT_REC,OFFSET,4))
offset = offset + 4
/* RWRO Convert */
QTPCCT = C2D(SUBSTR(INPUT_REC,OFFSET,4))
return
DSNDQ3ST:
/* DB2 Subsystem services fields */
offset= offset+4
/* Signon, meaningful only with CICS or IMS */
/* Nbr of signon for new user of an EXISTING thread*/
/* If Signon > CrtThread then there is Thread reuse */
Q3STSIGN = C2D(SUBSTR(INPUT_REC,OFFSET,4))
offset = offset + 4
/* Create thread (does not include DBAT) */
Q3STCTHD = C2D(SUBSTR(INPUT_REC,OFFSET,4))
offset = offset + 4
/* Terminate */
Q3STTERM = C2D(SUBSTR(INPUT_REC,OFFSET,4))
offset = offset + 8
/* Commit1 */
Q3STPREP = C2D(SUBSTR(INPUT_REC,OFFSET,4))
offset = offset + 4
/* Commit2 */
Q3STCOMM = C2D(SUBSTR(INPUT_REC,OFFSET,4))
offset = offset + 4
/* Aborts */
Q3STABRT = C2D(SUBSTR(INPUT_REC,OFFSET,4))
offset = offset + 4*9
/* HWM IDBACK*/
Q3STHWIB = C2D(SUBSTR(INPUT_REC,OFFSET,4))
offset = offset + 4
/* HWM IDFORE*/
Q3STHWIF = C2D(SUBSTR(INPUT_REC,OFFSET,4))
offset = offset + 4
/* HWM CTHREAD*/
Q3STHWCT = C2D(SUBSTR(INPUT_REC,OFFSET,4))
return
DSNDQJST:
offset=offset+4
/* eye catcher */
eyec = SUBSTR(INPUT_REC,OFFSET,4)
if ( eyec <> 'QJST' ) then
do
say 'DSNDQJST eye catcher not met, error'
exit(8)
end
offset=offset+40
/* active log output CI created */
QJSTBFFL = C2D(SUBSTR(INPUT_REC,OFFSET,4))
return
DSNDQDST:
if QWS00RCO = 0 then
/* No DDF information */
do
say 'There is no DDF information in this trace'
say ' '
QDSTQDBT =0
QDSTQCRT =0
QDSTQCIT =0
QDSTQMIT =0
QDSTCNAT =0
QDSTHWAT =0
QDSTHWDT =0
QDSTCIN2 =0
QDSTMIN2 =0
return
end
/* dbat queued */
QDSTQDBT = C2D(SUBSTR(INPUT_REC,OFFSET,4))
offset = offset + 20 /* 4x 5 */
/* dbat rejected condbat reached */
QDSTQCRT = C2D(SUBSTR(INPUT_REC,OFFSET,4))
offset = offset + 4
/* current inact 1 */
QDSTQCIT = C2D(SUBSTR(INPUT_REC,OFFSET,4))
offset = offset + 4
/* Max inact 1 */
QDSTQMIT = C2D(SUBSTR(INPUT_REC,OFFSET,4))
offset = offset + 4
/* curr pooled dbat : active and disconnect */
QDSTCNAT = C2D(SUBSTR(INPUT_REC,OFFSET,4))
offset = offset + 4
/* Max pooled dbat : active and disconnect */
QDSTHWAT = C2D(SUBSTR(INPUT_REC,OFFSET,4))
offset = offset + 4
/* Max dbat : Max active + inact */
QDSTHWDT = C2D(SUBSTR(INPUT_REC,OFFSET,4))
offset = offset + 8
/* cur inact 2 */
QDSTCIN2 = C2D(SUBSTR(INPUT_REC,OFFSET,4))
offset = offset + 4
/* Max inact 2 */
QDSTMIN2 = C2D(SUBSTR(INPUT_REC,OFFSET,4))
return
GET_FMT_TIME:
Old_Hour = Hour
RUN_HH = SM100TME % 360000
RUN_HH = RIGHT(RUN_HH,2,'0')
RUN_MIN = SM100TME % 6000 - RUN_HH*60
RUN_MIN = RIGHT(RUN_MIN,2,'0')
RUN_SEC = SM100TME % 100 - RUN_HH *3600 - RUN_MIN*60
RUN_SEC = RIGHT(RUN_SEC,2,'0')
RUN_FMT_TIME = RUN_HH!!':'!!RUN_MIN!!':'!!RUN_SEC
Hour = left(run_fmt_time,2)
/* Detect if we change hour */
if Old_Hour <> Hour then Change_Hour=1
else Change_Hour=0
RETURN
write_header:
say 'CSV file ' oufl ' will be produced'
queue "Lpar,ssid,date,dow,Hour,MstrTCB,MstrSRB,MstrPSRB,"!!,
"MstrPSRB_Ziip,Dbm1TCB,DBm1SRB,DBm1PSRB,Dbm1PSRB_Ziip,"!!,
"IrlmTCB,IrlmSRB,IrlmPSRB,IrlmPSRB_Ziip,"!!,
"DistTCB,DistSRB,DistPSRB,DistPSRB_Ziip,"!!,
"CrtThd,Sign,Term,Comm1,Comm2,Abort,MaxIDBACK,"!!,
"MaxIDFOR,CThread,"!!,
"Chkpt,"!!,
"MaxDSCur,DSClose,DSOpen,"!!,
"ROSwitch,"!!,
"Getpage,Syncio,SyncWr,AsyncWr,"!!,
"PageInR,PageInW,"!!,
"SPrefIO,CastIO,DynPrfIO,LstPrfIO,BpSio,"!!,
"MaxInac1,MaxActDbat,MaxAllDbat,"!!,
"MaxDbat,"!!,
"MaxAldThds,ThdMaxComp,ThdMaxComp2,"!!,
"MaxRealUsedDB2,MaxAuxUsedDB2,MinRealAvail,"!!,
"MaxExtRegion,Min31Avail,"!!,
"NotOptColProc,32KbUsed4Prf,4KbUsed32Prf,"!!,
,/* Logging */
"ActLogCI," !!,
,/* Workfile usage */
"Max4KwfMB,Max32KWfMB,MaxWfUseThdMB," !!,
"MaxDGTTMB,MaxOthMB"
/* Zones below correspond to the ibm provided excel columns */
/* "Z,BE,CV,CX,CZ,CU,CW,CY,CQ,Y,BD" */
"EXECIO" queued() "DISKW OUFL"
return
write_report:
/* summarize or Max min to report only by hour */
/* pas de rupture pour le 1er record lu */
if rupture = 0
then do
rupture=1
call init_summary
end
/* We change hour, start write */
if Change_Hour
then do
call write_summary
call init_summary
end
else do
/* if same hour, continue the sum */
sum_MstrTcb = sum_MstrTcb + dif_MstrTcb
sum_MstrSrb = sum_MstrSrb + dif_MstrSrb
sum_MstrpSRB = sum_MstrpSRB + dif_MstrpSRB
sum_MstrpSRB_Ziip = sum_MstrpSRB_Ziip + dif_MstrpSRB_Ziip
sum_dbm1Tcb = sum_dbm1Tcb + dif_dbm1Tcb
sum_dbm1Srb = sum_dbm1Srb + dif_dbm1Srb
sum_dbm1pSRB = sum_dbm1pSRB + dif_dbm1pSRB
sum_dbm1pSRB_Ziip = sum_dbm1pSRB_Ziip + dif_dbm1pSRB_Ziip
sum_IrlmTcb = sum_IrlmTcb + dif_IrlmTcb
sum_IrlmSrb = sum_IrlmSrb + dif_IrlmSrb
sum_IrlmpSRB = sum_IrlmpSRB + dif_IrlmpSRB
sum_IrlmpSRB_Ziip = sum_IrlmpSRB_Ziip + dif_IrlmpSRB_Ziip
sum_DistTcb = sum_DistTcb + dif_DistTcb
sum_DistSrb = sum_DistSrb + dif_DistSrb
sum_DistpSRB = sum_DistpSRB+ dif_DistpSRB
sum_DistpSRB_Ziip = sum_DistpSRB_Ziip+ dif_DistpSRB_Ziip
sum_Q3STCTHD = sum_Q3STCTHD + dif_Q3STCTHD /* cr threads*/
sum_Q3STSIGN = sum_Q3STSIGN + dif_Q3STSIGN /* Signon */
sum_Q3STTERM = sum_Q3STTERM + dif_Q3STTERM /* Terminate*/
sum_Q3STPREP = sum_Q3STPREP + dif_Q3STPREP /* commit ph1*/
sum_Q3STCOMM = sum_Q3STCOMM + dif_Q3STCOMM /* Commit Ph 2*/
sum_Q3STABRT = sum_Q3STABRT + dif_Q3STABRT /* Aborts */
if Q3STHWIB > Max_Q3STHWIB then /* Max IDBACK */
Max_Q3STHWIB = Q3STHWIB
if Q3STHWIF > Max_Q3STHWIF then /* Max IDFORE */
Max_Q3STHWIF = Q3STHWIF
if Q3STHWCT > Max_Q3STHWCT then /* Max IDFORE */
Max_Q3STHWCT = Q3STHWCT
if QTDSOPN > Max_QTDSOPN then /* Max DS Opened*/
Max_QTDSOPN = QTDSOPN
Sum_QXSTFND = Sum_QXSTFND + dif_QXSTFND /* Full prepare*/
Sum_QXSTNFND= Sum_QXSTNFND+ dif_QXSTNFND
Sum_QXSTIPRP= Sum_QXSTIPRP+ dif_QXSTIPRP
Sum_QXSTNPRP= Sum_QXSTNPRP+ dif_QXSTNPRP
Sum_QWSDCKPT= Sum_QWSDCKPT+ dif_QWSDCKPT /* Checkpoints */
Sum_QTDSDRN = Sum_QTDSDRN + dif_QTDSDRN /* Drain Close */
Sum_QTPCCT = Sum_QTPCCT + dif_QTPCCT /* RWRO Switch */
Sum2_QBSTDSO = Sum2_QBSTDSO + dif_QBSTDSO /* Open DS*/
sum2_QBSTGET = sum2_QBSTGET + dif_QBSTGET /* gp */
sum2_QBSTRIO = sum2_QBSTRIO + dif_QBSTRIO /* sync read */
sum2_QBSTIMW = sum2_QBSTIMW + dif_QBSTIMW /* Immed. write */
sum2_QBSTWIO = sum2_QBSTWIO + dif_QBSTWIO /* Async Write */
sum2_QBSTRPI = sum2_QBSTRPI + dif_QBSTRPI /* Page IN Read*/
sum2_QBSTWPI = sum2_QBSTWPI + dif_QBSTWPI /* Page In Writ*/
sum2_QBSTPIO = sum2_QBSTPIO + dif_QBSTPIO /* Seq Pref. IO */
sum2_QBSTMAX = sum2_QBSTMAX + dif_QBSTMAX /* Wrkfil no created*/
sum2_QBSTWFD = sum2_QBSTWFD + dif_QBSTWFD /* Wrkfil rejected*/
sum2_QBSTWFF = sum2_QBSTWFF + dif_QBSTWFF /* merge pass degrad*/
sum2_QBSTCIO = sum2_QBSTCIO + dif_QBSTCIO /* Castout IO */
sum2_QBSTDIO = sum2_QBSTDIO + dif_QBSTDIO /* Dyn Pr IO */
sum2_QBSTLIO = sum2_QBSTLIO + dif_QBSTLIO /* Lst Pr IO */
sum2_QBSTSIO = sum2_QBSTSIO + dif_QBSTSIO /* SIO */
if QDSTQMIT > Max_QDSTQMIT then /* Max inact type1*/
Max_QDSTQMIT = QDSTQMIT
if QDSTHWAT > Max_QDSTHWAT then /* Max act dbat */
Max_QDSTHWAT = QDSTHWAT
if QDSTHWDT > Max_QDSTHWDT then /* Max act&inact dbat*/
Max_QDSTHWDT = QDSTHWDT
if QDSTMIN2 > Max_QDSTMIN2 then /* Max dbat*/
Max_QDSTMIN2 = QDSTMIN2
if QW0225AT > Max_QW0225AT then /* Max allied threads*/
Max_QW0225AT = QW0225AT
if ThdComp < min_ThdComp then /* Max thread computed*/
min_Thdcomp = Thdcomp
if ThdComp2 < min_ThdComp2 then /* Max thread computed*/
min_Thdcomp2 = Thdcomp2
if TotalRealUsedByDB2 > Max_TotalRealUsedByDB2 then
Max_TotalRealUsedByDB2 = TotalRealUsedByDB2
if TotalAuxlUsedByDB2 > Max_TotalAuxlUsedByDB2 then
Max_TotalAuxlUsedByDB2 = TotalAuxlUsedByDB2
if QW0225_REALAVAIL < min_QW0225_REALAVAIL then
min_QW0225_REALAVAIL = QW0225_REALAVAIL
if QW0225RG > Max_QW0225RG then
Max_QW0225RG = QW0225RG /* Region Size extended */
if QW0225AV < Min_QW0225AV then /* 31 bits available */
Min_QW0225AV = QW0225AV
sum_QISTCOLS= Sum_QISTCOLS+ dif_QISTCOLS /* Cols not optimized*/
sum_QISTWFP1= Sum_QISTWFP1+ dif_QISTWFP1 /* 32KbUsed4Pref.*/
sum_QISTWFP2= Sum_QISTWFP2+ dif_QISTWFP2 /* 4KbUsed32Prf*/
sum_QJSTBFFL= Sum_QJSTBFFL+ dif_QJSTBFFL /* Log created*/
end
return
write_summary:
/* write only if some records have been read between writes*/
if RFlush= 0 ! ( RFlush=1 & recw<reci) then nop
else return
/* output counter */
reco= reco+ 1
recw= reci /* we save when we write */
/* Display some warnings */
Call Check_counters
/*rows in excel format */
queue sm100sid !! ',' !! sm100ssi !! ',' ,
!! '"' !! sm100dte !! '"' !! ',' ,
!! dayoweek !! ',' ,
!! Old_Hour !! ',' ,
!! sum_MstrTcb !! ',' ,
!! sum_MstrSrb !! ',' ,
!! sum_MstrpSRB !! ',' ,
!! sum_MstrpSRB_Ziip !! ',' ,
!! sum_dbm1Tcb !! ',' ,
!! sum_dbm1Srb !! ',' ,
!! sum_dbm1pSRB !! ',' ,
!! sum_dbm1pSRB_Ziip !! ',' ,
!! sum_IrlmTcb !! ',' ,
!! sum_IrlmSrb !! ',' ,
!! sum_IrlmpSRB !! ',' ,
!! sum_IrlmpSRB_Ziip !! ',' ,
!! sum_DistTcb !! ',' ,
!! sum_DistSrb !! ',' ,
!! sum_DistpSRB !! ',' ,
!! sum_DistpSRB_Ziip !! ',' ,
!! sum_Q3STCTHD !! ',' , /* Create Thd */
!! sum_Q3STSIGN !! ',' , /* Signon */
!! sum_Q3STTERM !! ',' , /* Terminate*/
!! sum_Q3STPREP !! ',' , /* Commit phase 1 */
!! sum_Q3STCOMM !! ',' , /* Commit Ph 2*/
!! sum_Q3STABRT !! ',' , /* Aborts */
!! Max_Q3STHWIB !! ',' , /* Max IDBACK */
!! Max_Q3STHWIF !! ',' , /* Max IDFORE */
!! Max_Q3STHWCT !! ',' , /* Max CTHREAD */
!! sum_QWSDCKPT !! ',' , /* Checkpoints */
!! Max_QTDSOPN !! ',' , /* DS Opened */
!! sum_QTDSDRN !! ',' , /* Drain Close */
!! sum2_QBSTDSO !! ',' , /* OPEN DS */
!! sum_QTPCCT !! ',' , /* RWRO switch */
!! sum2_QBSTGET !! ',' ,
!! sum2_QBSTRIO !! ',' ,
!! sum2_QBSTIMW !! ',' ,
!! sum2_QBSTWIO !! ',' ,
!! sum2_QBSTRPI !! ',' , /*page in read */
!! sum2_QBSTWPI !! ',' ,
!! sum2_QBSTPIO !! ',' ,
!! sum2_QBSTCIO !! ',' ,
!! sum2_QBSTDIO !! ',' ,
!! sum2_QBSTLIO !! ',' ,
!! sum2_QBSTSIO !! ',' ,
!! Max_QDSTQMIT !! ',' , /* Max . inact type 1*/
!! Max_QDSTHWAT !! ',' , /* Max active dbat*/
!! Max_QDSTHWDT !! ',' , /* Max act & inact dbat */
!! Max_QDSTMIN2 !! ',' , /* act dbat */
!! Max_QW0225AT !! ',' , /* allied threads*/
!! format(min_ThdComp ,4,0) !! ',' ,
!! format(min_ThdComp2,4,0) !! ',' ,
!! f2mb(Max_TotalRealUsedByDB2) !! ',' ,
!! f2mb(Max_TotalAuxlUsedByDB2) !! ',' ,
!! f2mb(min_QW0225_REALAVAIL) !! ',' ,
!! b2mb(Max_QW0225RG) !! ',' ,
!! b2mb(min_QW0225AV) !! ',' , /* 31 bits avail*/
!! sum_QISTCOLS !! ',' ,
!! sum_QISTWFP1 !! ',' ,
!! sum_QISTWFP2 !! ',' ,
!! sum_QJSTBFFL !! ',' , /*Log created*/
!! trunc(Max_QISTW4K/1024) !! ',' , /* Max MB 4K */
!! trunc(Max_QISTW32K/1024) !! ',' ,
!! trunc(QISTAMXU/1024) !! ',' , /*Max MB wk used thread*/
!! trunc(QISTDGTTMXU/1024) !! ',' , /* Max MB DGTT */
!! trunc(QISTWFMXU/1024) !! ',' /* Max MB Other*/
"EXECIO" queued() "DISKW OUFL"
return
/* SMF HEADER */
DSNDQWST:
OFFSET = OFFSET + 1
/* SM100RTY DS XL1 RECORD TYPE X'64' OR 100 */
SM100RTY = C2D(SUBSTR(INPUT_REC,OFFSET,1))
/* stop processing if not 100 */
if sm100rty <> 100 then return
OFFSET = OFFSET + 1
/* SM100TME DS XL4 TIME SMF MOVED RECORD */
SM100TME = C2D(SUBSTR(INPUT_REC,OFFSET,4))
CALL GET_FMT_TIME
OFFSET = OFFSET + 4
field = C2X(SUBSTR(INPUT_REC,OFFSET,4))
parse value field with 1 . 2 c 3 yy 5 ddd 8 .
if (c = 0) then
yyyy = '19'!!yy
else
yyyy = '20'!!yy
sm100dte = yyyy!!'.'!!ddd
/* get day of week : easier to select days */
test_date = yyyy ddd
sm100dte=DAT_MVS2SD(test_date)
dayoweek = DAT_S2DOW(sm100dte)
/* save date of smf records processed */
if reco = 0 then save_date=sm100dte
else do
if save_date <> sm100dte & displ = 0 then do
displ=1
say 'There is 2 different dates in this SMF extract'
say ' ' save_date sm100dte
say ' '
end
end
OFFSET = OFFSET + 4
sm100sid = SUBSTR(INPUT_REC,OFFSET,4)
OFFSET = OFFSET + 4
/* SM100SSI DS CL4 SUBSYSTEM ID */
sm100ssi = SUBSTR(INPUT_REC,OFFSET,4)
OFFSET = OFFSET + 10
/* TOTAL LENGTH = 28 */
RETURN
dsndqbst:
numeric digits 15
QBSTPID = C2D(SUBSTR(INPUT_REC,OFFSET,4))
offset = offset + 8
QBSTGET = C2D(SUBSTR(INPUT_REC,OFFSET,8))
offset = offset + 8
QBSTRIO = C2D(SUBSTR(INPUT_REC,OFFSET,8))
offset = offset + 8
offset = offset + 8*5
QBSTWIO = C2D(SUBSTR(INPUT_REC,OFFSET,8))
offset = offset + 16
QBSTRPI = C2D(SUBSTR(INPUT_REC,OFFSET,8))
offset = offset + 8
QBSTWPI = C2D(SUBSTR(INPUT_REC,OFFSET,8))
offset = offset + 8
/* Open Dataset */
QBSTDSO = C2D(SUBSTR(INPUT_REC,OFFSET,8))
offset = offset + 8
QBSTIMW = C2D(SUBSTR(INPUT_REC,OFFSET,8))
offset = offset + 16
/* Pages read seq Prefetch */
QBSTSPP = C2D(SUBSTR(INPUT_REC,OFFSET,8))
offset = offset + 56
/* OF SEQ PREFETCH (ASYNCHRONOUS) READ*/
QBSTPIO = C2D(SUBSTR(INPUT_REC,OFFSET,8))
offset = offset + 16
/* nb wkfile not created due to buffers resource */
QBSTMAX = C2D(SUBSTR(INPUT_REC,OFFSET,8))
offset = offset + 48
/* nb of workfiles denied during sort/merge */
QBSTWFD = C2D(SUBSTR(INPUT_REC,OFFSET,8))
offset = offset + 8
/* nb of time sort not optimized due to BP shortage*/
QBSTWFF = C2D(SUBSTR(INPUT_REC,OFFSET,8))
offset = offset + 40
/* nb of cast out IO */
QBSTCIO = C2D(SUBSTR(INPUT_REC,OFFSET,8))
offset = offset + 8
QBSTVPL = C2D(SUBSTR(INPUT_REC,OFFSET,8))
offset = offset + 24
/* save BP0 size - after 17:00 because i had time to modify */
if lpar = 'SUD2' & Old_Hour > '17' then
do
if bp0_vpsize = 0 then
do
if QBSTPID = 0 then do
bp0_vpsize = QBSTVPL
say ssid 'BP0VPSIZE=' bp0_vpsize
end
end
end
QBSTDIO = C2D(SUBSTR(INPUT_REC,OFFSET,8))
offset = offset + 8
QBSTLIO = C2D(SUBSTR(INPUT_REC,OFFSET,8))
offset = offset + 16
QBSTSIO = C2D(SUBSTR(INPUT_REC,OFFSET,8))
/* say 'Buffid =' QBSTPID, */
/* 'QBSTGET=' QBSTGET, */
/* 'QBSTRIO=' QBSTRIO, */
/* 'QBSTWIO=' QBSTWIO, */
/* 'QBSTIMW=' QBSTIMW, */
/* say 'QBSTPIO=' QBSTPIO, */
/* 'QBSTCIO=' QBSTCIO, */
/* 'QBSTDIO=' QBSTDIO, */
/* 'QBSTLIO=' QBSTLIO, */
/* 'QBSTSIO=' QBSTSIO */
offset = offset + 144 /* 8*18 */
/*****************************/
/* Processing the data read */
/*****************************/
/* test if BufferID QBSTPIDis already recorded */
i=1
do while i <= nbBP
if QBSTPID = BPList.i then leave
i=i+1
end
if i > nbBP then /* this BP is not recorded yet */
do
nbBP=nbBP+1
BPList.nbBP=QBSTPID
ListPrefLow.QBSTPID = 0
/* First entry is created with read value because */
/* records are cumulative (from yesterday value for example*/
Old_QBSTSPP.QBSTPID=QBSTSPP
Old_QBSTPIO.QBSTPID=QBSTPIO
end
/* Processing counters to report */
Dif_QBSTSPP.QBSTPID = QBSTSPP - Old_QBSTSPP.QBSTPID
Dif_QBSTPIO.QBSTPID = QBSTPIO - Old_QBSTPIO.QBSTPID
Old_QBSTSPP.QBSTPID=QBSTSPP
Old_QBSTPIO.QBSTPID=QBSTPIO
/*******************************/
/* Calculate prefetch quantity */
/*******************************/
/*say Dif_QBSTSPP.QBSTPID Dif_QBSTPIO.QBSTPID*/
if Dif_QBSTSPP.QBSTPID > 0 & Dif_QBSTPIO.QBSTPID > 0 then
do
PrefQty = trunc(Dif_QBSTSPP.QBSTPID/Dif_QBSTPIO.QBSTPID)
if PrefQty <= 4 then do
/* temR=1
rec.1= 'Prefetch Qty too low for BP ' QBSTPID,
sm100sid'/'sm100ssi '@'RUN_FMT_TIME PrefQty
call logW */
ListPrefLow.QBSTPID = ListPrefLow.QBSTPID+1
end
end
return
dsndqbgl:
numeric digits 15
/* Group BPID */
QBGLGN = C2D(SUBSTR(INPUT_REC,OFFSET,4))
offset = offset + 4+1+3
offset = offset + 8*17
/* Write requests failed no storage */
QBGLWF = C2D(SUBSTR(INPUT_REC,OFFSET,8))
offset = offset + 8*13
/* Write requests failed no storage secondary GBP */
QBGL2F = C2D(SUBSTR(INPUT_REC,OFFSET,8))
/* Write Around */
offset = offset + 8*17
QBGLWA = C2D(SUBSTR(INPUT_REC,OFFSET,8))
/* go to end of macro QBGL */
offset = offset + 8 + 24
/*****************************/
/* Processing the data read */
/*****************************/
/* test if BufferID QBGLGN is already recorded */
i=1
do while i <= nbGBP
if QBGLGN = GBPList.i then leave
i=i+1
end
if i > nbGBP then /* this GBP is not recorded yet */
do
nbGBP=nbGBP+1
GBPList.nbGBP=QBGLGN
/* First entry is created with read value because */
/* records are cumulative (from yesterday value for example*/
Old_QBGL2F.QBGLGN =QBGL2F
Old_QBGLWF.QBGLGN =QBGLWF
Old_QBGLWA.QBGLGN =QBGLWA
SumHr_QBGLWF.QBGLGN = 0
SumHr_QBGL2F.QBGLGN = 0
SumHr_QBGLWA.QBGLGN = 0
end
/* Processing counters to report */
Dif_QBGLWF.QBGLGN = QBGLWF - Old_QBGLWF.QBGLGN
Dif_QBGL2F.QBGLGN = QBGL2F - Old_QBGL2F.QBGLGN
Dif_QBGLWA.QBGLGN = QBGLWA - Old_QBGLWA.QBGLGN
Old_QBGLWF.QBGLGN = QBGLWF
Old_QBGL2F.QBGLGN = QBGL2F
Old_QBGLWA.QBGLGN = QBGLWA
if Dif_QBGLWA.QBGLGN > 0 then
SumHr_QBGLWA.QBGLGN=SumHr_QBGLWA.QBGLGN+Dif_QBGLWA.QBGLGN
if Dif_QBGL2F.QBGLGN > 0 then
SumHr_QBGL2F.QBGLGN=SumHr_QBGL2F.QBGLGN+Dif_QBGL2F.QBGLGN
if Dif_QBGLWF.QBGLGN > 0 then
SumHr_QBGLWF.QBGLGN=SumHr_QBGLWF.QBGLGN+Dif_QBGLWF.QBGLGN
return
ifcid_diff:
/* Cumulative values, report only the difference */
/* When diff is negative, this means that the value have been*/
/* reset (Seen at DB2 restart , but probably also if they */
/* reach their Max) */
Dif_MstrTcb = MstrTcb - Old_MstrTcb
Dif_MstrSrb = MstrSrb - Old_MstrSrb
Dif_MstrpSRB= MstrpSRB - Old_MstrpSRB
Dif_MstrpSRB_Ziip = MstrpSRB_Ziip - Old_MstrpSRB_Ziip
Dif_dbm1Tcb = dbm1Tcb - Old_dbm1Tcb
Dif_dbm1srb = dbm1srb - Old_dbm1srb
Dif_dbm1pSRB= dbm1pSRB - Old_dbm1pSRB
Dif_dbm1pSRB_Ziip = dbm1pSRB_Ziip - Old_dbm1pSRB_Ziip
Dif_irlmTcb = irlmTcb - Old_irlmTcb
Dif_irlmsrb = irlmsrb - Old_irlmsrb
Dif_irlmpSRB= irlmpSRB - Old_irlmpSRB
Dif_irlmpSRB_Ziip = irlmpSRB_Ziip - Old_irlmpSRB_Ziip
Dif_distTcb = distTcb - Old_distTcb
Dif_distsrb = distsrb - Old_distsrb
Dif_distpSRB= distpSRB - Old_distpSRB
Dif_distpSRB_Ziip = distpSRB_Ziip - Old_distpSRB_Ziip
if Dif_MstrTcb < 0 then
do
say '!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'
say 'Cumulative fields reset, possible DB2 RECYCLE'
say ' at' sm100dte run_fmt_time
say '!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'
say ''
Dif_MstrTcb = MstrTcb
Dif_MstrSrb = MstrSrb
Dif_MstrpSRB= MstrpSRB
Dif_MstrpSRB_Ziip = MstrpSRB_Ziip
Dif_dbm1Tcb = dbm1Tcb
Dif_dbm1srb = dbm1srb
Dif_dbm1pSRB= dbm1pSRB
Dif_dbm1pSRB_Ziip = dbm1pSRB_Ziip
Dif_irlmTcb = irlmTcb
Dif_irlmsrb = irlmsrb
Dif_irlmpSRB= irlmpSRB
Dif_irlmpSRB_Ziip = irlmpSRB_Ziip
Dif_distTcb = distTcb
Dif_distsrb = distsrb
Dif_distpSRB= distpSRB
Dif_distpSRB_Ziip = distpSRB_Ziip
end
Old_Mstrtcb = Mstrtcb
Old_MstrSrb = MstrSrb
Old_MstrpSRB= MstrpSRB
Old_MstrpSRB_Ziip = MstrpSRB_Ziip
Old_dbm1Tcb = dbm1Tcb
Old_dbm1srb = dbm1srb
Old_dbm1pSRB= dbm1pSRB
Old_dbm1pSRB_Ziip = dbm1pSRB_Ziip
Old_irlmTcb = irlmTcb
Old_irlmsrb = irlmsrb
Old_irlmpSRB= irlmpSRB
Old_irlmpSRB_Ziip = irlmpSRB_Ziip
Old_distTcb = distTcb
Old_distsrb = distsrb
Old_distpSRB= distpSRB
Old_distpSRB_Ziip = distpSRB_Ziip
/*********************************/
/* Subsystem services stats Q3ST */
/*********************************/
Dif_Q3STSIGN = Q3STSIGN-Old_Q3STSIGN
Dif_Q3STTERM = Q3STTERM-Old_Q3STTERM
Dif_Q3STCTHD = Q3STCTHD-Old_Q3STCTHD
Dif_Q3STPREP = Q3STPREP-Old_Q3STPREP
Dif_Q3STCOMM = Q3STCOMM-Old_Q3STCOMM
Dif_Q3STABRT = Q3STABRT-Old_Q3STABRT
if Dif_Q3STSIGN < 0 then
do
Dif_Q3STSIGN = Q3STSIGN
Dif_Q3STTERM = Q3STTERM
Dif_Q3STCTHD = Q3STCTHD
Dif_Q3STPREP = Q3STPREP
Dif_Q3STCOMM = Q3STCOMM
Dif_Q3STABRT = Q3STABRT
end
Old_Q3STSIGN = Q3STSIGN
Old_Q3STTERM = Q3STTERM
Old_Q3STCTHD = Q3STCTHD
Old_Q3STPREP = Q3STPREP
Old_Q3STCOMM = Q3STCOMM
Old_Q3STABRT = Q3STABRT
/***************************/
/* buffer pool stats */
/***************************/
Dif_QBSTGET = Sum_QBSTGET-Old_QBSTGET
Dif_QBSTRIO = Sum_QBSTRIO-Old_QBSTRIO
Dif_QBSTDSO = Sum_QBSTDSO-Old_QBSTDSO
Dif_QBSTIMW = Sum_QBSTIMW-Old_QBSTIMW
Dif_QBSTWIO = Sum_QBSTWIO-Old_QBSTWIO
Dif_QBSTRPI = Sum_QBSTRPI-Old_QBSTRPI
Dif_QBSTWPI = Sum_QBSTWPI-Old_QBSTWPI
Dif_QBSTPIO = Sum_QBSTPIO-Old_QBSTPIO
Dif_QBSTMAX = Sum_QBSTMAX-Old_QBSTMAX
Dif_QBSTWFD = Sum_QBSTWFD-Old_QBSTWFD
Dif_QBSTWFF = Sum_QBSTWFF-Old_QBSTWFF
Dif_QBSTCIO = Sum_QBSTCIO-Old_QBSTCIO
Dif_QBSTDIO = Sum_QBSTDIO-Old_QBSTDIO
Dif_QBSTlIO = Sum_QBSTlIO-Old_QBSTlIO
Dif_QBSTsIO = Sum_QBSTsIO-Old_QBSTsIO
if Dif_QBSTGET < 0 then
do
Dif_QBSTGET = Sum_QBSTGET
Dif_QBSTRIO = Sum_QBSTRIO
Dif_QBSTDSO = Sum_QBSTDSO
Dif_QBSTIMW = Sum_QBSTIMW
Dif_QBSTWIO = Sum_QBSTWIO
Dif_QBSTRPI = Sum_QBSTRPI
Dif_QBSTWPI = Sum_QBSTWPI
Dif_QBSTPIO = Sum_QBSTPIO
Dif_QBSTMAX = Sum_QBSTMAX
Dif_QBSTWFD = Sum_QBSTWFD
Dif_QBSTWFF = Sum_QBSTWFF
Dif_QBSTCIO = Sum_QBSTCIO
Dif_QBSTDIO = Sum_QBSTDIO
Dif_QBSTlIO = Sum_QBSTlIO
Dif_QBSTsIO = Sum_QBSTsIO
end
Old_QBSTGET = Sum_QBSTGET
Old_QBSTRIO = Sum_QBSTRIO
Old_QBSTIMW = Sum_QBSTIMW
Old_QBSTDSO = Sum_QBSTDSO
Old_QBSTWIO = Sum_QBSTWIO
Old_QBSTRPI = Sum_QBSTRPI
Old_QBSTWPI = Sum_QBSTWPI
Old_QBSTPIO = Sum_QBSTPIO
Old_QBSTMAX = Sum_QBSTMAX
Old_QBSTWFD = Sum_QBSTWFD
Old_QBSTWFF = Sum_QBSTWFF
Old_QBSTCIO = Sum_QBSTCIO
Old_QBSTDIO = Sum_QBSTDIO
Old_QBSTlIO = Sum_QBSTlIO
Old_QBSTsIO = Sum_QBSTsIO
/****************************************/
/* dsndqjst Log Manager stats IFCID 001*/
/****************************************/
Dif_QJSTBFFL = QJSTBFFL - Old_QJSTBFFL
if Dif_QJSTBFFL < 0 then
Dif_QJSTBFFL = QJSTBFFL
Old_QJSTBFFL = QJSTBFFL
/****************************************/
/* dsndqist Data Manager stats IFCID 002 */
/****************************************/
Dif_QTDSDRN = QTDSDRN - Old_QTDSDRN
Dif_QTPCCT = QTPCCT - Old_QTPCCT
Dif_QWSDCKPT = QWSDCKPT - Old_QWSDCKPT
Dif_QXSTFND = QXSTFND - Old_QXSTFND
Dif_QXSTNFND = QXSTNFND - Old_QXSTNFND
Dif_QXSTIPRP = QXSTIPRP - Old_QXSTIPRP
Dif_QXSTNPRP = QXSTNPRP - Old_QXSTNPRP
Dif_QISTRPDM = QISTRPDM - Old_QISTRPDM
Dif_QISTCOLS = QISTCOLS - Old_QISTCOLS
Dif_QISTWFP1 = QISTWFP1 - Old_QISTWFP1
Dif_QISTWFP2 = QISTWFP2 - Old_QISTWFP2
if Dif_QISTRLLM < 0 then
do
Dif_QTDSDRN = QTDSDRN
Dif_QTPCCT = QTPCCT
Dif_QWSDCKPT = QWSDCKPT
Dif_QXSTFND = QXSTFND
Dif_QXSTNFND = QXSTNFND
Dif_QXSTIPRP = QXSTIPRP
Dif_QXSTNPRP = QXSTNPRP
Dif_QISTRLLM = QISTRLLM
Dif_QISTRPDM = QISTRPDM
Dif_QISTCOLS = QISTCOLS
Dif_QISTWFP1 = QISTWFP1
Dif_QISTWFP2 = QISTWFP2
end
Old_QTDSDRN = QTDSDRN
Old_QTPCCT = QTPCCT
Old_QWSDCKPT = QWSDCKPT
Old_QXSTFND = QXSTFND
Old_QXSTNFND = QXSTNFND
Old_QXSTIPRP = QXSTIPRP
Old_QXSTNPRP = QXSTNPRP
Old_QISTRLLM = QISTRLLM
Old_QISTRPDM = QISTRPDM
Old_QISTCOLS = QISTCOLS
Old_QISTWFP1 = QISTWFP1
Old_QISTWFP2 = QISTWFP2
return
DisplayVStor:
if vsm='Y' & reco > 0 & lpar <> 'SUD2' then
do
rec.1= ' '; call LOGW ; rec.1= ' ' ; call LOGW
rec.1= 'Threads observed Max : ' MaxThdSee 'at' MaxThdSeeDate,
MaxThdSeeTime
call LOGW
rec.1= ' Min : ' MinThdSee 'at' MinThdSeeDate,
MinThdSeeTime
call LOGW
rec.1= ' '; call LOGW ; rec.1= ' ' ; call LOGW
rec.1= 'Max Threads allowed projected with this period is : '
call LOGW
rec.1= ' ' floor(MinThdComp) 'at' MinThdCompDate MinThdCompTime,
'/' floor(MaxThdComp) 'at' MaxThdCompDate MaxThdCompTime
call LOGW
rec.1= ' Formula without Min/Max applied : '
call LOGW
rec.1= ' ' floor(MinThdComp2) 'at' MinThdComp2Date MinThdComp2Time,
'/' floor(MaxThdComp2) 'at' MaxThdComp2Date MaxThdComp2Time
call LOGW
rec.1= ' '
call LOGW
rec.1= 'DBM1, Max Real Storage is : ' format(MaxReal4K_dbm1,5,2),
'MB at ' Date_MaxReal4K_dbm1 time_MaxReal4K_dbm1
call LOGW
rec.1= ' Min is : ' ,
format(MinReal4K_dbm1,5,2) 'MB at ',
Date_MinReal4K_dbm1 time_MinReal4K_dbm1
call LOGW
rec.1= 'DIST, Max Real Storage is : ' format(MaxReal4K_dist,5,2),
'MB at ' Date_MaxReal4K_dist time_MaxReal4K_dist
rec.1= ' Min is : ' ,
format(MinReal4K_dist,5,2) 'MB at ',
Date_MinReal4K_dist time_MinReal4K_dist
call LOGW
rec.1= ' '
call LOGW
/* rec.1= 'Max Real Storage used by LPAR :' MaxRealLPAR ' Frames --', */
/* f2mb(MaxRealLPAR) ' in MB' */
/* rec.1= ' at ' time_MaxRealLPAR */
temp=MinQW0225_REALAVAIL*4096 / 1048576 /* in MB*/
rec.1= 'Min Real Storage available for LPAR : ' MinQW0225_REALAVAIL,
'Frames --' f2mb(MinQW0225_REALAVAIL) ' MB'
call LOGW
rec.1= ' at ' Date_MinQW0225_REALAVAIL time_MinQW0225_REALAVAIL
call LOGW
rec.1= ' '
call LOGW
rec.1= 'Max Aux Storage used by DB2 :' MaxDB2AuxUse ' Frames --',
f2mb(MaxDB2AuxUse) ' MB'
call LOGW
rec.1= ' at ' DateMaxDB2AuxUse timeMaxDB2AuxUse
call LOGW
end
return
init_var:
if vsm='Y' then
do
MaxND=0
MinAS=999999999999999
MinTS=999999999999999
MaxTF=0
MaxThdSee =0
MaxThdComp=0
MaxThdComp2=0
MinThdSee =999999999999999
MinThdComp=999999999999999
MinThdComp2=999999999999999
MaxReal4K_dbm1=0
MinReal4K_dbm1=999999999999999
MaxReal4K_dist=0
MinReal4K_dist=999999999999999
MinQW0225_REALAVAIL=999999999999999
/* MaxRealLPAR = 0 */
MaxDB2AuxUse = -1
end
/* init counters */
Old_QBSTGET = 0
Old_QBSTRIO = 0
Old_QTDSDRN = 0
Old_QTPCCT = 0
Old_QWSDCKPT= 0
Old_QXSTFND = 0
Old_QXSTNFND= 0
Old_QXSTIPRP= 0
Old_QXSTNPRP= 0
Old_QBSTDSO = 0
Old_QBSTIMW = 0
Old_QBSTWIO = 0
Old_QBSTRPI = 0
Old_QBSTWPI = 0
Old_QBSTPIO = 0
Old_QBSTMAX = 0
Old_QBSTWFD = 0
Old_QBSTWFF = 0
Old_QBSTCIO = 0
Old_QBSTDIO = 0
Old_QBSTLIO = 0
Old_QBSTSIO = 0
Old_QJSTBFFL = 0
Old_QISTRLLM = 0
Old_QISTRPDM = 0
Old_QISTCOLS = 0
Old_QISTWFP1 = 0
Old_QISTWFP2 = 0
Old_Q3STSIGN = 0
Old_Q3STTERM = 0
Old_Q3STCTHD = 0
Old_Q3STPREP = 0
Old_Q3STCOMM = 0
Old_Q3STABRT = 0
Old_MstrTcb = 0
Old_MstrSrb = 0
Old_MstrpSRB= 0
Old_MstrpSRB_Ziip = 0
Old_dbm1Tcb = 0
Old_dbm1srb = 0
Old_dbm1pSRB= 0
Old_dbm1pSRB_Ziip = 0
Old_irlmTcb = 0
Old_irlmsrb = 0
Old_irlmpSRB= 0
Old_irlmpSRB_Ziip = 0
Old_distTcb = 0
Old_distsrb = 0
Old_distpSRB= 0
Old_distpSRB_Ziip = 0
/* compteurs input/output */
reco= 0
reci= 0
recs= 0
min_time ='26:00:00'
Max_time ='ZZ:00:00'
min_date ='20990101'
Max_date ='19700101'
return
FLOOR: procedure
parse arg F
return TRUNC(F) - (F < 0) * (F <> TRUNC(F))
CEIL: procedure
parse arg C
return TRUNC(C) + (C > 0) * (C <> TRUNC(C))
/* convert 4K frames to MB */
f2mb:
arg num
num = format(num*4/1024,,2)
return num
/* convert bytes to MB */
b2mb:
arg num
num = format(num/1048576,,0)
return num
/*========================================== */
/* Set SMF data set name , depending on lpar */
/*========================================== */
SetSmfDs:
oufl = 'systmp.wsyngud.smfexta'
Select
When lpar = 'SUD2' then
do
ssid='DBAP'
end
When lpar = 'XX10' then
do
ssid='DB2B'
end
When lpar = 'LIM' then
do
ssid='DBP1'
end
When lpar = 'CTR' then
do
ssid='DB2I'
end
When lpar = 'LIM2' then
do
ssid='DBP2'
end /* end Lpar XX10 Sofinco */
When lpar = 'LIM3' then
do
ssid='DBP3'
end /* end Lpar XX10 Sofinco */
When lpar = 'LIM4' then
do
ssid='DBP8'
end /* end Lpar XX10 Sofinco */
When lpar = 'MVSA' then
do
ssid='DB2P'
end /* end Lpar CRPP */
When lpar = 'IPO4' then
do
ssid='DSN2'
end /* end Lpar Prod CACIB */
When lpar = 'ZPR1' then
do
ssid='DB2E'
end /* end Lpar Prod CASA */
When lpar = 'PROD' then
do
clnt='CAAGIS'
end /* end Lpar Prod CAAG */
Otherwise
do
say 'Lpar not processed - End of program'
exit(0)
end
end /* End select */
return
init_summary:
sum_MstrTcb = dif_MstrTcb
sum_MstrSrb = dif_MstrSrb
sum_MstrpSRB = dif_MstrpSRB
sum_MstrpSRB_Ziip = dif_MstrpSRB_Ziip
sum_dbm1Tcb = dif_dbm1Tcb
sum_dbm1Srb = dif_dbm1Srb
sum_dbm1pSRB = dif_dbm1pSRB
sum_dbm1pSRB_Ziip = dif_dbm1pSRB_Ziip
sum_IrlmTcb = dif_IrlmTcb
sum_IrlmSrb = dif_IrlmSrb
sum_IrlmpSRB = dif_IrlmpSRB
sum_IrlmpSRB_Ziip = dif_IrlmpSRB_Ziip
sum_DistTcb = dif_DistTcb
sum_DistSrb = dif_DistSrb
sum_DistpSRB = dif_DistpSRB
sum_DistpSRB_Ziip = dif_DistpSRB_Ziip
sum_Q3STCTHD = dif_Q3STCTHD /* cr threads*/
sum_Q3STSIGN = dif_Q3STSIGN /* Signon */
sum_Q3STTERM = dif_Q3STTERM /* Terminate*/
sum_Q3STPREP = dif_Q3STPREP /* commit ph1*/
sum_Q3STCOMM = dif_Q3STCOMM /* Commit Ph 2*/
sum_Q3STABRT = dif_Q3STABRT /* Aborts */
Max_Q3STHWIB = Q3STHWIB
Max_Q3STHWIF = Q3STHWIF
Max_Q3STHWCT = Q3STHWCT
Max_QTDSOPN = QTDSOPN
SUm_QWSDCKPT= dif_QWSDCKPT /* Checkpoints */
SUm_QXSTFND = dif_QXSTFND /* Prepare */
SUm_QXSTNFND= dif_QXSTNFND
SUm_QXSTIPRP= dif_QXSTIPRP
SUm_QXSTNPRP= dif_QXSTNPRP
Sum_QTDSDRN = dif_QTDSDRN /* Drain Close */
Sum_QTPCCT = dif_QTPCCT /* RWRO switch */
SUm2_QBSTDSO = dif_QBSTDSO /* Open DS*/
sum2_QBSTGET = dif_QBSTGET /* gp */
sum2_QBSTRIO = dif_QBSTRIO /* sync read */
sum2_QBSTIMW = dif_QBSTIMW /* Immed. write */
sum2_QBSTWIO = dif_QBSTWIO /* Async Write */
sum2_QBSTRPI = dif_QBSTRPI /* Async Write */
sum2_QBSTWPI = dif_QBSTWPI /* Async Write */
sum2_QBSTPIO = dif_QBSTPIO /* Seq Pref. IO */
sum2_QBSTMAX = dif_QBSTMAX
sum2_QBSTWFD = dif_QBSTWFD
sum2_QBSTWFF = dif_QBSTWFF
sum2_QBSTCIO = dif_QBSTCIO /* Castout IO */
sum2_QBSTDIO = dif_QBSTDIO /* Dyn Pr IO */
sum2_QBSTLIO = dif_QBSTLIO /* Lst Pr IO */
sum2_QBSTSIO = dif_QBSTSIO /* SIO */
Max_QDSTQMIT = QDSTQMIT
Max_QDSTHWAT = QDSTHWAT
Max_QDSTHWDT = QDSTHWDT
Max_QDSTMIN2 = QDSTMIN2
Max_QW0225AT = QW0225AT
min_Thdcomp = Thdcomp
min_Thdcomp2 = Thdcomp2
Max_TotalRealUsedByDB2 = TotalRealUsedByDB2
Max_TotalAuxlUsedByDB2 = TotalAuxlUsedByDB2
min_QW0225_REALAVAIL = QW0225_REALAVAIL
Max_QW0225RG = QW0225RG /* Region Size extended */
Min_QW0225AV = QW0225AV
sum_QISTCOLS= dif_QISTCOLS /* Cols not optimized*/
sum_QISTWFP1= dif_QISTWFP1 /* 32KbUsed4Pref.*/
sum_QISTWFP2= dif_QISTWFP2 /* 4KbUsed32Prf*/
sum_QJSTBFFL= dif_QJSTBFFL /* Log created*/
return
DSNDQWSD:
/* Nbr of checkpoints cumulative value */
QWSDCKPT = C2D(SUBSTR(INPUT_REC,OFFSET,4))
return
Check_counters:
/* Workfiles */
if sum2_QBSTMAX > 0 then do
temR=1
rec.1= 'Workfile Not Created NoBuf QBSTMAX',
sm100sid'/'sm100ssi '@'Old_Hour Sum2_QBSTMAX
call logW
end
if sum2_QBSTWFD > 0 then do
temR=1
rec.1= 'Workfile Rejected NoBuf QBSTWFD',
sm100sid'/'sm100ssi '@'Old_Hour Sum2_QBSTWFD
call logW
end
if sum2_QBSTWFF > 0 then do
temR=1
rec.1= 'Merge Pass degraded Low Buf QBSTWFF',
sm100sid'/'sm100ssi '@'Old_Hour Sum2_QBSTWFF
call logW
end
/* Only for SUD2 */
if lpar = 'SUD2' then
do
SumBP_SUD2_all = sum2_QBSTGET + SumBP_SUD2_all
/* record Max getpage */
if sum2_QBSTGET > Max_SUD2_gp then do
Max_SUD2_gp = sum2_QBSTGET
Max_SUD2_gp_hour = Old_Hour
end
/* record activity between 9-18 */
if (Old_Hour > '08' & Old_Hour < '19') then
do
SumBP_SUD2 = sum2_QBSTGET + SumBP_SUD2
if sum2_QBSTGET < 1000000 then,
SUD2_BpInact = SUD2_BpInact + 1
end
return
end
/* Global Dynamic Stmt cache hit ratio > 90% */
/* Hit = Sum_QXSTFND / (Sum_QXSTFND+Sum_QXSTNFND + 0.01)
if Hit < 0.90 then
do
rec.1= 'Warning : Global Dyn. Cache Hit < 90%',
format(Hit,3,2) ' @' run_fmt_time
call logw
retcode=4
end
/* Local Dynamic Stmt cache hit ratio > 70% */
/* Source Optimizing DB2 System Performance using db2 statistics*/
Hit = Sum_QXSTNPRP/ (Sum_QXSTNPRP + Sum_QXSTIPRP + 0.01)
if Hit = 0 then do
if tsaylocal=0 then do
rec.1= 'Warning : Local Dyn. Cache probably not used'
call LOgw
tsayLocal = 1
end
end
else if Hit < 0.70 then
do
rec.1= 'Warning : Local Dyn. Cache Hit < 70%',
format(Hit,3,2) ' @' run_fmt_time
call logw
retcode=4
end
*/
if (sum_dbm1Tcb*3) > sum_dbm1Srb & sum_dbm1Tcb > 100 then do
rec.1= 'DBM1 TCB time too high vs DBM1 SRB ',
'Hour/DBM1TCB/DBM1SRB ' Old_Hour sum_dbm1TCB sum_dbm1SRB
call LOGW
end
if sum_QWSDCKPT > 13 then do
rec.1= 'Checkpoint frequency too high, Max should be 1/ 5mn',
'Hour/Checkpoints ' Old_Hour sum_QWSDCKPT
call LOGW
end
if sum_QTDSDRN > 1 & sum_dbm1Tcb > 100 then do
rec.1= 'DSMax reached ',
'Hour/DrainClose ' Old_Hour sum_QTDSDRN
call LOGW
end
if sum_QTPCCT > 900 sum_dbm1Tcb > 100 then do
rec.1= 'RWRO Switch too high (15/mn is ok)',
'Hour/ROSwitch ' Old_Hour sum_QTPCCT
call LOGW
end
if (sum2_QBSTRPI + sum2_QBSTWPI) > 100 then do
rec.1= 'Page In for RW observed ',
'Hour/PageIn R/PageInWrite' Old_Hour sum2_QBSTRPI sum2_QBSTWPI
call LOGW
end
/* Bypassed columns - Invalid Select Procedure */
if (sum_QISTCOLS ) > 500 then do
temR=1
rec.1= 'Not optimized SProc observed',
'Hour/Number ' Old_Hour sum_QISTCOLS
call LOGW
end
if (Max_QDSTMIN2+Max_QW0225AT) > min_ThdComp ! ,
(Max_QDSTMIN2+Max_QW0225AT) > min_ThdComp2 then do
rec.1= 'DBAT + AlliedThreads > Theoric Minimum Thread Number',
'Hour/DBAT/Allied/min_ThdComp/min_ThdComp2 '
call LOGW
rec.1= Old_Hour Max_QDSTMIN2 Max_QW0225AT min_ThdComp min_ThdComp2
call LOGW
end
/* GBP counters */
h=1
do while h <= nbGBP
i = GBPList.h
h=h+1
if SumHr_QBGLWA.i> 0 then
do
temR=1
rec.1= 'GBP' i 'Write Around happened',
sm100sid'/'sm100ssi '@'Old_Hour SumHr_QBGLWA.i
call logW
end
if SumHr_QBGL2F.i> 0 then
do
temR=1
rec.1= 'GBP' i 'Write SecGBP NoStorage',
sm100sid'/'sm100ssi '@'Old_Hour SumHr_QBGL2F.i
call logW
end
if SumHr_QBGLWF.i > 0 then
do
temR=1
rec.1= 'GBP' i 'Write GBP NoStorage',
sm100sid'/'sm100ssi '@'Old_Hour SumHr_QBGLWF.i
call logW
end
SumHr_QBGLWF.i=0
SumHr_QBGL2F.i=0
SumHr_QBGLWA.i=0
end /* End do */
return
LOGW:
say rec.1
if temR=0 then return /* No file report if not set */
"EXECIO 1 DISKW OUFw (STEM rec. "
temR=0 /* No file report is the default */
return
/* for SUD2 */
LOGW2:
say rec.1
"EXECIO 1 DISKW OUFs2 (STEM rec. "
return
/* Report dataset on output */
CrOutput:
ope = 1
/* caagis ssid forced to some value */
if clnt = 'CAAGIS' then
do
if sm100ssi = 'DBPR' ! sm100ssi = 'DBAP' then
do
lpar='SUDM'
ssid='DBPR'
end
if sm100ssi = 'DB2I' ! sm100ssi = 'DB2V' then
do
lpar='SUDB'
ssid='DB2I'
end
end
oufL = "'" !! hlq !! '.reportS.' !! lpar !! '.' !! ssid !! "'"
X=outtrap(tmp.)
"DELETE" oufL "PURGE"
X=outtrap(off)
say 'Allocate' oufL
/* if with header */
OPT2 = 'H'
if OPT2 = 'H' then
"ALLOC FI(OUFL) DA("oufL") NEW CATALOG REUSE" ,
"LRECL(900) RECFM(V B) TRACKS SPACE(15,15)"
else
"ALLOC FI(OUFL) DA("oufL") NEW CATALOG REUSE" ,
"LRECL(500) RECFM(V B) TRACKS SPACE(15,15)"
rcalloc = rc
if rcalloc <> 0 then Do
say "**********************************************"
say " Error allocating report file" rcalloc
say " Abnormal end "
say "**********************************************"
Exit 8
end
/* WRITE report header */
OPT2 = 'H'
if OPT2 = 'H' then
CALL write_header
/* Report warning messages */
oufw = "'" !! hlq !! '.reportsw.' !! lpar !!'.' !! ssid !! "'"
X=OUTTRAP(TMP.)
"DELETE" oufw "PURGE"
X=OUTTRAP(OFF)
"ALLOC FI(OUFw) DA("oufw") NEW CATALOG REUSE" ,
"LRECL(80) RECFM(F B) TRACKS SPACE(5,5) RELEASE"
rcalloc = rc
if rcalloc <> 0 then Do
say "**********************************************"
say " Error allocating report warnings file" rcalloc
say " Abnormal end "
say "**********************************************"
Exit 8
end
/* Only SUD2 report BP usage Generate ALTER BP command */
if lpar = 'SUD2' & temX=0 then
do
temX=1
oufs2= "'" !! hlq !! '.reportsw.alrt2' !! "'"
say 'Output to' oufs2
X=OUTTRAP(TMP.)
"DELETE" oufs2 "PURGE"
x=OUTTRAP(OFF)
"ALLOC FI(OUFs2) DA("oufs2") NEW CATALOG REUSE" ,
"LRECL(80) RECFM(F B) TRACKS SPACE(2,2) RELEASE"
rcalloc = rc
if rcalloc <> 0 then Do
say "**********************************************"
say " Error allocating report warnings bp file" rcalloc
say " Abnormal end "
say "**********************************************"
Exit 8
end
end /* SUD2*/
rec.1= ' '
call logw
rec.1= '*** Processing for Subsys ***' ssid lpar
call logw
return
DSNDQXST:
/*************************************************/
/* RDS STATISTICS BLOCK DSNDQXST */
/*************************************************/
/* Fields from IFCID002 : cumulative */
/* calculate difference between interval */
offset=offset+4
/* eye catcher */
eyec = SUBSTR(INPUT_REC,OFFSET,4)
if ( eyec <> 'QXST' ) then
do
say 'offset=' offset
eyec = SUBSTR(INPUT_REC,1,100)
say 'eyec' eyec
say 'DSNDQXST eye catcher not met, error'
exit(8)
end
offset = offset + 4
/* Selects */
QXSELECT = C2D(SUBSTR(INPUT_REC,offset,8))
offset = offset + 8
/* Inserts */
QXINSRT = C2D(SUBSTR(INPUT_REC,offset,8))
offset = offset + 8
/* Update */
QXUPDTE = C2D(SUBSTR(INPUT_REC,offset,8))
offset = offset + 8
/* Delete */
QXDELET = C2D(SUBSTR(INPUT_REC,offset,8))
offset = offset + 8 * 20
/* Fetch */
QXFETCH = C2D(SUBSTR(INPUT_REC,offset,8))
offset = offset + 8 * 14
/*---*/
/*#RID List failed No storage */
QXNSMIAP = C2D(SUBSTR(INPUT_REC,offset,8))
offset = offset + 8
/*# Failed Limit exceeded */
QXMRMIAP = C2D(SUBSTR(INPUT_REC,offset,8))
offset = offset + 8*31
/*# Short Prepare */
QXSTFND = C2D(SUBSTR(INPUT_REC,offset,8))
offset = offset + 8
/*# Full Prepare */
QXSTNFND = C2D(SUBSTR(INPUT_REC,offset,8))
offset = offset + 8
/*# Implicit Prepare = FULL prepare */
QXSTIPRP = C2D(SUBSTR(INPUT_REC,offset,8))
offset = offset + 8
/*# Avoided Prepare */
QXSTNPRP = C2D(SUBSTR(INPUT_REC,offset,8))
offset = offset + 8
/*# Stmt discarded - MaxKEEPD */
QXSTDEXP = C2D(SUBSTR(INPUT_REC,offset,8))
/* (...) */
offset = offset + 8*61
/*# RID list Overflowed to Workfile No Storage */
QXWFRIDS = C2D(SUBSTR(INPUT_REC,offset,8))
offset = offset + 8
/*# RID list overflowed to wKk Limit Exceeded */
QXWFRIDT = C2D(SUBSTR(INPUT_REC,offset,8))
offset = offset + 8
/*# RID list append for a hybrid join was interrupt No Storage*/
QXHJINCS = C2D(SUBSTR(INPUT_REC,offset,8))
offset = offset + 8
/*# RID list append for a hybrid join Limit exceeded*/
QXHJINCT = C2D(SUBSTR(INPUT_REC,offset,8))
offset = offset + 8
return
DSNDQXST0:
/* say '!!! Record' reci 'no DSNDQXST data' */
QXSELECT = 0
QXINSRT = 0
QXUPDTE = 0
QXDELET = 0
QXFETCH = 0
QXNSMIAP = 0
QXSTFND = 0
QXSTNFND = 0
QXSTIPRP = 0
QXSTNPRP = 0
QXSTDEXP = 0
QXWFRIDS = 0
QXWFRIDT = 0
QXHJINCS = 0
QXHJINCT = 0
QXMRMIAP = 0
return
/*-----------------------------------------*/
/* Specific for lpar SUD2 : Check BP usage */
/*-----------------------------------------*/
SUD2_report_bp_usage:
/* report usage activity */
rec.1= ' '
call LOGW
rec.1 = 'BP Usage report :'
call LOGW
/* compute average usage */
SUD2avg_bp_all = SumBP_SUD2 % 24
rec.1 = ,
'SUD2: ' ssid 'has BP inact - avg gp/h :' SUD2avg_bp_all
call LOGW
rec.1 = ,
' Max gp/h observed :' Max_SUD2_gp ' at ',
Max_SUD2_gp_hour
call LOGW
rec.1 = ,
' avg gp/h office hours:' SUD2avg_bp
call LOGW
rec.1=' SUD2 avg getpage for 00:00-2359 :' SUD2avg_bp_all
call logW
SUD2avg_bp = SumBP_SUD2 % 10
rec.1=' SUD2_BpInact hours from 9:00-18:00:' SUD2_BpInact
call logW
rec.1=' SUD2avg getpage during 9:00-18:00 :' SUD2avg_bp
call logW
/********************/
/* SET VPSIZE PART */
/********************/
/* important activity observed all day */
if su2avg_bp_all > 2000000 & bp0_vpsize < 55000 then
do
rec.1 ='BP probably small vs. observed activity, recommend :'
call LOGW2
rec.1 ='DSN SYSTEM('ssid')'
call LOGW2
rec.1 ='-ALTER BPOOL(BP0) VPSIZE(300000)'
call LOGW2
rec.1 ='-ALTER BPOOL(BP1) VPSIZE(100000)'
call LOGW2
return
end
/* Max gp/hour high at somes time => higher a little */
if Max_SUD2_gp > 5000000 & bp0_vpsize < 55000 then
do
rec.1 ='DSN SYSTEM('ssid')'
call LOGW2
rec.1 ='-ALTER BPOOL(BP0) VPSIZE(100000)'
call LOGW2
return
end
/* Not enough activity */
if Max_SUD2_gp < 5000000 & bp0_vpsize > 55000 then
do
rec.1 ='DSN SYSTEM('ssid')'
call LOGW2
rec.1 ='-ALTER BPOOL(BP0) VPSIZE(50000)'
call LOGW2
return
end
return
/*---------------------------------------*/
/* Date functions from Chuck Meyer paper */
/*---------------------------------------*/
/* yyyymmdd => weekday */
DAT_S2DOW: Procedure
Parse Arg 1 yyyy +4 mm +2 dd +2 .
f = yyyy + (mm-14)%12
w = ((13*(mm+10-(mm+10)%13*12)-1)%5+dd+77 ,
+ 5 * (f - f%100*100)%4 + f%400 - f%100*2) //7
Return WORD('Sun Mon Tue Wed Thur Fri Sat',w+1)
/*---------------------*/
/* Is this leap year ? */
/*---------------------*/
LY?: Procedure
Parse Arg 1 y +4
Return ((y//4)=0)
/*---------------------*/
/* yyyyddd => yyyymmdd */
/*---------------------*/
DAT_MVS2SD: Procedure
Parse Value REVERSE(arg(1)) With 1 j +3 y
Parse Value REVERSE(j y) With y j
If LENGTH(y) = 2 Then y = YY2YYYY(y)
months = '31' (28 + LY?(y)) ,
'31 30 31 30 31 31 30 31 30 31'
Do m = 1 To 12 While j > WORD(months,m)
j = j - WORD(months,m)
End
Return RIGHT(y,4,0) !! RIGHT(m,2,0) !! RIGHT(j,2,0)
/********************************************/
/* Display list of BP with low Prefetch Qty */
/********************************************/
DisplayPref:
temR=1
rec.1= 'Lpar:' sm100sid 'SSID:' sm100ssi
call logW
temR=1
rec.1= 'List of Bufferpols with a low Prefetch Quantity'
call logW
i=1
do while i <= nbBP
temR=1
j=BPList.i
rec.1= j ListPrefLow.j
if ListPrefLow.j > 0 then
call logW
i=i+1
end
Thursday, May 11, 2017
Thursday, April 6, 2017
Rexx to decode IFCID 369 (Aggregate accounting statistics)
03/05/2021
Refresh this Rexx because i just used it to evaluate the impact of Asynchronous Duplexed Locking.
Very useful IFCID , should be better known.
All the accounting figures grouped by Connection Type.
Update : Ziip figures and correction of bugs - validated figures with BMC Mainview Performance Reporter (V11 tested).
The first period recorded should be deleted (similar problem with all accumulated data: meaningful only if there is a figures for the start and the end period)
06/04/2017
There is a problem with this IFCID because all the presentations and even DB2 manuals or SDSNMACS and SDSNIVPD contents let think that this IFCID can be output to SMF. Which is wrong (maybe a bug ?) , because if you do -START TRACE(STAT) CLASS(9) DEST(SMF) , you will never find IFCID 369 in your SMF records ...
In fact, the only way to get it is with the READS commands.
Below is the code to do this. Just submit this Rexx, it will start the trace , read the contents of the OPx buffer every x minutes and then report the data in a report dataset.
Why IFCID369 is interesting ? You can have the same information by doing sums on your accounting report (Check my REX101 program)
IFCID369 is interesting on my site because there is too much accounting data that it has been decided that the accounting records from CICS are only kept from 9:00 to 10:00. This means that the only way to have some hints on the CPU on another period that is not 09:00 to 10:00 is to go to SMF30 and look at your CICS STC consumption. With IFCID369, i can have a lot of accounting data, not all (the most interesting figure, the number of getpage, is not there !!! in fact everything reported by DSNDQWAC) on all period, in an aggregated version.
Have fun !
Duc
Follow this link on Github to get the Rexx
Tuesday, December 6, 2016
An utility (Excel) to deal with dates from my execs
SMF data often gives dates in format of YYYY.nnn , (For example 2016.307 , corresponding to 02/11/2016), I am in general a bit lazy to transform this in my rexx ...
I use this Excel in my daily work to switch between "normal date" format and this YYYY.nnn format (there is a name for this, but no place in my litle brain to remember)
Here is the link to my Excel to do this :
https://www.evernote.com/shard/s381/sh/cc820363-7867-4292-bba1-30f45b541ed7/a63aa3cdea70a145badf6b39d254896f
I use this Excel in my daily work to switch between "normal date" format and this YYYY.nnn format (there is a name for this, but no place in my litle brain to remember)
Here is the link to my Excel to do this :
https://www.evernote.com/shard/s381/sh/cc820363-7867-4292-bba1-30f45b541ed7/a63aa3cdea70a145badf6b39d254896f
Saturday, October 15, 2016
There is no Guru
Don't believe in gurus , find your own truth.
And this is true , even with DB2.
I don't go to IDUG conferences anymore, because there is no "research" presentations, all of subjects are just an extract of of the manuals. Read them and the redbooks, you will save your money.
I dealt with DB2 performance for some time, for several customers, the technical presentations helped me a lot, but when we dig in, sometimes we need more things in depth, and the presentation contents is not enough specific. Most of the time, contents are copied from one to another ...
So every time i write to the authors, i realised that a lot of them have never tested things that they claim ... if they reply to you.
In preference, guys from DB2 development team always reply, they love technology as you and i , and they love to spread their knowledge to the others.
The professional speakers are to take with care. Lot of them don't spend enough time in "the real world" and just relay something they have heard ...I've had some bad surprise in my career applying updates on blind faith because the presenter said it.
And this is true , even with DB2.
I don't go to IDUG conferences anymore, because there is no "research" presentations, all of subjects are just an extract of of the manuals. Read them and the redbooks, you will save your money.
I dealt with DB2 performance for some time, for several customers, the technical presentations helped me a lot, but when we dig in, sometimes we need more things in depth, and the presentation contents is not enough specific. Most of the time, contents are copied from one to another ...
So every time i write to the authors, i realised that a lot of them have never tested things that they claim ... if they reply to you.
In preference, guys from DB2 development team always reply, they love technology as you and i , and they love to spread their knowledge to the others.
The professional speakers are to take with care. Lot of them don't spend enough time in "the real world" and just relay something they have heard ...I've had some bad surprise in my career applying updates on blind faith because the presenter said it.
Subscribe to:
Comments (Atom)