How to delete old Journal Receivers (*JRNRCV)

  • Home
  • /
  • Blog
  • /
  • How to delete old Journal Receivers (*JRNRCV)

September 12, 2024

How to delete old Journal Receivers (*JRNRCV)

By NickLitten

September 12, 2024

JRNRCV, CLLE, CMD, Housekeeping, Journal, Receiver

IBM i Housekeeping 101 – Deleting old Journal Receivers

Following on from the blog I wrote about “What is an IBM i Journal?

We know that IBM i journals record what happens to files, and we know that this record is kept in these things called journal receivers.

What is a Journal Receiver?

An IBMi journal receiver is a component used in the journaling process on IBM’s IBMi (AS400/iSeries) systems. Here’s a brief overview:

  • Purpose: The journal receiver is where the journal entries are actually recorded. It captures all changes made to the objects being journaled, such as updates, deletions, and additions.
  • Function: When a journal is created, it must be associated with a journal receiver. The receiver stores the detailed records of all changes, which can be used for recovery, auditing, or replication purposes.
  • Management: Journal receivers can be configured to fit specific needs, including setting their size and managing their lifecycle. They are “bound” to the journal, meaning they work together to ensure data integrity and consistency.
what is an ibm i journal and receiver JRN JRNRCV

Now – since a journal can record thousands, millions or even squillions of updates to any given file, what happens to the RECEIVER when they get full of data?

IBM-i will create a new receiver and detach the old one.

So – any given journal can have 1, 2, 3, 4, 5, and so on receivers on the system. It will always be connected to, pointed at, the most recent receiver.

Once a receiver is disconnected it’s frozen and no new updates will be stored there.

All new updates will be stored in the next newer receiver in the chain.

How do we DELETE (PURGE) old JOURNAL RECEIVERS as part of our housekeeping?

Let’s take a simple CMD and CL program to do exactly that.

disclaimer – I’m not going to add nice error handling and messaging. That bit is up to you. This is just a quick utility built on these premises (1) you have backed up your receivers (2) you are not testing this on production (3) use at your own risk 😉

Me.

CODE EXAMPLE – PURGE JOURNAL RECEIVER

CMD

