Admin Alert: The Pitfalls of Duplicating Data to a Test Library
October 25, 2006 Joe Hertvik
i5, iSeries, and AS/400 administrators frequently need to set up test libraries containing files that were duplicated from a live environment. While creating test environment data is not difficult, there are some pitfalls and shortcuts to the process that you should be aware of. This week, I will look at the method behind duplicating files and how you can easily maneuver files from one library to another.
The best way to illustrate i5/OS file duplication techniques is to create a sample scenario that you can modify for your own test library creation. For my situation, let’s assume that I am going to copy a file called FILE1 from a library called LIB1 to another library called LIB2. I’ll also assume that the LIB1/FILE1 file has three logical files built over it. These logical files (named FILE1L01, FILE1L02, and FILE1L03) must also be transferred to LIB2 and these new objects must be built over the newly created LIB2/FILE1 object. All objects (the physical and its associated logicals) must also contain all the same attributes as my original files, including the same authorization lists, the same number of records, and the same trigger programs that were attached to the original files.
Given this scenario, here are the steps that I would perform to insure that I can correctly transfer FILE1 and its associated logical files from one library to another.
Step One: Which Files Am I Working With?
When duplicating physical and logical files from library to library, I first need to determine the set of files that I am working with. I need to know which logical files are based on the physical file that I want to copy, so that I can produce a complete list of files to duplicate. To get a list of logical files that are based on my FILE1 physical file, I can use the Display Data Base Relations command (DSPDBR), like this:
The output of this command displays all the logical files that are dependent on my physical file. Once I get my complete list of logical files that need to be created in my new library, I also need to answer the following questions.
Once I have this information, I’m ready to start copying files.
Step Two: Duplicating Files from One Library to Another
In order to duplicate a physical file and all its associated logical files from one library to another, I can use the following Create Duplicate Object command (CRTDUPOBJ) to create an exact replica of the LIB1/FILE1 file into library LIB2.
CRTDUPOBJ OBJ(FILE1) FROMLIB(LIB1) OBJTYPE(*FILE) TOLIB(LIB2) DATA(*YES)
This command creates a duplicate LIB1/FILE1 file in LIB2. My duplicate object will contain the exact same file structure as the original file and it will also contain the exact same owner and object authorities as the original. Because I set the Duplicate Data parameter (DATA) to *YES, the LIB2 object will also contain the same records that were present in my original LIB1 file. If I had set the DATA parameter to *NO (its default), the command would have duplicated the physical file and authorities, but it would not have copied the data.
This command can also be prompted from the Work with Objects (WRKOBJ) screen. To do this, I first need to find the file by using the following WRKOBJ command:
WRKOBJ OBJ(LIB1/FILE1) OBJTYPE(*FILE)
Once the file is displayed on the WRKOBJ screen, I can enter option ‘3’ (Copy) in front of the object, press ENTER, and the command will prompt me with a CRTDUPOBJ screen where I can fill in all the parameters that I want to use when copying FILE1 to LIB2.
When duplicating a physical file and its associated logical files between libraries, I need to remember that the physical file must be copied to the new library first; otherwise I will not have a base file in the new library upon which I can build my new logical files over. For logical files that are built over multiple physical files, I also must remember to first copy all the physical files that my logical files are based on before I attempt to copy my logicals.
Once my physical file is copied to the new library, it’s now time to copy its associated logical files over to that same library. I have two choices on how to use the CRTDUPOBJ command to do this.
First, I can individually copy each logical file to LIB2 by running separate CRTDUPOBJ commands, executing one command for each logical file object that I want to copy. Here’s what those commands would look like in my sample scenario.
CRTDUPOBJ OBJ(FILE1L01) FROMLIB(LIB1) OBJTYPE(*FILE) TOLIB(LIB2) DATA(*YES)
If my file naming structure is set up correctly, I could also duplicate the physical and all its associated logical files in one statement by running the following CRTDUPOBJ command:
CRTDUPOBJ OBJ(FILE1*) FROMLIB(LIB1) OBJTYPE(*FILE) TOLIB(LIB2) DATA(*YES)
Here I am taking advantage of CRTDUPOBJ’s ability to specify a wildcard literal in its From object parameter (OBJ). The wildcard tells CRTDUPOBJ to consecutively duplicate any object in this library whose name starts with the same basic naming structure defined by the wildcard (FILE1* in this case). When run as a wildcard, this command would first copy the FILE1 physical file to LIB2. CRTDUPOBJ would then copy any other file in the LIB1 library whose name started with the ‘FILE1’ literal, which would tell it to create duplicates of the FILE1L01, FILE1L02, and FILE1L03 logical files in LIB2. As CRTDUPOBJ created each duplicated logical file in LIB2, it would base them on the FILE1 physical file in LIB2 as long as that object already existed in the library.
The pitfall of using a wildcard to copy physical and logical files as a group is that it assumes that I have set up my file naming structure so that my physical file is chronologically listed first before my logical files (i.e. FILE1 comes before FILE1L01, FILE1L02, and FILE1L03). If that’s not the case, the wildcard scenario will not work because CRTDUPOBJ processes the wildcard files in alphabetical order, and at least some of the targeted logical files would not be created (or they could be created and based on a physical file in another library in your library list). Since physical files must always be duplicated to a new library before their associated logical files, correct wildcard file duplication is always dependent on whether your database naming convention can support how the objects will be duplicated.
Step Three: Beware of the Big Glitch
Unfortunately, the CRTDUPOBJ scenario falls apart when you are trying to duplicate one or more logical files that reside in a different library than their associated physical file. If I had a fourth logical file for LIB1/FILE1 called FILE1L04 that resided in library LIB3, CRTDUPOBJ will not be able to correctly copy FILE1L04. In this case, the newly created logical would continue to be associated with the physical file it was originally created over (LIB1), not the physical file in the library FILE1L04 is duplicated to (LIB2). This is a known issue with logical file duplication that cannot presently be solved. However, Ted Holt, the senior technical editor of this newsletter, devised a workaround that can be used for this scenario. I suggest reviewing Ted’s article if you find yourself in this situation.
Step Four: Watch Out for Trigger Programs
Another concern occurs when you try to duplicate files that have trigger programs associated with them. In this case, there are some very specific rules about what trigger program the copied physical file will be associated with.
If the target physical file and its associated trigger program are copied to the same library, the duplicated physical will always point to the new library for its trigger program, even if the trigger program does not exist in that library. So if my original FILE1 file in LIB1 pointed to a trigger program called TRIG1 (which also resides in LIB1) and I duplicated FILE1 to library LIB2 without also copying TRIG1 to LIB2, the new LIB2/FILE1 file would point to a non-existent LIB2/TRIG1 program object as its trigger program. This means the trigger could not be pulled for this file unless the trigger program is also duplicated to the new library. Once copied, the new trigger programmer will automatically be associated with the new file.
It goes easier if the trigger program and the duplicated physical file are in different libraries. In this scenario, the new physical file will still be associated with the original trigger program. This is true even if the physical file is duplicated to the same library as the trigger program.
Given these scenarios, the morale in designing your application and data libraries is to always separate your trigger programs from your data files because that allows you to more easily move data files between libraries.
The other problem with trigger programs occurs when you try to duplicate a physical file containing a trigger to the QTEMP library (i5/OS’ temporary working library for each job). According to IBM, you cannot attach a trigger program to any file in the QTEMP library, so watch out for triggers when you are duplicating a file to QTEMP.
Not Hard, But. . .
As you can see, it’s fairly easy to copy live data files to a test library by using the CRTDUPOBJ command. However, you also have to be aware of the pitfalls and plan accordingly so that all your files point to the proper objects and execute the proper trigger programs, as they need to.
About Our Testing Environment
All configurations described in this article were tested on an i5 550 box running i5/OS V5R3. Most of the commands used here are also available in earlier versions of the i5/OS and OS/400 operating systems, so the configurations should be usable in prior releases. However, you may notice minor variations in pre-V5R3 copies of these commands. These differences may be due to incremental command improvements that have occurred from release to release.