How can I solve "WER046A SORT CAPACITY EXCEEDED" in SYNCSORT JCL - mainframe

I am trying to sort a data set and writing into a new data set, Every time i am executing the job, its abending (ABEND=U0016).
message form SYSOUT.
WER276B SYSDIAG= 24646562, 29667262, 29667262, 27500165
WER164B 307,288K BYTES OF VIRTUAL STORAGE AVAILABLE, MAX REQUESTED,
WER164B 0 BYTES RESERVE REQUESTED, 307,272K BYTES USED
WER036B G=5174,B=1,BIAS=99
WER162B 75 PREALLOCATED SORTWORK TRACKS, 3,750,000 DYNAMICALLY
ALLOCATED,
WER162B 26,721,480 ACQUIRED IN 2,230 SECONDARY EXTENTS, 0 RELEASED,
TOTAL 30,471,555 TRACKS USED
WER046A SORT CAPACITY EXCEEDED
WER493I ZIIP PROCESSOR USED
WER211B SYNCSMF CALLED BY SYNCSORT; RC=0000
WER449I SYNCSORT GLOBAL DSM SUBSYSTEM ACTIVE
WER066A APROX RCD CNT 30430982
Here is my code:
//STEP50 EXEC SORTD
//SORTIN DD DSN=FILEXYZ(0),
// DISP=SHR,DCB=BUFNO=192
//SORTOUT DD DSN=FILE2XXY,
// DISP=(NEW,CATLG,DELETE),RETPD=365,VOL=(,,,99),
// DCB=(RECFM=FB,LRECL=30050,BLKSIZE=0,BUFNO=192),
// UNIT=(TAPE,2)
//SYSOUT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSIN DD *
SORT FIELDS=(19,5,PD,A,8,6,PD,A,50,2,ZD,A)
OUTREC IFTHEN=(WHEN=(70,18,CH,EQ,C' encoding="IBM037"'),
OVERLAY=(70:C' encoding="UTF-8"'))
OPTION DYNALLOC=(SYSDA,255)
/*
Here is code from SORTD from the jcl:
4 //STEP40 EXEC SORTD
5 XXSORTD PROC CYLS=1,SYSFICH='*',
XX DMPCLAS='1,DEST=ABNORMAL'
XX*
XX* REMOVED SEP PARAMETER 89/07/20
XX*
6 XXSORTD EXEC PGM=SORT
7 //SYSOUT DD SYSOUT=*
X/SYSOUT DD SYSOUT=&SYSFICH
IEFC653I SUBSTITUTION JCL - SYSOUT=*
8 XXSORTWK01 DD DSN=&WORK1,SPACE=(CYL,(&CYLS)),UNIT=SORTWORK
IEFC653I SUBSTITUTION JCL - DSN=&WORK1,SPACE=(CYL,
(1)),UNIT=SORTWORK
9 XXSORTWK02 DD DSN=&WORK2,SPACE=(CYL,(&CYLS)),UNIT=SORTWORK
IEFC653I SUBSTITUTION JCL - DSN=&WORK2,SPACE=(CYL,
(1)),UNIT=SORTWORK
10 XXSORTWK03 DD DSN=&WORK3,SPACE=(CYL,(&CYLS)),UNIT=SORTWORK
IEFC653I SUBSTITUTION JCL - DSN=&WORK3,SPACE=(CYL,
(1)),UNIT=SORTWORK
11 XXSORTWK04 DD DSN=&WORK4,SPACE=(CYL,(&CYLS)),UNIT=SORTWORK
IEFC653I SUBSTITUTION JCL - DSN=&WORK4,SPACE=(CYL,
(1)),UNIT=SORTWORK
12 XXSORTWK05 DD DSN=&WORK5,SPACE=(CYL,(&CYLS)),UNIT=SORTWORK
IEFC653I SUBSTITUTION JCL - DSN=&WORK5,SPACE=(CYL,
(1)),UNIT=SORTWORK
13 XXSYSABEND DD SYSOUT=&DMPCLAS
IEFC653I SUBSTITUTION JCL - SYSOUT=1,DEST=ABNORMAL
14 XXSYSUDUMP DD SYSOUT=&DMPCLAS
IEFC653I SUBSTITUTION JCL - SYSOUT=1,DEST=ABNORMAL
15 //SORTIN DD DSN=FILEXYZ(0),
// DISP=SHR,DCB=BUFNO=192
16 //SORTOUT DD DSN=FILE2XXY,
// DISP=(NEW,PASS,DELETE),RETPD=365,VOL=(,,,99),
// DCB=(RECFM=FB,LRECL=30050,BLKSIZE=0,BUFNO=192),
// UNIT=TAPE
17 //SYSPRINT DD SYSOUT=*
18 //SYSIN DD *
Please suggest me some hints to over come this issue.
Thank you.

I'll go out-on-a-limb here and assume that the files in question here are the same as previous question with same file attributes by same OP at:
How can I reduce CPU in SORT operation
With 80,000,000 records at an LRECL of 30050, your input file is approximately 2.2TB.
A generally accepted rule-of-thumb for sort work space is 1.3x the input file size. So, you’ll need to target ~2.85TB (I.e ~3.7 million CYLS or ~55 million tracks) of sort work space.
With SyncSort’s maximum of 255 SORTWK DDs, you’ll need to acquire ~14,500 CYLs across each of the supported 255 DDs to accommodate your space requirements. This is a bit extreme, and will likely present a number of challenges, but there are a few options that could allow you to achieve this.
Disclaimer - I have not personally used SyncSort myself, but after perusing the docs, these concepts look to be consistent with other sort products that I do have experience with.
Rely on DYNALLOC
You have specified DYNALLOC=(SYSDA,255) and this is generally the recommended approach. However, there are a couple of issues with your current setup:
By using the SORTD PROC, you are robbing yourself of 5 DDs that could have been more appropriately utilized. The hardcoded SORTWK DDs in the PROC with SPACE=(CYL,(1)) limit the total work space you can acquire because DYNALLOC now only has 250 DDs to work with. As #SaggingRufus suggests, calling SYNCSORT directly would avoid the 1-CYL allocations of the PROC DDs and allow DYNALLOC to work with all 255 DDs.
SyncSort is not projecting the necessary work space accurately. Based on the output that you provided, SyncSort initially acquired 75 tracks (1 CYL for each of 5 hardcoded DDs in the SORTD proc… in other words, 5 DDs at 1 CYL * 15 Tracks-per-CYL = 75) explicitly, then dynamically acquired an additional 3,750,000 tracks (1,000 CYLs (or 15,000 tracks) * 250 DDs). It then acquired an additional 26.7 million tracks (1.78MM CYLs) across 2,230 secondary extents, which indicates an average of 799 CYLs (or 11,983 tracks) per secondary extent and an average of 8.75 secondary extents per volume/DD. All of this results in a total of ~1.6TB (~2MM Cyls) being allocated for sort work space, which is way below the estimated work space requirements for a 2.2TB input file. Even if we apply the DYNALLOC attributes to the hardcoded SORTWK DDs from the PROC, that only adds about 32GB to the total work space and is still woefully inadequate. So, as #phunsoft suggests, adding the SIZE=Ennnnnnnn parameter may be necessary for SyncSort to project work space appropriately.
Additional note - The fact that you're getting an average of <10 secondary extents per DD/volume indicates that you're exhausting the available free space on volumes in the work space pool for your environment. You should coordinate with your storage admins to ensure that enough disk space is available for your work space.
So, bypassing the PROC to provide access to all 255 DDs and providing an estimated record count could allow SyncSort to more reliably calculate the necessary work space, but this amount of data in a single sort is likely an outlier and default calculations may not be sufficient. Also, the available free space in your work space pool may be a limiting factor.
Hardcode SORTWK DDs
If you hardcode the SORTWK DDs in your JCL, you bypass the DDs in the PROC and eliminate some of the uncertainty of the DYNALLOC calculations. This is actually the approach that I, personally, would take first in this scenario… hardcode each SORTWK DD with the best possible options to acquire ~14,500 CYLS on each DD. So:
Hardcode each of 255 DDs (SORTWK01 - SORTWKFF) in job
Include SPACE=(CYL,(4000,1000)) on each DD (even though SyncSort will supposedly calculate secondary allocations itself)
Include DSNTYPE=LARGE on each DD to allow greater than 4G per volume (each SORTWK is restricted to 1 volume)
The aggregate of these DDs should provide sufficient work space for your sort requirements.
Each of the above options assume that sufficient vols/extents/overall-space are available in the work space pool for your shop. I’d recommend coordinating with your storage management team to ensure availability of resources
Use MAXSORT
SyncSort provides the MAXSORT capability to accommodate extremely large data sets. It sorts sections of an input file into intermediate files, and re-uses SORTWK space for subsequent sections, until the intermediate files for each section can be combined into a single output file. There are particular requirements for using MAXSORT. As referenced earlier, I don’t have access to SyncSort, so I can’t test this capability myself. You'll have to research the SyncSort doc yourself for the details of this capability.

Since your sort input is read from tape, sort cannot reliably calculate the sort work space needed. Try adding the SIZE=Ennnnnnn parameter to the SORT statement. nnnnnnn is the number of records to be read. E tells sort this is an estimate.

try calling SYNCSORT directly instead of calling this proc. This PROC only has 5 workfiles set up. It is usually best to let SYNCSORT allocate as may workfiles as needed rather than telling it how many it can use.
I believe it is the workfiles that have run out of space. Try this:
//SORT10 EXEC PGM=SYNCSORT,
// PARM=('INCORE=OFF,DYNALLOC=(SYSDA,255)',EQUALS)
//SORTIN DD DSN=FILEXYZ(0),
// DISP=SHR,DCB=BUFNO=192
//SORTOUT DD DSN=FILE2XXY,
// DISP=(NEW,CATLG,DELETE),RETPD=365,VOL=(,,,99),
// DCB=(RECFM=FB,LRECL=30050,BLKSIZE=0,BUFNO=192),
// UNIT=(TAPE,2)
//SYSOUT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SORTMSG DD SYSOUT=*
//SYSIN DD *
SORT FIELDS=(19,5,PD,A,8,6,PD,A,50,2,ZD,A)
OUTREC IFTHEN=(WHEN=(70,18,CH,EQ,C' encoding="IBM037"'),
OVERLAY=(70:C' encoding="UTF-8"'))
OPTION DYNALLOC=(SYSDA,255)
/*

Related

How to know what does the variable in SYSTSIN contains?

While going through a JCL job, i found the following code snippet. What does this mean? How do we know what %var2fix contains?
//JS0005 EXEC PGM=IKJEFT01
//SYSEXEC DD DSN=ISPFGRP.ICEC.ISPFEXEC,DISP=SHR
//INPUT DD DSN=PSMC.CMDS.N001(0),DISP=SHR
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSTSPRT DD SYSOUT=*
//SYSTSIN DD *
%VAR2FIX
/*
The first thing of importance is the program that is invoked by the JCL, which is IKJEFT01, which is basically TSO (TIME SHARING OPTION) via batch.
If for argument's sake the program were IEFBR14 (do nothing based upon BR 14 which is Branch to Register 14, Register 14 holding the return address). The SYSTSIN is not even opened and thus %VAR2FIX wouldn't even be looked.
Back to IKJEFT01 the ddname SYSTSIN is read as Terminal Input i.e. it's basically the command line for native TSO. As such %VAR2FIX is a command, which you could replicate by typing TSO %VAR2FIX where a command can be typed (note the vast majority of people don't directly use native TSO nowadays, rather they use a "friendlier environment" such as ISPF/PDF or Roscoe).
Now if instead of %VAR2FIX there was IEFBR14 then I could say what that meant as IEFBR14 is a well known common program that can be invoked as a command. e.g. you could do TSO IEFBR14 (remember it does nothing). Now %VAR2FIX is not a common command, in fact it is virtually definitely an in-house command.
Back to the JCL, there is a DD statement with a dd name of SYSEXEC, which, if I recall correctly, allows Rexx programs, in the respective dataset, to be run as commands. I think if you look at the dataset allocated to SYSEXEC you will find a member called VAR2FIX and it is this program/command that will be invoked. If I recall correctly the % is ignored as regards to the command name.

Passing input for COND through a file

We usually pass condition parameters in Syncsort directly through inline in SYSIN:
//SYSIN DD *
INCLUDE COND=(1,9,CH,EQ,C'000000000')
/*
For dynamic usage we could pass the parameters using "JPn" statements:
// SET XDSN=000000000
//STEP EXEC PGM=SYNCSORT, PARM='JP1"&XDSN"'
.....
//SYSIN DD *
INCLUDE COND=(1,9,CH,EQ,JP1)
/*
But could we pass the input for "conditional statements" through a file?
No.
I'm hoping but not necessarily expecting that you have a dataset name for SYSIN in Production.
There are a couple of approaches available, depending on the exact task.
Firstly, you can generate the control cards. Each time your dynamic selection changes, you re-generate the control cards. If the selection data can change by actions you don't know about in advance, you can even generate the control cards immediately before using them.
Secondly, you can look at using JOINKEYS.
For up to 10 items, your JPn approach is fine. You could even specify multiple selections per JPn (using an SS data-type for a Sub-String search in place of the CH).
If you know you are going to need more than can be reasonably expressed/maintained by the JPn solution, but you don't have a massive amount of selections, generate the control cards.
If you have a massive number of selection items, then use JOINKEYS.

How to find JCL MSGCLASS=?

I am working on a basic JCL script from the IBM publib.boulder site. Below is the JCL that simply sorts a list of characters in ascending order. The job executes just fine, but the contents of SYSIN are not printed to the job status, as is shown in the publib demonstration
Here is my code:
//SORT JOB OTIMPF01,CLASS=A,MSGCLASS=H
/*
//STEP1 EXEC PGM=SORT
//SYSIN DD * SORT FIELDS=(1,75,CH,A)
/*
//SYSOUT DD SYSOUT=*
//SYSIN DD *
NEPTUNE
PLUTO
EARTH
VENUS
MERCURY
MARS
URANUS
SATURN
JUPITER
/*
//SORTOUT DD SYSOUT=*
/*
I know that it has something to do with the MSGCLASS= statement. The sample code from publib uses MSGCLASS=H, and I was told that that is different depending on who set the option on the mainframe. My question is, how can I figure out what my mainframe's MSGCLASS is set to without having to ask anyone? Again, I just want the result of the characters sorted in ascending order to be displayed in the job status.
It should look like this...
ICE134I 0 NUMBER OF BYTES SORTED: 720
ICE180I 0 HIPERSPACE STORAGE USED = 0K BYTES
ICE188I 0 DATA SPACE STORAGE USED = 0K BYTES
ICE052I 0 END OF DFSORT
EARTH
JUPITER
MARS
MERCURY
NEPTUNE
PLUTO
SATURN
URANUS
VENUS
...Only my job status read-out does not display the characters Earth through Venus in the output of the job status.
My job status looks like this...
IEF373I STEP/STEP1 /START 2014002.1033
IEF374I STEP/STEP1 /STOP 2014002.1033 CPU 0MIN 00.00SEC SRB 0MIN 00.00SEC VIRT 212K SYS 248K EXT 8K SYS 11592K
IEF375I JOB/SORT /START 2014002.1033
IEF376I JOB/SORT /STOP 2014002.1033 CPU 0MIN 00.00SEC SRB 0MIN 00.00SEC
ICE000I 1 - CONTROL STATEMENTS FOR 5694-A01, Z/OS DFSORT V1R5 - 10:33 ON THU JAN 02, 2014 -
ICE010A 0 NO SORT OR MERGE CONTROL STATEMENT
ICE751I 0 C5-K05352 C6-Q95214 E7-K90000
ICE052I 3 END OF DFSORT
I imagine it has to do with properly setting the MSGCLASS. I have tried Googling z/OS MSGCLASS and to no surprise, it comes up with very little.
The key problem is ICE010A 0 NO SORT OR MERGE CONTROL STATEMENT. Assuming you transcribed your JCL correctly here, you typed:
//SYSIN DD * SORT FIELDS=(1,75,CH,A)
/*
In which case, you presented an empty input stream to SORT, because the SORT FIELDS=(1,75,CH,A) was treated as a comment on the DD statement.
You should have typed:
//SYSIN DD *
SORT FIELDS=(1,75,CH,A)
/*
Try ST jobname in SDSF and it will show you all the output. ST is the status of jobs and shows all the output for all jobs on the system submitted or finished.
Also if you are looking on the held queue H jobname then see what output classes for you job it shows and try changing the msgclass to one of the classes shown on the held queue. For example on my system I can see class X and H on the held queue but only see class A when I use the ST command
Indeed, you have uncovered a documentation error in the manual page you link to. However, you have also introduced an error of your own.
For your Mainframe installed SORT package (likely to be IBM's DFSORT or the competing SyncSort, but also possible the further rival CA-SORT):
//SYSIN DD whatever
Is where you put the control cards.
In the above, whatever can be *, DATA or parameters for an actual dataset.
The DDNAME for input to the SORT program you use is SORTIN:
//SORTIN DD whatever (same as above)
You accidentally made that SYSIN as well. It should be:
//SYSIN DD *
NEPTUNE
PLUTO
EARTH
VENUS
MERCURY
MARS
URANUS
SATURN
JUPITER
You should then see the output from the example in your SORTOUT spool file.
There are other DDs for when you do other things with SORT (like MERGE, JOINKEYS, OUTFIL) which can or do use differently-named DDs. It is also possible to override the standard names, but you would not be able to override them to SYSIN.
//SYSIN DD * is a bit like STDIN, but don't get carried away with the comparison. By convention, many Mainframe utilities use SYSIN for input. If a JCL-stream contains "cards" not preceded by a DDName, then a DDName of SYSIN will be automatically generated. COBOL has an ACCEPT verb for a type of input, and the default DD for this is SYSIN. However, simply including a SYSIN in the JCL for a step is no guarantee that it will be used. If the program on the EXEC does not use SYSIN, then simply including SYSIN is not going to cause data to be read from there.

Use Linux dd to copy and read file at specified location

I have destination drive which I know is partitioned in 512b sectors. I want to transfer let's say 150b file with dd to this drive at a given destination, let's say start sector 2099200, and then to read exactly the same amount of bytes as the file size (150b) from the same location sector. I tried something like this:
sudo dd if=my.txt of=/dev/sdb obs=512 seek=2099199
sudo dd if=/dev/sdb of=my.txt obs=150 count=1 ibs=512 skip=2099199
It almost works but I can't make it transfer only 150b:
1+0 records in
3+1 records out
512 bytes (512 B) copied
What is wrong and how to do what I need? May be I get it wrong and some other solution would be better, but I need to be file system independent.
From the man page:
count=BLOCKS
copy only BLOCKS input blocks
When you copy the file back from the drive, you are copying 512 bytes because you specify the input to be copied in 512 byte blocks with the ibs option and you copy one whole block with the count option. Instead, you could just specify the number of blocks you wish to copy as your ibs value:
sudo dd if=/dev/sdb of=my.txt ibs=150 count=1 skip=2099199
EDIT: As pointed out in the comments, this method would require recomputing the skip value. An alternative would be this:
sudo dd if=/dev/sdb ibs=512 count=1 skip=2099199 | dd count=150 of=my.txt

Copying sectors?

Is there a script i can use to copy some particular sectors of my Harddisk?
I actually have two partitions say A and B, on my Harddisk. Both are of same sizes. What i want is to run a program which starts copying data from the starting sector of A to the starting sector of B until the end sector of A is copied to the end sector of B.
Looking for possible solutions...
Thanks a lot
How about using dd? Following copies 1024 blocks (of 512 bytes size, which is usually a sector size) with 4096 block offset from sda to sdb partition:
dd if=/dev/sda1 of=/dev/sdb1 bs=512 count=1024 skip=4096
PS. I also suppose it should be SuperUser or rather ServerFault question.
If you want to access the hard drive directly, not via partitions, then, well, just do that. Something like
dd if=/dev/sda of=/dev/sda bs=512 count=1024 skip=XX seek=YY
should copy 1024 sectors starting at sector XX to sectors YY->YY+1024. Of course, if the sector ranges overlap, results are probably not going to be pretty.
(Personally, I wouldn't attempt this without first taking a backup of the disk, but YMMV)
I am not sure if what you are looking for is a partion copier.
If that is what you mean try clonezilla.
(it will show you what exact statement it uses so can be used to find out how to do that in a script afterwards)

Resources