This is the second part of the trilogy I started last week:
- Change the file's size and reuse deleted records
- Remove the deleted records from the file
- Create a program to perform both of the above
In this post I will be giving an example of how I chose to remove the deleted records from all of the files in a library.
When a record is deleted from a file its space is not available to be reused, unless the file is reusing deleted records. Over time this can result in files have a few active records and many deleted ones. This is a waste of the available storage.
The Reorganize Physical File Member command, RGZPFM, is the command that will remove the delete records from a physical file. You need to be careful when using this command. If any of the files in the library are record address files the reorganization could make it impossible to retrieve the expected records from the file, do not reorganize them.
As data is contained in members, and a file can contain more than one member I need to work at the member level, rather than at the file level. In my years of experience most applications do not use multi-member files, but there is always one or two. If I RGZPFM without giving the member's name only the first member in the file will be reorganized.
I am going to use the SQL View SYSMEMBERSTAT to provide the list of files and members in any library. If you are on a system that is using a release that does not have SYSMEMBERSTAT, the view SYSPARTITIONSTAT can be used instead. I believe that the columns I will be using have the same names in both Views.
In this example I am going to same files I used in the previous post. Below is a statement I can use to see how many deleted records each of these files contain:
01 SELECT A.SYSTEM_TABLE_NAME,A.SYSTEM_TABLE_MEMBER, 02 A.NUMBER_ROWS,A.NUMBER_DELETED_ROWS 03 FROM QSYS2.SYSMEMBERSTAT A, QSYS2.SYSFILES B 04 WHERE (A.SYSTEM_TABLE_SCHEMA,A.SYSTEM_TABLE_NAME) = 05 (B.SYSTEM_TABLE_SCHEMA,B.SYSTEM_TABLE_NAME) 06 AND A.SYSTEM_TABLE_SCHEMA = 'MYLIB' 07 AND B.NATIVE_TYPE = 'PHYSICAL' 08 AND B.FILE_TYPE = 'DATA' 09 AND NUMBER_DELETED_ROWS > 0 10 ORDER BY 1,2 |
Lines 1 and 2: I think the column names explain what data is contained within them.
Line 3: I need data from both SYSMEMBERSTAT and SYSFILES. I need to use SYSFILES to identify the file type. I cannot reorganize logical files, and I do not want to reorganize source files.
Lines 4 and 5: This is "shortcut" method for giving the files to join Views together. I prefer this method doing it rather than the "long handed" way shown below:
WHERE A.SYSTEM_TABLE_SCHEMA = B.SYSTEM_TABLE_SCHEMA
AND A.SYSTEM_TABLE_NAME = B.SYSTEM_TABLE_NAME
|
Line 6: I am only interested in reorganizing the files in my library.
Lines 7 and 8: These are the columns in SYSFILES that allow me to identify what is a physical file, line 7, and that it is a data file, line 8.
Line 9: I only want to find files with deleted records within them.
Line 10: I want the results sorted by file and member name.
The results are:
SYSTEM_ SYSTEM_ NUMBER_ TABLE_ TABLE_ NUMBER DELETED NAME MEMBER _ROWS _ROWS --------- --------- ------ ------- TESTFILE1 TESTFILE1 5000 5000 TESTFILE2 TESTFILE2 6667 3333 TESTFILE3 TESTFILE3 7500 2500 TESTFILE4 TESTFILE4 1 9999 |
As I mentioned before I will be using the RGZPFM command to perform the reorganization of the files. The basic syntax of the command I will be using is:
RGZPFM FILE( < library name > / < file name > ) MBR( < member name > ) +
RBDACCPTH(*OPTIMIZE))
|
Like I did when I changed the files I am going to use the QCMDEXC scalar function to execute the CL command:
01 SELECT QSYS2.QCMDEXC('RGZPFM FILE(' || A.SYSTEM_TABLE_SCHEMA || '/' || A.SYSTEM_TABLE_NAME ||
02 ') MBR(' || A.SYSTEM_TABLE_MEMBER || ') RBDACCPTH(*OPTIMIZE)'),
03 ('RGZPFM FILE(' || A.SYSTEM_TABLE_SCHEMA || '/' || A.SYSTEM_TABLE_NAME ||
04 ') MBR(' || A.SYSTEM_TABLE_MEMBER || ') RBDACCPTH(*OPTIMIZE)')
05 FROM QSYS2.SYSMEMBERSTAT A, QSYS2.SYSFILES B
06 WHERE (A.SYSTEM_TABLE_SCHEMA,A.SYSTEM_TABLE_NAME) =
07 (B.SYSTEM_TABLE_SCHEMA,B.SYSTEM_TABLE_NAME)
08 AND A.SYSTEM_TABLE_SCHEMA = 'MYLIB'
09 AND B.NATIVE_TYPE = 'PHYSICAL'
10 AND B.FILE_TYPE = 'DATA'
11 AND NUMBER_DELETED_ROWS > 0
12 ORDER BY NUMBER_DELETED_ROWS DESC
|
Lines 1 and 2: The QCMDEXC scalar function contains the CL command RGZPFM. I am sure you all know by now that the double pipe symbol ( || ) is the equivalent of concatenate. This scalar function returns one of two values:
- 1 = This command successfully completed
- -1 = The command failed
Lines 3 and 4: I want to show the command that was executed.
Lines 5 – 11: This is the same as the previous SQL statement.
Line 12: I want to sort the results from the file with the most deleted records first and descending to ones with the least. Why? If I only have a limited amount of time I would add the following to this statement:
13 LIMIT 1000 |
And this statement would only reorganize the "worst" 1,000 files. The rest would be left for another day.
The results are:
00001 00002
----- ------------------------------------------------------------------
1 RGZPFM FILE(RPGPGM1/TESTFILE4) MBR(TESTFILE4) RBDACCPTH(*OPTIMIZE)
1 RGZPFM FILE(RPGPGM1/TESTFILE1) MBR(TESTFILE1) RBDACCPTH(*OPTIMIZE)
1 RGZPFM FILE(RPGPGM1/TESTFILE2) MBR(TESTFILE2) RBDACCPTH(*OPTIMIZE)
1 RGZPFM FILE(RPGPGM1/TESTFILE3) MBR(TESTFILE3) RBDACCPTH(*OPTIMIZE)
|
All of the files were successfully reorganized.
The common reason for failing to be reorganized is the file is in use by another job.
To verify that none of my files contain delete records I can take the first SQL statement I showed and modify it:
01 SELECT A.SYSTEM_TABLE_NAME,A.SYSTEM_TABLE_MEMBER, 02 A.NUMBER_ROWS,A.NUMBER_DELETED_ROWS 03 FROM QSYS2.SYSMEMBERSTAT A, QSYS2.SYSFILES B 04 WHERE (A.SYSTEM_TABLE_SCHEMA,A.SYSTEM_TABLE_NAME) = 05 (B.SYSTEM_TABLE_SCHEMA,B.SYSTEM_TABLE_NAME) 06 AND A.SYSTEM_TABLE_SCHEMA = 'MYLIB' 07 AND B.NATIVE_TYPE = 'PHYSICAL' 08 AND B.FILE_TYPE = 'DATA' 09 ORDER BY 1,2 |
The only difference between this and the first one is that I needed to remove the line that checked if there were more than zero delete records. As this files have all be reorganized all the files have no deleted records:
SYSTEM_ SYSTEM_ NUMBER_ TABLE_ TABLE_ NUMBER DELETED NAME MEMBER _ROWS _ROWS --------- --------- ------ ------- TESTFILE1 TESTFILE1 5000 0 TESTFILE2 TESTFILE2 6667 0 TESTFILE3 TESTFILE3 7500 0 TESTFILE4 TESTFILE4 1 0 |
That is the first two parts of the trilogy completed. In my next post I will show an example program, containing both statements, that can be used repeatedly.
This article was written for IBM i 7.6, and should work for some earlier releases too.




No comments:
Post a Comment
To prevent "comment spam" all comments are moderated.
Learn about this website's comments policy here.
Some people have reported that they cannot post a comment using certain computers and browsers. If this is you feel free to use the Contact Form to send me the comment and I will post it for you, please include the title of the post so I know which one to post the comment to.