如何立即判斷 AS/400 物件是否有被設定日誌(journal)功能 ?(Command CHKOBJJRN with API QUSROBJD)
前一期是從 Journal 來產生該 Journal 針對哪些物件(PF, Data Queue, Data Area) 做日誌記錄,
本期直接透過 API QUSROBJD 來判斷單一物件是否有啟動日誌功能。
File : QRPGLESRC
Member: CHKOBJJRNR
Type : RPGLE
Usage : CRTBNDRPG CHKOBJJRNR
**
** Program . . : CHKOBJJRNR
** Description : Check Object journaled or not
** Author . . : Vengoal Chang
** Published . : Dimerco Data System Corporation
** Date . . . : June 15, 2005
**
**
** Program summary
** ---------------
**
** Parameters:
** INPUT PxObjNam Object name, the object for which to
** check journaled or not.
**
** INPUT PxObjLib Object library.
**
** OUTPUT PxRtnJrn Journal library and journal name
** Value: If object wasn't journal,
** Return NONE
**
** Object - User space APIs:
** QUSROBJD Retrieve Object Description with OBJD0400 format.
**
**
** Programmer's notes:
** This program checks object journed or not.
**
**
** Compile options:
**
** CrtBndRpg Pgm( CHKOBJJRNR) SrcFile(lib/QRPGLESRC)
** SrcMbr( CHKOBJJRNR ) DbgView( *List )
** **
**-- Header specifications: --------------------------------------------**
H Option( *SrcStmt ) DftActGrp(*NO) Debug
**-- System information: -----------------------------------------------**
D ApiFmtTyp S 8 Based( NulPtrTyp )
D ChrTyp S 1 Based( NulPtrTyp )
D IntTyp S 10I 0 Based( NulPtrTyp )
D LglTyp S 1N Based( NulPtrTyp )
D NamTyp S 10 Based( NulPtrTyp )
D QNamTyp S 20 Based( NulPtrTyp )
D TxtTyp S 50 Based( NulPtrTyp )
D sndpgmmsg PR
D peMsgID 7A const
D peMsgDta 256A const
D outMsgType 10A const
*---------------------------------------------------------------------
* Does the object exist?
*---------------------------------------------------------------------
D ObjExists Pr Like( LglTyp )
D ObjNam Like( NamTyp ) Value
D ObjLib Like( NamTyp ) Value
* Name, *CURLIB, or *LIBL
D ObjTyp Like( NamTyp ) Value
*---------------------------------------------------------------------
* Get the description of an object
*---------------------------------------------------------------------
D GetObjDsc Pr Like( LglTyp )
D ObjNam Like( NamTyp ) Value
D ObjLib Like( NamTyp ) Value
* Name, *CURLIB, or *LIBL
D ObjTyp Like( NamTyp ) Value
D DscFmt Like( ApiFmtTyp ) Value
D ObjDsc Like( ObjDscDs )
* Description formats
D BrfObjDscFmt C 'OBJD0200'
D DtlObjDscFmt C 'OBJD0400'
* Object description returned
D ObjDscDs Ds Inz
* BrfObjDscFmt
D ObjDscLen Like( IntTyp )
D ObjDscSiz Like( IntTyp )
D ObjNam Like( NamTyp )
D ObjLib Like( NamTyp )
D ObjTyp Like( NamTyp )
D ObjRtnLib Like( NamTyp )
D ObjAsp Like( IntTyp )
D ObjOwnr Like( NamTyp )
D ObjDmn 2
D ObjCrtDat 7
D ObjCrtTim 6
D ObjChgDat 7
D ObjChgTim 6
D ObjAtr Like( NamTyp )
D ObjTxt Like( TxtTyp )
D ObjSrcFil Like( NamTyp )
D ObjSrcLib Like( NamTyp )
D ObjSrcMbr Like( NamTyp )
* DtlObjDscFmt
D ObjSrcChgDat 7
D ObjSrcChgTim 6
D ObjSavDat 7
D ObjSavTim 6
D ObjRstDat 7
D ObjRstTim 6
D ObjCrtUsr Like( NamTyp )
D ObjCrtSys 8
D ObjResDat 7
D ObjSavSiz Like( IntTyp )
D ObjSavSeq Like( IntTyp )
D ObjStg Like( NamTyp )
D ObjSavCmd Like( NamTyp )
D ObjSavVolId 71
D ObjSavDvc Like( NamTyp )
D ObjSavFil Like( NamTyp )
D ObjSavLib Like( NamTyp )
D ObjSavLbl 17
D ObjSavLvl 9
D ObjCompiler 16
D ObjLvl 8
D ObjUsrChg Like( ChrTyp )
D ObjLicPgm 16
D ObjPtf Like( NamTyp )
D ObjApar Like( NamTyp )
D ObjUseDat 7
D ObjUsgInf Like( ChrTyp )
D ObjUseDay Like( IntTyp )
D ObjSiz Like( IntTyp )
D ObjSizMlt Like( IntTyp )
D ObjCprSts Like( ChrTyp )
D ObjAlwChg Like( ChrTyp )
D ObjChgByPgm Like( ChrTyp )
D ObjUsrAtr Like( NamTyp )
D ObjOvrflwAsp Like( ChrTyp )
D ObjSavActDat 7
D ObjSavActTim 6
D ObjAudVal Like( NamTyp )
D ObjPrmGrp Like( NamTyp )
D ObjJrnSts Like( ChrTyp )
D ObjJrnNam Like( NamTyp )
D ObjJrnLib Like( NamTyp )
D ObjJrnImg Like( ChrTyp )
D ObjJrnEntOmt Like( ChrTyp )
D ObjJrnStrDat 13
D ObjDgtSgn Like( ChrTyp )
D ObjSavUnt Like( IntTyp )
D ObjSavMul Like( IntTyp )
D ObjLibAsp Like( IntTyp )
D ObjAspDev Like( NamTyp )
D ObjLibAspDev Like( NamTyp )
D ObjDgtSgnSrc Like( ChrTyp )
D ObjDgtSgnMor Like( ChrTyp )
**-- Parameters: -------------------------------------------------------**
D PxObjNam s 10a
D PxObjLib s 10a
D PxObjTyp s 10a
D PxRtnJrn s 20a
**
D ExistLgl S 1N
D PeMsg S 256
C *Entry Plist
C Parm PxObjNam
C Parm PxObjLib
C Parm PxObjTyp
C* Parm PxRtnJrn
C If GetObjDsc( PxObjNam: PxObjLib:
C PxObjTyp: DtlObjDscFmt:
C ObjDscDs )
C If ObjJrnLib <> *blanks
C Eval PeMsg = 'Object ' + %trim(ObjRtnLib) +
C '/' + %trim(PxObjNam) +
C ' with type ' + %trim(PxObjTyp) +
C ' journaled by Journal ' +
C %trim(ObjJrnLib) + '/' +
C %trim(ObjJrnNam)
C Eval PxRtnJrn = ObjJrnLib + ObjJrnNam
C Else
C Eval PeMsg = 'Object ' + %trim(ObjRtnLib) +
C '/' + %trim(PxObjNam) +
C ' with type ' + %trim(PxObjTyp) +
C ' wasn''t journaled'
C Eval PxRtnJrn = 'NONE'
C EndIf
C callp sndpgmmsg('CPF9898' : PeMsg : '*INFO')
C EndIf
C* dump
C
C Return
*==================================================================
P ObjExists B
*==================================================================
D Pi Like( LglTyp )
D ObjNam Like( NamTyp ) Value
D ObjLib Like( NamTyp ) Value
* Name, *CURLIB, or *LIBL
D ObjTyp Like( NamTyp ) Value
C Return GetObjDsc( ObjNam: ObjLib:
C ObjTyp: BrfObjDscFmt:
C ObjDscDs )
P E
*=====================================================================
P GetObjDsc B
*====================================================================
D Pi Like( LglTyp )
D ObjNam Like( NamTyp ) Value
D ObjLib Like( NamTyp ) Value
* Name, *CURLIB, or *LIBL
D ObjTyp Like( NamTyp ) Value
D DscFmt Like( ApiFmtTyp ) Value
D ObjDsc Like( ObjDscDs )
D QObjNam S Like( QNamTyp )
D BrfObjDscSiz C 180
D DtlObjDscSiz C %Size( ObjDscDs )
**-- Api error data structure: ----------------------------------
D ApiError Ds
D AeBytPro 10i 0 Inz( %Size( ApiError ))
D AeBytAvl 10i 0 Inz
D AeMsgId 7a
D 1a
D AeMsgDta 256a
C Reset ObjDscDs
C Eval QObjNam = ObjNam + ObjLib
C If DscFmt = BrfObjDscFmt
C Eval ObjDscSiz = BrfObjDscSiz
C Else
C Eval ObjDscSiz = DtlObjDscSiz
C EndIf
C Eval ObjDsc = ObjDscDs
C Call 'QUSROBJD'
C Parm ObjDsc
C Parm ObjDscSiz
C Parm DscFmt
C Parm QObjNam
C Parm ObjTyp
C Parm ApiError
C If AeBytAvl > *Zero
C callp sndpgmmsg(AeMsgID: AeMsgDta : '*ESCAPE')
C EndIf
C Return ( AeBytAvl = 0 )
P E
*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
* This ends this program abnormally, and sends back an escape.
* message explaining the failure.
*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
P sndpgmmsg B
D sndpgmmsg PI
D peMsgID 7A const
D peMsgDta 256A const
D outMsgType 10A const
D QMHSNDPM PR ExtPgm('QMHSNDPM')
D MessageID 7A Const
D QualMsgF 20A Const
D MsgData 256A Const
D MsgDtaLen 10I 0 Const
D MsgType 10A Const
D CallStkEnt 10A Const
D CallStkCnt 10I 0 Const
D MessageKey 4A
D ErrorCode 32766A options(*varsize)
D dsEC DS
D dsECBytesP 1 4I 0 INZ(256)
D dsECBytesA 5 8I 0 INZ(0)
D dsECMsgID 9 15
D dsECReserv 16 16
D dsECMsgDta 17 256
D wwMsgLen S 10I 0
D wwTheKey S 4A
c eval wwMsgLen = %len(%trimr(peMsgDta))
c if wwMsgLen<1
c return
c endif
c callp QMHSNDPM (PeMsgID : 'QCPFMSG *LIBL':
c peMsgDta: wwMsgLen: %trim(outMsgType):
c '*PGMBDY': 1: wwTheKey: dsEC)
c return
P E
File : QCMDSRC
Member: CHKOBJJRN
Type : CMD
Usage : CRTCMD CMD(CHKOBJJRN) PGM(CHKOBJJRNR)
/********************************************************************/
/* Title: CHKOBJJRN : Check Object Journaled or not */
/* */
/* Author: Vengoal Chang */
/* Date : June 15,2005 */
/* */
/* The Create Command command should include the following: */
/* */
/* CRTCMD CMD(CHKOBJJRN) PGM(CHKOBJJRNR) */
/* */
/********************************************************************/
/*------------------------------------------------*/
/* Command Definition */
/*------------------------------------------------*/
CMD PROMPT('Check Object Journaled')
PARM KWD(OBJECT) TYPE(*NAME) LEN(10) MIN(1) +
EXPR(*YES) PROMPT('Object')
PARM KWD(LIBRARY) +
TYPE(*NAME) +
LEN(10) +
DFT(*LIBL) +
SPCVAL( +
(*LIBL ) +
(*CURLIB *CURLIB )) +
EXPR(*YES) +
PROMPT('Library')
PARM KWD(OBJTYPE) +
TYPE(*CHAR) +
LEN(10) +
RSTD(*YES) +
SPCVAL( +
(*ALRTBL *ALRTBL) +
(*AUTL *AUTL) +
(*BNDDIR *BNDDIR) +
(*CFGL *CFGL) +
(*CHTFMT *CHTFMT) +
(*CLD *CLD) +
(*CLS *CLS) +
(*CMD *CMD) +
(*CNNL *CNNL) +
(*COSD *COSD) +
(*CRG *CRG) +
(*CRQD *CRQD) +
(*CSI *CSI) +
(*CSPMAP *CSPMAP) +
(*CSPTBL *CSPTBL) +
(*CTLD *CTLD) +
(*DEVD *DEVD) +
(*DOC *DOC) +
(*DTAARA *DTAARA) +
(*DTADCT *DTADCT) +
(*DTAQ *DTAQ) +
(*EDTD *EDTD) +
(*EXITRG *EXITRG) +
(*FCT *FCT) +
(*FILE *FILE) +
(*FLR *FLR) +
(*FNTRSC *FNTRSC) +
(*FNTTBL *FNTTBL) +
(*FORMDF *FORMDF) +
(*FTR *FTR) +
(*GSS *GSS) +
(*IGCDCT *IGCDCT) +
(*IGCSRT *IGCSRT) +
(*IGCTBL *IGCTBL) +
(*IMGCLG *IMGCLG) +
(*IPXD *IPXD) +
(*JOBD *JOBD) +
(*JOBQ *JOBQ) +
(*JOBSCD *JOBSCD) +
(*JRN *JRN) +
(*JRNRCV *JRNRCV) +
(*LIB *LIB) +
(*LIND *LIND) +
(*LOCALE *LOCALE) +
(*MEDDFN *MEDDFN) +
(*MENU *MENU) +
(*MGTCOL *MGTCOL) +
(*MODD *MODD) +
(*MODULE *MODULE) +
(*MSGF *MSGF) +
(*MSGQ *MSGQ) +
(*M36 *M36) +
(*M36CFG *M36CFG) +
(*NODGRP *NODGRP) +
(*NODL *NODL) +
(*NTBD *NTBD) +
(*NWID *NWID) +
(*NWSD *NWSD) +
(*OUTQ *OUTQ) +
(*OVL *OVL) +
(*PAGDFN *PAGDFN) +
(*PAGSEG *PAGSEG) +
(*PDG *PDG) +
(*PGM *PGM) +
(*PNLGRP *PNLGRP) +
(*PRDDFN *PRDDFN) +
(*PRDLOD *PRDLOD) +
(*PSFCFG *PSFCFG) +
(*QMFORM *QMFORM) +
(*QMQRY *QMQRY) +
(*QRYDFN *QRYDFN) +
(*RCT *RCT) +
(*SBSD *SBSD) +
(*SCHIDX *SCHIDX) +
(*SPADCT *SPADCT) +
(*SQLPKG *SQLPKG) +
(*SQLUDT *SQLUDT) +
(*SRVPGM *SRVPGM) +
(*SSND *SSND) +
(*SVRSTG *SVRSTG) +
(*S36 *S36) +
(*TBL *TBL) +
(*USRIDX *USRIDX) +
(*USRPRF *USRPRF) +
(*USRQ *USRQ) +
(*USRSPC *USRSPC) +
(*VLDL *VLDL) +
(*WSCST *WSCST)) +
MIN(1) +
EXPR(*YES) +
PROMPT('Object type')
A blog about IBM i (AS/400), MQ and other things developers or Admins need to know.
星期二, 11月 07, 2023
2005-06-29 如何立即判斷 AS/400 物件是否有被設定日誌(journal)功能 ?(Command CHKOBJJRN with API QUSROBJD)
2005-06-18 如何列出 journaled File ?(Command LSTJRNFILE with API QjoRetrieveJournalInformation)
如何列出 journaled File ?(Command LSTJRNFILE with API QjoRetrieveJournalInformation)
應用程式有時會需要針對 PF 執行 Commit 或 Rollback 後,
所以會執行 STRJRNPF 將資料的異動過程紀錄至 journal(日誌)中,
所以 journal 中會記錄哪些 PF 或 Object 被 journal, 可以透過
Journal API QjoRetrieveJournalInformation 取得相關資訊, 此工具
LSTJRNFILE command 會將所指定的 journal file 資訊輸出至報表
File : QCLSRC
Member: LSTJRNFILC
Type : CLP
Usage : CRTCLPGM LSTJRNFILC
/*-------------------------------------------------------------------*/
/* LSTJRNFILE List processing for Journal */
/* */
/*-------------------------------------------------------------------*/
/* Author: Vengoal Chang */
/* 2005/06/13 */
/*-------------------------------------------------------------------*/
PGM (&JRNLIB)
DCL &JRNLIB *CHAR 20
DCL &LIB *CHAR 10
DCL &JRN *CHAR 10
dcl &Abending *lgl
dcl &MsgID *char 7
dcl &MsgDta *char 256
dcl &MsgF *char 10
dcl &MsgFLib *char 10
dcl &MsgKey *char 4
dcl &MsgType *char 10
dcl &RtnType *char 2
dcl &PgmName *char 10
dcl &Sender *char 80
monmsg cpf0000 exec(goto abend)
/* retrieve the program name */
sndpgmmsg msg(' ') topgmq(*same) msgtype(*info) keyvar(&msgkey)
rcvmsg pgmq(*same) msgtype(*info) sender(&sender) rmv(*yes)
chgvar &PgmName %sst(&Sender 56 10)
CHGVAR &JRN %SST(&JRNLIB 1 10)
CHGVAR &LIB %SST(&JRNLIB 11 10)
CHKOBJ OBJ(&LIB/&JRN) OBJTYPE(*JRN)
CALL LSTJRNFILR (&JRNLIB)
/* normal end of job */
sndpgmmsg msgid(cpf9898) msgf(qcpfmsg) msgtype(*comp) +
msgdta('Program' *bcat &PgmName *bcat +
'completed normally')
return
/* Routine to handle unexpected errors */
Abend:
if &Abending then(return)
chgvar &Abending '1'
rcvmsg msgtype(*last) msgdta(&msgdta) msgid(&msgid) +
rtntype(&RtnType) +
msgf(&msgf) sndmsgflib(&msgflib)
if ((&RtnType *eq '15') *or (&RtnType *eq '17')) do /* *escape */
sndpgmmsg msgid(&msgid) msgf(&msgf) msgtype(*diag) +
msgdta(&msgdta)
enddo
Escape:
sndpgmmsg msgid(cpf9898) msgf(qcpfmsg) msgtype(*escape) +
msgdta('Program' *bcat &PgmName *bcat +
'ended abnormally')
endpgm
ENDPGM
File : QRPGLESRC
Member: LSTJRNFILR
Type : RPGLE
Usage : CRTBNDRPG PGM(LSTJRNFILR) SRCFILE(lib/QRPGLESRC) SRCMBR(LSTJRNFILR)
* /// MBR name: LSTJRNFILR QRPGLESRC
*----------------------------------------------------------------
* LSTJRNFILR List journaled File..
*
* This program modify from on Craig Rutledge's LSTJRNA utility
* Modified by Vengoal Chang 2005/06/13
*
* Right now the program is set up to load a subfile with a list of journalled files.
*
* NOTE: the api can return data for more files than there is space in the api variable.
* The limit for the variable is 32767 which allows for 668 files in a single rcvr. I do not
* know why they didn't make this a user space application or give me a continuation handle.
* This will probably not be a problem in most shops anyway, just be aware of it.
*
*
* NOTE : This program MUST be compiled with DFTACTGRP = '*NO'. This is due to the bound
* call to the jrn API. I put the API to get the file text in a function. Some people
* may not need the file text and this will make it easier to remove if desired.
*
* Usage: CALL LSTJRNFILR ('journalNamjournalLib')
* parameter is 20 chars 10 journal name
* 10 journal library
*----------------------------------------------------------------
H DFTACTGRP(*NO) ACTGRP(*CALLER)
* api calls:
*
* api (application program interfaces) used:
* QjoRetrieveJournalInformation
* qbdrtvfd retrieve file description
* see system programmer'S INTERFACE REFERENCE for API detail.
*
*----------------------------------------------------------------
FQSYSPRT O F 132 Printer
*
D jrnlib s 21
D count s 7 0
D KeyOffset s 5 0
D opt s 1 make alpha
D sbfFileLib s 10
D sbfFileNam s 10
D sbfFileTxt s 50
D scrAttRcvL s 10
D scrAttRcvN s 10
D scrJrnLib s 10
D scrJrnName s 10
D scrJrnText s 30
D scrTotFile s 7 0
D scrTotMbrs s 7 0
*
*---------------------------------------------------------------------------------------------
* Prototype for calling Retrieve Journal Attributes API.
*---------------------------------------------------------------------------------------------
D ApiName c 'QjoRetrieveJournalInformation'
*---------------------------------------------------------------------------------------------
D $s s 5 0
D ds
Drtnvarlen 1 4b 0 inz(%size(qjon0100))
*
*---------------------------------------------------------------------------------------------
* These DS are used to map the STUPIDLY hard Journal Info to Retrieve parameter.
* the 2 InfoCount means I want the Journal Receiver AND the journaled file info.
*---------------------------------------------------------------------------------------------
D InfoToRtv ds
D InfoCount 1 4b 0 inz(2)
D InfoVarDS 100
*
D InfoVar ds align
D InfoVLlen 1 4b 0 inz(0) length of VL record
D InfoKey 5 8b 0 inz(0) key of info to retur
D InfoLOD 9 12b 0 inz(0) length of data
D InfoData 38 actual data
*
*---------------------------------------------------------------------------------------------
* The following are from QRPGLESRC in QSYSINC member QJOURNAL.
*---------------------------------------------------------------------------------------------
*
********************************************************************
*Type Definition for the RJRN0100 Format, for the Retrieve
*Journal Information (QjoRetrieveJournalInformation) API
*receiver variable.
********************************************************************
DQJON0100 DS 32767 inz
D QJOBRTN01 1 4B 0 Bytes Returned
D QJOBAVL01 5 8B 0 Bytes Available
D QJOOKI 9 12B 0 Off Key Info
D QJOJN00 13 22 Jrn Name
D QJOJLN 23 32 Jrn Lib Name
D QJOASP 33 36B 0 Aux Stg Pool
D QJOMQN 37 46 Message Queue Name
D QJOMQLN 47 56 Message Queue Lib
D QJOMRO 57 57 Manage Rcvr Option
D QJODRO 58 58 Delete Rcvr Option
D QJONTENT 59 59 Rcv Size Opt
D QJOIXLEN 60 60 Rcv Size Opt
D QJORSV1 61 65 Reserved 1
D QJOJT 66 66 Journal Type
D QJORJT00 67 67 Remote Jrn Type
D QJOJS 68 68 Journal State
D QJOJDM 69 69 Journl Delivery Mode
D QJOLJN 70 79 Lcl Jrn Name
D QJOLJLN 80 89 Lcl Jrn Lib Name
D QJOLJS 90 97 Lcl Jrn System
D QJOSJN 98 107 Src Jrn Name
D QJOSJLN 108 117 Src Jrn Lib Name
D QJOSJS 118 125 Src Jrn System
D QJORRLN 126 135 Redirectd Rcv Lib Nm
D QJOJT00 136 185 Journal Text
D QJORSV2 186 196 Reserved 2
D QJONAJR 197 200B 0 Num Att Jrn Rcvs
D QJOAJRN 201 210 Att Jrn Rcv Name
D QJOAJRLN 211 220 Att Jrn Rcv Lib Name
D QJOSAAJR 221 228 Lcl Jrn Sys Asc Att
D QJOSAAJR00 229 236 Src Jrn Sys Asc Att
D QJOADJRN 237 246 Att Dual JrnRcv
D QJODJRLN 247 256 Att Dual JrnRcvLib
D QJORSV3 257 448 Reserved 3
D QJONOKF 449 452B 0 number keys
*
********************************************************************
*Type Definition for the Repeating Key 1 Output, for the Retrieve
*Journal Information (QjoRetrieveJournalInformation) API
*receiver variable.
********************************************************************
D JONRK1O DS
D QJOJRN 1 10 Jrn Rcv Name
D QJOJRLN 11 20 Jrn Rcv Lib Name
D QJOJRNBR 21 25 Jrn Rcv Number
D QJOJRADT 26 38 Jrn Rcv Att DateTime
D QJOJRS 39 39 Jrn Rcv Status
D QJOJRSDT 40 52 Jrn Rcv Sav DateTime
D QJOJSAJR 53 60 LclJrn Sys AscJrnRcv
D QJOJSAJR00 61 68 SrcJrn Sys AscJrnRcv
D QJOJRS00 69 72B 0 Jrn Rcv Size
D QJOERVED01 73 128 Reserved
*
********************************************************************
*Type Definition for the Key 1 Output Section, for the Retrieve
*Journal Information (QjoRetrieveJournalInformation) API
*receiver variable.
********************************************************************
DQJONK1OS DS
D QJOTNJR 1 4B 0 Tot Num Jrn Rcvs
D QJOTSJR 5 8B 0 Tot Size Jrn Rcvs
D QJOERVED00 9 20
*
********************************************************************
*Type Definition for the Key 2 Output Section, for the Retrieve
*Journal Information (QjoRetrieveJournalInformation) API
*receiver variable.
********************************************************************
DQJONK2OS DS
D QJOTNJF 1 4B 0 Tot Num Jrn Files
D QJOTNJM 5 8B 0 Tot Num Jrn Mbrs
D QJOERVED02 9 36 Reserved
*
********************************************************************
*Type Definition for the Repeating Key 2 Output, for the Retrieve
*Journal Information (QjoRetrieveJournalInformation) API
*receiver variable.
********************************************************************
DQJONRK2O DS
D QJOOBJT00 1 10 Object Type
D QJOOBJN00 11 20 Object Name
D QJOOBJLN 21 30 Object Lib Name
D QJOERVED03 31 48 Reserved
*
*---------------------------------------------------------------------------------------------
* repeat for each key specified. rjrn0100 format. Offsets to key data
*---------------------------------------------------------------------------------------------
D RepeatKey ds align inz
D repKey 1 4b 0 Key value
D repStartOfKey 5 8b 0 Offset to start
D repLenHeader 9 12b 0 length of header dta
D repNumEntries 13 16b 0 number entries
D repLenEntry 17 20b 0 length of entry
*
*---------------------------------------------------------------------------------------------
* Error return code parm for APIs.
*----------------------------------------------------------------
D vApiErrDs ds
D vbytpv 10i 0 inz(%size(vApiErrDs)) bytes provided
D vbytav 10i 0 inz(0) bytes returned
D vmsgid 7 error msgid
D vresvd 1 reserved
D vexdta 50 replacement data
*
*---------------------------------------------------------------------------------------------
* Define function prototype to return file text from API.
*---------------------------------------------------------------------------------------------
D GetFileTxt pr 50
D 10
D 10
*
*
*---------------------------------------------------------------------------------------------
C *entry plist PASSED PARMS
C parm $JrnLib 20 OBJ LIB 20
C RefreshTag tag
*
*---------------------------------------------------------------------------------------------
* Load DS with values to return journaled object info.
* 1 = key value for journal receivers
* 0 = length of object type selector (N/A for receivers)
* *blanks = (N/A for receivers)
*---------------------------------------------------------------------------------------------
C eval InfoKey = 1 journal receivers
C eval InfoLOD = 0
C eval InfoVLlen = 12 length of VL record
C eval InfoData = *blanks
C eval InfoVarDS = InfoVar
*
* 2 = key value for objects
* 10 = length of object type selector *all
* *ALL = return all object types being journaled
C eval InfoKey = 2 files journaled
C eval InfoLOD = 10
C eval InfoVLlen = 22
C eval InfoData = '*FILE '
C eval InfoVarDS = %trimr(InFoVarDS) + InfoVar
*
C callb ApiName LOAD JRN DATA
C parm qjon0100
C parm rtnvarlen
C parm $JrnLib qualifiedJ 20
C parm 'RJRN0100' $fornm 8 TYPE FORMAT
C parm InfoToRtv
C parm vApiErrDs
*
*---------------------------------------------------------------------------------------------
* I am arbitrarily going to show only the
* first attached journal receiver on the screen. All my journals (and probably most of
* everybody elses) only have one receiver attached. If you are interested in multiple
* receivers though, let me know and I can add this code.
*---------------------------------------------------------------------------------------------
C move *blanks scrAttRcvN
C move *blanks scrAttRcvL
C move *blanks scrJrnName
C move *blanks scrJrnLib
C move *blanks scrJrnText
*
C eval scrAttRcvN = qjoajrn Attached Receiver
C eval scrAttRcvL = qjoajrln Attached Rcv Lib
*
C eval scrJrnName = qjojn00 Journal name
C eval scrJrnLib = qjojln Journal library
C eval scrJrnText = qjojt00 Journal text
*
*---------------------------------------------------------------------------------------------
* First we want to get the number of Keys
* that where returned. In this case it should be 2 as that is all I asked for.
*
* Then spin down the key offsets until we find key number 2. That will be the journaled
* files.
*---------------------------------------------------------------------------------------------
C z-add 453 KeyOffset
1B C do qjonokf number of keys
C eval RepeatKey = %subst(qjon0100:KeyOffset:20)
2B C select
2X C when repKey = 1 Journal Receivers
****** exsr GetJrnRcvs
2X C when repKey = 2 Journaled files
C exsr GetFileNames
2X C when repKey = 3 Remote Journal Info
***** exsr GetRemote
2E C endsl
C add 20 KeyOffset
1E C enddo
*
C eval *inlr = *on PROGRAM END
*
*---------------------------------------------------------------------------------------------
* Process the journaled file names. use the offsets to spin through file names.
*---------------------------------------------------------------------------------------------
C GetFileNames begsr
C z-add 0 scrTotFile
C z-add 0 scrTotMbrs
C move *blanks sbfFileNam
C move *blanks sbfFileLib
*
C eval $s=(repStartOfKey + qjooki + 5)
C eval qjonk2os = %subst(qjon0100:$s:repLenHeader)
C z-add QJOTNJF scrTotFile Tot Num Jrn Files
C z-add QJOTNJM scrTotMbrs Tot Num Jrn Mbrs
*
C add repLenHeader $s step over to list
*
C eval JrnLib = %trim(%subst($JrnLib:11:10))+
C '/' +
C %trim(%subst($JrnLib:1:10))
C except HEAD
1B C do repNumEntries count
C eval qjonrk2o = %subst(qjon0100:$s:repLenEntry)
C move qjoobjn00 sbfFileNam
C move qjoobjln sbfFileLib
c* sbfFileNam dsply
*
* ----------------------------------------------------------------
* Execute a function to get the file text.
* ----------------------------------------------------------------
C eval sbfFileTxt =
C GetFileTxt(sbfFileNam:sbfFileLib)
*
C except out LOAD SUBFILE
*
* ----------------------------------------------------------------
C add repLenEntry $s next entry
1E C enddo
C endsr
*
OQSYSPRT E HEAD 1
O 9 'Journal:'
O JrnLib 31
O E HEAD 1
O 5 'File'
O 19 'Library'
O 28 'Text'
O E OUT 1
O sbfFileNam B 11
O sbfFileLib B 22
O sbfFileTxt B 74
*
*---------------------------------------------------------------------------------------------
* Function to return File Text. This was done a function to isolate the D specs from
* the complexity of the Journal API.
*---------------------------------------------------------------------------------------------
PGetFileTxt B Begin Procedure
D GetFileTxt pi 50 Procedure Interface
D sbfFileNam 10 incoming arguement
D sbfFileLib 10 incoming arguement
D fillib s 20 file library
D $fltxt s 50 file library
D$systm$ c const('*FILETYPE')
*
*----------------------------------------------------------------
* this value is used as an offset to the file scope array section
* fhflg = rd bit is used to determine if original file is
* physical or logical file.
* fscope = offset
*----------------------------------------------------------------
D $rcvds ds
D $rcvln 1 4b 0 inz(32000)
D $rcvar ds 32000 inz
D fhflg 9 9 file type bits
D qdbfmtnum 62 63b 0 number record fmts
D qdbfhtxt 85 134 file text
D $flfld$ 207 208b 0 number of fields
D $fllen$ 305 306b 0 file length
D fscope 317 320b 0 offest to file scope
*
*----------------------------------------------------------------
* Error return code parm for APIs.
*----------------------------------------------------------------
D vApiErrDs ds
D vbytpv 10i 0 inz(%size(vApiErrDs)) bytes provided
D vbytav 10i 0 inz(0) bytes returned
D vmsgid 7 error msgid
D vresvd 1 reserved
D vexdta 50 replacement data
*
C eval fillib = sbfFileNam + sbfFileLib
*
*----------------------------------------------------------------
* call API to get file description.
*----------------------------------------------------------------
C call 'QDBRTVFD' LOAD DBR
C parm $rcvar RECEIVER VARIAB
C parm $rcvln RECEIVER LENGTH
C parm $rtnfl 20 RETRN FILE/LIB
C parm 'FILD0100' $fornm TYPE FORMAT
C parm fillib $fillb 20 FILE LIB 20
C parm '*FIRST ' $formt 10 ALL FORMATS
C parm '0' $ovrrd 1 NO OVERRIDES
C parm $systm$ $systm 10 WHICH SYSTEM
C parm '*EXT' $frmtp 10 FORMAT TYPE?
C parm vApiErrDs
*
C eval $fltxt=qdbfhtxt
C return $fltxt return value
PGetFileTxt E End Procedure
File : QCMDSRC
Member: LSTJRNFILE
Type : CMD
Usage : CRTCMD CMD(LSTJRNFILE) PGM( lib/LSTJRNFILC)
/*-------------------------------------------------------------*/
/* Author: Vengoal Chang */
/* 2005/06/13 */
/*-------------------------------------------------------------*/
/* To Compile: */
/* CREATE RPGLESRC PGM --> LSTJRNFILR */
/* CREATE CLP PGM --> LSTJRNFILC CMD PGM */
/* CRTCMD CMD(XXX/LSTJRNFILE) PGM(XXX/LSTJRNFILC) + */
/* SRCFILE(XXX/QCMDSRC) */
/*-------------------------------------------------------------*/
LSTJRNFILE: CMD PROMPT('List Journaled File')
PARM KWD(JOURNAL) TYPE(NAME1) MIN(1) +
PROMPT('Journal name')
NAME1: QUAL TYPE(*NAME) LEN(10) EXPR(*YES)
QUAL TYPE(*NAME) LEN(10) DFT(*LIBL) +
SPCVAL((*LIBL)) EXPR(*YES) CHOICE('Name, +
*LIBL') PROMPT('Library')
星期四, 11月 02, 2023
Journaling - Common Remote Journal Questions
https://www.redbooks.ibm.com/abstracts/tips0724.html?Open
Why did remote journaling end?
Probably the number one question remote journal users have is “Why did remote journaling end?” This question is not as hard to answer as one would think.
Every time remote journaling ends, the operating system sends a message to the journal’s message queue. The Work with Journal Attributes (WRKJRNA) command indicates the message queue associated with the journal. The Display message queue (DSPMSGQ) command can be used to display the messages on the queue. Sometimes user or third party applications monitor the journal message queue for messages that need action, and remove them from the queue. Because of this, starting in release 6.1 of the IBM i operating system, the remote journal messages are also sent to the system history log. The system history log is now the first place to look for messages. The Display Log (DSPLOG) command can be used to see messages in the system history log.
On the source system a message is sent to the journal message queue when remote journaling ends. The reason code in this message details why remote journaling ended. If the reason is related to a communications problem (reason code 2, 3, or 4 in CPF70D5) then a diagnostic CPExxxx message is also sent to the journal message queue detailing the exact communications problem. If the reason code in the CPF70D5 message is 20 (target side error), then the problem occurred on the target system and the messages on that system are the key to determining what happened.
On the target system a message is also sent to the journal message queue when remote journaling ends. The reason code in the message details why remote journaling ended. Again, if the error was related to a communications problem, then a diagnostic CPExxxx message will also be sent. If the message is CPF70DB, CPF70D7, or CPF70DC, there should be another message related to the error. Take note of the job that sent this message (often QDBSRV02 or QDBSRV03). In this situation, the real key to why remote journaling ended might be in the job log of the job that sent this additional message.
To see the messages related to remote journaling on the source system, use the following Display Log (DSPLOG) command:
- DSPLOG MSGID(CPF70D3 CPF70D5 CPC6984 CPC6983 CPF70C5 CPI7012 CPI7016)
To see the messages related to remote journaling on the target system, use the following DSPLOG command:
- DSPLOG MSGID(CPF70D4 CPF70D5 CPF70DB CPF70DC CPF70D7 CPC6983 CPF70C4 CPF70C5 CPI7012 CPI7016)
The above DSPLOG commands reveal the time frame of the error and return messages detailing the history of the remote journal environment.
If the reason code in the remote journal ended message indicates a communications error, then display messages from the history log in the time frame of the error to see any diagnostic CPExxxx messages.
Why did remote journaling fail to activate?
Another question remote journal users have is “Why did remote journaling fail to activate?” If remote journaling fails to activate, there should be messages in the job log of the job that was performing the activation to indicate what caused the failure. Usually the key to what went wrong is in these messages. Occasionally, the reason why remote journaling failed to start can be found in the target job. In the job log of the job performing the activate request, there will be a message (CPI9155) indicating the job on the target system that was involved in the activate request. Sometimes the messages in this job log can help determine what is wrong. There is also a message in the target job (CPI9152) that notes the job on the source system that is related. This can be used to verify that you are looking at the correct job log on the target system. Another useful piece of information is the names of the journal receivers that exist on the target system. Usually the names of these journal receivers, along with careful reading of the error message, is all that is needed to determine what is wrong.
Is my request to activate remote journal stuck?
It can take a while to activate remote journaling when a large amount of existing journal data needs to be sent. The activate request sends a status message when beginning to send entries for a given journal receiver, but those status messages are infrequent when large journal receivers must be sent. Sometimes it appears that progress is not being made and the activate request is ended prematurely. How do you know if it is progressing?
To see if progress is being made by remote journal simply display the receiver attributes of the journal receiver attached to the remote journal. If the number of journal entries for the journal receiver is increasing then remote journaling is progressing. There may be some time between updates to this number so sample it for a minute or two before concluding that progress is not being made. From the source system it may very well look like things are stuck when activating, but rest assured that remote journaling is sending entries as efficiently as possible during this catch-up time.
Why is remote journal falling behind sending entries?
Another frequent question concerning remote journal is “Why is remote journal falling behind sending entries?” The primary reason that remote journal is falling behind is likely that the communication line is undersized. Another common reason for remote journal to fall behind is that the target system is undersized and cannot keep up. Another common reason for remote journal to fall behind is problems with the communication network that result in retransmissions of data. To see if retransmissions could be a factor, use the Work with TCP/IP Network Status (NETSTAT) command to check the number of retransmissions. Ideally you would see no retransmissions.
On the Work with TCP/IP Network Status menu select the appropriate option for your remote journal connections: option 3 for IPV4 connection status, or option 6 for IPV6 connection status. On the IPV4 connection status panel, look for local ports with the value “rmtjour >” or 3777. These are the remote journal connections. Option 5 will display the connection-specific information. The retransmission information is available on the resulting panels. On the IPV6 connection status panel, look for local ports with the value “3888.” If there are a significant number of retransmissions, or if the count is changing, it is likely that a communication network problem is the source of your remote journal performance problems.