Model 204
Reading the Journal with UTILJ
by Donna Goodwin
Most of you have generated an audit trail using the Audit204 utility. It is often used to check for processing information that may have occurred during a Model 204 run. You can see:
The utility program that you may not have used is UTILJ. The only experience most Model 204 users have with UTILJ is to write an end-of-file marker on the journal. But you can also run UTILJ to produce a formatted dump of journal records in microscopic detail.
When would you want to use UTILJ?
Here are two challenging questions I have gotten answering the Customer Support phone:
In such cases, it is necessary to look very closely at what was written to the journal and UTILJ is exactly what is needed.
The UTILJ utility extracts and formats all the journal information related to file updating, not available from Audit204 output.
Somebody changed the database!
Take the question, "Somebody changed the database!..." The customer and I needed to look at the roll-forward entries (Types 1-6). For OS/390 and VSE, the record layouts for these journal records are described in an installation file, MACLIB dataset in member RFOFST. In VM, use the MACLIB 204MACS command to access RFOFST.
Making atomic changes
Figure 1 is an update example using the demonstration database - find a record and change an indexed field to another value. The code in Figure 1 changes the VEHICLE USE CLASS field value from 12 to 99.
Figure 1. BEGIN IN VEHICLES FOR 1 RECORD - WHERE VEHICLE USE CLASS=12 CHANGE VEHICLE USE CLASS TO 99 END
Figure 1.
BEGIN
IN VEHICLES FOR 1 RECORD -
WHERE VEHICLE USE CLASS=12
CHANGE VEHICLE USE CLASS TO 99
END
From your basic User Language class you may remember that Model 204 writes atomic updates to the journal that are used for recovery - roll forward. The atomic updates recorded in the journal for the code in Figure 1 are:
To find these updates on the journal, you need to run UTILJ. The System Manager's Guide has instructions on how to run UTILJ using code similar to Figure 2.
Figure 2. Running a UTILJ report //UTILJ JOB ... //UTILJ EXEC PGM=UTILJ,PARM='REPORT=2,FROMTIME=085100,TOTIME=090000, X // RECTYPE=6' //CCAJRNL DD DSN=Your.M204.CCAJRNL,DISP=SHR //STEPLIB DD DSN=Your.M204.LOADLIB,DISP=SHR //CCAPRINT DD SYSOUT=*
Figure 2. Running a UTILJ report
//UTILJ JOB ...
//UTILJ EXEC PGM=UTILJ,PARM='REPORT=2,FROMTIME=085100,TOTIME=090000, X
// RECTYPE=6'
//CCAJRNL DD DSN=Your.M204.CCAJRNL,DISP=SHR
//STEPLIB DD DSN=Your.M204.LOADLIB,DISP=SHR
//CCAPRINT DD SYSOUT=*
For OS/390 sites: Use member RFOFST in the Model 204 MACLIB to interpret the output. Within the RECTYPE=6 records we find the atomic update records for the previous example, that is:
CHANGE AN A=V PAIR IN PLACE
DELETE A=V PAIR FROM INDEX
ADD A=V PAIR TO INDEX
For the three journal entries above, the UTILJ output is shown in Figure 3.
Figure 3. Sample UTILJ output 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 0000000 xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx 3 3 3 3 3 3 3 2 3 4 5 6 7 8 000020 xxxxxxxx xxxxxxxx xxxxxxxx 0000000 00260607 00170009 00000023 80000000 0128E000 00806864 00003201 FFFFCA02 * * 000020 F9F9CA02 F1F20022 *99 12* 0000000 00220606 00170009 00000023 80000000 0128E000 00806864 00003201 00FFCA02 * * 000020 F1F20022 *12* 0000000 00220605 00170009 00000023 80000000 0128E000 00806864 00003201 0000CA02 * * 000020 F9F901A8 *99*
Figure 3. Sample UTILJ output
1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
0000000 xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx
3 3 3 3 3 3 3
2 3 4 5 6 7 8
000020 xxxxxxxx xxxxxxxx xxxxxxxx
0000000 00260607 00170009 00000023 80000000 0128E000 00806864 00003201 FFFFCA02 * *
000020 F9F9CA02 F1F20022 *99 12*
0000000 00220606 00170009 00000023 80000000 0128E000 00806864 00003201 00FFCA02 * *
000020 F1F20022 *12*
0000000 00220605 00170009 00000023 80000000 0128E000 00806864 00003201 0000CA02 * *
000020 F9F901A8 *99*
All three entries have the same format at the beginning of the record. Let's examine the beginning of the first record.
In the previous table, the fieldcode X'E0000080' in decimal is 3758096512. This is the fieldcode for VEHICLE USE CLASS. Use the $LSTFLD function to determine fieldcodes. Fieldcodes are actually two bytes in Table A, but two extra flag bytes are added for journal records just prior to output.
Now let's examine the second line of each record starting with record 0607 (CHANGE AN A=V PAIR IN PLACE). The offset for an old value is variable, depending on the length of the new value. The new field value is at offset 32 and, in this case, the old value is at offset 36.
The second line is:
For the second line of record 0606 (DELETE A=V PAIR FROM INDEX), the value to be deleted from the index starts at offset 32. The second line is:
For the second line of record 0605 (ADD A=V PAIR TO INDEX), the value to be added to the index starts at offset 32. The second line is:
My journal is suddenly enormous. What is going on?
For this call the audit trail looked normal, so the customer and I decided to examine what was on the journal. By using multiple runs of UTILJ and referencing it against the audit trail, we found one update that took 1.5 minutes of a two hour run and used up 3,000 lines of a 17,000-line journal. So we investigated this update unit that was consuming 18 percent of the journal.
We found a huge number of RECTYPE=6, SUBTYPE=X'OA' records. These records store bitmaps for each segment that is updated with a FILE RECORDS statement. We found a loop of FILE RECORDS UNDER fieldname=SET1, SET2, SET3... SET3000, which was repeated several times. When the customer saw this, he easily deduced the cause of the spike in the CCAJRNL size.
Security considerations
Don't forget that access to the journal is a two-edged sword: the more users who might find data helpful, the more security might be needed from your site's security product - RACF, ACF2, Top Secret. The system administration manuals for these products can help you create access rules that limit viewing on a need to know basis, especially for CCAJRNL datasets and UTILJ module.
Conclusion
So, that's the power of UTILJ. Although challenging, it can be done and several Model 204 customers have used it to their advantage.
System 1032
Optimizing Reporting
by Tym Stegner
This article reviews some common inefficiencies found in reporting programs over the past 16 years, culled from the System 1032 Customer Support database. Apply some or all of these tips to see improved performance in your reporting procedures.
Parameter Processing
Take advantage of data validation
For interactive report processing, where the end-user answers prompts for report parameters, consider entering parameter data directly into System 1032, rather than from the command file.
When System 1032 processes parameter data, it validates values entered immediately against the data type. For example, if System 1032 is prompting for a report date, the end-user is unable to enter an invalid date.
Define variables on the command line
Many reporting jobs are designed to run in BATCH. Therefore, there is little external user interaction; report parameters are passed on the command line or obtained from other sources. Often times report parameter data is encoded into DCL symbols or logical names. Then these system items are read from within System 1032 using the tools procedures GET_SYMBOL or SHOW_LOGICAL.
Remember that you can pass data into System 1032 by defining variables on the command line. This approach eliminates calls to System 1032 tools procedures, as well as eliminating the variables that support the procedure calls. For example, to pass a text parameter into System 1032:
$! some COM file...
$! p1 = "report comment"
$!
$ if p1 .eqs. "" - !abort if no parameter
then EXIT 44
$! ...other processing...
$ S1032 var rCmt text varying -
initially " ' 'p1' ";
...
Symbol substitution is done at the DCL level, and the variable command results in a variable assignment. Note this method works extremely well for short text strings, and numeric items, as the DCL command line length is limited.
System 1032 Environmental
Suppress information messages
Cut down IO overhead of displaying the informational messages for a System 1032 procedure. Use the following SET MESSAGE command to suppress the display of messages that you really don't need to see:
Issue multitasking commands
The OPEN, VARIABLE, and LET commands are notoriously over-used within some report procedures. For corrective action, issue the commands with multiple expressions whenever possible, rather than issuing separate commands for each open or assignment.
Performing several operations in the same command reduces the number of command invocations required to do the same amount of work. For the OPEN command this approach also means that when catalogs are unavailable, the command or the procedure terminates more quickly.
Put static text into format specifiers
Some reporting procedures define any static text into a text variables. This holdover from COBOL or RPG programming under-utilizes System 1032. For greater efficiency place static text directly into format specifiers. This reduces the evaluation time required to process variables.
Explicitly declare constants
In many cases the solution to a report program problem is an unquoted text string that is recognized as an unremembered alternate name to an attribute or a variable from one of those libraries that have been opened. The general quick fix is to enclose dates and times with single quotation marks and test with double quotation marks.
I highly recommend that you explicitly declare constants. In System 1032, this is done using constant specifiers (no need to define additional variables), as described in the "Type-Coded Constants" section of the System 1032 Programmer's Reference, Module 2, pages 35ñ46.
Customize your report template
Many sites use a report command file template - inserting only the commands necessary to produce a report desired. A typical report template opens all the datasets and all the libraries. Usually a particular report job needs only a few datasets and libraries. Open only the datasets and libraries you actually need.
This cuts down the processing and resource overhead. Also, it is easier to track down which process was accessing a particular dataset, if a damage event occurs.
Consolidate query commands
Refine the selection set up front
Process only the records you actually need. Often I see simple selection criteria that locates a large set of records for a report. The selection set is later refined by data rejection code within a loop reading records for processing.
While System 1032's command structure can't be beat for ad-hoc or iterative query creation, an up-front refinement of the selection set might make a later processing loop obsolete. Checking individual records within a program loop is processing power better expended elsewhere.
Update WRITE commands
My best tip is: revise WRITE commands by moving static text in the form of constants or static variables values into the FORMAT clause. This reduces the item-expression list of the WRITE command.
Countless times I have examined reporting programs that layout an entire page using one or more WRITE commands. The WRITE command might include long lists of quoted text strings or variables containing all the page layout text. It might also include elaborate mechanisms for updating page-specific items such as page count and attribute-embedded headings.
Each item-expression in a WRITE command, causes more evaluation work for System 1032 to output the data, especially for static text as constants or in variables.
Although the PRINT and PAGE commands are usually the more efficient way to describe page layout, you can realize huge savings simply by moving the static text from the item list into a FORMAT clause. The performance improvement is because item-expressions must be evaluated; text enclosed in quotation marks in a FORMAT clause is not.
Example:
In place of:
Variable rptName text 6 init "RPT321 Variable cmpName text 20 init "BZQ Corp" >WRITE " " WRITE rptName " " cmpName - " " "Page: " $page
WRITE " "
For greater efficiency rewrite the commands as follows:
! eliminate variables completely... ! use only 1 write commando...
WRITE $page -
- ! embed static text into format... FORMAT(/ "RPT321" 15x "BZQ Corp" - 17x "Page:" i3 // - 25x "Quarterly Financial Report" / ) Modernize!
Modernize with the PRINT command
Some older report programs, especially those translated from 3GL programs, often rely on the following commands:
These report programs are perfect candidates for conversion to the PRINT and PAGE commands.
Replace the WRITE commands for titles and headings with a PRINT command that specifies explicit column titles and the layout. A PAGE command provides further layout options.
The PRINT engine itself can replace both FOR EACH RECORD DO loops and the SORT command.
You can optimize reporting programs to take advantage of available System 1032 commands by utilizing many of the preceding items.
Coming attractions
The next installment in the continuing series of articles explaining how to get the most out of System 1032 will feature an in-depth examination of the FIND command, incorporating key tables, selection sets, and the CONSIDER command.
If there are particular areas of System 1032 you want to learn about in future Optimizing... articles or other questions, please email System 1032 Customer Support at 1032_support@cca-int.com. Include the phrase CCAPRINT in your subject line. Your inquiry may form the whole or part of a future article.
Copyright © 2003 Computer Corporation of America. All right reserved. Published in the United States of America.
Contact CCA Webmaster Copyright 2008