/* -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- *-*/
/*                     Delete Journal Receivers                  *-*/
/* -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- *-*/
/*  Command Id ....... PRGJRNRCV                                 *-*/
/*  Calling Program .. Command=PRGJRNCPP                         *-*/
/* -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- *-*/
/* Apr 2022 - Nick Litten - Created                              *-*/
/* -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- *-*/

 CMD         PROMPT('Purge Journal Receivers')
             PARM       KWD(JRNRCV) TYPE(JRNFILPRM) PROMPT('Journal +
                          Receiver')
 JRNFILPRM:  QUAL       TYPE(*GENERIC) LEN(10) SPCVAL((*ALL *ALL)) +
                          MIN(1) EXPR(*YES) PASSATR(*YES)
             QUAL       TYPE(*CHAR) LEN(10) DFT(*LIBL) +
                          SPCVAL((*ALLUSR) (*ALL) (*USRLIBL) +
                          (*LIBL) (*CURLIB)) EXPR(*YES) +
                          PASSATR(*YES) PROMPT('Library')     

To Compile — CRTCMD CMD(yourlib/PRGJRNRCV) PGM(PRGJRNCPP)

CLLE

/* -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */
/*                       Purge Journal Receivers                 */
/* -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */
/*  Program Id ....... PRGJRNCPP                                 */
/*  Calling Program .. Command=PRGJRNRCV                         */
/* -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */
/* Apr 2022 - Nick Litten - Created                              */
/* -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */
 PGM        PARM(&PARMJRNRCV)

 DCL        VAR(&PARMJRNRCV) TYPE(*CHAR) LEN(22)
 DCL        VAR(&RCVHEXGEN) TYPE(*CHAR) LEN(1)
 DCL        VAR(&RCV) TYPE(*CHAR) LEN(10)
 DCL        VAR(&LIBHEXGEN) TYPE(*CHAR) LEN(11)
 DCL        VAR(&LIBRARY) TYPE(*CHAR) LEN(10)

 DCL        VAR(&COUNT) TYPE(*DEC) LEN(7 0)
 DCL        VAR(&COUNTALF) TYPE(*CHAR) LEN(7)
 DCL        VAR(&ENDSTS) TYPE(*CHAR) LEN(1) VALUE('0')

 DCLF       FILE(QADSPOBJ)

 SNDPGMMSG  MSG(('Loading list of all +
                Journal Receivers in lib(' *TCAT &LIBRARY *TCAT ')')

 CHGVAR     VAR(&RCVHEXGEN) VALUE(%SST(&PARMJRNRCV 1 1))
 CHGVAR     VAR(&RCV) VALUE(%SST(&PARMJRNRCV 02 10))
 CHGVAR     VAR(&LIBHEXGEN) VALUE(%SST(&PARMJRNRCV 12 1))
 CHGVAR     VAR(&LIBRARY) VALUE(%SST(&PARMJRNRCV 13 10))

 DSPOBJD    OBJ(&LIBRARY/&RCV) OBJTYPE(*JRNRCV) OUTPUT(*OUTFILE) +
                OUTFILE(QTEMP/PRGJRNRCV)

 OVRDBF     FILE(QADSPOBJ) TOFILE(QTEMP/PRGJRNRCV)

 LOOP:
 DOWHILE    COND(&ENDSTS = '0')
    RCVF
    MONMSG     MSGID(CPF0864) EXEC(LEAVE)

    IF         COND(&ODSDAT *NE ' ') THEN(DO)
       SNDPGMMSG  MSG('Purging' *BCAT +
                      &ODLBNM *TCAT '/' *TCAT &ODOBNM *TCAT '...') 

/* -- This is where you could add some logic to check if the receiver has been saved, or select by date, or name, or whatever... go on do it... make this code prettier */
       DLTJRNRCV  JRNRCV(&ODLBNM/&ODOBNM) DLTOPT(*IGNINQMSG)
       CHGVAR     VAR(&COUNT) VALUE(&COUNT + 1)
    ENDDO

    RTVJOBA    ENDSTS(&ENDSTS)

 ENDDO

 LEAVE:
 CHGVAR     VAR(&COUNTALF) VALUE(&COUNT)

 SNDPGMMSG  MSG('Purge Journal Receivers +
                completed with' *bcat &countalf *tcat ' processed.') 

 DLTOVR     FILE(QADSPOBJ)
 MONMSG     MSGID(CPF0000)

 DLTF       FILE(QTEMP/PRGJRNRCV)
 MONMSG     MSGID(CPF0000)

 RETURN
 
 ENDPGM:    ENDPGM 

To Compile —

CRTBNDCL PGM(YOURLIB/PRGJRNCPP) SRCFILE(QCLLESRC) SRCMBR(PRGJRNCPP)

And that’s that. Hope it helps…

  • are you aware there is a command in QSYS already called DLTJRNRCV?

    while I carefully commented out the the line
    /* DLTJRNRCV JRNRCV(&ODLBNM/&ODOBNM) DLTOPT(*IGNINQMSG)*/
    in the cl pgm, the original command deleted them anyway.

    some typos in CL
    line 2 /- should be /*

    SNDPGMMSG MSG((‘Loading list of all +
    Journal Receivers in lib(‘ *TCAT &LIBRARY *TCAT ‘)’)

    remove first (

    • Hi “Da”

      This is a CL Program that wraps around the IBM-i system DLTJRNRCV command. This CL has a purpose of building a list of Journal Receivers, and then as it reads through that list it runs a DLTJRNRCV on each one.

      Sorry about the typos – copy/paste sometimes poops when pasting ‘*’ into the website. I fixed them.

      You’ve inspired me to add this code to my free CL PROGRAMMING lessons – I will update here when I’ve recorded an example lesson uploading this code and running it. Hopefully that will answer all your questions 😉

  • {"email":"Email address invalid","url":"Website address invalid","required":"Required field missing"}

    Join the IBM i Community for FREE Presentations, Lessons, Hints and Tips

    >