Les cookies nous permettent de vous proposer nos services plus facilement. En utilisant nos services, vous nous donnez expressément votre accord pour exploiter ces cookies.En savoir plus OK

DB2 UDB for AS/400 Object Relational Support

DB2 UDB for AS/400 Object Relational Support

Revenir à l'accueil

 

Au format "texte" :

DB2 UDB for AS/400 Object Relational Support Jarek Miszczyk, Bronach Bromley, Mark Endrei Skip Marchesani, Deepak Pai, Barry Thorn International Technical Support Organization SG24-5409-00 www.redbooks.ibm.com International Technical Support Organization SG24-5409-00 DB2 UDB for AS/400 Object Relational Support February 2000 © Copyright International Business Machines Corporation 2000. All rights reserved. Note to U.S Government Users - Documentation related to restricted rights - Use, duplication or disclosure is subject to restrictions set forth in GSA ADP Schedule Contract with IBM Corp. First Edition (February 2000) This edition applies to Version 4 Release 4 of the Operating System/400 (5769-SS1). Comments may be addressed to: IBM Corporation, International Technical Support Organization Dept. JLU Building 107-2 3605 Highway 52N Rochester, Minnesota 55901-7829 When you send information to IBM, you grant IBM a non-exclusive right to use or distribute the information in any way it believes appropriate without incurring any obligation to you. Before using this information and the product it supports, be sure to read the general information in Appendix B, “Special notices” on page 229. Take Note! iii Contents Figures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . vii Preface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xi The team that wrote this redbook . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xi Comments welcome . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xii Chapter 1. Introduction. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1 1.1 Why we need complex objects on an AS/400 system . . . . . . . . . . . . . . . . .1 1.2 Using complex objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2 Chapter 2. Large object support in DB2 UDB for AS/400 . . . . . . . . . . . . . . .3 2.1 A need for large objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3 2.2 What is an LOB?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4 2.3 Using LOBs with SQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5 2.3.1 Creating a table with LOB data types . . . . . . . . . . . . . . . . . . . . . . . . .5 2.3.2 Adding data to the CUSTOMERHUS table . . . . . . . . . . . . . . . . . . . . .7 2.4 LOB locators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .8 2.4.1 LOB locator characteristics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .8 2.4.2 LOB locator processing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .9 2.4.3 Commitment control and LOB locators . . . . . . . . . . . . . . . . . . . . . . .12 2.5 LOB file reference variable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .12 2.5.1 LOB file reference characteristics . . . . . . . . . . . . . . . . . . . . . . . . . . .13 2.5.2 LOB file reference processing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .14 2.6 Commitment control and journaling for LOBs . . . . . . . . . . . . . . . . . . . . . .18 2.7 SQL functions supporting LOBs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .19 2.7.1 Basic predicate support for LOBs . . . . . . . . . . . . . . . . . . . . . . . . . . .19 2.7.2 Column functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .21 2.7.3 Scalar functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .21 2.8 LOBs and the native interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .22 2.9 LOB column considerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .24 2.9.1 Triggers. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .25 2.9.2 Using in Net.Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .25 Chapter 3. User-defined Distinct Types (UDTs). . . . . . . . . . . . . . . . . . . . . .27 3.1 A need for user-defined types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .27 3.2 Creating distinct types. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .28 3.2.1 Creating UDT sourced from DECIMAL . . . . . . . . . . . . . . . . . . . . . . .28 3.2.2 Creating a table using UDTs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .29 3.2.3 Creating distinct types with the SQL interface . . . . . . . . . . . . . . . . . .32 3.2.4 Altering and deleting distinct types . . . . . . . . . . . . . . . . . . . . . . . . . .34 3.3 Casting for distinct types. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .34 3.3.1 Explicit casting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .35 3.3.2 Implicit casting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .38 3.3.3 Implicit casting and promotion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .40 3.3.4 Implicit casting and host variables. . . . . . . . . . . . . . . . . . . . . . . . . . .42 3.4 SQL support for distinct types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .43 3.4.1 Using predicates with UDT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .44 3.4.2 Joining on UDT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .45 3.4.3 Using a default value with UDT . . . . . . . . . . . . . . . . . . . . . . . . . . . . .47 3.5 DB2 UDB for AS/400 implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . .49 3.5.1 Native system interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .49 iv DB2 UDB for AS/400 Object Relational Support 3.5.2 Keeping track of distinct types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57 3.5.3 Database recovery. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62 Chapter 4. User Defined Functions (UDFs) . . . . . . . . . . . . . . . . . . . . . . . . 69 4.1 A need for User Defined Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69 4.2 UDF types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 4.2.1 Sourced . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 4.2.2 SQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 4.2.3 External . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71 4.3 Resolving UDF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71 4.3.1 UDF function overloading and function signature . . . . . . . . . . . . . . . 72 4.3.2 Function path and the function selection algorithm. . . . . . . . . . . . . . 72 4.3.3 Parameter matching and promotion . . . . . . . . . . . . . . . . . . . . . . . . . 74 4.3.4 The function selection algorithm . . . . . . . . . . . . . . . . . . . . . . . . . . . 76 4.4 Coding UDFs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77 4.4.1 Coding sourced UDFs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78 4.4.2 Coding SQL UDFs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85 4.4.3 Coding external UDFs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95 4.5 Function resolution and parameter promotion in UDFs . . . . . . . . . . . . . 108 4.5.1 An example of function resolution in UDFs. . . . . . . . . . . . . . . . . . . 108 4.5.2 An example of parameter promotion in UDF . . . . . . . . . . . . . . . . . 112 4.6 The system catalog for UDFs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116 4.6.1 SYSROUTINES catalog. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116 4.6.2 SYSPARMS catalog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117 4.7 Dropping UDFs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118 4.8 Saving and restoring UDFs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119 4.9 Debugging UDFs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119 4.10 Coding considerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127 Chapter 5. Programming alternatives for complex objects. . . . . . . . . . . 129 5.1 Using complex objects in Java client applications . . . . . . . . . . . . . . . . . 129 5.1.1 Getting ready to use JDBC 2.0 driver. . . . . . . . . . . . . . . . . . . . . . . 129 5.1.2 Using a Blob object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130 5.1.3 Using a Clob object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134 5.1.4 Using metadata . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137 5.2 Using complex objects in CLI or ODBC . . . . . . . . . . . . . . . . . . . . . . . . . 139 5.2.1 DB2 CLI application flow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139 5.2.2 Passing LOB to a stored procedure written in CLI . . . . . . . . . . . . . 139 5.2.3 Calling the CLI stored procedure . . . . . . . . . . . . . . . . . . . . . . . . . . 143 5.2.4 Retrieving LOBs in CLI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143 Chapter 6. DataLinks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147 6.1 A need for DataLinks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147 6.2 DataLinks components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150 6.2.1 DataLink data type. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150 6.2.2 DataLink file manager . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151 6.2.3 DataLink filter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153 6.2.4 APIs. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153 6.3 DataLinks system configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154 6.3.1 Initializing the DLFM server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156 6.3.2 DLFM configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157 6.3.3 Starting the DLFM server. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163 6.4 Using DataLinks with SQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164 6.4.1 DataLink options: General . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165 v 6.4.2 DataLink options: DB2 Universal Database for AS/400 . . . . . . . . . .167 6.4.3 Data manipulation examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .178 6.4.4 DataLink SQL scalar functions . . . . . . . . . . . . . . . . . . . . . . . . . . . .182 6.4.5 Using the DataLink in dynamic Web pages . . . . . . . . . . . . . . . . . . .183 6.4.6 Using the DataLink access control token . . . . . . . . . . . . . . . . . . . . .186 6.5 Native interface considerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .193 6.6 DataLinks management considerations . . . . . . . . . . . . . . . . . . . . . . . . . .202 6.6.1 Backup and recovery procedures . . . . . . . . . . . . . . . . . . . . . . . . . .202 6.7 Using DataLinks in a heterogeneous environment. . . . . . . . . . . . . . . . . .212 6.7.1 DataLinks Manager for Windows NT and for AIX. . . . . . . . . . . . . . .212 Appendix A. Source code listings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215 A.1 UDTLABA: Using UDTs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215 A.2 UDTLABB: Casting UDTs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216 A.3 PictCheck: External UDF. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218 A.4 ChkHdr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 220 A.5 RunGetPicture: Testing GetPicture UDF. . . . . . . . . . . . . . . . . . . . . . . . . . . . 220 A.6 Rating: External UDF using SCRATCHPAD. . . . . . . . . . . . . . . . . . . . . . . . . 221 A.7 RtvPrdNbr3: External stored procedure written in CLI . . . . . . . . . . . . . . . . . 222 Appendix B. Special notices. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 229 Appendix C. Related publications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 231 C.1 IBM Redbooks publications. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 231 C.2 IBM Redbooks collections. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 231 C.3 Other resources . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 231 C.4 Referenced Web sites. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 232 How to get IBM Redbooks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .233 IBM Redbooks fax order form. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 234 List of abbreviations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .235 Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .237 IBM Redbooks evaluation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .241 vi DB2 UDB for AS/400 Object Relational Support © Copyright IBM Corp. 2000 vii Figures 1. Pictorial demonstration of a database with large objects . . . ...............3 2. LOB types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 3. CUSTOMERHUS table . . .........................................7 4. LOB file reference variables. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 5. LOB file reference variable expanded structure. . . . . . . . . . . . . . . . . . . . . . . . 13 6. Comparing lengths of CLOB values. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 7. Using "=" predicate with CLOB values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 8. Using TRIM with CLOB values. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 9. Using "<>" predicate with CLOB values. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 10. Result of the Count function. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 11. Result of concat Customer_Number and House_Decsription . . . . . . . . . . . . . 22 12. Displaying LOB data with ISQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 13. Displaying LOB data with the DSPPFM command . . . . . . . . . . . . . . . . . . . . . 23 14. Displaying LOB column information with the DSPFFD command . . . . . . . . . . 24 15. New type dialog for distinct type MONEY . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 16. Casting functions registered in QSYS2/SYSROUTINES . . . . . . . . . . . . . . . . . 29 17. Casting function parameters registered in QSYS2/SYSPARMS . . . . . . . . . . . 29 18. New table dialog. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 19. Column type list in a new table dialog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 20. Products master table 01 properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 21. Results window for explicit cast from MONEY to DECIMAL . . . . . . . . . . . . . . 36 22. UDT not equal query results . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 23. UDT IN query results . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 24. UDT JOIN query results . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47 25. PRODMAST01 table properties with the UDT column default value . . . . . . . . 48 26. UDT column set using default value . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49 27. UDTLABC test program results . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 28. UDTLABC job log error message. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 29. UDTLABC job log additional message information . . . . . . . . . . . . . . . . . . . . . 52 30. UDTLFA display file screen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 31. UDTLABD native I/O read results . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54 32. UDTLABE native I/O results. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 33. UDTLABE job log entry with no error messages . . . . . . . . . . . . . . . . . . . . . . . 56 34. Column read-only error . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57 35. SYSTYPES catalog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58 36. SYSCOLUMNS catalog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58 37. SYSCOLUMNS catalog with SYSTYPES.SOURCE_TYPE . . . . . . . . . . . . . . 59 38. Operations Navigator view of user type objects. . . . . . . . . . . . . . . . . . . . . . . . 59 39. UDT properties dialog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60 40. Work with *SQLUDT objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60 41. File field description for the PRODMAST01 table . . . . . . . . . . . . . . . . . . . . . . 61 42. UDT cannot be dropped error window . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63 43. UDT cannot be dropped message details . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64 44. UDT not found error window . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66 45. Job log for UDT not found . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66 46. UDT error message details . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 47. SYSCOLUMNS details for PRODMAST01 table . . . . . . . . . . . . . . . . . . . . . . . 67 48. Function resolution algorithm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77 49. Opening up a Run SQL Scripts session. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79 50. The CREATE FUNCTION statement for sourced UDF . . . . . . . . . . . . . . . . . . 79 viii DB2 UDB for AS/400 Object Relational Support 51. The SUBSTR( PRDDESC, INTEGER, INTEGER ) sourced function . . . . . . . .81 52. Using the SUBSTR( PRDDESC, INTEGER, INTEGER ) function in a query . .81 53. Creating the MAX( MONEY ) sourced UDF as a column function . . . . . . . . . .82 54. Running the MAX( MONEY ) column UDF . . . . . . . . . . . . . . . . . . . . . . . . . . . .83 55. Creating the "+"( MONEY, MONEY ) sourced UDF over arithmetic operators .84 56. Using the "+"( MONEY, MONEY ) sourced UDF . . . . . . . . . . . . . . . . . . . . . . .84 57. Creating an SQL UDF using the new SQL function dialog . . . . . . . . . . . . . . . .86 58. New SQL function dialog. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .86 59. Defining the input parameters for the SQL UDF . . . . . . . . . . . . . . . . . . . . . . . .87 60. Typing in the body of the SQL UDF. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .87 61. Creating an SQL UDF with UDT parameter . . . . . . . . . . . . . . . . . . . . . . . . . . .90 62. Using SQL UDF GetDescription( PRDDESC ) in a query. . . . . . . . . . . . . . . . .91 63. Creating the GetPicture SQL UDF which returns a BLOB as a return value . .92 64. Calling the RunGetPicture. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .94 65. The result of the call to the GetPicture SQL UDF . . . . . . . . . . . . . . . . . . . . . . .94 66. Running the IsGif external UDF with the SQL parameter style. . . . . . . . . . . .102 67. Running the IsBmp external UDF with the SQL parameter style . . . . . . . . . .103 68. Creating the rating UDF with the DB2SQL parameter style . . . . . . . . . . . . . .104 69. Using the rating external function with DB2SQL parameter style . . . . . . . . . .108 70. Finding the number and name of the customer using the rating function . . . .108 71. Executing the GetDescription ( CHAR(5) ) function . . . . . . . . . . . . . . . . . . . .109 72. The query fails when it is run over the Prodmast01 table . . . . . . . . . . . . . . . .110 73. Creating the GetDescrption( SRLNUMBER ) sourced UDF . . . . . . . . . . . . . .111 74. Running the GetDescription( SRLNUMBER ) UDF. . . . . . . . . . . . . . . . . . . . .111 75. The GetSize( CLOB(50K) )SQL UDF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .112 76. Running the GetSize( CLOB(50K ) function . . . . . . . . . . . . . . . . . . . . . . . . . .113 77. Creating the GetSize( VARCHAR(5) )SQL UDF. . . . . . . . . . . . . . . . . . . . . . .114 78. Running the GetSize( VARCHAR(5) ) SQL UDF . . . . . . . . . . . . . . . . . . . . . .115 79. Creating the GetSize( CHAR(5) ) SQL UDF . . . . . . . . . . . . . . . . . . . . . . . . . .115 80. Running the GetSize( CHAR(5) ) function. . . . . . . . . . . . . . . . . . . . . . . . . . . .116 81. Content of SYSROUTINES catalog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .117 82. UDF parameter details in SYSPARMS catalog. . . . . . . . . . . . . . . . . . . . . . . .118 83. The Work with Active Jobs screen listing all currently active jobs. . . . . . . . . .120 84. Working with the job in Session B. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .121 85. Adding a breakpoint to the debug session . . . . . . . . . . . . . . . . . . . . . . . . . . .122 86. Invoking the IsGif( PICTURE ) external UDF . . . . . . . . . . . . . . . . . . . . . . . . .123 87. Debugging the PICTCHECK service program . . . . . . . . . . . . . . . . . . . . . . . .124 88. Checking the value of the program variables using the F11 key . . . . . . . . . .125 89. Displaying the information in pointer variables using the EVAL command. . .126 90. Displaying the contents of a variable in hexadecimal format . . . . . . . . . . . . .127 91. Using Java to display DB2 UDB for AS/400 BLOBs . . . . . . . . . . . . . . . . . . . .132 92. Large objects in tables: The LOB approach . . . . . . . . . . . . . . . . . . . . . . . . . .148 93. Large objects in tables: The DataLink approach. . . . . . . . . . . . . . . . . . . . . . .149 94. DataLinks components summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .150 95. Inserting a column of data type DataLink . . . . . . . . . . . . . . . . . . . . . . . . . . . .151 96. DLFM objects in library QDLFM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .152 97. Distributed heterogeneous DLFM environment . . . . . . . . . . . . . . . . . . . . . . .153 98. Adding the TCP/IP server name . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .154 99. Adding the IP server name: IP address already configured . . . . . . . . . . . . . .155 100.Adding the relational database directory entry (WRKRDBDIRE) . . . . . . . . . .155 101.Initializing the DLFM tables (INZDLFM) . . . . . . . . . . . . . . . . . . . . . . . . . . . . .156 102.ADDPFXDLFM command prompt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .158 103.ADDHDBDLFM command prompt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .160 ix 104.Table DFM_DBID in QDLFM library: Viewed with Operations Navigator . . . 162 105.Table DFM_FILE in QDLFM library: Viewed with Operations Navigator. . . . 162 106.Table DFM_PRFX in QDLFM library: Viewed with Operations Navigator. . . 162 107.Starting the DLFM server jobs. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163 108.DLFM server jobs in Operations Navigator . . . . . . . . . . . . . . . . . . . . . . . . . . 164 109.DLFM server jobs in subsystem QSYSWRK. . . . . . . . . . . . . . . . . . . . . . . . . 164 110.New table dialog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167 111.Inserting a DataLink column . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168 112.Create table: DataLink column display . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169 113.Create table: DataLink column link control Read FS/Write FS . . . . . . . . . . . 170 114.Create table: DataLink column link control Read DB/Write Blocked . . . . . . . 171 115.File ownership: Before linking . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172 116.File ownership: After linking. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173 117.Summary of DB2 Universal Database for AS/400 link control options . . . . . 174 118.DataLink column with read permission DB/Write permission blocked . . . . . 175 119.DataLink column with read permission FS/Write permission FS. . . . . . . . . . 175 120.Create table with DataLinks: SQL (Mode DB2Options). . . . . . . . . . . . . . . . . 176 121.Detailed journal entry: DataLink row insert . . . . . . . . . . . . . . . . . . . . . . . . . . 177 122.DSPFFD output for a table with a DataLink column . . . . . . . . . . . . . . . . . . . 178 123.Insert with DLVALUE DataLink scalar function . . . . . . . . . . . . . . . . . . . . . . . 178 124.DLVALUE function overloading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179 125.Table with empty DataLink column . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179 126.Update with DLVALUE DataLink scalar function. . . . . . . . . . . . . . . . . . . . . . 180 127.Order by on DataLink column . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181 128.DataLink SQL scalar functions script. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182 129.Result set from the DLURLCOMPLETE scalar function . . . . . . . . . . . . . . . . 182 130.Result set from the DLURLPATH scalar function . . . . . . . . . . . . . . . . . . . . . 183 131.Result set from the DLURLPATHONLY scalar function . . . . . . . . . . . . . . . . 183 132.Result sets from DLURLSCHEME and DLURLSERVER scalar functions . . 183 133.Using linked image files in HTML pages . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186 134.Executing program READPM02: Direct file operations on boot1.jpg. . . . . . . 187 135.Executing program READPM02: Read of boot1.jpg with control token. . . . . 188 136.Executing program READPM03: Direct file operations on boot4.jpg. . . . . . . 192 137.Access control token: Dynamic generation . . . . . . . . . . . . . . . . . . . . . . . . . . 193 138.Table SPORTS for native tests . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194 139.Table with DataLink input to RPG program: Error . . . . . . . . . . . . . . . . . . . . . 198 140.Table with DataLink input to RPG program: Recovery . . . . . . . . . . . . . . . . . 198 141.Script for save/restore exercise: Restore table before file. . . . . . . . . . . . . . . 203 142.DSPFD of table: Link pending status after file restore. . . . . . . . . . . . . . . . . . 204 143.WRKPFDL TEAMXX/SAVETABLE: Link pending . . . . . . . . . . . . . . . . . . . . . 205 144.DataLink file attributes for TEAMXX/SAVETABLE . . . . . . . . . . . . . . . . . . . . 205 145.Delete from table in link pending status: Error message . . . . . . . . . . . . . . . . 206 146.WRKPFDL TEAMXX/SAVETABLE: Link pending after file restore . . . . . . . . 206 147.EDTDLFA display: Status LNKPND . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207 148.EDTDLFA display: Status READY. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 208 149.EDTDLFA display: Links reconciled . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 208 150.DSPFD of TEAMXX/SAVETABLE: Link pending status after reconciliation . 209 151.WRKPFDL TEAMXX/SAVETABLE: After link reconciliation . . . . . . . . . . . . . 210 152.DSPFD of TEAMXX/SAVETABLE: Link pending status after table restore. . 211 153.WRKPFDL TEAMXX/SAVETABLE: No link pending. . . . . . . . . . . . . . . . . . . 211 154.The IBM heterogeneous DataLink server environment . . . . . . . . . . . . . . . . . 212 155.DataLink environment for Windows NT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214 156.DataLink environment for AIX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214 x DB2 UDB for AS/400 Object Relational Support © Copyright IBM Corp. 2000 xi Preface Learn to efficiently use Universal Database (UDB) functions provided by the AS/400 database using the suggestions, guidelines, and examples in this redbook.This redbook is intended for programmers, analysts, and database administrators. It specifically focuses on the need to take the database applications beyond traditional numeric and character data to images, video, voice, and complex documents. By reading this redbook, you gain a broad understanding of DB2 UDB for AS/400 implementation that you can use for building a new generation of multimedia and Web-enabled database applications. This redbook contains information that you may not find anywhere else and includes detailed coverage of the following topics: • Large objects support • LOB locators and LOB file reference variable processing • User Defined Types (UDTs) • User Defined Functions (UDFs) • DataLinks It also documents how the Universal Database enhancements support the object-oriented paradigms of data encapsulation and function overloading. This redbook reports a wide range of code examples developed in several programming languages (SQL, C, Java) using different interfaces (JDBC, CLI). Prior to reading this book, you should be familiar with SQL and object-oriented programming concepts. The team that wrote this redbook This redbook was produced by a team of specialists from around the world working at the International Technical Support Organization, Rochester Center. Jarek Miszczyk is an International Technical Support Organization Specialist at the ITSO Rochester Center. He writes extensively and teaches IBM classes worldwide in all areas of DB2 UDB for AS/400. Before joining the ITSO more than two years ago, he worked in IBM Poland as a Systems Engineer. He has over 12 years experience in the computer field. His areas of expertise include cross-platform database programming, SQL, and Object Oriented programming. Bronach Bromley is the Technical Advisor for the Database and Languages team within the UK AS/400 Support Center. She has 16 years of experience in the IT field. She holds a degree in Business Information Technology from Bournemouth University. Her areas of expertise include databases, DB2/400, UDB2, SQL, and C++. She has written extensively on Large Complex Objects. Mark Endrei is a Senior IT Architect in Australia. He has 10 years of experience in the application development and maintenance field. He holds a bachelor's degree in Computer Systems Engineering from Royal Melbourne Institute of Technology, and an MBA (Technology Management) from Deakin University/APESMA. His areas of expertise include C++, midrange systems, and DBMS. xii DB2 UDB for AS/400 Object Relational Support Skip Marchesani retired from IBM in June of 1993 after a successful 25-year career. He is recognized by many as the leading industry expert on DB2 for AS/400. Skip is now a consultant with Custom Systems Corp, an independent consulting firm in Newton, NJ. In the past two years, he has spent much of his time teaching a variety of AS/400 topics, including Year 2000, Notes/Domino, and DB2 for AS/400. Skip spent much of his IBM career working with the Rochester Lab on projects for S/38 and AS/400 and was involved with the development of the AS/400 system. Skip is a frequent speaker for various AS/400 Technical Conferences, COMMON, and local user groups in the United States and worldwide. Deepak Pai is a software engineer in India. He holds a degree in computer science from B.M.S College of Engineering, Bangalore India. His areas of expertise include database programming using ILE C/400 and SQL/400, client/server architecture, and native programming using COBOL/400 and RPG/400. He has written extensively on database programming in DB2/400. Barry Thorn is a Consultant IT Specialist in IBM United Kingdom providing technical support to EMEA. He has 29 years of IT experience in IBM, including 11 years with AS/400. His areas of expertise include Business Intelligence and database. He has written papers and presentations and runs classes on AS/400 Business Intelligence and data warehouse implementation. Thanks to the following people for their invaluable contributions to this project: Mark Anderson Rob Bestgen Russ Bruhnke John Edwards Jim Flanagan Kent Milligan Cliff Nock Tony Poirier IBM Rochester Comments welcome Your comments are important to us! We want our Redbooks to be as helpful as possible. Please send us your comments about this or other Redbooks in one of the following ways: • Fax the evaluation form found in “IBM Redbooks evaluation” on page 241 to the fax number shown on the form. • Use the online evaluation form found at http://www.redbooks.ibm.com/ • Send your comments in an Internet note to redbook@us.ibm.com © Copyright IBM Corp. 2000 1 Chapter 1. Introduction Object-oriented programming is rapidly gaining acceptance because it can reduce the cost and time required to build complex applications. During the last several years, a new generation of database systems, called object-relational systems, appeared in the marketplace. The object-relational database systems combine a high-level query language (SQL) and multiple views of data, which provides the ability to define new data types and functions for storage and manipulation of complex objects. With V4R4 enhancements, IBM Rochester has set a clear direction for the product to evolve toward support for the object-oriented paradigm. The new database functions that were made available on the AS/400 include Large Binary Objects (LOBs), User Defined Types (UDTs), and User Defined Functions (UDFs). We sometimes refer to these functions as a complex object support. UDTs are data types that you define. UDTs, such as built-in types, can be used to describe the data that is stored in columns of tables. UDFs are functions that you define. UDFs, such as built-in functions or operators, support the manipulation of UDT instances. Therefore, UDT instances are stored in columns of tables and manipulated by UDFs in SQL queries. UDTs can be internally represented in different ways. LOBs are just one example of this. 1.1 Why we need complex objects on an AS/400 system The IT industry is undergoing very rapid changes, stimulated by the dramatic growth of Internet-based businesses. The applications used on the Internet face fundamentally different challenges than traditional host-centric applications. The new paradigm of programming has been devised and implemented for the Web to cope with problems, such as demand for very high availability, scalability, and seamless integration of heterogeneous environments. This new programming model is based on the three-tier application architecture, which consists of the thin client, the dedicated application server, and the database server. To implement the three-tier architecture, the software vendors often use a new set of tools based on the Java technology (Applets, Servlets, Java Script, Enterprise Java Beans). Furthermore, the Web applications need to be easy to use and visually attractive. A typical Internet page contains a lot of multimedia content, such as graphics, audio, and video. So, how does DB2 UDB for AS/400 fit into this new programming paradigm? We believe that the complex object support available in V4R4 makes the AS/400 system an excellent choice for a robust and highly scalable database server. With the LOB and Datalinks support, you can use DB2 UDB for AS/400 as a central repository of multimedia objects. UDT and UDF support allow you to reflect the object-oriented features of a Java application directly in your database design. UDTs provide for data encapsulation, and UDFs provide for function overloading and polymorphism. 2 DB2 UDB for AS/400 Object Relational Support 1.2 Using complex objects Generally, the DB2 UDB for AS/400 supports complex objects only through an SQL interface. On the AS/400 system, there are many different ways to work with the SQL. You can use the following methods: • Interactive SQL in a traditional 5250 emulation • Operations Navigator GUI • Operations Navigator SQL script utility • High-level language with embedded SQL • DB2 Call Level Interface (CLI) • Native JDBC • SQLJ • Client/server through ODBC, JDBC, OLE DB The Operations Navigator provides an attractive graphical interface that allows you to perform typical database administration tasks. It allows easy access to all server administration tools, gives a clear overview of the entire database system, enables remote database management, and provides assistance for complex object manipulation. The Run SQL Scripts window lets you create, edit, run, and troubleshoot scripts of SQL statements. You can save the scripts with which you work on your PC. In this redbook, we decided to use the Operations Navigator as a primary user interface. Most of our coding examples are written in ILE C with embedded SQL and Java language. We assume that the Client Access Express with the Operation Navigator Interface is installed on your workstation. Refer to AS/400 Client Access Express for Windows: Implementing V4R4M0, SG24-5191, for more details on how to install this product. © Copyright IBM Corp. 2000 3 Chapter 2. Large object support in DB2 UDB for AS/400 This chapter describes: • Large Object Types, concepts, and benefits • SQL functions supporting LOBs • LOB column considerations • LOB locators, concepts, and benefits • LOB file references, concepts, and benefits 2.1 A need for large objects Today’s multimedia applications depend on the storage of many types of large data objects, such as X-ray images, large text documents, and audio messages. The data types provided by DB2 for AS/400 were not large enough to hold this amount of data, the limit being 32 KB. With Large Object support, the AS/400 database can store and manipulate data objects that are much larger than the current limits. In the V4R4 release of OS/400, this limit is extended to 15 MB, with future releases of the AS/400 providing an increase to 2 GB. Figure 1 demonstrates how large objects can be used within a database. For each video title in a repository, there is a record in the database that contains the traditional information, such as how many copies there are, the rating, the artist, and so on. With Large Object support, we can also hold the actual video recording, a picture of the video cover, and the sound track for the video. Figure 1. Pictorial demonstration of a database with large objects 4 DB2 UDB for AS/400 Object Relational Support Table 1 shows examples of the types of data that might be required to be held in a database. It also demonstrates how large some of these typical objects can become. Table 1. Average size for LOB objects The AS/400 system provides support for three Large Object data types: Binary Large Objects (BLOB), Character Large Object (CLOB), and Double Byte Large Objects (DBCLOB). This chapter discusses how we store, access, and control these new LOB data types within DB2 UDB for AS/400 databases. 2.2 What is an LOB? An LOB, put simply, is a Large Object. Currently, an LOB field holds a string of ordered bytes from zero to 15 MB in length. There is the potential in future releases of the AS/400 to increase this value up to 2 GB in length. There are three different type of LOBs, each with its own definition, behavior, functionality, and so on. Figure 2 illustrates these three LOB types. Figure 2. LOB types Object From To Bank checks 45 K - Text 30 KB per page 40 KB per page Small image 30 KB 40 KB Large image 200 KB 3 MB Color image 20 MB 40 MB Radiology image 40 MB 60 MB Video 1 GB per hour - Feature-length movie 2 GB - High-resolution video 3 GB per hour - High-resolution movie 5 GB 6 GB High-definition TV 200 MB per second - Large object support in DB2 UDB for AS/400 5 The following list contains a short description of the LOB data types supported on the AS/400 system: • Binary Large Object (BLOB) strings A Binary Large Object (BLOB) is a varying-length string with a maximum length of 15 MB. A BLOB is designed to store non-traditional data, such as pictures, voice, and mixed media. BLOBs can also store structured data for use by distinct types and user defined functions. A BLOB is considered to be a binary string. A BLOB cannot be assigned or compared with values of other data types. • Character Large Object (CLOB) strings A Character Large Object (CLOB) is a varying-length character string with a maximum length of 15 MB and an associated code page. A CLOB is designed to store large Single Byte Character Set (SBCS) data or mixed data, such as lengthy documents, where the data could grow beyond the limits of a regular VARCHAR data type. For example, you can store information, such as an employee resume, the script of a play, or the text of novel in a CLOB. A CLOB can be assigned to, and compared with, values of other character-string data types: CHAR and VARCHAR. • Double-byte Character Large Object (DBCLOB) strings A Double-Byte Character Large Object (DBCLOB) is a varying-length graphic string with a maximum length of 15 MB double-byte characters and an associated code page. A DBCLOB is designed to store large DBCS data, such as lengthy documents using, for example, UCS-2. A DBCLOB can be assigned to or compared with values of other double byte string data types, Graphic, and VARGRAPHIC. In this chapter, we mainly discuss and give examples of BLOBs and CLOBs. Whenever a CLOB is discussed, a DBCLOB may be substituted. 2.3 Using LOBs with SQL In this section, we document the steps required to create and insert data into a table with LOB fields. We then carry out some of the SQL functions supporting LOB data types. 2.3.1 Creating a table with LOB data types As mentioned in 1.2, “Using complex objects” on page 2, we decided to use the Operations Navigator as a primary interface to manipulate the complex objects on the AS/400 system. By doing so, we want to encourage you to have a closer look at this powerful DB2 UDB for AS/400 interface. Where applicable, we also provide the corresponding SQL statements that can be run either in the Run SQL Scripts utility or in the traditional 5250 Interactive SQL session. Any operation that combines an LOB type along with any of the other character types always returns a result that is an LOB. Refer to DB2 UDB for AS/400 SQL Reference, SC41-5612, for detailed information on casting allowed for the new data types. Note 6 DB2 UDB for AS/400 Object Relational Support The example table we are going to create is used to store information about house details. It consists of three fields: • Customer Number: A unique character data type of length 5 MB, short name CUSNUM, used to hold a reference number for a customer. • House Reference: A BLOB data type of length 1 MB, short name HUSREF, used to hold a reference number for a particular house. • House_Description: A CLOB data type of length 1 MB, short name HUSDES, used to hold a large string of text describing the house and its location in detail. LOB data types are varying length types. When declaring a column of an LOB data type, you must declare its maximum length which, at the V4R4 release, can be anywhere in the range from one byte to 15 MB. The maximum length can be declared as a single integer representing a number of bytes or as an integer followed by one of the following suffixes: • K = size value *1024, the number of kilobytes. • M = size value * 1048576, the number of megabytes The CCSID for a BLOB field is set to 65535 and, consequently, requires no CCSID conversion at I/O time. The default CCSID, for example, for a U.S. English-based system and for a CLOB field, is 37 and, therefore, may require conversion at I/O time. The default CCSID for a DBCLOB is 835 and, therefore, may require conversion at I/O time. The major steps required to create a table with LOB columns using the Create Table dialog of the Operations Navigator are outlined here: 1. Start Operations Navigator and expand the Database object by right-clicking the (+) icon next to it. 2. Select a library that should contain the new table, and right-click it. From the context menu, select New->Table. The Create New Table dialog window appears as shown in Figure 3. 3. Enter the details as shown in Figure 3. To define and then manipulate a column, which is based on one of the LOB data types, you must use one of the SQL interfaces. In other words, the new data types, are not supported by either the Data Definition Specification (DDS) or native I/O functions. Important Large object support in DB2 UDB for AS/400 7 Figure 3. CUSTOMERHUS table The corresponding SQL statement to create the CUSTOMERHUS table is shown here: create table TEAMXX/CUSTOMERRHUS (Customer_Number Char(5) not null with default, House_Ref Blob(1M) not null with default, House_Description Clob(1M) not null with default) 2.3.2 Adding data to the CUSTOMERHUS table We insert data into a table with LOB objects through the Operations Navigator Script utility. You can access this utility from the main Operations Navigator window by right-clicking the Database object and selecting Run SQL Scripts from its context menu. An example SQL syntax for inserting data into the CUSTOMERHUS table is as follows: INSERT INTO CUSTOMERHUS VALUES ('12345, BLOB(X'1234'), 'A very long text string'); Note, that in a real life application, you would probably never insert BLOB data in the way shown in this SQL statement. In 2.5, “LOB file reference variable” on page 12, we show code examples on how to use file reference variables to insert BLOB data into a table. The purpose of the above SQL statement is to illustrate important differences between LOB and CLOB data types. We use system You can run the same SQL statements in the Interactive SQL session. Note 8 DB2 UDB for AS/400 Object Relational Support supplied function BLOB to insert data of type BLOB, but we don’t use the CLOB function to insert CLOB data. The reason for this is the compatibility of data types. CLOB and VARCHAR data types are both character data. Because of this, there is no problem in mapping from VARCHAR to CLOB on an insert request. The character constant, such as "A very long text string" in the INSERT statement shown previously, is treated by DB2 UDB for AS/400 as VARCHAR, and the system knows how to implicitly convert it to CLOB. However, a BLOB value is binary data, and binary data is incompatible with character data. As a result, we are unable to automatically map from a character data type to a BLOB. The same is true for character and integer. We do not allow the insert of a character value into an integer field without first casting the character to an integer. For more information on the BLOB function, see DB2 UDB for AS/400 SQL Reference, SC41-5612. 2.4 LOB locators LOB fields can be up to 15 MB in length, which is more than the current maximum record length within the AS/400 system. This would be costly in both performance and space if we had to keep moving large objects back and forth between the database and an application. It would be more desirable to defer the actual movement of the data from the database into the application for as long as possible and, if possible, move only those portions of data that are really needed. For example, say a user wants to read an LOB value from one file and update a second file with that value. A poorer performing implementation would copy the LOB value into a separate buffer space at read time and then update the second file using this copy as the update image. A better performing implementation would be to defer any data movement until the update operation itself. Sometimes, however, it is reasonable to access LOB data without a locator. For example, if you know that you always need the data in a variable, you may materialize the LOB immediately instead of using a locator. 2.4.1 LOB locator characteristics An LOB locator is intended to refer to the data we are manipulating. Operations against the LOB Locator avoid the need for copies of the data to be held in a host variable. Conceptually, LOB locators represent a simple idea and use a small, easily managed value to refer to a much larger value. Specifically, an LOB locator is a 4-byte value stored in a host variable that a program uses to refer to an LOB value (or LOB expression) held in the database. Using an LOB locator, a program can manipulate the LOB value as if the LOB value was stored in a regular host variable An LOB locator gives read-only access to the data it addresses. It is important to understand that the LOB locator is associated with an LOB value or LOB expression, not a row or physical storage location in the database. Once a value is selected into a locator, no operation performed on the original rows or tables Large object support in DB2 UDB for AS/400 9 would have any effect on the value referenced by the locator. The value associated with the locator is constant until the unit of work ends, or the locator is explicitly freed, whichever comes first. In our example, if the user were to select the LOB value into an LOB locator rather than buffer area, we would set the locator to reference the actual data in the file rather than copying the data from the file into a buffer area. Using the LOB locator, the application program can issue subsequent database operations on the LOB value (such as applying the scalar functions SUBSTR, CONCAT, VALUE, LENGTH, doing an assignment, searching the LOB with LIKE or POSSTR, or applying UDFs against the LOB) by supplying the locator value as input. The resulting output of the locator operation, for example, the amount of data assigned to a client host variable, would then typically be a small subset of the input LOB value. An LOB locator is only a mechanism used to refer to an LOB value during a transaction. It does not persist beyond the transaction in which it was created. Also, it is not a database data type. It is never stored in the database and, as a result, cannot participate in views or check constraints. However, since a locator is a representation of an LOB type, there are SQLTYPEs for LOB locators. They can be described within an SQLDA structure that is used by FETCH, OPEN, CALL, and EXECUTE statements. The FREE LOCATOR statement releases a locator from its associated value. In a similar way, a commit or rollback operation frees all LOB locators associated with the transaction. 2.4.2 LOB locator processing An LOB locator variable is a host variable that contains the locator representing an LOB value on the application server, which can be defined in the following host languages: • C • C++ • ILE RPG • ILE COBOL • PL/I A locator variable in an SQL statement must identify an LOB locator variable described in the program according to the rules for declaring locator variables. This is always indirectly through an SQL statement, for example, in C: SQL TYPE IS BLOB_LOCATOR blobhand; SQL TYPE IS CLOB_LOCATOR clobhand; SQL TYPE IS DBCLOB_LOCATOR dbclobhand; The AS/400 JDBC driver uses locators under the covers so it is transparent to the client code. Note 10 DB2 UDB for AS/400 Object Relational Support 2.4.2.1 C example 1 using an LOB locator The example program shown in this section demonstrates how to declare an LOB locator and select a CLOB value into it. It also shows how to use the locator to substring a portion of the CLOB and display it to the screen. The numbered sections of the source code are explained in the notes following this listing. #include #include #include EXEC SQL INCLUDE SQLCA; char dummy[[ 5 ]; void main(int argc, char **argv) { /* Host variable declarations */ 1 EXEC SQL BEGIN DECLARE SECTION; SQL TYPE IS CLOB(1M) desc01; SQL TYPE IS CLOB_LOCATOR clobhand; long pos; long len; EXEC SQL END DECLARE SECTION; EXEC SQL 2 SELECT House_description INTO :clobhand FROM TEAMXX/CUSTOMERHUS WHERE CUSNUM = ('00001'); 3 EXEC SQL VALUES posstr(:clobhand, 'Description') INTO :pos; EXEC SQL VALUES char_length(:clobhand) INTO :len; EXEC SQL VALUES substr(:clobhand, :pos, :len - 105) INTO :desc01; printf( "The Description of the House Details for Customer 00001 is: \n" \ "%s\n", desc01.data); printf( "\n" \ " Hit enter key TWICE to continue and end the program \n"); getchar (); gets(dummy); exit(0); badnews: printf( "Error occured in stored procedure. SQLCODE = %5d\n", SQLCODE); gets(dummy); exit(1); } Example 1 LOB locator program notes 1. Declare host variables. The BEGIN DECLARE SECTION and END DECLARE SECTION statements delimit the host variable declarations. Host variables are prefixed with a colon (:) when referenced in an SQL statement. A CLOB locator host variable clobhand is declared. 2. Select the LOB value into the Locator clobhand host variable. A SELECT routine is used to obtain the location of the LOB field House_description, in the database to a locator host variable clobhand. 3. Use the locator host variable clobhand to substring a portion of the CLOB into another CLOB desc1. Our example 1 program was coded in ILE C with embedded SQL. The following CL commands show how to compile and bind the sample on the AS/400 system: CRTSQLCI OBJ(TEAMXX/EXAMPLE1) COMMIT(*ALL) 1 CRTPGM PGM(TEAMXX/EXAMPLE1) MODULE(TEAMXX/EXAMPLE1) Large object support in DB2 UDB for AS/400 11 CL commands note 1 For performance reasons, we use the COMMIT(*ALL) isolation level. Refer to 2.4.3, “Commitment control and LOB locators” on page 12, for more details. 2.4.2.2 C example 2 using LOB locators The following example program demonstrates how to declare two LOB locators. Select a CLOB value into one, use it to access specific data in the CLOB, and then use the other LOB to create a new record in the database. The numbered sections of the source code are explained in the notes following the listing. #include #include #include EXEC SQL INCLUDE SQLCA; char dummy[ 5 ]; void main(int argc, char **argv) { /* Host variable declarations */ 1 EXEC SQL BEGIN DECLARE SECTION; SQL TYPE IS CLOB_LOCATOR clobhand; SQL TYPE IS CLOB_LOCATOR newhand; long pos; long len; EXEC SQL END DECLARE SECTION; /* Using a CLOB Locator to access specific data in a CLOB field */ /* and using a new CLOB Locator to inset the retrieved data back */ /* into the table as a new record. */ EXEC SQL WHENEVER SQLERROR GO TO badnews; /* Select the LOB Locator for the CLOB field House_Description */ /* for Customer '00001' into 'clobhand' */ 2 EXEC SQL SELECT House_description INTO :clobhand FROM TEAMXX/CUSTOMERHUS WHERE CUSNUM = ('00001'); /* Find the word 'Description' in the CLOB and copy the word, */ /* 'Description' plus the CLOB's remaining trailing text */ /* into the value for the CLOB Locator, newhand. */ 3 EXEC SQL VALUES posstr(:clobhand, 'Description') INTO :pos; EXEC SQL VALUES char_length(:clobhand) INTO :len; EXEC SQL VALUES substr(:clobhand, :pos, :len - 105) INTO :newhand; /* Insert a new record into table CUSTOMERHUS for */ /* CUSNUM '12345', HUSREF X'4444', with a HUSDES from the */ /* value referenced by the CLOB Locator 'newhand'. */ /* INSERT into TEAMxx/CUSTOMERHUS VALUES ('12345', */ /* Blob(X'4444'), :newhand); */ 4 EXEC SQL INSERT into TEAMxx/CUSTOMERHUS VALUES ('12345', Blob(X'4444'), :newhand); /* To check that the record has been inserted we must first */ /* COMMIT the database changes i.e the INSERT. */ /* EXEC SQL COMMIT WORK; */ 5 EXEC SQL COMMIT WORK; ... badnews: ... error handling code ... } 12 DB2 UDB for AS/400 Object Relational Support Example 2 LOB locator program notes 1. Declare host variables. The BEGIN DECLARE SECTION and END DECLARE SECTION statements delimit the host variable declarations. Host variables are prefixed with a colon (:) when referenced in an SQL statement. Two CLOB locator host variables clobhand and newhand are declared. 2. Select the LOB value into the Locator clobhand host variable. A SELECT routine is used to obtain the location of the LOB field House_description in the database to a locator host variable clobhand. 3. Use the locator host variable clobhand to substring a portion of the CLOB into the data space for the CLOB Locator newhand. 4. Insert a new record into the database table with a House_description from the databases referred to by the CLOB Locator newhand, 5. Commit the SQL so that the insertion of this row could be seen through the Operations Navigator’s Quick View context menu option. Refer to 2.6, “Commitment control and journaling for LOBs” on page 18, for more details on commitment control considerations while using locators to access data. 2.4.3 Commitment control and LOB locators The commit level of *NONE is not allowed for programs using LOB locators, because DB2 UDB for AS/400 implementation requires the commitment control to cleanup the internal structures used to keep track of the locators. We recommend that you use the commit level of *ALL for programs using LOB locators if you want to achieve best performance. DB2 UDB for AS/400 doesn’t have to create a copy of the LOB data when running under this isolation level. However, the down side of using this setting is a more restricted concurrent access to the underlying tables. The following example shows how to use the SQL precompiler options to set the commitment control level of *ALL for a C program: CRTSQLCI OBJ(TEAMXX/LOBLOCLB4) COMMIT(*ALL) OUTPUT(*PRINT) DBGVIEW(*SOURCE) CRTPGM PGM(TEAMXX/LOBLOCLB4) MODULE(TEAMXX/LOBLOCLB4) 2.5 LOB file reference variable File reference variables are similar to host variables, except they are used to transfer data to and from IFS files, rather than to and from memory buffers. A file reference variable represents (rather than contains) the file, just as an LOB locator represents (rather than contains) the LOB value. Database queries, updates, and inserts may use file reference variables to store or retrieve single LOB values. For very large objects, files are natural containers. It is likely that most LOBs begin as data stored in files on the client before they are moved to the database on the server. The use of file reference variables assists in moving LOB data. Programs use file reference variables to transfer LOB data from the IFS file directly to the database engine. To carry out the movement of LOB data, the application does not have to write utility routines to read and write files using host variables. Large object support in DB2 UDB for AS/400 13 2.5.1 LOB file reference characteristics A file reference variable has a data type of BLOB, CLOB, or DBCLOB as shown in Figure 4. It is used either as the source of data (input) or as the target of data (output). The file reference variable may have a relative file name or a complete path name of the file. The file name length is specified within the application program. The data length portion of the file reference variable is unused during input. During output, the data length is set by the application requestor code to the length of the new data that is written to the file. Figure 4. LOB file reference variables Figure 5 shows an example on how the SQL precompiler expands the file reference variable into a structure containing four fields. In this example, we use a CLOB File Reference Variable myfile_txt. Figure 5. LOB file reference variable expanded structure When using file reference variables, there are different options on both input and output. You must choose an action for the file by setting the file_options field in The file referenced by the file reference variable must be accessible from (but not necessarily reside on) the system on which the program runs. For a stored procedure, this would be the server. Note SQL TYPE IS CLOB_FILE myfile_txt; struct { unsigned long name_length; /* Length of file name */ unsigned long data_length; /* Length of data in file */ unsigned long file_options; /* Denote usage of file */ char name[255]; /* Filename */ } myfile_txt; 14 DB2 UDB for AS/400 Object Relational Support the file reference variable structure. Choices for assignment to the field covering both input and output values are shown in Table 2. Table 2. File reference variable file options 2.5.1.1 CCSID and file reference variables As stated earlier, a large object of data type BLOB has a CCSID of 65535 associated with it, and no conversion is carried out on this data type. An LOB of data type CLOB can have a CCSID associated with it. If the file option CREATE is used, where the column in the table to be auctioned is a CLOB, the created file has the same CCSID as the column in the database table. For example, if a CLOB column in a table is created with CCSID of 37, which represents US English, and a file reference variable with a file option CREATE is used on that column, the resulting created file will also have a CCSID of 37. This means that the character data is stored in EBCDIC format. If you want to store a CLOB value in a file that is used by a PC application, you need to force an EBCDIC to ASCII conversion while writing the data into the file. You can achieve this by creating a dummy file in the IFS with an ASCII code page of 437 and use the file option OVERWRITE to write the new data to the file. For example, you can map an IFS directory to a network drive on your PC and use WordPad to create an empty file myfile.txt in this directory. Then, you can use the file reference variable with the file_option set to SQL_FILE_OVERWRITE to copy the CLOB column data into myfile.txt. The data is then converted on the fly from EBCDIC to ASCII by the database manager. 2.5.2 LOB file reference processing An LOB file reference variable is used for direct file input and output for an LOB, which can be defined in the following host languages: • C • C++ • ILE RPG • ILE COBOL • PL/1 Since these are not native data types, SQL extensions are used, and the precompilers generate the host language constructs necessary to represent each variable. A file reference variable represents, rather than contains, the file. Option Option value Meaning SQL_FILE_READ 2 This is a file that can be opened, read, and closed. DB2 determines the length of the data in the file (in bytes) when opening the file. DB2 then returns the length through the data_length field of the file reference variable structure. SQL_FILE_CREATE 8 This option creates a new file. Should the file already exist, an error message is returned. SQL_FILE_OVERWRITE 16 This option creates a new file if none already exist. If the file already exists, the new data overwrites the data in the file. SQL_FILE_APPEND 32 This option has the output appended to the file if it exists. Otherwise, it creates a new file. Large object support in DB2 UDB for AS/400 15 Database queries, updates, and inserts may use file references variables to store or retrieve single column values. As with all host variables, a file reference variable may have an associated indicator variable. 2.5.2.1 C example 3 using LOB file reference variables The following example demonstrates how to declare an LOB file reference variable and move data from the Integrated File System to a CLOB column in a database table using the file option READ. The numbered sections are explained in the notes that follow. /* DB2 UDB for AS/400 File Reference Test Program */ /* Use a File Reference to move data from the IFS to a column in */ /* the table USERPROGRAMS. This is using the File option Code */ /* SQL_FILE_READ. */ #include #include #include EXEC SQL INCLUDE SQLCA; char dummy[ 5 ]; void main(int argc, char **argv) { /* Host variable Declaration */ /* CLOB FILE REFERENCE host variable set up. */ /* for the File Reference txt_file. */ 1 EXEC SQL BEGIN DECLARE SECTION; SQL TYPE IS CLOB_FILE txt_file; EXEC SQL END DECLARE SECTION; EXEC SQL WHENEVER SQLERROR GO TO badnews; /*set up the txt_file variable */ 2 strcpy(txt_file.name, "/TEAMXX/Text_Files/qcsrc.txt"); txt_file.name_length = strlen(txt_file.name); txt_file.file_options = SQL_FILE_READ; /* Insert the File Reference txt_file for option Read, */ /* into the CLOB column of the USERPROGRAMS table, for */ /* a Identiy Number of 100. */ 3 EXEC SQL INSERT INTO TEAMXX/USERPROGRAMS VALUES ('100','C', :txt_file); EXEC SQL COMMIT WORK; ... badnews: ... error handling code ... } Example 3 LOB file reference variable program notes 1. Declare Host Variable. The BEGIN DECLARE SECTION and END DECLARE SECTION statements delimit the host variable declarations. Host variables are prefixed with a colon (:) when referenced in an SQL statement. A CLOB File Reference host variable txt_file is declared. 2. CLOB file reference host variable is set up. The attributes of the file reference are set up. Note: A file name without a fully declared path is, by default, placed in the user’s current directory. If the pathname does not begin with the forward slash(/) character, it is not qualified. String copy the full pathname into name, the string length of name into name_length, and the usage of file, in this case READ, into file_options. 16 DB2 UDB for AS/400 Object Relational Support 3. Insert a new record in the database table USERPROGRAMS. Insert the file reference variable txt_file for option read into the CLOB column of the database table. 2.5.2.2 C example 4 using LOB file reference variables The following example program demonstrates how to declare an LOB file reference variable and move data from the Integrated File System to a CLOB column in a database table using the file option READ. Then, manipulate the data in the LOB column via the LOB Locator, and send the manipulated data to a file in the IFS via a file reference variable. The numbered sections are explained in the notes that follow. #include #include #include EXEC SQL INCLUDE SQLCA; char dummy[ 5 ]; void main(int argc, char **argv) { 1 EXEC SQL BEGIN DECLARE SECTION; SQL TYPE IS CLOB_FILE txt_file; SQL TYPE is CLOB_FILE outtxt_file; SQL TYPE is CLOB_LOCATOR clobhand; SQL TYPE is CLOB_LOCATOR newhand; long pos; long len; EXEC SQL END DECLARE SECTION; EXEC SQL WHENEVER SQLERROR GO TO badnews; /*set up the txt_file variables */ 2 strcpy(txt_file.name, "/TEAMXX/Text_Files/lobloclab2.txt"); txt_file.name_length = strlen(txt_file.name); txt_file.file_options = SQL_FILE_READ; /* set up the outtext_file variable */ strcpy(outtxt_file.name, "/TEAMXX/Text_Files/loblab2bak.txt"); outtxt_file.name_length = strlen(outtxt_file.name); outtxt_file.file_options = SQL_FILE_OVERWRITE; /* Insert the File Reference txt_file for option Read, */ /* into the CLOB column of the USERPROGRAMS table, for */ /* a Identity Number of 999. */ 3 EXEC SQL INSERT INTO TEAMXX/USERPROGRAMS VALUES ('999','C', :txt_file); /* Select the column PRMSRC (which was created from a */ /* file reference) form USERPROGRAMS where IDNUM is */ /* equal to '999'. */ 4 EXEC SQL SELECT PRMSRC INTO :clobhand FROM TEAMXX/USERPROGRAMS WHERE IDNUM = ('999'); /* Manipulate the data using the CLOB handler, so that */ /* we find the string IBM Corp, and insert in front of */ /* it '& 2000'. When the manipulation is complete the */ /* text line should look like this : */ /* Copyright (c) 1999 & 2000 IBM Corp */ 5 EXEC SQL VALUES posstr(:clobhand, 'IBM Corp') INTO :pos; EXEC SQL VALUES char_length(:clobhand) INTO :len; EXEC SQL SET :newhand = 6 concat(substr(cast(:clobhand as clob(200k)), 1, :pos -1 ), ' & 2000 '); EXEC SQL 6 VALUES concat(cast(:newhand as clob(200k)), Large object support in DB2 UDB for AS/400 17 substr(cast(:clobhand as clob(200k)), :pos, :len - :pos)) INTO :clobhand; /* Insert the now maipulated data, via an LOB Locator */ /* into a new record in table USERPROGRAMS. */ EXEC SQL INSERT INTO TEAMXX/USERPROGRAMS VALUES ('919','C', :clobhand); printf( /* Select column PRMSRC (CLOB) from table USERPROGRAMS */ /* where IDNUM = '919', into File Reference outtxt_file */ /* That is, move the manipulated data in the CLOB to */ /* the file in the IFS system referenced by outtxt_file */ 7 EXEC SQL SELECT PRMSRC INTO :outtxt_file FROM USERPROGRAMS WHERE IDNUM = '919'; EXEC SQL COMMIT WORK; ... badnews: ... error handling code ... } Example 4 LOB file reference variable program notes 1. Declare Host Variable. The BEGIN DECLARE SECTION and END DECLARE SECTION statements delimit the host variable declarations. Host variables are prefixed with a colon (:) when referenced in an SQL statement. Two CLOB File Reference host variables txt_file and outtext_file are declared. Two CLOB LOB locators clobhand and newhand are also declared. 2. CLOB file reference host variables are set up. The attributes of the file reference are set up. String copy the full pathname of lobloclab2.txt into txt_file.name, string length of name into name_length, and the usage of file, in this case READ, into file_options. String copy the full pathname of loblab2bak.txt into outtext_file.name, string length of name into name_length, and the usage of file, in this case OVERWRITE, into file_options. 3. Create a new record in the database table USERPROGRAMS where column PRMSRC is referenced by the file reference txt_file. 4. The LOB locator clobhand is set to reference the column PRMSRC (which was created from the file reference). 5. Manipulate the data in the column via the LOB locators clobhand and newhand to add some characters before a certain point in the LOB. Put the manipulated data into the data space for LOB locator newhand. 6. Cast the locator to its underlying CLOB type. The file option OVERWRITE is used because we have a file in the IFS with a CCSID that allows us to view the contents of the file through Operations Navigator. Note 18 DB2 UDB for AS/400 Object Relational Support 7. Move the contents of the manipulated column into the file reference outtxt_file that has a file option of overwrite. We selected this file option so that we could view the resulting manipulated column in the IFS via Operations Navigator. See 2.5.1.1, “CCSID and file reference variables” on page 14, for an explanation of CCSID and file reference variable’s interfaces. 2.6 Commitment control and journaling for LOBs As you probably noticed in the coding examples discussed in the previous sections, you need to commit your changes to an LOB object before other users can get access to this object. The reason why "dirty data" is not viewable for records that hold LOB data is pretty straightforward. It is a result of the way the database returns LOB data at read time. For every other data type on the AS/400 system, a read of a record makes a copy of the data in the user's I/O buffer. However, for LOBs, the database does not return a copy of the data. DB2 UDB for AS/400 treats LOB data differently primarily because of a restriction on the amount of data that can be returned for each record. For now, the database is only able to return 32 KB of data for each record. The performance cost of changing that limit to be able to accommodate 15 MB (in the future 2 GB) of copied data was too high. Because the database returns a pointer rather than a copy of the data, it must ensure that the LOB data addressed does not change while the pointer is in use. The LOB data that is addressed in one cursor cannot be updated or deleted by another cursor. We cannot allow the holder of this address to look at LOB data that has been updated. Even if an LOB has been deleted, the disk location may be reused and end up holding other data. For security reasons, the database must ensure that the data it is addressing stays fixed while a user is looking at it. Even though we may not be running under commitment control, we need to acquire a read lock on the record (or, in a Get Multiple, the records) that we read. This cast is required since the database manager does not know the size of the locator result when it is validating the concat( ..., substr(..)) operation. First, the database manager tries to determine the result size of the substring. Because there is no size associated with any LOB Locator, and because the substring in this program uses host variables rather than constants, the database cannot assess the size of the locator operand at validation time. Consequently, it chooses the maximum LOB size. After choosing the max LOB size, the concatenation of even a single byte literal along with the substring result will result in exceeding the maximum result size limit. One way of getting around this is to cast the CLOB Locator to a CLOB of a defined length: EXEC SQL VALUES concat( substr(cast(:clobhand as clob(200k)), 1, :pos -1 ), ' & 2000 ') By doing this, the validation code is able to use 200 KB as the maximum size of the result rather than 15 MB. Note Large object support in DB2 UDB for AS/400 19 We do not escalate the lock level from *None to *Cursor Stability but, instead, simply get read locks on each record. We hold these locks until the next read request or until the cursor is closed. The bottom line is that, since we work with addresses into the data space, rather than copies of the data, we can never allow another cursor to read a record that holds LOB data without acquiring at least a read lock on that record. The following example illustrates this database behavior. We insert a new record into the CUSTOMERHUS table with the following SQL statement: INSERT INTO customerhus VALUES ('11111', BLOB(X'1111'), CLOB('This is a house description')) This statement is run under the commitment control level of *CHG. Now, we switch to another session, which runs under a commitment level of *NONE, and issue the following SQL statement: SELECT customer_number, HEX(CAST(house_ref AS BLOB(1k))) FROM customerhus Since we didn’t commit our changes in the first session, the database manager is not able to obtain the required read lock on the newly inserted record, and the SELECT statement times out with the inquiry message QRY5050 Record in use. Note, that if the CUSTOMER table had not contained LOB columns, the SELECT statement would have run to completion with uncommitted changes visible in the session run under the commitment control level of *NONE. 2.7 SQL functions supporting LOBs This section describes the basic predicates, and the most important column and scalar function that support LOB data types. For a complete list of functions that support the new data types, refer to DB2 UDB for AS/400 SQL Reference, SC41-5612. 2.7.1 Basic predicate support for LOBs The basic predicates supported are:"=", ">", "<", "¬=", "<>", "<=", "¬>", ">=", "¬<" 2.7.1.1 Comparing CLOB data When comparisons are made between CLOB data, the database runtime removes the trailing spaces first and then compares the character values. Note that the leading spaces are not trimmed. To clarify this, let’s take a closer look at the following example. From the data that we inserted into the CUSTOMERHUS table, we can see that Customer_Number 00001, 00003, and 00004 have a House_Description CLOB value, which looks the same as the example shown in Figure 6 on page 20. Notice the actual length of the House_Description column values. 20 DB2 UDB for AS/400 Object Relational Support Figure 6. Comparing lengths of CLOB values Now, let’s check how the"=" basic predicate works with CLOB values. In the Run SQL Scripts utility, run the following SQL statement: select * from customerhus where House_Description = 'Description: This is a large modern family house, situated on the edge of town.'; Note that the result set from this query, as shown in Figure 7, only contains the records for Customer_Number "00001" and "00004." Figure 7. Using "=" predicate with CLOB values You may now wonder why the row for Customer_Number "00003" is not shown in the result set. The reason for this is that the database manager first removes the trailing space from the CLOB value in row 00004 so that the values in rows 0001 and 00004 are exactly the same as the character constant used in the equal expression in the WHERE clause of our SELECT statement. The House_Description column for row 00003 still has the leading space, so it doesn’t satisfy the search condition. Now, we modify the SELECT statement to remove both trailing and leading spaces. To achieve this, we use the TRIM function as shown here: select * from customerhus where trim(House_Description) = 'Description: This is a large modern family house, situated on the edge of town.'; Figure 8 shows the results for this statement. Figure 8. Using TRIM with CLOB values As expected, this time the result set contains three rows. The next example uses the not equal predicate. In the Run SQL Script window, run the following SQL statement: select * from customerhus where House_Description <> 'Description: This is a large modern family house, situated on the edge of town.'; Large object support in DB2 UDB for AS/400 21 The results are shown in Figure 9. Figure 9. Using "<>" predicate with CLOB values Notice that Customer_Number 00003 is displayed as part of this result set. 2.7.1.2 Comparing BLOB data When comparisons are made between BLOB data types, the first comparison is of their length. Once the lengths are found to be equal, a comparison of the binary contents is made. If it is not equal, no further comparison is made. It applies the predicate to test their binary content only if the database finds out that the length of the objects is equal. For example, the following expression is evaluated as FALSE: blob(X'123456') > blob(X'1234') Because the lengths of the two BLOB objects are different, no further comparison is made. In other words, blob(X’123456’) is neither greater, nor equal, nor smaller than blob ('1234'). Because it’s different, only the '<>' predicate is evaluated as TRUE. 2.7.2 Column functions The most important column functions supporting LOBs are: COUNT() and COUNT ALL. In our example, we count the number of times a particular House Reference Number is present in the CUSTOMERHUS table using the COUNT function. Remember, we have declared the House Reference Number as data type BLOB. In the Run SQL Script window, run the following SQL statement: select count(*) as Count from CUSTOMERHUS where House_Ref = blob(X'1234'); The result set for this query is shown in Figure 10. Figure 10. Result of the Count function Again, you can see the method of comparing the LOBs at work. The database first compares the length. Then, if it is equal, it compares the binary content. 2.7.3 Scalar functions The most important scalar functions supporting LOBs are: CHAR(), CONCAT(), LENGTH(), and SUBSTR(). 22 DB2 UDB for AS/400 Object Relational Support In Figure 6 on page 20, we demonstrated how the LENGTH scalar function works. Now, we will concatenate the Customer_Number (Character 5) with the House_Description (of type CLOB) using the CONCAT function. In an operation where one of the operands is an LOB, the result from the operation is always an LOB. For example, if you added a Hex value to a BLOB, the result is always of data type BLOB. In the Run SQL Script window, run the following SQL statement, where ‘|’ represents the pipe character: select Customer_Number concat '|' concat House_Description as Concatenate from CustomerHUS The results of the query are shown in Figure 11. Figure 11. Result of concat Customer_Number and House_Decsription 2.8 LOBs and the native interface As previously stated, LOBs are not supported by either DDS or native I/O. The only interface that allows access to the new data types is SQL. However, we conducted a number of tests to identify the behavior of various traditional 5250 interfaces with tables containing LOB columns. Our tests were based on the CUSTOMERHUS table. Its definition is shown in Figure 3 on page 7. The table was created with both BLOB and CLOB columns. First, we check how the Interactive SQL utility handles LOB data: 1. Open a 5250 session, and at the command prompt, start the Interactive SQL session with the following CL command: STRSQL 2. To display the rows contained in the CUSTOMERHUS table, type the following SQL statement at the ISQL prompt: select * from customerhus The results are shown in Figure 12. Make sure that you have the DB2 Query Manager and SQL Development Kit for AS/400 (5769-ST1) license program installed on your AS/400 system. Note Large object support in DB2 UDB for AS/400 23 Figure 12. Displaying LOB data with ISQL Note, that no content for LOB objects is displayed. Instead, the ISQL shows *POINTER as the value for both BLOB and CLOB columns. We can also display the content of the CUSTOMERHUS table with the Display Physical File Member (DSPPFM) command. Again, the values for the LOB columns are displayed as *POINTER. The results are shown in Figure 13. Figure 13. Displaying LOB data with the DSPPFM command The Display File Field Description (DSPFFD) CL command has been updated in V4R4 so that it can now be used to display column-level information for a file containing LOBs. The results of running the DSPFFD command for the CUSTOMERHUS table are shown in Figure 14 on page 24. Display Data Data width . . . . . . : 94 Position to line . . . . . Shift to column . . . . . . ....+....1....+....2....+....3....+....4....+....5....+....6....+....7....+.... Customer Number House Ref Nbr House Description 00001 *POINTER *POINTER 00002 *POINTER *POINTER 00003 *POINTER *POINTER 00004 *POINTER *POINTER ******** End of data ******** Bottom F3=Exit F12=Cancel F19=Left F20=Right F21=Split Display Physical File Member File . . . . . . : CUSTO00001 Library . . . . : TEAMXX Member . . . . . : CUSTO00001 Record . . . . . : 1 Control . . . . . Column . . . . . : 1 Find . . . . . . . *...+....1....+....2....+....3....+....4....+....5....+....6....+....7....+... 00001 *POINTER *POINTER 00002 *POINTER *POINTER 00003 *POINTER *POINTER 00004 *POINTER *POINTER 24 DB2 UDB for AS/400 Object Relational Support Figure 14. Displaying LOB column information with the DSPFFD command Note, that the Buffer Length is the space needed to store the LOB column pointer value in the buffer. DB2 UDB for AS/400 uses 32 bytes to store this pointer. However, since any AS/400 pointer must be aligned on a 16-byte boundary, the buffer for the HUSREF column is 43 bytes long. 11 bytes are needed to offset from the end of the CUSNUM column buffer to the next 16-byte boundary and 32 bytes for the pointer itself. The buffer for the HUSDES column is just 32 bytes long because it’s already aligned. 2.9 LOB column considerations This section describes the restrictions that are in place on LOB columns at this time: • A single column can only be up to 15 MB (architecture to 2 GB). • LOB column is not allowed in distributed tables. • LOB column is not allowed as a key field in an index. LOBs are not allowed as key fields because of the size restriction. • Distinct, Union, and Group By on LOB fields are not supported because each of these functions require the building of an index over the fields. • LOB column is not allowed in IN predicate. • LOB column is not allowed in COUNT(DISTINCT c1). • LOB parameters are allowed in external stored procedures but not in SQL stored procedures. • There is no support for REXX with LOBs. • The following scalar functions are not supported at this time: Display Spooled File File . . . . . : QPDSPFFD Page/Line 1/26 Control . . . . . Columns 1 - 78 Find . . . . . . *...+....1....+....2....+....3....+....4....+....5....+....6....+....7....+... Field Level Information Data Field Buffer Buffer Field Column Field Type Length Length Position Usage Heading CUSNUM CHAR 5 5 1 Both Customer Num Field text . . . . . . . . . . . . . . . : Customer ID Number Alternative name . . . . . . . . . . . . : CUSTOMER_NUMBER Allows the null value Coded Character Set Identifier . . . . . : 37 HUSREF BLOB 1048576 43 6 Both House Ref Nb Field text . . . . . . . . . . . . . . . : House Reference Number Alternative name . . . . . . . . . . . . : HOUSE_REF Allocated Length . . . . . . . . . . . . : 0 Allows the null value Coded Character Set Identifier . . . . . : 65535 HUSDES CLOB 1048576 32 49 Both House Descri Field text . . . . . . . . . . . . . . . : House Description Alternative name . . . . . . . . . . . . : HOUSE_DESCRIPTION Allocated Length . . . . . . . . . . . . : 0 Allows the null value Coded Character Set Identifier . . . . . : 37 Large object support in DB2 UDB for AS/400 25 – LAND – LNOT – LOR – XOR • CHECK constraints are limited on tables with LOBs. • REUSEDLT(*YES) must be used with tables with LOB columns. 2.9.1 Triggers A file containing LOB fields cannot support triggers. The buffer images passed to trigger programs are currently unable to handle LOB data. Creating a new trigger parameter to make the LOB data available to the trigger program would present a non-SQL interface with pointers that directly address LOB data in the database file. By doing this, the database would lose control over the LOB data. Access to the LOB data should only be through the use of LOB locators. The Add Physical File Trigger (ADDPFTRG) command has been changed so that it will not allow adding a trigger to a file that contains LOB fields. 2.9.2 Using in Net.Data You can store large object files (LOBs) in DB2 databases and access them using the SQL language environment for your Web applications. The SQL language environment does not store large objects in Net.Data table processing variables (such as V1 or V2), or Net.Data table fields when a SQL query returns LOBs in a result set. Instead, when Net.Data encounters an LOB, it stores the LOB in a file that Net.Data creates. This file is in a directory specified by the HTML_PATH path configuration variable. The values of Net.Data table fields and table processing variables are set to the path of the file. Note that, in a busy Web environment, the number of files created on the fly by Net.Data may grow very rapidly and your application is responsible for cleaning up the directory on a regular basis. Therefore, we recommend that you use DataLinks, which eliminate the need to store files in directories by the SQL language environment, resulting in better performance and the use of much less system resources. Refer to Net.Data Administration and Programming Guide for OS/400, available for download from the Web at: http://www.as400.ibm.com/products/netdata/docs/doc.htm 26 DB2 UDB for AS/400 Object Relational Support © Copyright IBM Corp. 2000 27 Chapter 3. User-defined Distinct Types (UDTs) This chapter describes: • User-defined Distinct Types concepts and benefits • Creating and using distinct types • Casting of distinct types • SQL support for distinct types • Specifics on the AS/400 implementation of distinct types 3.1 A need for user-defined types DB2 UDB for AS/400 provides a range of built-in data types, which include the basic data types, such as INTEGER, DECIMAL, CHAR, plus the large object data types discussed in the previous chapters of this book (BLOB, CLOB, DBCLOB). Your database design may, however, require that you use one of the built-in data types in a specialized way. You may use, for example, DECIMAL(11,2) data type to represent amounts of money. From the database semantic point of view, it makes sense to add and subtract two amounts of money, but it probably makes no sense to multiply two amounts of money. DB2 UDB for AS/400 provides a way to declare such specialized usages of data types and the rules that go with them in a form of User-defined Distinct Type or UDT. Distinct data types are user-defined types that are derived from existing built-in types (predefined types, such as INTEGER, DECIMAL, CLOB). They share the same representation with the types they are derived from but, because they are incompatible types, they can have quite different semantics. The most important characteristics of user-defined types include: • Strong typing Strong typing insures that your UDTs behave appropriately. It guarantees that only user-defined functions defined on your UDT can be applied to instances of the UDT. • Casting Casting from a distinct type to its source types and vice versa is allowed. • Performance Distinct types are highly integrated into the database manager. Because distinct types are internally represented the same way as built-in data types, they share the same efficient code used to implement built-in functions, comparison operators, indexes, joins, and so forth, for built-in data types. Once the type check or conversion is completed, a join, for example, can be performed with no overhead. • Foundation for object-oriented extensions UDTs are the foundation for most object-oriented features. They represent the most important step towards object-oriented extensions and future support for abstract or complex data types. • Compatible with the ANSI X3H2-99 standard (better known as SQL3) 28 DB2 UDB for AS/400 Object Relational Support 3.2 Creating distinct types DB2 UDB for AS/400 supports User-defined Distinct Types only through the SQL interface. This section describes how to use Operations Navigator to: • Create User-defined Distinct Types • Create a table containing distinct type columns We also repeat the procedure using the CREATE DISTINCT TYPE SQL statement. 3.2.1 Creating UDT sourced from DECIMAL The Operations Navigator Library context menu can be used to create a new distinct type. Select the New->Type option from this menu to display the New Type dialog. This dialog allows you to set: • Type name • Description • Source data type details The source data type is the existing system data type that the distinct type is derived from. To create a new distinct type using Operations Navigator, open the Libraries folder under the Database object. Select a library from the list, and right-click it to open its context menu. Select New->Type to display the New Type dialog. Figure 15 shows the New Type dialog settings used to create a distinct type called MONEY with source data type of DECIMAL(11,2). It may be used to store and manipulate money values. Figure 15. New type dialog for distinct type MONEY Once you have entered the required details, click the OK button to create the new distinct type in the selected library. Along with the new type definition, the database manager also registers casting functions in the selected library. You can see these casting functions in the QSYS2/SYSROUTINES catalog and the casting function parameters in the QSYS2/SYSPARMS catalog. User-defined Distinct Types (UDTs) 29 Running the following SQL statement in the Operations Navigator Run SQL Script window displays the casting functions registered for the TEAMXX library: select * from qsys2/sysroutines where specific_schema = 'TEAMXX'; Having previously created the MONEY distinct type source from DECIMAL(11,2), the results window for this SQL statement query is shown in Figure 16. It shows that three casting functions were created for the MONEY distinct type. Figure 16. Casting functions registered in QSYS2/SYSROUTINES Running the following SQL statement in the Operations Navigator Run SQL Script window will display the casting parameters registered for the TEAMXX library: select * from qsys2/sysparms where specific_schema = 'TEAMXX'; The results window, shown in Figure 17, shows that two parameters were registered for each casting function. For example, the DECIMAL casting function has a MONEY IN parameter and a DECIMAL OUT (return) parameter. Figure 17. Casting function parameters registered in QSYS2/SYSPARMS The database manager has automatically registered the following casting functions: • DECIMAL(MONEY) returns DECIMAL • MONEY(DECIMAL) returns MONEY • NUMERIC(MONEY) returns NUMERIC These functions allow you to convert from the underlying built-in source types into the new distinct type and vice versa. 3.2.2 Creating a table using UDTs Having created a distinct type, it is possible to use the new type in table column definitions when creating or altering a table. To create a table using Operations Navigator, open the Libraries folder under the Database object. Select a library from the list, and right-click to open its context menu. Select New->Table to 30 DB2 UDB for AS/400 Object Relational Support display the New Table dialog. Figure 18 shows the New Table dialog settings for our example table using distinct types. Figure 18. New table dialog The purpose of our example table is to store information about the ski equipment offered in a Web warehouse. We store a GIF file with the equipment picture and a detailed, structured description of the product in the table rows. The aim is to make a Web application visually attractive and, at the same time, easy to use. Once you enter the Table name and optional Description, click the OK button to begin column definition using the New Table dialog. As shown in Figure 19, the column type drop-down list in the New Table dialog contains the available data types. The available data types include the new built-in types implemented in V4R4 (DATALINK, BLOB, CLOB, DBCLOB), other built-in types, and User-defined Distinct Types. Figure 19. Column type list in a new table dialog User-defined Distinct Types (UDTs) 31 To add a new column, click the Insert button. Type in a column name and select the required distinct type from the drop-down list of available types as shown in Figure 19. You can also set other column options, such as Short column name or not null. Table 3 shows the required column definitions of our example table. Table 3. Products Master Table 01 properties Table 4 lists the distinct types needed in our table. Table 4. Distinct type properties Refer to 3.2.3, “Creating distinct types with the SQL interface” on page 32, for the SQL DDL statements to create these distinct types. Figure 20 on page 32 shows the completed table definition for our example table. Name Type Size Default value Short column name Must contain a value Product_Number TEAMXX. SRLNUMBER PMNBR Yes Product_Name CHARACTER 25 PMNAM Yes Product_Description TEAMXX.PRDDESC PMDESC No Product_Price TEAMXX.MONEY PMPRIC Yes Product_Picture TEAMXX.PICTURE PMPICT No Type name Description Source data type PRDDESC UDT sourced from CLOB(50 K) CLOB(50 K) MONEY UDT sourced from DECIMAL(11,2) DECIMAL(11,2) PICTURE UDT sourced from BLOB(1 M) BLOB(1 M) SRLNUMBER UDT sourced from CHAR(5) CHAR(5) 32 DB2 UDB for AS/400 Object Relational Support Figure 20. Products master table 01 properties If required, constraints and triggers can also be defined for a table containing distinct types. To create the table, click the OK button. The new table object appears in the selected library in the right panel of the main Operations Navigator window. 3.2.3 Creating distinct types with the SQL interface The CREATE DISTINCT TYPE statement creates a distinct type sourced from one of the built-in data types: CREATE [DISTINCT] TYPE distinct-type-name AS source-data-type [WITH COMPARISONS] This statement allows you to: • Set the distinct type name • Select the source data type Note that the WITH COMPARISONS option is the default, so that the system generates comparison operators whether it is specified. However, we recommend that you specify it for compatibility with other DB2 products. You can add a description to the distinct type using the COMMENT ON DISTINCT TYPE statement. To run an SQL statement using Operations Navigator, right-click on the Database object under your AS/400 Connection, and select Run SQL Script. After typing in the SQL statement, either place the cursor over the statement you want to run User-defined Distinct Types (UDTs) 33 and click the Run Selected icon, or click the Run All icon to run all SQL statements. The following SQL statement creates a distinct type called money sourced from built-in type DECIMAL(11,2): create distinct type teamxx/money as decimal(11,2) with comparisons; Optionally, use the COMMENT ON DISTINCT TYPE SQL statement to add a description to the distinct type: comment on distinct type teamxx/money is 'UDT sourced from DECIMAL(11,2)'; The following SQL statements create a distinct type called prddesc sourced from built-in type CLOB(50K) and adds a description to the new type: create distinct type teamxx/prddesc as clob(50k) with comparisons; comment on distinct type teamxx/prddesc is 'UDT sourced from CLOB(50K)'; The following SQL statements create other distinct types used in our test table: CREATE DISTINCT TYPE teamxx/srlnumber AS CHAR( 5 ) WITH COMPARISONS; COMMENT ON DISTINCT TYPE teamxx/srlnumber IS 'UDT sourced from CHAR(5)'; CREATE DISTINCT TYPE teamxx/picture AS BLOB(1M) WITH COMPARISONS; COMMENT ON DISTINCT TYPE teamxx/picture IS 'UDT sourced from BLOB(1M)'; The following SQL statement creates a table called prodmast01 with five columns: create table teamxx/prodmast01( product_number for column pmnbr teamxx/srlnumber not null, product_name for column pmnam char(25) not null, product_description for column pmdesc teamxx/prddesc, product_price for column pmpric teamxx/money not null, product_picture for column pmpict teamxx/picture); The table column definitions are in the following form: column-name FOR COLUMN system-column-name data-type ... The data-type can be a built-in data type specification or a distinct type name. If the distinct type is specified without a collection name, the distinct type name is resolved by searching the collections in the SQL path. We explicitly qualified the distinct type names with the TEAMXX library name in this CREATE TABLE example. Optionally, use the COMMENT ON TABLE SQL statement to add a description to the table: comment on table teamxx/prodmast01 is 'Products Master Table 01'; The above steps use the Operations Navigator Run SQL Scripts window. The SQL statements could equally be used in a 5250 Interactive SQL session. The only change needed is to leave out the terminating semicolon. 34 DB2 UDB for AS/400 Object Relational Support 3.2.4 Altering and deleting distinct types The database manager does not allow a distinct type to be deleted if it is being used by an existing table. The dependent table must be deleted first. This may be a problem if you want to alter a distinct type without having to delete the dependent tables. If you need to alter a User-defined Distinct Type without having to delete all the dependent tables, follow these steps: 1. Use alter table to change the data type of the distinct type column to its source type. 2. Delete the distinct type. 3. Re-create the distinct type with its new attributes. 4. Use alter table to change the data type of the column back to the distinct type. A practical example may involve the product_discription column in the PRODMAST01 table, which is a distinct type prddesc sourced from clob(50k). You may want to alter the prddesc distinct type to increase its CLOB size from 50 KB to 100 KB: 1. To alter the data type of the product_description column to the source data type of the prddesc distinct clob(50k), use the following SQL statement: alter table teamxx/prodmast01 alter column product_description set data type clob(50k); 2. To drop the prddesc distinct type, use the following SQL statement: drop distinct type teamxx/prddesc; 3. To re-create the prddesc distinct type as clob(100k), use the following SQL statements: create distinct type teamxx/prddesc as clob(100k) with comparisons; comment on distinct type teamxx/prddesc is 'UDT sourced from CLOB(100K)'; 4. To alter the product_description column data type back to distinct type prddesc, enter the following SQL statement: alter table teamxx/prodmast01 alter column product_description set data type prddesc; 3.3 Casting for distinct types The strong typing characteristic of distinct types means that distinct types are not compatible with other types. Compatibility with other types can be achieved by casting. Casting allows a value of one data type to be changed to another data type. When a data type can be changed to another data type, it is castable from the source data type to the target data type. Casting functions are used to convert one data type to another. We saw in 3.2.1, “Creating UDT sourced from DECIMAL” on page 28, that the database manager automatically registers distinct type casting functions to allow casting between the distinct type and its source types. Casting can occur implicitly or explicitly. It occurs explicitly when you use casting functions to cast a data type. Casting occurs implicitly when the database manager recognizes that an automatic cast is allowed in certain situations. User-defined Distinct Types (UDTs) 35 Strong typing requires that distinct types be explicitly cast when using: • Built-in functions and operators • Basic predicate comparisons, such as "=", "<", ">", involving different types • Other predicate comparisons, such as BETWEEN, IN, LIKE Implicit casting allows some distinct type assignments without exact type matching. Implicit casting allows: • Castable constant and other type values to be assigned to distinct types • Castable distinct type values to be assigned to other types • Host variable assignments for non-SQL language access to distinct types Promotion of data types allows the database manager to consider additional data types when performing implicit casts based on the precedence of data types. 3.3.1 Explicit casting The strong typing characteristic of distinct types prevents comparisons between distinct types and other types. It is meaningless, for example, to compare APPLES with ORANGES. The strong typing characteristic also prevents distinct types from being accepted as parameters to built-in functions or operators. The built-in functions and operators are not defined for distinct types. It may be pointless to take the square root of a MONEY value, for example. Explicit casting can be used on the many occasions when you need to use built-in functions or operators with distinct types or compare distinct types with other types. Table 5 provides a summary of the various SQL elements and their compatibility with distinct types. Incompatible SQL elements require that a distinct type be explicitly cast to its source type. Table 5. UDT compatibility with various SQL elements SQL element Examples Distinct type compatible Comment Basic predicates "=", "<>", "<", ">" Yes Defined by the with comparisons default. Explicit cast only necessary if comparing a UDT with another type. Other predicates BETWEEN, IN, LIKE Yes Same as above. Expressions CASE Yes Same as above. Special case scalar functions NULLIF, COALESCE, VALUE Yes NULLIF, COALESCE, and VALUE were special cased to be allowed for UDTs. Other scalar functions LENGTH, MAX, MIN No Not defined for new type. Explicitly cast UDT or create a UDF sourced from built-in function. Column functions SUM, AVG, MIN, MAX, COUNT No Same as above. 36 DB2 UDB for AS/400 Object Relational Support The following examples demonstrate how explicit casting can be used to: • Use a built-in operator with a distinct type • Compare a distinct type with another type • Use a built-in function with a distinct type 3.3.1.1 Explicit casting UDT sourced from DECIMAL This example demonstrates why explicit casting of User-defined Distinct Types is needed and how it can be used for UDT sourced from DECIMAL. Say you want to add a 10 percent sales tax to the price of each product in a table named prodmast01. The product_price column in this table is distinct type money. Money is sourced from built-in type DECIMAL(11,2). You could try multiplying the product_price column, which is distinct type money, by the decimal constant 1.1, as follows: select product_price * 1.1 as "AFTER_TAX_PRICE" from teamxx/prodmast01; Running this SQL statement in the Operations Navigator Run SQL Script window will fail with the following message in the run history: SQL0402 - * use not valid. It fails because the multiplication operator * does not accept arguments that are User-defined Distinct Types, such as the product_price in this case. Explicit casting can be used to cast a User-defined Distinct Type to a data type that is accepted by the multiplication operator. Use the decimal casting function to cast the product_price to decimal, a type that is accepted by the multiplication operator, as follows: select decimal(product_price) * 1.1 as "AFTER_TAX_PRICE" from teamxx/prodmast01; Running this SQL statement in the Operations Navigator Run SQL Script. window will successfully display a results window as shown in Figure 21. Figure 21. Results window for explicit cast from MONEY to DECIMAL The multiplication operator can multiply two decimal values. We have explicitly cast the product_price money value to a decimal value using the decimal casting function, allowing multiplication with the decimal constant: 1.1. Arithmetic operators "*", "+", "-" No Same as above. SQL element Examples Distinct type compatible Comment User-defined Distinct Types (UDTs) 37 Notice how the value displayed in the AFTER_TAX_PRICE column in Figure 21 is not in the decimal(11,2) format of money. You could use explicit casting to cast the multiplication result back to money: select money(decimal(product_price) * 1.1) as "AFTER_TAX_PRICE" from teamxx/prodmast01; You could also use the built-in decimal function to set the required precision and scale of the decimal result: select decimal(decimal(product_price) * 1.1,11,2) as "AFTER_TAX_PRICE" from teamxx/prodmast01; You could also create a User Defined Function (UDF) to register a new '*' function that accepts money data type as input parameters. See Chapter 4, “User Defined Functions (UDFs)” on page 69, for details. Explicit casting can also be used for comparisons between a User-defined Distinct Type and another type. For example, you may want to find the number of products with a price less than $500.00. The SQL statement: select product_price from teamxx/prodmast01 where product_price < 500.00; will fail with the following message in the run history: SQL0401 - Comparison operator < operands not compatible. The less than comparison operator cannot compare distinct type value with a DECIMAL constant: 500.00. The database manager treats the constant 500.00 as DECIMAL data type. Use the money casting function to cast the decimal constant to money as follows: select product_price from teamxx/prodmast01 where product_price < money(500.00); Running this SQL statement in the Operations Navigator Run SQL Script window successfully displays a results window showing products with a price of < $500.00. The less than comparison operator can compare two money values. We have explicitly cast the decimal constant to a money value using the money casting function, therefore allowing comparison with the product_price money value. 3.3.1.2 Explicit casting UDT sourced from CLOB This example demonstrates how to use explicit casting to cast a distinct type sourced from CLOB to a data type that is accepted by the POSSTR built-in function. For example, you may want to find all the ski products in a table named PRODMAST01 that have a description containing the word moguls. The PRODUCT_DESCRIPTION column in this table is distinct type PRDDESC. PRDDESC is sourced from built-in type CLOB(50K). You could try passing the PRODUCT_DESCRIPTION column, which is distinct type PRDDESC, to the POSSTR function as follows: 38 DB2 UDB for AS/400 Object Relational Support select product_number, product_description from teamxx/prodmast01 where posstr(product_description, 'moguls') <> 0; This statement will fail with the following run history message: SQL0171 - Argument 1 of function POSSTR not valid. The PRODUCT_DESCRIPTION column is distinct type PRDDESC. The POSSTR built-in function does not accept arguments that are User-defined Distinct Types, such as the PRODUCT_DESCRIPTION in this case. Explicit casting can be used to cast a User-defined Distinct Type to a data type that is accepted by the function. Use the CLOB casting function to cast the PRODUCT_DESCRIPTION to CLOB, a type that is accepted by the POSSTR function, as follows: select product_number, product_description from teamxx/prodmast01 where posstr(clob(product_description), 'moguls') <> 0; Running this SQL statement in the Operations Navigator Run SQL Script window will successfully display a results window showing the list of products with PRODUCT_DESCRIPTION containing the word moguls. The POSSTR built-in function can search for a substring in a CLOB. By explicitly casting the PRODUCT_DESCRIPTION to CLOB using the CLOB casting function, POSSTR can be used on the PRODUCT_DESCRIPTION. Alternatively, you can create a User Defined Function that accepts the PRDDESC distinct type as an argument. The UDF could be sourced from the built-in POSSTR function. See Chapter 4, “User Defined Functions (UDFs)” on page 69, for details. 3.3.2 Implicit casting The database manager can perform implicit casting on assignments involving User-defined Distinct Types. Table 6 shows that a distinct data type is castable to its source data type. It also shows that the source data type of a distinct data type is castable to the distinct data type. Table 6. Supported casts when a distinct type is involved Data type ... Is castable to data type ... Distinct type DT Source data type of distinct type DT. Source data type of distinct type DT Distinct type DT. Distinct type DT Distinct type DT. Data type A Distinct type DT, where A is promotable to the source data type of distinct type DT (see “Implicit casting and promotion” on page 40). INTEGER Distinct type DT if the DTs source type is SMALLINT. DOUBLE Distinct type DT if the DTs source type is REAL. VARCHAR or VARGRAPHIC Distinct type DT if the DTs source type is CHAR or GRAPHIC. User-defined Distinct Types (UDTs) 39 Implicit casting occurs on assignments where a distinct type is the source or the target of an assignment with its source data type. This allows you to make assignments between a distinct type and its source type without the need for explicit casting. The following statement is an example on how implicit casting works when a distinct type is the target in an SQL assignment: update teamxx/prodmast01 set product_price = 99.999 where product_number = srlnumber('00001'); This statement assigns the DECIMAL constant 99.999 to PRODUCT_PRICE of the MONEY distinct type column. The source data type of distinct type MONEY is DECIMAL; so, DECIMAL is castable to MONEY. The database manager can, therefore, implicitly cast the DECIMAL constant on assignment to the MONEY PRODUCT_PRICE column. Note that the price assigned to product 00001 will be truncated to 99.99 using the standard numeric assignments rules, that is, extra trailing digits in the fractional part of the number are eliminated. The next statement is an example of how implicit casting works when a distinct type is the source in an SQL assignment: update teamxx/prodmast01 set product_name = srlnumber('12345') where product_number = srlnumber('00001'); Implicit casting can also occur when assigning a distinct type to a compatible built-in type. The SRLNUMBER functions casts the CHAR constant '12345' to distinct type SRLNUMBER, which is sourced from built-in type CHAR(5). The database manager performs an implicit cast when assigning a SRLNUMBER distinct type value to the PRODUCT_NAME column, which is built-in type CHAR. Table 6 shows that Distinct type DT is castable to data type Source data type of distinct type DT. The source data type of distinct type SRLNUMBER is CHAR, so, SRLNUMBER is castable to CHAR. We have seen that implicit casting can occur when a distinct type is either the source or the target in an assignment with a compatible built-in type using SQL. Implicit casting can also occur for assignments involving host variables in embedded SQL. Using the C programming language, we can declare a DECIMAL host variable named dec_price_in with an initial value of 88.88 as follows: /* host variable declaration */ decimal(11,2) dec_price_in = 88.88d; Note that a C program must include the decimal.h header file to use the decimal type: #include The following embedded SQL UPDATE statement assigns the dec_price_in host variable to the product_price column using an implicit cast from DECIMAL to distinct type MONEY: 40 DB2 UDB for AS/400 Object Relational Support /* implicit cast on assignment from decimal into money */ exec sql update prodmast01 set product_price = :dec_price_in where product_number = srlnumber('00001'); The dec_price_in host variable is implicitly cast to the target MONEY distinct type, to allow assignment to the PRODUCT_PRICE column. A DECIMAL host variable named dec_price_out is declared as follows: /* host variable declaration */ decimal(11,2) dec_price_out = 0.00d; The next embedded SQL statement uses the MONEY distinct type PRODUCT_PRICE column as the source of an assignment to the dec_price_out host variable: /* implicit cast on assignment from money into decimal */ exec sql select product_price into :dec_price_out from prodmast01 where product_number = srlnumber('00001'); The SQL SELECT statement assigns a MONEY value from the PRODUCT_PRICE column to the dec_price_out host variable using an implicit cast. See A.1, “UDTLABA: Using UDTs” on page 215, for the full source listing of the source fragments used in this section. 3.3.3 Implicit casting and promotion Promotion of source types allows additional source types to be assigned to the target distinct type. Table 7 shows the precedence that the database manager uses to promote one data type to another. As an example, Table 7 shows that the INTEGER data type can be promoted from INTEGER to DECIMAL or NUMERIC, to REAL, and to DOUBLE. This means that we can assign an INTEGER field to a MONEY distinct type field. The MONEY distinct type is sourced from DECIMAL, and INTEGER can be promoted to DECIMAL so that implicit casting can occur. Table 7. Precedence of Data Types Data type Data type precedence list (in best-to-worst order) CHAR or GRAPHIC CHAR or GRAPHIC, VARCHAR or VARGRAPHIC, CLOB or DBCLOB VARCHAR or VARGRAPHIC VARCHAR or VARGRAPHIC, CLOB or DBCLOB CLOB or DBCLOB CLOB or DBCLOB BLOB BLOB SMALLINT SMALLINT, INTEGER, DECIMAL or NUMERIC, REAL, DOUBLE INTEGER INTEGER, DECIMAL or NUMERIC, REAL, DOUBLE DECIMAL or NUMERIC DECIMAL or NUMERIC, REAL, DOUBLE REAL REAL, DOUBLE User-defined Distinct Types (UDTs) 41 Implicit casting with promotion will allow an INTEGER column to be assigned to a distinct type column sourced from DECIMAL. Consider a simple table named TABLEA with an INTEGER column named INT_COL and one row of data created using the following SQL statements: create table teamxx/tablea (int_col integer); insert into teamxx/tablea values (12); Implicit casting with promotion will allow a value from INT_COL to be assigned to a column of distinct type MONEY, where MONEY is sourced from DECIMAL(11,2). The following SQL statement selects INT_COL from the TABLEA table and assigns it to PRODUCT_PRICE to update a row in the PRODMAST01 table: update teamxx/prodmast01 set product_price = (select int_col from teamxx/tablea) where product_number = srlnumber('00001'); The PRODUCT_PRICE column is distinct type MONEY sourced from DECIMAL(11,2). The INT_COL is built-in type INTEGER. Table 7 shows that the INTEGER Data Type has DECIMAL second in its Data Type Precedence List. The INTEGER Data Type is, therefore, promotable to DECIMAL. The database manager performs this assignment by promoting INTEGER to DECIMAL and implicitly casting DECIMAL to MONEY. Now, let’s look at the Data Type Precedence List for the DECIMAL Data Type in Table 7. Notice that DECIMAL can only be promoted to REAL or DOUBLE. Promotion will not occur if attempting to assign a DECIMAL value to an INTEGER value. The promotion precedence order does not allow the reverse assignment used in our previous example. We cannot assign a MONEY distinct type column to an INTEGER column. We may try selecting PRODUCT_PRICE from the PRODMAST01 table and assigning it to INT_COL to update a row in the TABLEA table as follows: update teamxx/tablea set int_col = ( select product_price from teamxx/prodmast01 where product_number = srlnumber('00001')); DOUBLE DOUBLE DATE DATE TIME TIME TIMESTAMP TIMESTAMP DATALINK DATALINK A distinct type The same distinct type Data type Data type precedence list (in best-to-worst order) 42 DB2 UDB for AS/400 Object Relational Support Then, the following error will be returned: SQL0408 - Value for column or variable INT_COL not compatible. INTEGER cannot be promoted to DECIMAL, so, the assignment fails. The precedence order of data types does not allow reverse promotion. 3.3.4 Implicit casting and host variables Programming languages do not allow host variables to be declared with distinct types. Special rules extend implicit casting on assignment of distinct types to host variables. The source type of the distinct type must be assignable to the host variable for implicit casting to occur. The following C-program fragment declares a long integer host variable named int_price_in with an initial value of 111: /* host variable declaration */ long int_price_in = 111; /* implicit cast on assignment from long integer into money */ exec sql insert into prodmast01 (product_number, product_name, product_price) values( '00004', 'New product', :int_price_in); The embedded SQL INSERT statement inserts a row and assigns the int_price_in host variable to the PRODUCT_PRICE column. Again, the PRODUCT_PRICE column is distinct type MONEY, and MONEY is sourced from DECIMAL(11,2). The database manager performs this assignment using an implicit cast from an INTEGER type to DECIMAL. The database manager will also allow the reverse assignment of a MONEY value to a INTEGER host variable. In the next C-program fragment, a host variable array named product_rec is declared with an INTEGER field named int_price_out: /* host variable declaration */ _Packed struct { char number[5]; char name[25]; long int_price_out; } product_rec[10]; struct { short ind[3]; } product_ind[10]; /* declare and open fetch cursor */ exec sql declare c1 cursor for select product_number, product_name, product_price from prodmast01; exec sql open c1; /* implicit cast on assignment from money into long integer */ exec sql fetch c1 for 10 rows into :product_rec indicator :product_ind; We then use embedded SQL to declare and open a cursor to be used in a multiple-row fetch statement. The SQL FETCH statement will assign the PRODUCT_PRICE MONEY column to the int_price_out field in the product_rec host variable array using an implicit cast. User-defined Distinct Types (UDTs) 43 The FETCH statement sets the SQLERRD(3) field in the SQL Communication Area to the number of rows fetched. Include the SQLCA structure declaration in a C-program using the following statement: exec sql include SQLCA; The SQLERRD(3) field can then be accessed using the SQLCA structure member sqlca.sqlerrd[2]. The following for loop displays the records fetched: for (i=0; i", "<", ">", "<=", ">=", can therefore be used to compare values of the same distinct type. Basic predicates also allow distinct type columns to be used in SQL table joins and in SQL subqueries. Other predicates, such as BETWEEN and IN, cannot be used with distinct types directly, but casting functions allow use with some restrictions. The COALESCE (or VALUE), NULLIF scalar functions, and the CASE expression can be used to compare distinct type values. Assignment operations are performed during the execution of statements, such as INSERT and UPDATE. In our look at casting on assignments in 3.3, “Casting for distinct types” on page 34, we found that the source and target data types in an assignment must be compatible. Specifying a DEFAULT value when creating a table is another example where SQL can assign a value to a distinct type column. Strong typing prevents the use of functions defined for other types on distinct types. SQL distinct type operations can be extended by using User Defined Functions. See Chapter 4, “User Defined Functions (UDFs)” on page 69, for details. 3.4.1 Using predicates with UDT The basic predicates: "=", "<>", "<", ">", "<=", ">=", allow comparison of two values. The BETWEEN predicate compares a value with a range of values. The IN predicate compares a value with a set of values. Other predicates include the LIKE predicate and the NULL predicate. The values being compared by a basic predicate must be compatible. Strong typing means that distinct type values are not compatible with other types. We may attempt to compare the PRODUCT_PRICE column, which is distinct type MONEY, with a NUMERIC constant using the following SQL statement: select product_name, product_price from teamxx/prodmast01 where product_price <> 530; Then, the following error will be returned: SQL0401 - Comparison operator ¬= operands not compatible. The not equals operator <> cannot compare a MONEY value with a NUMERIC constant. As shown in 3.3.1, “Explicit casting” on page 35, explicit casting can be used to compare distinct types with other data types. We can use the MONEY casting function to cast the NUMERIC constant to distinct type MONEY as follows: select product_name, product_price from teamxx/prodmast01 where product_price <> money(530); User-defined Distinct Types (UDTs) 45 If we run this statement using the Operations Navigator Run SQL Scripts window, the query results viewer successfully displays the rows with a PRODUCT_PRICE that does not equal $530.00 as shown in Figure 22. Figure 22. UDT not equal query results As with basic predicates, the values being compared by other predicates must be compatible. The following SQL statement attempts to use the IN predicate to compare a distinct type MONEY value with a set of NUMERIC constants: select product_name, product_price from teamxx/prodmast01 where product_price in (530, 705); This statement will fail with the following message: SQL0401 - Comparison operator IN operands not compatible. The IN predicate cannot compare MONEY with NUMERIC constants. The DECIMAL casting function can be used to cast the PRODUCT_PRICE column to DECIMAL to allow comparison with a set of NUMERIC constants as follows: select product_name, product_price from teamxx/prodmast01 where decimal(product_price) in (530, 705); If we run this statement using the Operations Navigator Run SQL Scripts window, the query results viewer successfully displays the rows with PRODUCT_PRICE in 530.00 and 705.00 as shown in Figure 23. Figure 23. UDT IN query results 3.4.2 Joining on UDT User-defined Distinct Type columns can be used to join tables in an SQL statement. The system-generated distinct type comparison operator behavior is the same as for the source data type. Comparison operator behavior for distinct types cannot be customized. Note 46 DB2 UDB for AS/400 Object Relational Support For example, we may have a table called PRODMAST01 containing an inventory list of products with the columns listed in Table 3 on page 31. Another table, called ORDERDTL, contains a row for each product listed on a customer order with the columns listed in Table 8. Table 8. Order Detail table properties Both the PRODMAST01 and ORDERDTL tables have a PRODUCT_NUMBER column with data type of distinct type SRLNUMBER. We can list the ORDER_NUMBER from the ORDERDTL table with the PRODUCT_NAME from the PRODMAST01 table using the following SQL statement: select order_number, product_name from prodmast01, orderdtl where prodmast01.product_number = orderdtl.product_number; This statement performs a default inner join on the PRODMAST01 table and the ORDERDTL table with join condition, prodmast01.product_number = orderdtl.product_number. The join columns are both distinct type SRLNUMBER sourced from CHAR(5) so that the database manager can perform the join comparison. If we run this statement using the Operations Navigator Run SQL Scripts window, the query results viewer successfully displays the required list of ORDER_NUMBER versus PRODUCT_NAME as shown in Figure 24. Name Type Size Default value Short column name Must contain a value Order_Number TEAMXX. SRLNUMBER ODONBR Yes Product_Number TEAMXX. SRLNUMBER ODPNBR Yes Orderdtl_Quantity DECIMAL() 5,0 ODOQTY No Orderdtl_Item_Cost TEAMXX.MONEY ODDCST Yes Order_Abstract CLOB() 50 K ODABS Yes User-defined Distinct Types (UDTs) 47 Figure 24. UDT JOIN query results 3.4.3 Using a default value with UDT As with built-in data type columns, a default value can be specified for User-defined Distinct Type columns. A default value can be specified using the Table Properties window in Operations Navigator. To display the Table Properties window, open the Libraries folder under the Database object. Click on the required library to display its contents. Right-click the required table, and select Properties. Figure 25 on page 48 shows the Table Properties window for the table named PRODMAST01. The default value field shows that we have selected the PRODUCT_PRICE column and set its default value to: MONEY(99.99) Use casting functions when joining tables on columns that are not of the same distinct type. Note 48 DB2 UDB for AS/400 Object Relational Support Figure 25. PRODMAST01 table properties with the UDT column default value Click the OK button to update the table properties. The column default value is used when adding a new row without specifying a value for the column. You can also set the same default value using the following SQL ALTER TABLE statement: alter table teamxx/prodmast01 alter column product_price set default money(99.99); If you need to create a new table using a distinct type column default value, the following example applies: create table teamxx/prodmast01( product_number for column pmnbr teamxx/srlnumber not null, product_name for column pmnam char(25) not null, product_description for column pmdesc teamxx/prddesc, product_price for column pmpric teamxx/money not null with default money(99.99), product_picture for column pmpict teamxx/picture ); comment on table teamxx/prodmast01 is 'Products Master Table 01'; The column default value will be used when inserting a new row without specifying a value for the column: insert into teamxx/prodmast01 (product_number,product_name) values('00004','New product'); The Operations Navigator Quick View window should show that the PRODUCT_PRICE column in the new row has been assigned the default value of 99.99 as shown in Figure 26. User-defined Distinct Types (UDTs) 49 Figure 26. UDT column set using default value 3.5 DB2 UDB for AS/400 implementation In this section, we examine specifics related to the DB2 UDB for AS/400 implementation of User-defined Distinct Types. These specifics include distinct type access limitations using native I/O, keeping track of distinct types, and database recovery. Data Description Specification (DDS) does not support distinct types, so native I/O access to distinct type fields is not possible. The preferred alternative is to use embedded SQL to handle distinct type columns. Otherwise, restricted native I/O access to tables containing distinct type columns is possible using logical files or SQL views. A logical file or SQL view that excludes distinct type columns can provide read and write access to the non-distinct type columns in a table. An SQL view can also cast distinct type fields to their source type to provide read only access to a distinct type column. The AS/400 implementation of distinct types provides a number of data dictionary facilities that can be used to keep track of your distinct types. The SYSTYPES catalog contains information on all distinct types in the database. The SYSCOLUMNS catalog also contains information on all columns in the database. The AS/400 implementation creates distinct types as *SQLUDT objects. The basic Work with Objects options are available using a 5250 session. The DSPFFD CL command can also be used to display File Field Descriptions providing details, such as column definitions and distinct type source types. Dependencies exist between distinct type objects and other objects that use the distinct type, such as tables or user-defined functions. These dependencies have implications for the sequence in which you save and restore objects that use distinct types. For example, the implications of restoring a table before restoring a distinct type that it uses need to be considered. The AS/400 implementation does not log distinct types when journaling. Only the source type is logged. This is consistent with the database manager using the same internal representation for a distinct type and its source type. 3.5.1 Native system interfaces As stated in the introduction of this section, Data Description Specification (DDS) does not support distinct types, so native I/O access to distinct type fields is not possible. While the preferred alternative is to use embedded SQL to handle 50 DB2 UDB for AS/400 Object Relational Support distinct type columns, restricted native I/O access is possible using logical files or SQL views. 3.5.1.1 Creating a logical file from a table containing UDT A C program attempting to access a table (physical file) containing distinct type columns using native I/O is shown in the following source listing. The numbered lines are explained in the notes that follow the listing. #include #include #include #pragma mapinc("prodmast01","PRODMAST01(*ALL)","both","d z _P","") 1 #include "prodmast01" static char* FILE_NAME = "PRODMAST01"; int main(int argc, char** argv) { 2 TEAMXX_PRODMAST01_PRODMAST01_both_t buf; 3 _RFILE *fp; _RIOFB_T *fb; printf("\n"); printf("AS/400 DB2 UDB UDT Lab Test Program: %s\n", argv[0]); printf("\n"); 4 if ((fp = _Ropen(FILE_NAME, "rr")) == NULL) { perror("File open error"); return 0; } printf("Read all records: %s\n", FILE_NAME); printf("\n"); printf("%-25.25s\n", "PRODUCT_NAME"); 5 for ( fb = _Rreadf(fp, (void *)&buf, sizeof(buf), __NO_LOCK); fb->num_bytes == sizeof(buf); fb = _Rreadn(fp, (void *)&buf, sizeof(buf), __NO_LOCK)) { printf("%-25.25s\n", buf.PRODUCT_NAME); } 6 _Rclose(fp); return -1; } C program notes 1. Include the typedefs generated from the external AS/400 file descriptions (DDS) based on the preceding mapinc pragma. 2. Declare record file pointers needed to work with native files. These are defined in recio.h. 3. Declare a record buffer using the typedef generated from the DDS. You can compile your ILE C program with OUTPUT(*PRINT) OPTION(*SHOWUSR) to see the typedefs in your compiler listing. 4. Open existing native file for reading records, setting fp to the return record file pointer. User-defined Distinct Types (UDTs) 51 5. The for loop initializes by reading the first record from the file. It checks that the record buffer has been successfully read before each iteration, and it reads the next record at the end of each iteration, 6. Close the native file on exit. Create the bound C program using the following CL command: CRTBNDC PGM(TEAMXX/UDTLABC) SRCMBR(UDTLABC) The UDTLABC test program attempts to open the PRODMAST01 table for read using native I/O. This table contains a number of distinct type fields. If we call the program using: CALL TEAMXX/UDTLABC, the program terminates with a File open error as shown in Figure 27. Figure 27. UDTLABC test program results Displaying the job log using the DSPJOBLOG command, we find the following error message under the CALL TEAMXX/UDTLABC job log entry as shown in Figure 28. Figure 28. UDTLABC job log error message The Additional Message Information screen for this message is shown in Figure 29 on page 52. Cause 3 applies in this case. The native I/O interface is not able to process user defined data type fields. The recovery information suggests that embedded SQL be used. AS/400 DB2 UDB UDT Lab Test Program: TEAMXX/UDTLABC File open error: A non-recoverable I/O error occurred. Press ENTER to end terminal session. 4 > CALL TEAMXX/UDTLABC Open of member PRODMAST01 file PRODMAST01 in TEAMXX failed. 52 DB2 UDB for AS/400 Object Relational Support Figure 29. UDTLABC job log additional message information We now examine another alternative using native I/O. It is possible to use logical files or SQL views to gain limited native I/O access to tables with distinct type columns. We can create a logical file from a table that contains distinct types. We can create it without including the source table distinct types fields. Figure 30 shows the Data Description Specification source to create a logical file named UDTLFA that only defines the PMNAM field from our PRODMAST01 table. Table 3 on page 31 shows that this is the PRODUCT_NAME field, which is built-in type CHARACTER. Figure 30. UDTLFA display file screen Create the logical file from the DDS using the following command: CRTLF FILE(TEAMXX/UDTLFA) SRCFILE(TEAMXX/QDDSSRC) We need to change the UDTLABC program to access the UDTLFA view rather than the PRODMAST01 table. See the following program listing of the updated program UDTLABD. The numbered lines are explained in the note that follows. Additional Message Information Message ID . . . . . . : CPF428A Severity . . . . . . . : 40 Message type . . . . . : Escape Message . . . . : Open of member PRODMAST01 file PRODMAST01 in TEAMXX failed. Cause . . . . . : Member PRODMAST01 file PRODMAST01 in library TEAMXX was not opened because of error code 3. The error codes and their meanings are: 1 -- The format for file PRODMAST01 contains one or more large object fields and the open request did not indicate that large object fields could be processed by the user of the open. 2 -- The format for file PRODMAST01 contains one or more data link fields and the open request did not indicate that data link fields could be processed by the user of the open. 3 -- The format for file PRODMAST01 contains one or more user defined data type fields and the open request did not indicate that user defined data type fields could be processed by the user of the open. 4 -- A user-defined type for a field for the file does not exist. Recovery . . . : Either specify a different file, use the DSPFFD command to determine what user-defined type is missing, change the open request to indicate that the specified field type can be processed, or change the program to use embedded SQL to process the file. Then try your request again. These field types are fully supported only through SQL. Therefore, if you do not have the DB2 Query Manager and SQL Development Tool Kit for AS/400 product, your program may not be able to access file PRODMAST01. Browse : TEAMXX/QDDSSRC(UDTLFA) Record . : 1 of 2 by 15 Column: 13 of 92 by 79 Control : ..+....2....+....3....+....4....+....5....+....6....+....7....+....8....+....9. ************Beginning of data************** R PRODMAST01 PFILE(TEAMXX/PRODMAST01) PMNAM ************End of Data******************** User-defined Distinct Types (UDTs) 53 #include #include #include #pragma mapinc("udtlfa", "UDTLFA(*ALL)", "both", "d z _P","") 1 #include "udtlfa" static char* FILE_NAME = "UDTLFA"; int main(int argc, char** argv) { 2 TEAMXX_UDTLFA_PRODMAST01_both_t buf; _RFILE *fp; _RIOFB_T *fb; printf("\n"); printf("AS/400 DB2 UDB UDT Lab Test Program: %s\n", argv[0]); printf("\n"); if ((fp = _Ropen(FILE_NAME, "rr")) == NULL) { perror("File open error"); return 0; } printf("Read all records: %s\n", FILE_NAME); printf("\n"); printf("%-25.25s\n", "PRODUCT_NAME"); for ( fb = _Rreadf(fp, (void *)&buf, sizeof(buf), __NO_LOCK); fb->num_bytes == sizeof(buf); fb = _Rreadn(fp, (void *)&buf, sizeof(buf), __NO_LOCK)) { printf("%-25.25s\n", buf.PRODUCT_NAME); } _Rclose(fp); return -1; } UDTLABD program notes 1. Changed mapinc pragma and include to use UDTLFA logical file. 2. Changed record buffer declaration to use the new typedef generated from the UDTLFA DDS. Create the bound C program using the following CL command: CRTBNDC PGM(TEAMXX/UDTLABD) SRCMBR(UDTLABD) The UDTLABD test program attempts to open the UDTLFA logical file for read using native I/O. This logical file excludes the distinct type fields in the PRODMAST01 table. If we call the program using: CALL TEAMXX/UDTLABD, the program terminates having read all records successfully as shown in Figure 31 on page 54. 54 DB2 UDB for AS/400 Object Relational Support Figure 31. UDTLABD native I/O read results We have demonstrated that native read can be performed on a table containing distinct types if we create a logical file excluding the distinct types. 3.5.1.2 Creating an SQL view from a table containing UDT We have seen that logical files can be used to provide native I/O access to non-distinct type fields in tables using distinct types. SQL views can be used to extend native I/O access to enable read-only access to distinct type columns. The SQL interface provides access to distinct type casting functions. These casting functions can be used to cast a distinct type column in a table to a source type in a view. View columns are read-only if a column function is used. The cast distinct type field will, therefore, be read-only. The following SQL statement creates a view named UDTLFB: create view teamxx/udtlfb (product_name, product_dec_price) as select product_name, decimal(product_price) from teamxx/prodmast01; The statement selects the PRODUCT_NAME column and DECIMAL of the PRODUCT_PRICE column from our PRODMAST01 table. The following source listing of a C program attempts to access this SQL view containing distinct type column cast to its source type using native I/O. The numbered lines are explained in the note that follows. #include #include #include #pragma mapinc("udtlfb", "UDTLFB(*ALL)", "both", "d z _P","") 1 #include "udtlfb" static char* FILE_NAME = "UDTLFB"; int main(int argc, char** argv) { TEAMXX_UDTLFB_UDTLFB_both_t buf; _RFILE *fp; _RIOFB_T *fb; printf("\n"); printf("AS/400 DB2 UDB UDT Lab Test Program: %s\n", argv[0]); printf("\n"); 2 if ((fp = _Ropen(FILE_NAME, "rr+")) == NULL) AS/400 DB2 UDB UDT Lab Test Program: TEAMXX/UDTLABD Read all records: TEAMXX/UDTLFA PRODUCT_NAME Atomic Betaflex 9.08 Atomic BetaCarvX 9.26 Tecnica Explosion SR Press ENTER to end terminal session. User-defined Distinct Types (UDTs) 55 { perror("File open error"); return 0; } 3 sprintf(buf.PRODUCT_NAME, "%-25.25s", "New name"); buf.PRODUCT_DEC_PRICE = 0; printf("Update first record: %s\n", FILE_NAME); printf("\n"); printf("%-25.25s %-17.17s\n", "PRODUCT_NAME", "PRODUCT_DEC_PRICE"); printf("%-25.25s ", buf.PRODUCT_NAME); printf("%17D(11,2)\n", buf.PRODUCT_DEC_PRICE); printf("\n"); 4 _Rlocate(fp, NULL, 0, __FIRST); 5 fb = _Rupdate(fp, (void *)&buf, sizeof(buf)); 6 if (fb->num_bytes != sizeof(buf)) { perror("File update error"); } printf("Read all records: %s\n", FILE_NAME); printf("\n"); printf("%-25.25s %-17.17s\n", "PRODUCT_NAME", "PRODUCT_DEC_PRICE"); 7 for ( fb = _Rreadf(fp, (void *)&buf, sizeof(buf), __NO_LOCK); fb->num_bytes == sizeof(buf); fb = _Rreadn(fp, (void *)&buf, sizeof(buf), __NO_LOCK)) { printf("%-25.25s ", buf.PRODUCT_NAME); printf("%17D(11,2)\n", buf.PRODUCT_DEC_PRICE); } _Rclose(fp); return -1; } C program notes 1. mapinc pragma and include set to use UDTLFB logical file. 2. Open existing native file for reading, writing, or updating records. 3. Initialize the record buffer with the record update data. 4. Locate the first record. 5. Update the first record with the data in the record buffer. 6. Check that the record was successfully updated. 7. Read all records. Create the bound C program using the following CL command: CRTBNDC PGM(TEAMXX/UDTLABE) SRCMBR(UDTLABE) The UDTLABE test program attempts to open the UDTLFB SQL view for read and update using native I/O. This logical file excludes the distinct type fields in the PRODMAST01 table. If we call the program using: CALL TEAMXX/UDTLABE, the program terminates having updated the first record and then reads all records successfully as shown in Figure 32 on page 56. 56 DB2 UDB for AS/400 Object Relational Support Figure 32. UDTLABE native I/O results Looking closely at these results, we can see that the first record was updated with PRODUCT_NAME set to New name, and PRODUCT_DEC_PRICE set to 0.00. When reading all records after the write, we can see that the PRODUCT_NAME field was successfully updated, but the PRODUCT_DEC_PRICE was not. As shown in Figure 33, the DSPJOBLOG command shows no error or warning messages under the CALL TEAMXX/UDTLABE job log entry. Figure 33. UDTLABE job log entry with no error messages The following SQL statement updates the same column using the SQL interface: update teamxx/udtlfb set product_dec_price = 0 where product_name = 'New name'; This statement will fail with the following message: SQL0151 - Column PRODUCT_DEC_PRICE in table UDTLFB in TEAMXX read-only. The job log provides further details on SQL execution errors. In the Operations Navigator Run SQL Scripts window, select View->Job Log.... Then double-click the Message ID of interest, SQL0151, to display the Detailed Message Information window as shown in Figure 34. In this case, the detailed message information indicates that the PRODUCT_DEC_PRICE column is read only because it is derived from an AS/400 DB2 UDB UDT Lab Test Program: TEAMXX/UDTLABE Update first record: TEAMXX/UDTLFB PRODUCT_NAME PRODUCT_DEC_PRICE New name 0.00 Read all records: TEAMXX/UDTLFB PRODUCT_NAME PRODUCT_DEC_PRICE New name 455.00 Atomic BetaCarvX 9.26 705.00 Tecnica Explosion SR 530.00 Press ENTER to end terminal session. 4 > CALL TEAMXX/UDTLABE As we have seen, the native I/O interface does not flag an error when attempting to update a distinct type field using a view that casts the distinct type column to its source type. Important User-defined Distinct Types (UDTs) 57 expression. The recovery advice suggests removing the PRODUCT_DEC_PRICE column from the column list. Figure 34. Column read-only error 3.5.2 Keeping track of distinct types The database manager provides a number of data dictionary facilities that can be used to keep track of User-defined Distinct Types. In this section, we see how to view UDT information using the SYSTYPES catalog, the SYSCOLUMNS catalog, the *SQLUDT object, and the DSPFFD CL command. 3.5.2.1 SYSTYPES catalog Distinct types (and built-in types) are stored in the SYSTYPES catalog. Refer to DB2 UDB for AS/400 SQL Reference, SC41-5612, for the detailed description of the catalog views. The following SQL statement displays SYSTYPES information on User-defined Distinct Types in the TEAMXX library: select * from systypes where user_defined_type_schema = 'TEAMXX'; If we run this statement using the Operations Navigator Run SQL Scripts window, with the distinct types listed in Table 4 on page 31 in the TEAMXX library, the query results viewer displays distinct type details as shown in Figure 35 on page 58. 58 DB2 UDB for AS/400 Object Relational Support Figure 35. SYSTYPES catalog 3.5.2.2 SYSCOLUMNS catalog Column details are stored in the SYSCOLUMNS catalog. Refer to DB2 UDB for AS/400 SQL Reference, SC41-5612, for the detailed description of the catalog views. The following SQL statement displays SYSCOLUMNS information on the PRODMAST01 table in the TEAMXX library: select column_name, data_type, user_defined_type_name from syscolumns where table_name = 'PRODMAST01' and table_schema = 'TEAMXX'; If we run this statement using the Operations Navigator Run SQL Scripts window, with the PRODMAST01 table defined, as shown in Table 3 on page 31, the query results viewer displays PRODMAST01 column details as shown in Figure 36. Figure 36. SYSCOLUMNS catalog We can join the SYSCOLUMNS table to the SYSTYPES table to find the source data type as follows: select syscolumns.column_name, syscolumns.data_type, syscolumns.user_defined_type_schema as "UDT_SCHEMA", syscolumns.user_defined_type_name as "UDT_NAME", systypes.source_type from syscolumns left join systypes on syscolumns.user_defined_type_schema = systypes.user_defined_type_schema and syscolumns.user_defined_type_name = systypes.user_defined_type_name where syscolumns.table_name = 'PRODMAST01' and syscolumns.table_schema = 'TEAMXX'; If we run this statement using the Operations Navigator Run SQL Scripts window, with the PRODMAST01 table defined, as shown in Table 3 on page 31, the query results viewer displays PRODMAST01 column details and source type as shown in Figure 37. User-defined Distinct Types (UDTs) 59 Figure 37. SYSCOLUMNS catalog with SYSTYPES.SOURCE_TYPE 3.5.2.3 The *SQLUDT object The *SQLUDT object type contains all of the information for a distinct type. There is one *SQLUDT object for each distinct type in the system. To view *SQLUDT objects using Operations Navigator, click the required library object in the Libraries folders. Objects in the library are displayed in the right panel as shown in Figure 38. This view contains a list of the distinct types in the TEAMXX library. Figure 38. Operations Navigator view of user type objects To view the properties of an *SQLUDT object, right-click the required object, and select Properties. The Properties window appears showing details on the Source data type. Figure 39 on page 60 shows properties for the MONEY distinct type. 60 DB2 UDB for AS/400 Object Relational Support Figure 39. UDT properties dialog You can also view distinct type information using the *SQLUDT object from a 5250 session. To work with *SQLUDT objects in the TEAMXX library, use the following command: WRKOBJ OBJ(TEAMXX/*ALL) OBJTYPE(*SQLUDT) The Work with Objects screen is displayed as shown in Figure 40. Information on the source types of distinct types is not available here, but you can find out what distinct types are in a library. Figure 40. Work with *SQLUDT objects 3.5.2.4 The DSPFFD CL command The Display File Field Description (DSPFFD) CL command can be used to view table column descriptions from a 5250 session. The following command displays the File Field Description for the PRODMAST01 table in the TEAMXX library: DSPFFD FILE(TEAMXX/PRODMAST01) If we run this statement with the PRODMAST01 table defined, as shown in Table 3 on page 31, the DSPFFD Display Spooled File screen is displayed as shown in Figure 41. Work with Objects Type options, press Enter. 2=Edit authority 3=Copy 4=Delete 5=Display authority 7=Rename 8=Display description 13=Change description Opt Object Type Library Attribute Text MONEY *SQLUDT TEAMXX UDT sourced from DECIMAL(11 PICTURE *SQLUDT TEAMXX UDT sourced from BLOB(1M) PRDDESC *SQLUDT TEAMXX UDT sourced from CLOB(100K) SRLNUMBER *SQLUDT TEAMXX UDT sourced from CHAR(5) User-defined Distinct Types (UDTs) 61 Figure 41. File field description for the PRODMAST01 table The File Field Description contains a Field Level Information section that lists the Data Type, Field Length, Buffer Length, Buffer Position, Field Usage, and Column Heading for each field. The User defined-type name and User defined-type library name are provided for fields using a distinct type. Display Spooled File File . . . . . : QPDSPFFD Page/Line 1/1 Control . . . . . Columns 1 - 130 Find . . . . . . *...+....1....+....2....+....3....+....4....+....5....+....6....+....7....+....8.... Display File Field Description Input parameters File . . . . . . . . . . . . . . . . . . . : PRODMAST01 Library . . . . . . . . . . . . . . . . . : TEAMXX File Information File . . . . . . . . . . . . . . . . . . . : PRODMAST01 Library . . . . . . . . . . . . . . . . . : TEAMXX File location . . . . . . . . . . . . . . . : *LCL Externally described . . . . . . . . . . . : Yes Number of record formats . . . . . . . . . : 1 Type of file . . . . . . . . . . . . . . . : Physical SQL file type . . . . . . . . . . . . . . . : TABLE File creation date . . . . . . . . . . . . : 09/28/99 Record Format Information Record format . . . . . . . . . . . . . . . : PRODMAST01 Format level identifier . . . . . . . . . . : 5D683E61EECB3 Number of fields . . . . . . . . . . . . . : 5 Record length . . . . . . . . . . . . . . . : 112 Field Level Information Data Field Buffer Buffer Field Column Field Type Length Length Position Usage Heading PMNBR CHAR 5 5 1 Both PRODUCT_NUMBER Alternative name . . . . . . . . . . . . : PRODUCT_NUMBER User defined-type name . . . . . . . . . : SRLNUMBER User defined-type library name . . . . . : TEAMXX Default value . . . . . . . . . . . . . . : None Coded Character Set Identifier . . . . . : 37 PMNAM CHAR 25 25 6 Both PRODUCT_NAME Alternative name . . . . . . . . . . . . : PRODUCT_NAME Default value . . . . . . . . . . . . . . : None Coded Character Set Identifier . . . . . : 37 PMDESC CLOB 102400 34 31 Both PRODUCT_DESCRIPTION Alternative name . . . . . . . . . . . . : PRODUCT_DESCRIPTION Allocated Length . . . . . . . . . . . . : 0 User defined-type name . . . . . . . . . : PRDDESC User defined-type library name . . . . . : TEAMXX Allows the null value Coded Character Set Identifier . . . . . : 37 PMPRIC PACKED 11 2 6 65 Both PRODUCT_PRICE Alternative name . . . . . . . . . . . . : PRODUCT_PRICE User defined-type name . . . . . . . . . : MONEY User defined-type library name . . . . . : TEAMXX Default value . . . . . . . . . . . . . . : None PMPICT BLOB 1048576 42 71 Both PRODUCT_PICTURE Alternative name . . . . . . . . . . . . : PRODUCT_PICTURE Allocated Length . . . . . . . . . . . . : 0 User defined-type name . . . . . . . . . : PICTURE User defined-type library name . . . . . : TEAMXX Allows the null value Coded Character Set Identifier . . . . . : 65535 62 DB2 UDB for AS/400 Object Relational Support Note how the Buffer Length was adjusted for the PRODUCT_DESCRIPTION and PRODUCT_PICTURE fields. Both fields are sourced from an LOB type. An LOB type value is represented in the record structure by a pointer to a data space location. This pointer must be aligned on a 16-byte boundary. Therefore, the database manager assigns a buffer, which is large enough to accommodate a required shift to the next 16-byte boundary and 32 bytes for the pointer. Note also how the Data Type (PACKED) and Field Length (11 2) of the PRODUCT_PRICE column relate to the source type of MONEY, that is, DECIMAL(11,2). 3.5.3 Database recovery This section describes how to save and restore distinct types and dependent tables and some of the considerations that apply. 3.5.3.1 Saving a table using UDT To save a table using a distinct type to a save file, complete these steps: 1. Use the CRTSAVF CL command to create a new save file. 2. Use the SAVOBJ CL command to save the table object. To create a new save file in the TEAMXX library, use the following command: CRTSAVF FILE(TEAMXX/UDTASAVF) TEXT('UDT Lab A Save File') To save the PRODMAST01 table in the TEAMXX library, defined as shown in Table 3 on page 31, use the following command: SAVOBJ OBJ(PRODMAST01) LIB(TEAMXX) DEV(*SAVF) OBJTYPE(*FILE) SAVF(TEAMXX/UDTASAVF) 3.5.3.2 Saving a UDT To save a distinct type to a save file, perform these steps: 1. Use the CRTSAVF CL command to create a new save file. 2. Use the SAVOBJ CL command to save the distinct type object. Note that, as with other objects, distinct types can also be saved to other offline media. To create a new save file in the TEAMXX library, use the following command: CRTSAVF FILE(TEAMXX/UDTBSAVF) TEXT('UDT Lab B Save File') To save the MONEY distinct type in the TEAMXX library, defined as shown in Table 4 on page 31, use the following command: SAVOBJ OBJ(MONEY) LIB(TEAMXX) DEV(*SAVF) OBJTYPE(*SQLUDT) SAVF(TEAMXX/UDTBSAVF) The database manager allows you to save a table that is using distinct types without saving the required distinct types. A database administrator may want to distribute a shared UDT library to a number of servers without having to save the UDT library on each server. Note User-defined Distinct Types (UDTs) 63 3.5.3.3 Dropping a UDT in use There are dependencies between User-defined Distinct Types and other objects, such as tables with distinct type columns. The database manager requires that dependent objects be dropped first. This section shows what to expect if attempting to drop a distinct type that is being used by a table. To drop a distinct type using Operations Navigator, you open the required library, right-click on the distinct type object you wish to delete, and select Delete from the context menu. If you attempt to delete the MONEY distinct type from the TEAMXX library when it is in use by a table, a Database Error window appears indicating that the distinct type cannot be dropped as shown in Figure 42. Figure 42. UDT cannot be dropped error window The error occurs if the database manager finds another object that uses the distinct type to be dropped. In this case, the error message indicates that the dependent object is the ORDERDTL table, which has a column of distinct type MONEY. As advised in the error message Recovery note, dependent objects must be dropped first. To drop a distinct type using the SQL interface, use the DROP DISTINCT TYPE statement. We may attempt to delete the MONEY distinct type from the TEAMXX library when it is in use by a table as follows: drop distinct type teamxx/money; Then, the run history in the Operations Navigator Run SQL Scripts window shows that this statement failed by providing the following message: SQL0478 - Object MONEY in TEAMXX of type SQLUDT cannot be dropped. The job log provides further details on SQL execution errors. In the Operations Navigator Run SQL Scripts window, select View->Job Log... to display the Job Log window. Double-clicking the Message ID of interest (in this case SQL0478) displays the Detailed Message Information window as shown in Figure 43 on page 64. 64 DB2 UDB for AS/400 Object Relational Support The detailed message information indicates that the dependent object is the PRODMAST01 table, which has a column of distinct type MONEY. The Recovery note again advises that dependent objects must be dropped first. Figure 43. UDT cannot be dropped message details 3.5.3.4 Dropping a table using UDT As seen in 3.5.3.3, “Dropping a UDT in use” on page 63, objects that depend on a User-defined Distinct Type must be dropped before the distinct type can be dropped. To drop a table using Operations Navigator, you open the required library, right-click on the table object you want to delete, and select Delete from the context menu. To drop a table using the SQL interface, use the DROP TABLE statement. For example, use the following statement to drop the PRODMAST01 table in the TEAMXX library: drop table teamxx/prodmast01; 3.5.3.5 Dropping a UDT A distinct type can be dropped by issuing the DROP DISTINCT TYPE statement. This statement accepts two additional options that determine what actions are performed by the database manager: • No option specified: If a user-defined type can be dropped, every User-defined Function that has the following elements is also dropped: – Parameters of the type being dropped – A return value of the type being dropped – A reference to the type being dropped User-defined Distinct Types (UDTs) 65 Consider this example: DROP DISTINCT TYPE money If there is no table using the money data type, the type definition, along with all dependent functions, are dropped. • CASCADE: All dependent objects, along with the UDT definition, are dropped, for example: DROP DISTINCT TYPE money CASCADE This statement drops all tables and UDFs that reference the money distinct type. • RESTRICT: The UDT is dropped only if there are no dependent objects, for example: DROP DISTINCT TYPE money RESTRICT This statement drops the UDT only if there are no UDFs and tables that refer to it. To drop a distinct type using Operations Navigator, you open the required library, right-click on the distinct type object you wish to delete, and select Delete from the context menu. If there are no dependent objects, the right panel refreshes and you should see that the distinct type object has been removed from the library. Note that the Operations Navigator Delete Object dialog uses the DROP TYPE statement with no option specified. 3.5.3.6 Restoring a table using a UDT with UDT not restored As shown in 3.5.3.3, “Dropping a UDT in use” on page 63, there are dependencies between User-defined Distinct Types and other objects, such as tables with distinct type columns. These dependencies need to be considered when restoring objects that use distinct types. We now examine what to expect if a table is restored from a save file when a required distinct type is not accessible. We may restore the PRODMAST01 table, used in our example 3.5.3.1, “Saving a table using UDT” on page 62, with the following CL command: RSTOBJ OBJ(PRODMAST01) SAVLIB(TEAMXX) DEV(*SAVF) OBJTYPE(*FILE) SAVF(TEAMXX/UDTASAVF) Then, the following message appears in the 5250 message line, indicating that the table was successfully restored: 1 objects restored from TEAMXX to TEAMXX. If we then try accessing the restored table using Operations Navigator by double-clicking the table object, a Database Error window appears. The error indicates that a distinct type cannot be found as shown in Figure 44 on page 66. You can omit the keyword DISTINCT in the DROP DISTINCT TYPE statement. Note 66 DB2 UDB for AS/400 Object Relational Support Figure 44. UDT not found error window The error occurs if the database manager cannot find a required distinct type. In this case, the MONEY distinct type is missing. If the missing distinct type is not known, the data dictionary facilities discussed in 3.5.2, “Keeping track of distinct types” on page 57, can be used to identify it. If we try accessing the restored table using the SQL interface as follows: select * from teamxx/prodmast01; The run history shows that this statement failed and the following message appears: SQL0204 - *N in *N type *SQLUDT not found. We can select View->Job Log... in the Run SQL Scripts window to display the Job Log window. Figure 45. Job log for UDT not found Double-clicking on the Message ID of interest, in this case SQL0204, does not identify the missing UDT. Returning to the job log, we see two other messages logged with the SQL0204 message as shown in Figure 45. Double-clicking on the Datalink, user-defined type, or LOB field error, reason code 6. message, as highlighted in Figure 45, displays the Detailed Message Information window shown in Figure 46. User-defined Distinct Types (UDTs) 67 Figure 46. UDT error message details The detailed message information shown in Figure 46 indicates that the UDT not found problem is with the PMPRIC column in the TEAMXX/PRODMAST01 table. We can check the data type of the PMPRIC column in the SYSCOLUMNS catalog with the following SQL statement: select system_column_name, user_defined_type_schema, user_defined_type_name from syscolumns where table_name = 'PRODMAST01' and table_schema = 'TEAMXX'; If we run this statement using the Operations Navigator Run SQL Scripts window, the query results viewer displays PRODMAST01 column details as shown in Figure 47. Figure 47. SYSCOLUMNS details for PRODMAST01 table 68 DB2 UDB for AS/400 Object Relational Support Looking at Figure 47 on page 67, we can see that USER_DEFINED_TYPE_NAME for the PMPRIC column is TEAMXX/MONEY. We need to redefine the MONEY distinct type or restore it from the save file to reestablish access to the PMPRIC column. You could also use the DSPFFD CL command to find the data type of the PMPRIC column instead of using the SYSCOLUMNS catalog. Refer to 3.5.2.4, “The DSPFFD CL command” on page 60, for further details. Another alternative is to use Operations Navigator interface. We show how to display the UDT’s Property dialog in 3.5.2.3, “The *SQLUDT object” on page 59. Note: Only columns that are defined using missing distinct types are inaccessible. You can still select other columns. The following SQL example will work because the PRODUCT_NAME column is a built-in data type: select product_name from teamxx/prodmast01; 3.5.3.7 Restoring a UDT to allow access to a table using UDT We may restore the MONEY distinct type, used in our example 3.5.3.2, “Saving a UDT” on page 62, with the following CL command: RSTOBJ OBJ(MONEY) SAVLIB(TEAMXX) DEV(*SAVF) OBJTYPE(*SQLUDT) SAVF(TEAMXX/UDTBSAVF) Then, the following message appears in the 5250 message line, indicating that the distinct type was successfully restored: 1 objects restored from TEAMXX to TEAMXX. If we then try accessing the restored table using Operations Navigator by double-clicking on the table object, the Edit Table window appears, confirming that the distinct type has been correctly restored. If we try accessing the restored table using the SQL interface as follows: select * from teamxx/prodmast01; the query results viewer is displayed, again confirming that the distinct type has been correctly restored. Restoring the distinct type also reestablishes access to objects dependent on the distinct type. © Copyright IBM Corp. 2000 69 Chapter 4. User Defined Functions (UDFs) This chapter describes: • User-defined Function (UDF) types • Resolving UDFs • Coding UDFs in SQL and High-level Languages • Parameters styles for external UDFs • Using LOBs and UDTs with UDFs • Debugging UDFs • Backup/Recovery considerations for UDFs 4.1 A need for User Defined Functions A function is a relationship between a set of input values and a set of result values. When invoked, a function performs some operation (for example, concatenate) based on the input and returns a single result to the invoker. Functions can be specified anywhere where an expression is allowed in SQL. On a DB2 UDB system, the functions that are available for use fall into three categories: • Built-in Functions: These functions come pre-installed with the system. They are built into the code of the DB2 UDB system. Examples of such functions are the SUBSTR and the CONCAT function. • System Generated Functions: These functions are automatically generated when a distinct type is created on the system. When a distinct type is created, you are automatically provided with the cast functions between the distinct type and its source type. You are also provided with comparison operators, such as =, <, and >. • User Defined Functions (UDFs): These functions are explicitly created by the users of the system using the CREATE FUNCTION SQL statement. This statement names the function and specifies its characteristics. The User Defined Function (UDF) support is a facility given to the database programmers to create a function that can, subsequently, be used in SQL. It can be thought of as an interface that lets you extend and customize SQL to meet your needs. DB2 UDB for AS/400 comes with a set of built in functions, such as SUBSTRING and CONCAT, but these may not satisfy all of your requirements. With UDFs, you can write your own scalar functions and then, subsequently, use them in SQL statements just like any other system supplied function. UDFs are useful for the following reasons: • Supplement built-in functions: A User Defined Function is a mechanism with which you can write your own extensions to SQL. The built-in functions supplied with DB2 are a useful set of functions, but they may not satisfy all of your requirements. So, you may need to extend SQL. For example, porting applications from other database platforms may require coding of some platform specific functions. • Handle user-defined data types: You can implement the behavior of a User-defined Distinct Type (UDT) using UDFs. When you create a distinct type, the database provides only cast functions and comparison operators for 70 DB2 UDB for AS/400 Object Relational Support the new type. You are responsible for providing any additional behavior. It is best to keep the behavior of a distinct type in the database where all of the users of the distinct type can easily access it. Therefore, UDFs are the best implementation mechanism for UDTs. • Provide function overloading: Function overloading means that you can have two or more functions with the same name in the same library. For example, you can have several instances of the SUBSTR function that accept different data types as input parameters. Function overloading is one the key features required by the object-oriented paradigm. • Allow code re-use and sharing: A business logic implemented as a UDF becomes part of the database, and it can be accessed by any interface or application using SQL. UDFs can be written in any of the languages available on the AS/400 system, with the exception of REXX and Java (with Java support coming very soon). You can also use the SQL scripting language to write UDFs. 4.2 UDF types There are three categories into which User Defined Functions can be divided. These categories and their characteristics are discussed in this section. Refer to 4.4, “Coding UDFs” on page 77, for code examples and implementation details. 4.2.1 Sourced A sourced UDF enhances the functionality of a function that already exists on the system at the time of creation of the sourced function. In other words, these are functions registered to the database that themselves reference another function. There is no coding involved. You simply register a new function to the database using the CREATE FUNCTION statement. Sourced UDFs are often used to implement the required behavior of UDTs. The following example illustrates how to implement the "-" operator for the money data type without the need for reinventing arithmetic operations: create function TEAMxx/"-"( MONEY, MONEY ) returns MONEY specific MINUS00001 source QSYS2/"-"( decimal, decimal ); 4.2.2 SQL These are functions that are written entirely using SQL. The body of the function is embedded within the CREATE FUNCTION statement. The SQL UDFs have the structure as shown here: create function myUDF (Parameters ) returns ReturnvValue language SQL BEGIN sql statements END; Since these functions are written using pure SQL, it is easy to port them to other database platforms. In the following, SQL UDF is used to retrieve the first two and last two characters of a CLOB value: User Defined Functions (UDFs) 71 CREATE FUNCTION slice( p1 clob ) RETURNS CHAR(4) LANGUAGE SQL -- returns the first two and the last two characters of the clob s1: BEGIN DECLARE temp CHAR(4); SET temp = CONCAT(SUBSTR(p1,1,2), SUBSTR(p1,LENGTH(p1)-1,2)); RETURN temp; END s1; 4.2.3 External An external function is one that has been written by the user in one of the programming languages on the AS/400 system. External functions can be written in ILE C/400, ILE RPG/400, ILE COBOL/400, ILE CL/400, RPG/400, COBOL/400, and CL/400. You can compile the host language programs to create either programs or service programs. To create an external UDF, the source code for the host language program must first be compiled so that a program or a service program object is created. Then, the CREATE FUNCTION statement is used to tell the system where to find the program object that implements the function. The function registered in the following example checks whether the passed BLOB object contains a picture in GIF format. The function was implemented in the C language: create function TEAMxx/ISGIF( BLOB ) returns INTEGER language C specific ISGIF00001 no sql no external action external name 'TEAMXX/PICTCHECK(fun_CheckPictureType)' parameter style SQL; The following SQL statement uses the newly created function to retrieve product numbers of those products that have an accompanying GIF picture: select product_number from prodmast01 where isgif(product_picture) = 1; 4.3 Resolving UDF Resolving to the correct function to use for an operation is more complicated than other resolution operations since DB2 UDB supports function overloading. This means that a user may define a function with the same name as a built-in function or another UDF on the system. For example, SUBSTR is a built-in function, but the user may define their own SUBSTR function that takes slightly different parameters. Therefore, even resolving to a supposedly built-in function still requires that function resolution be performed. The following sections explain how DB2 UDB for AS/400 resolves references to functions. To create an SQL UDF, you must have the SQL Development Kit and the ILE C/400 products installed on your development system. Once created, the SQL UDF may be run on an AS/400 system without needing these license programs. The run time support for the SQL UDFs is part of the OS/400. Note 72 DB2 UDB for AS/400 Object Relational Support 4.3.1 UDF function overloading and function signature As mentioned earlier, DB2 UDB supports the concept of function overloading. This means that you can have two or more functions with the same name in the same library, provided they have a different signature. The signature of a function can be defined as the combination of the qualified function name and the data types of the input parameters of the function. No two functions on the system can have the same signature. The lengths and precision of the input parameters is not considered to be part of the signature. Only the data type of the input parameters is considered to be part of the signature. Therefore, if you have a function called myUDF in library LIB1 that accepts an input parameter of type CHAR(5), you cannot have another function called myUDF in the same LIB1 that accepts CHAR(10). The length of the variable is not considered part of the signature. However, it is possible to have another function myUDF in library LIB1 that accepts a DECIMAL value as an input parameter. The following examples illustrate the concept of the function signature. These two functions can exist in the same collection: lib1.myUDF( char(5)) lib1.myUDF(decimal) These two functions cannot exist in the same collection: myUDF(char(10)) myUDF(char(5)) Notice that certain data types are considered equivalent when it comes to function signatures. For example, CHAR and GRAPHIC are treated as the same type from the signature point of view. The data type of the value returned by the function is not considered to be part of the function signature. This means that you cannot have two functions called myUDF in library LIB1 that accept input parameters of the same data type, even if they return values of different data types. 4.3.2 Function path and the function selection algorithm On the AS/400 system, there are two types of naming conventions when using SQL. One of them is called the system naming convention, and the other one is called the SQL naming convention. The system naming convention is native to the AS/400 system, and the SQL naming convention is specified by the ANSI SQL standard. The function resolution process depends on which naming convention you are using at the time you execute the SQL statement, which refers to a UDF. 4.3.2.1 Function path When unqualified references are made to a UDF inside an SQL statement, DB2 UDB for AS/400 uses the concept of PATH to resolve references to the UDF. The path is an ordered list of library names. It provides a set of libraries for resolving unqualified references to UDFs as well as UDTs. In cases where a reference to a UDF matches more than one UDF in different libraries, the order of libraries in the path is used to resolve to the correct UDF. User Defined Functions (UDFs) 73 The path can be set to any desired set of libraries using the SQL SET PATH statement. The current setting of the path is stored in the CURRENT PATH special register. For the SQL naming convention, the path is set initially to the following default value: "QSYS", "QSYS2", "" For the system naming convention, the path is set initially to the following default value: *LIBL When you are using the system naming convention, the system uses the library list of the current job as the path and uses this list to resolve the reference to the unqualified references to the UDFs. The current path can be changed with the SET PATH statement. Note that this statement overrides the initial setting for both naming conventions. For example, you can use the following statement: SET PATH = MYUDFS, COMMONUDFS to set the path to the following list of libraries: QSYS, QSYS2, MYUDFS, COMMONUDFS Notice that the libraries QSYS and QSYS2 are automatically added to the front of the list. This is the case unless you explicitly change the position of these libraries in the SET PATH statement. For example, the following statement sets the CURRENT PATH registry to myfunc, QSYS, QSYS2: SET PATH myfunc, SYSTEM PATH For portability reasons, we recommend that you use SYSTEM PATH registry rather then QSYS and QSYS2 library names on the SET PATH statement. 4.3.2.2 Function resolution in the CREATE FUNCTION statements The function resolution for the supported naming conventions works as described here: • SQL naming convention: If the function name is qualified, the function is created in the library specified. If a user profile with the same name as the qualifying library exists, that user profile is the owner of the created function; otherwise, the user profile that is creating the function is the owner of the created function. If the function name is not qualified, the function is created in a library with the same name as the user profile executing the SQL statement. If such a library does not exist, you will receive an error message when executing the statement. • System naming convention: If the function name is qualified, the function is created in the specified library. The owner of the function is the name of the user profile that executes the SQL statement. If the function name is not qualified, the function is created in the current library (*CURLIB). If there is no current library, the function is created in QGPL. 74 DB2 UDB for AS/400 Object Relational Support If you are using system naming convention, you code the qualified function name in the CREATE FUNCTION SQL statement in the following way: CREATE FUNCTION LIB1/myUDF(CHAR(5) ) ... If you are using SQL naming convention, you code the qualified function name in the CREATE FUNCTION SQL statement in the following way: CREATE FUNCTION LIB1.myUDF( CHAR(5) ) ... 4.3.2.3 Function resolution in data manipulation statements The function resolution for the supported naming conventions works as described here: • SQL naming convention: If the name of the UDF is qualified, the system searches for the function in the specified library. The function matching the function signature specified in the SQL statement is chosen. The following statements show how to invoke a UDF with its qualified name: SELECT LIB1.myUDF( FIELD1 ) FROM LIB1.TABLE1 • System Naming Convention: You cannot have qualified references to UDFs using the system naming convention. Qualified references to functions are allowed only in the SQL naming convention. Therefore, a statement, such as SELECT LIB1/myUDF( FIELD1 ) FROM LIB1/TABLE1, is not allowed. If there is more than one function having a signature that matches those specified in the SQL statement, the list of libraries in the current path is used to resolve the reference. The system picks the first function matching the signature from the libraries specified in the path. In case there are no functions exactly matching the signature, the system uses parameter promotion (this concept is discussed in the following section) to find the "best fit" for the function specified in the SQL statement. If the system cannot find the function matching the required signature, you receive an SQL error message similar to the one shown here: SQL0204 - GETDESCRIPTION in *LIBL type *N not found. All functions on the system, including built-in functions, have to pass through the function selection algorithm before being selected for execution. 4.3.3 Parameter matching and promotion When an SQL DML statement references a UDF, the system, at first, tries to find an exact match for the function by searching for functions that have the same signature. If the system finds a function having input parameters that exactly match those specified in the DML statement, that function is chosen for execution. In case the system cannot find any function in the path that exactly matches those specified on the DML statement, the parameters on the function call in the DML statement are promoted to their next higher type. Then, another search is made for a function that accepts the promoted parameters as input. During parameter promotion, a parameter is cast to its next higher data type. For example, a parameter of type CHAR is promoted to VARCHAR, and then to CLOB. There are restrictions on the data type to which a particular parameter can be promoted. We explain this concept with an example. User Defined Functions (UDFs) 75 Let us assume that you have created a table CUSTOMER in library LIB1. This table has, among its other fields, a field named CUSTOMER_NUMBER, which is a CHAR(5). Let us also assume that you have written a function GetRegion that will perform some processing and return the region to which your customer belongs. The data type of the parameter that this function accepts as input is defined to be of type CLOB(50K). Let us assume that there are no other functions called GetRegion in the path. Now, if you execute the following query, you will see that the function GetRegion( CLOB(50K) ) is actually executed: select GetRegion( customer_number ) from customer How is this possible? The field CUSTOMER_NUMBER from the CUSTOMER table has the data type CHAR(5). The function GetRegion actually accepts a CLOB as a parameter, and there are no other functions called GetRegion in the path. In its attempt to resolve the function call, the system first searched the library path for a UDF called GetRegion, which accepts an input parameter of type CHAR. However, no such UDF was found. The system then promoted the input parameter, in our case the customer number, up in the hierarchy list of promotable types to a VARCHAR. Then, a search was made for an UDF called GetRegion, which accepted an input parameter of type VARCHAR. Again, no such UDF was found. Then, the system promoted the input parameter up the hierarchy list to a CLOB. A search was made for an UDF called GetRegion, which accepted an input parameter of type CLOB. This time the search was successful. The system invoked the UDF GetRegion( CLOB(50K) ) to satisfy the user request. The concept of parameter promotion is clearly demonstrated in the previous example. Table 9 on page 76 gives a list of data types and the data types to which they can be promoted. 76 DB2 UDB for AS/400 Object Relational Support Table 9. Precedence of data types As you see from Table 9, data types can be promoted up the hierarchy only to particular data types. Distinct types cannot be promoted. Even though distinct types are based on one of the built-in data types, it is not possible to promote distinct types to anything other than the same type. Parameters cannot be demoted down the hierarchy list as shown in Table 9. This means that, if the CUSTOMER_NUMBER column of the CUSTOMER table is a CLOB, and the GetRegion UDF was defined to accept a CHAR as an input parameter, a call, such as the one shown here, will fail because function resolution will not find the UDF: SELECT GetRegion( CUSTOMER_NUMBER ) from customer 4.3.4 The function selection algorithm The function selection algorithm searches the library path for a UDF using the steps outlined here: 1. Finds all functions from the catalog (SYSFUNCS) and built-in functions that match the name of the function. If a library was specified, it only gets those functions from that library. Otherwise, it gets all functions whose library is in the function path. 2. Eliminates those functions whose number of defined parameters does not match the invocation. 3. Eliminates functions whose parameters are not compatible or "promotable" to the invocation. Data type Data type precedence list (in best to worst order) CHAR or GRAPHIC CHAR or GRAPHIC, VARCHAR or VARGRAPHIC, CLOB, or DBCLOB VARCHAR or VARGRAPHIC VARCHAR or VARGRAPHIC, CLOB, or DBCLOB CLOB or DBCLOB CLOB or DBCLOB BLOB BLOB SMALLINT SMALLINT, INTEGER, DECIMAL or NUMERIC, REAL, DOUBLE INTEGER INTEGER, DECIMAL or NUMERIC, REAL, DOUBLE DECIMAL or NUMERIC DECIMAL or NUMERIC, REAL, DOUBLE REAL REAL, DOUBLE DOUBLE DOUBLE DATE DATE TIME TIME TIMESTAMP TIMESTAMP DATALINK DATALINK A distinct type The same distinct type User Defined Functions (UDFs) 77 For the remaining functions, the algorithm follows these steps: 1. Considers each argument of the function invocation, from left to right. For each argument, it eliminates all functions that are not the best match for that argument. The best match for a given argument is the first data type appearing in the precedence list. Lengths, precessions, scales, and the "FOR BIT DATA" attribute are not considered in this comparison. For example, a DECIMAL(9,1) argument is considered an exact match for a DECIMAL(6,5) parameter, and a VARCHAR(19) argument is an exact match for a VARCHAR(6) parameter. 2. If more than one candidate function remains after the above steps, it has to be the case (the way the algorithm works) that all the remaining candidate functions have identical signatures but are in different schemas. It chooses the function whose schema is earliest in the user's function path. 3. If there are no candidate functions, it signals the error SQLSTATE 42884. Figure 48 summarizes the steps performed by DB2 UDB for AS/400 to resolve a call to a UDF. Figure 48. Function resolution algorithm 4.4 Coding UDFs Before a UDF can be used in a Data Manipulation Language (DML) statement, it must be registered with the database. This can be done by using the CREATE FUNCTION DDL statement. The CREATE FUNCTION statement is used to define the name of the function, the type of the function, the number and data type of the input parameters, and the data type of the value returned by the UDF to the invoking process. The CREATE FUNCTION statement can be embedded in an application program, or it can be executed interactively. All three types of UDFs can be created by this statement. The syntax of the statement is different for Locate all function signatures with same function name schema name in function path same number of parameters (exact match or "promotable") Is qualified name given? Function signatures remaining? Error Function selected Choose function whose schema is earliest in the user's function path No Yes =0 >1 =1 Locate all function signatures with qualified name same number of parameters (exact match or "promotable") Process arguments from first to last for each argument eliminate all functions that are not the "best match" 78 DB2 UDB for AS/400 Object Relational Support sourced UDFs, SQL, and external UDFs. After a UDF is registered, it can be used in any SELECT, UPDATE, DELETE DML statement from any interface from where an SQL statement can be executed. When a UDF is registered with the database, entries are made into the SYSFUNCS and SYSPARMS system tables. These tables store information on every function that is registered with the database. The information that is recorded in these tables is discussed in 4.6, “The system catalog for UDFs” on page 116. UDFs can be defined to accept and return parameters of any datatype including distinct types. Apart from being classified as sourced, SQL, and external, UDFs can also be classified as scalar or column. The scalar functions return a single value each time they are invoked. These functions are executed once for every row of the table. The SUBSTR() built-in function is an example of a scalar function. Column functions receive a set of values as input. They return one value. The AVG() built-in function is an example of a column function. Scalar functions can be created as External, SQL, and Sourced functions. Column functions can only be created as sourced functions. 4.4.1 Coding sourced UDFs A sourced function is a function that references another function which, in turn, is already registered with the database. The UDF can be sourced from any function that is registered to the database, including built in functions. These operators are: +, -, *, /, ||, CONCAT. The name of the sourced function cannot be any of the comparison operators on the system. Functions for these operators are part of the database system. There is also a number of other system functions that cannot be used as the name of the sourced UDF. For more information on these restrictions, refer to DB2 UDB for AS/400 SQL Reference, SC41-5612. If the Sourced UDF being created references a scalar function, it inherits all the attributes of the referenced function. When a sourced UDF is created, a small service program is automatically created by the system in the background. This service program is there to assist the system in the save/restore and grant/revoke operations. You can think of it as a place holder for a function body, which is implemented elsewhere (typically by a built-in function). 4.4.1.1 Creating sourced UDFs as scalar functions We illustrate the use of the CREATE FUNCTION statement with an example. We create an overloaded version of the SUBSTR function. The function accepts three input parameters: a distinct type PRDDESC and two integers. It returns a parameter of type PRDDESC. The function is sourced from the built-in function SUBSTR(CLOB, INTEGER, INTEGER ). In this example, we show you how to create the script through the Operations Navigator Run SQL Scripts utility. To open the Run SQL Scripts window, follow the steps outlined here: 1. Open an Operations Navigator session. 2. Right-click the Database object. 3. From the Database context menu, select the Run SQL Scripts option. This opens the Run SQL Scripts window (Figure 49). User Defined Functions (UDFs) 79 Figure 49. Opening up a Run SQL Scripts session Figure 50 shows the CREATE FUNCTION statement for the SUBSTR( PRDDESC, INTEGER, INTEGER ) function. The result of running the statement is shown in the Run History panel of the Run SQL Scripts utility. Figure 50. The CREATE FUNCTION statement for sourced UDF Let us examine the CREATE FUNCTION statement shown in Figure 50 in detail. The numbered sections are explained in the list that follows: create function TEAMxx/SUBSTR( PRDDESC, INTEGER, INTEGER ) 1 returns PRDDESC 2 specific SUBSTR0001 3 source QSYS2/SUBSTR( CLOB, INTEGER, INTEGER ); 4 80 DB2 UDB for AS/400 Object Relational Support CREATE FUNCTION statement notes 1. We qualify the function name with the library name, TEAMxx in this case. We use the system naming convention. If you do not qualify the function’s name in the CREATE FUNCTION statement, the function is created in the current library. The function takes three input parameters: the distinct type PRDDESC and two parameters of type INTEGER. The definition for the distinct type PRDDESC is taken from a library in the library list. If no definition of the UDT is found, the CREATE FUNCTION statement returns an error. If multiple definitions of the distinct type are found, the first definition found in the library list is used. 2. The RETURNS clause specifies the data type of the value returned by the function. Note that the data type of the value returned by the function can be different from the type of the value returned from the referenced program object. However, the type returned from the program object must be castable to the data type of the value returned by the function you are creating. For example, you cannot define a SUBSTR function that returns a DECIMAL data type as the return value of the function. 3. This is the SPECIFIC NAME clause of the CREATE FUNCTION statement. Every function created on the AS/400 system must have a specific name. This name must be unique for a given library. The service program that is created by the DB2 UDB for AS/400 to implement the function has the same name as the specific name provided in this clause. This is an optional clause. If you do not specify a specific name for the function, the system will generate a specific name. Normally, the specific name is the same as the function’s name, provided it is a valid system name (for instance, it’s not longer than 10 characters). However, if a function with that specific name already exists, the system generates a unique name. When the service program created for the sourced function is saved and restored to another system, the attributes of the CREATE FUNCTION statement are automatically added to the system catalogs. 4. This is the SOURCE clause of the CREATE FUNCTION statement, which points to the existing function that is the source for the function being created. In our example, the source function is SUBSTR(CLOB, INTEGER, INTEGER) and it exists in the QSYS2 library. You can use the Operations Navigator to check that your function was created correctly. To see the definition of your function, follow the steps outlined here: 1. In the main Operations Navigator window, click the (+) icon next the Database object to expand its content. 2. Expand the Libraries object. You see all the libraries in your library list. 3. Click the name of the library where you created the function. You should see all the database objects in that library displayed in the right panel of the display. Please note that only database objects are shown in this panel. You should now see your function listed as shown in Figure 51. User Defined Functions (UDFs) 81 Figure 51. The SUBSTR( PRDDESC, INTEGER, INTEGER ) sourced function Once you register the function with the database, you can use it in your SQL DML statements. The following example shows you how to use the newly created SUBSTR function in a SELECT statement. Our PRODMAST01 test table has a column named PRODUCT_DESCRIPTION that is based on the PRDDESC distinct type. The PRODUCT_DESCRIPTION column is a structured text of type CLOB, which contains the description of the product, the range of sizes for the product, the color of the product, and the best use of the product. Let us assume that we want to get the range of sizes for all products in the PRODMAST01 table. We execute a SELECT statement, such as the one shown in Figure 52. Figure 52. Using the SUBSTR( PRDDESC, INTEGER, INTEGER ) function in a query Notice that in the SELECT statement shown in Figure 52, we have to cast the PRODUCT_DESCRIPTION to CLOB when it is used in the LOCATE built-in function. This is because there is no function called LOCATE that accepts a column of type PRDDESC as an input parameter. However, there is a function 82 DB2 UDB for AS/400 Object Relational Support called LOCATE that accepts a CLOB as an input parameter. Therefore, we cast the PRODUCT_DESCRIPTION column of the PRODMAST01 table to a CLOB when we pass it as a parameter to the LOCATE function. Notice also that we do not cast the PRODUCT_DESCRIPTION column when we pass it as a parameter to the SUBSTR function. This is because we just created a SUBSTR function that accepts an input parameter of type PRDDESC. If we were to create a function called LOCATE( CLOB, PRDDESC, INTEGER ), we would not need to cast the PRODUCT_DESCRIPTION column in the call to the function in the above statement. 4.4.1.2 Creating sourced UDFs as column functions We have just seen how to create a scalar sourced UDF. We can also create sourced UDFs as column functions. Recall that the argument of a column function is a set of values derived from one or more columns and that it returns one value as the result. Only sourced UDFs can be created as column functions. External and SQL UDFs cannot be created as column functions. As an example, we create a new MAX function as sourced UDF. The function takes one input parameter of distinct type MONEY. The function returns a value of type MONEY. It is based on the built-in function MAX( DECIMAL ), which exists in the QSYS2 library. The CREATE FUNCTION statement for this function is shown in Figure 53. Figure 53. Creating the MAX( MONEY ) sourced UDF as a column function We can now use the newly created MAX( MONEY ) function with the ORDER_TOTAL column of the ORDERHDR table as the input parameter. The ORDER_TOTAL column of the ORDERHDR table is of type MONEY. The query and its results are shown in Figure 54. User Defined Functions (UDFs) 83 Figure 54. Running the MAX( MONEY ) column UDF Notice that, in the SOURCE clause of the CREATE FUNCTION statement in Figure 53, the precision of the DECIMAL input parameter for the referenced function is not specified. If you do not specify the precision of a parameter, the system ignores the precision of the value supplied as the input parameter to the function. In the example in Figure 53, this approach is used in the SOURCE CLAUSE. Similarly, you can specify input parameters without specifying their precision. If you do so, the system ignores the precision of the values that you are supplying as input to the UDF at run time. If the precision was specified for the function’s parameters, the system looks for a function that has input parameters which exactly match the precision of those specified on the CREATE FUNCTION statement. 4.4.1.3 Creating sourced UDFs over arithmetic operators You can define a sourced UDF over the arithmetic operators available in the system, provided one of the new function’s parameters is a distinct type. These operators are +, -, *, /, ||. You cannot define sourced UDFs over comparison operators, such as =, <, >, and so forth. As an example, we create a sourced UDF over the "+" operator. This function accepts two input parameters of type MONEY. The function returns a value of type MONEY. The function is based on the built-in function "+"( DECIMAL, DECIMAL ). Figure 55 on page 84 shows the CREATE FUNCTION statement used to create this function. 84 DB2 UDB for AS/400 Object Relational Support Figure 55. Creating the "+"( MONEY, MONEY ) sourced UDF over arithmetic operators An example query using the newly created function is shown in Figure 56. Figure 56. Using the "+"( MONEY, MONEY ) sourced UDF Note that we use the prefix notation for calling the "+"( MONEY, MONEY ) UDF. Currently, DB2 UDB for AS/400 does not support the infix notation for calls to UDFs, even if the UDFs are created over arithmetic operators. Calls, such as the one shown here, will fail: User Defined Functions (UDFs) 85 select order_number, order_total, order_total + order_total as DoubleCost from OrderHdr; In addition, when an UDF is defined over an arithmetic operator, you have to enclose the name of the called UDF in double quotes. 4.4.2 Coding SQL UDFs Until now, you’ve seen how to create sourced UDFs. In this section, we discuss SQL UDFs. SQL UDFs are functions that use the SQL language to implement their business logic. In SQL UDFs, the entire procedure body is embedded within the CREATE FUNCTION statement. When you execute the CREATE FUNCTION statement for the SQL UDF, DB2 UDB for AS/400 walks through a multiphase process to create an ILE C service program object (*SRVPGM). During this process, DB2 UDB for AS/400 generates an intermediary ILE C code with embedded SQL statements. This ILE C code is then precompiled, compiled, and linked automatically. This means that the SQL Development Kit for AS/400, and the ILE C compiler, need to be installed on the system where you plan to develop SQL stored procedures. Once the ILE C object is created, it can be restored onto any V4R4 or higher system and run without the SQL Development Kit and ILE C compiler. Note that the ILE C program object is created with the Activation Group parameter set to *CALLER. As an example, we create the GetDescription function, which accepts one parameter: product number of type CHAR(5). The function returns the description of the product as a VARCHAR( 1024 ) by substringing the structured text stored in the PRODUCT_DESCRIPTION field of the PRODMAST04 table. In this example, we also show you how to create a UDF using the Operations Navigator Create SQL Function dialog. The required steps are listed here: 1. In the main Operations Navigator window, click the (+) icon next to the Database object to expand its content. 2. Expand the Libraries object. You see all the libraries in your library list. 3. Right-click the library in which you want to create the SQL UDF. A context menu appears (Figure 57 on page 86). 86 DB2 UDB for AS/400 Object Relational Support Figure 57. Creating an SQL UDF using the new SQL function dialog 4. Choose the New->Function->SQL option. The New SQL Function dialog box appears on the screen. 5. Type the name, description, and specific name of the function. Select the datatype of the value returned by the function (Figure 58). Figure 58. New SQL function dialog 6. Click the Parameters tab of the dialog. Click the Insert button. Type in the name of the parameter and the length of the parameter. Select the datatype of the parameter (Figure 59). User Defined Functions (UDFs) 87 Figure 59. Defining the input parameters for the SQL UDF 7. Click the SQL Statements tab. Click in the Statements area, and type the SQL statements that will make up the body of the procedure. Click the OK button (Figure 60). Figure 60. Typing in the body of the SQL UDF. As you can see, this is a much easier method to create a UDF than with the Run SQL Scripts utility. However, you may find it advantageous to preserve the sources for all of your SQL functions in the form of an SQL script. In this form, your functions can be maintained and re-created more easily. 88 DB2 UDB for AS/400 Object Relational Support The SQL source for the GetDescription function is shown here. The numbered sections are explained in the list that follows. create function TEAMxx/GETDESCRIPTION( chs_ProductNumber CHAR(5) ) 1 returns VARCHAR(1024) 2 language SQL 3 specific GTDESC0001 4 is deterministic 5 reads SQL DATA 5 no external action 7 BEGIN 8 DECLARE chs_Description CLOB(50K); DECLARE chs_ReturnValue VARCHAR(1024); select product_description 9 into chs_Description from prodmast04 where product_number = chs_ProductNumber; set chs_ReturnValue = VARCHAR( CLOB( SUBSTRING( chs_Description, 1, ( LOCATE('Sizes', 10 chs_Description, 1) - 1 ) ) ), 1024 ); return chs_ReturnValue; 11 END 12 GetDescription function notes 1. The qualified name of the function and the input parameters to the function and their data types are specified here. Unlike the sourced UDFs, here you have to specify names for the input parameters to the function. The GetDescription function shown above has only one input parameter: the product number ( chs_ProductNumber ) which is of type CHAR(5). 2. This is the RETURNS clause of the CREATE FUNCTION statement. Here, you specify the data type of the value returned by the function. This can be any data type available on the system, including complex data types and distinct types. The only restriction is that you cannot return a distinct type if it is based on a datalink. It is a mandatory clause. 3. This is the LANGUAGE clause of the CREATE FUNCTION statement. It must be specified in SQL functions. If you specify the language of a function to be SQL, then the body of the function must be specified within the body of the CREATE FUNCTION statement. Also, when you specify the language of a function to be SQL, you cannot specify the EXTERNAL NAME clause. The EXTERNAL NAME clause identifies the name of the program to be executed when an external function is being created. The LANGUAGE SQL and the EXTERNAL NAME clauses are mutually exclusive. Several options on the CREATE FUNCTION statement are not allowed for the SQL UDFs: • FINAL CALL/NO FINAL CALL • SCRATCHPAD/NO SCRATCHPAD • DBINFO/NO DBINFO However, these options may be used in external UDFs. Refer to 4.4.3.3, “Coding external UDFs using the DB2SQL parameter style” on page 103, for more details. Important User Defined Functions (UDFs) 89 4. This is the SPECIFIC NAME clause of the CREATE FUNCTION statement. Every function that is created must have a specific name, and this name must be unique for a given library. This clause specifies the specific name of the function. It is not mandatory, but if you do not specify this clause, the system generates a specific name for the function. The system generated name is normally the same as that of the function, provided it is a valid system name. However, if another function exists with the same specific name, the name is generated using rules that are similar to those used for generating unique table and column names. 5. This is the DETERMINISTIC or NOT DETERMINISTIC clause of the CREATE FUNCTION statement. Here, you specify whether the function returns the same value if it is called repeatedly with the same value of the input parameter. If you specify IS DETERMINISTIC, the function always returns the same value from successive invocations of the function with the same values of input parameters. If you specify IS NOT DETERMINISTIC, the function does not return the same value from successive invocations of the function. In the previous example, the function has been declared as DETERMINISTIC. For an example of a NON DETERMINISTIC function, look at the following scenario. Let us say you have written a function GetPrice that picks up the price of a specified product from the product master file, converts it to pounds, and returns the result. Let us also assume that it picks up the current rate of conversion from another file that contains the conversion rates from US dollars to any other currency for all major currencies. This would be an example of a non-deterministic function. This is because the value returned by the GetPrice depends on two variables: the conversion rate from the U.S. dollar to the pound, and the current U.S. price per unit of the product. Both of these values may change dynamically. Therefore, successive calls to the GetPrice function with the same input parameters might produce different results. The default setting for this clause is DETERMINISTIC. 6. This is the NO/READS/MODIFIES/CONTAINS SQL DATA clause of the CREATE FUNCTION statement. Here, you specify what kind of SQL statements the function will execute. Refer to DB2 UDB for AS/400 SQL Reference, SC41-5612, for detailed description of valid SQL statements for a given clause. 7. This is the EXTERNAL / NO EXTERNAL ACTION clause of the CREATE FUNCTION statement. This clause defines whether the function performs any action on external objects. This would be in addition to any processing the function performs on the input parameters that are sent to it. If the function writes/deletes/updates records in files, calls another sub program, or initiates any kind of processing, the EXTERNAL ACTION clause should be specified. In our GetDescription function, the function does not do any processing other than executing a SELECT statement. Therefore, NO EXTERNAL ACTION is specified. 8. The body of the SQL function begins here. This is signified by the BEGIN SQL statement in the CREATE FUNCTION statement above. 9. This is the SET SQL statement in the function where the function selects the structured CLOB value to a host variable. The description part of this variable is then extracted by the substring function. 10.Substrings and extracts the description part of the host variable and stores this value in the variable to be returned to the invoking process. 90 DB2 UDB for AS/400 Object Relational Support 11. Returns the value stored in the return variable to the invoking process 12.The end of the function’s body. 4.4.2.1 Passing LOBs and UDTs as parameters In this section, we discuss a function that accepts a parameter being a distinct type based on a LOB. The function’s name is GetDescription. It manipulates data from the PRODUCT_DESCRIPTION column in our test table PRODMAST01. The column stores the description of the product in a structured format. The contents of this column include a short description of the product, the range of sizes for the product, the color of the product, and the best use for the product. The data type of this column is the distinct type PRDDESC. This distinct type is sourced from the base type CLOB(50K). The GetDescription function takes the value of this column as an input, extracts the description part of the column, and returns this value to the calling program. In our example, the data type of the value returned by the function is VARCHAR( 1024 ). Figure 61 shows the CREATE FUNCTION statement for this function. Figure 61. Creating an SQL UDF with UDT parameter Notice in the CREATE FUNCTION statement in Figure 61 that the following clause is included in addition to the ones already described: static dispatch This is the STATIC DISPATCH clause of the CREATE FUNCTION statement. When you define an input parameter to a function as UDT, you have to specify this clause. If this clause is not specified, you are not allowed to create the function. The following error message is returned by the database: SQL0104 - Token was not valid. Valid tokens: STATIC. Figure 62 shows how to use the GetDescription SQL UDF in an SQL statement. User Defined Functions (UDFs) 91 Figure 62. Using SQL UDF GetDescription( PRDDESC ) in a query As seen from the example shown in Figure 61, there is no extra handling involved in using LOBs in SQL UDFs. SQL Functions provide a simple interface for handling LOB parameters, since the system takes care of most of the complexities on how to pass and receive the LOB parameter into the function. If you want to write an external function that uses LOBs, this is also possible. However, the handling of how to receive the LOB value into the function would have to be taken care of by you in the function program. This would be in addition to any other processing you do as part of the function. 4.4.2.2 Returning LOBs and UDTs as a result In this section, we describe how an SQL function returns a LOB type value. Our PRODMAST01 test table contains the PRODUCT_DESCRIPTION column that stores a description of the product and the PRODUCT_PICTURE column that stores the picture of the product. It would be useful to have a function that accepts this description as an input and then returns a picture of the product. This way, you can have a list of product descriptions displayed on the screen, and upon selection you could display the picture for that product. The GetPicture function, which implements the outlined logic, accepts three parameters: avalue of type CLOB(50K), a value of type PRDDESC, and a value of type PICTURE. The first parameter is the description for which you require the picture of the product. The second parameter is the value of the PRODUCT_PICTURE column of the PRODMAST01 table. The third parameter is the PRODUCT_PICTURE column of the PRODMAST01 table. The CREATE FUNCTION statement is shown in Figure 63 on page 92. 92 DB2 UDB for AS/400 Object Relational Support Figure 63. Creating the GetPicture SQL UDF which returns a BLOB as a return value Notice that the CREATE FUNCTION statement defines the data type of the parameter returned by the function to be the distinct type PICTURE. This data type is based on the base type BLOB(1M). You also see that no other extra clauses are needed in the CREATE FUNCTION statement when you define the return type of the function to be a distinct type. create functionTEAMxx/GETPICTURE( chs_QueryDescription CLOB(50K), chs_ProductDescription PRDDESC, bin_ProductPicturePICTURE ) returns PICTURE languageSQL specific GTPICT0001 is deterministic reads SQL DATA no external action static dispatch BEGIN if CLOB(chs_ProductDescription) = chs_QueryDescription then return bin_ProductPicture; else return NULL; end if; END; In the code snippet of the GetPicture function shown here, you see that a comparison is made of the two descriptions sent as input to the program. One of the descriptions is the one for which you want the picture, and the other one is the description value for the product for the row of the table. If they match, the function returns the picture back to the calling program. Otherwise, it returns a NULL value. Now, let us run this function and check the result. To demonstrate how this function works, we created a stored procedure called RunGetPicture. The stored procedure has a SELECT statement that calls the GetPicture function. The stored procedure accepts one parameter: the product number. Then, the stored procedure retrieves the description of the product corresponding to this product User Defined Functions (UDFs) 93 number. Next, the SELECT statement, which invokes the GetPicture UDF, is executed. The following code sample shows the most important parts of the stored procedure: ... EXEC SQL BEGIN DECLARE SECTION; SQL TYPE IS BLOB(1M) bin_ProductPicture; SQL TYPE IS CLOB(50K) chs_ProductDescription; char chs_ProductNumber[ 5 ]; char chs_Description[ 1024 ]; EXEC SQL END DECLARE SECTION; void main( int argc, char **argv ) { strcpy( chs_ProductNumber, argv[1 ] ); printf( "The product number - %s\n", chs_ProductNumber ); EXEC SQL select Product_Description into :chs_ProductDescription from prodmast01 where product_number = SRLNUMBER( :chs_ProductNumber ); EXEC SQL DECLARE cur_Picture CURSOR FOR Select GetPicture( :chs_ProductDescription, Product_Description, Product_Picture ) from prodmast01; ..... while ( sqlca.sqlcode != 100 ) { printf( "\n" ); if ( bin_ProductPicture.length != 0 ) { printf("Values returned by GetPicture(CLOB,PRDDESC,PICTURE):\n" ); printf( "The picture length - %d\n", bin_ProductPicture.length ); printf( "The picture data - %s\n", bin_ProductPicture.data ); } else { printf("GetPicture (CLOB,PRDDESC,PICTURE) returned NULL\n"); } bin_ProductPicture.length = 0; strcpy( bin_ProductPicture.data, " " ); EXEC SQL fetch cur_Picture into :bin_ProductPicture; } .... } The stored procedure prints out the length and the contents of the picture returned to it by the BLOB. The full code of the stored procedure is given in Appendix A, “Source code listings” on page 215. The stored procedure was called from the interactive SQL prompt. Figure 64 on page 94 shows the call to the stored procedure from the interactive SQL prompt. 94 DB2 UDB for AS/400 Object Relational Support Figure 64. Calling the RunGetPicture The result of the call to the GetPicture is shown in Figure 65. Figure 65. The result of the call to the GetPicture SQL UDF As shown in Figure 65, the length and data is returned only by the first call to the function. The other two calls to the function result in a NULL value. This is because one description matches only one product. If there were multiple products matching the same description, multiple non-null results would have Enter SQL Statements Type SQL statement, press Enter. Current connection is to relational database RCHASM23. ===> CALL RUNGETPICTURE( '00001' ) Bottom F3=Exit F4=Prompt F6=Insert line F9=Retrieve F10=Copy line F12=Cancel F13=Services F24=More keys (C) COPYRIGHT IBM CORP. 1982, 1999. The product number - 00001 Values returned by GetPicture( CLOB, PRDDESC, PICTURE ): The picture length - 26810 The picture data - åñã / { The GetPicture function( CLOB, PRDDESC, PICTURE ) returned NULL The GetPicture function( CLOB, PRDDESC, PICTURE ) returned NULL Press ENTER to end terminal session. ===> F3=Exit F4=End of File F6=Print F9=Retrieve F17=Top F18=Bottom F19=Left F20=Right F21=User Window User Defined Functions (UDFs) 95 been returned. Since the data for the picture is in binary format, you cannot display this data on the 5250 terminal. You see some non-printable characters displayed on the screen. However, if you called the function from an interface that is capable of displaying graphics data, you could see the picture displayed on the screen. 4.4.3 Coding external UDFs External functions are functions coded in one of the High Level Languages (HLL) available on the AS/400 system. Implementing an external function is more difficult than writing an SQL function. However, if you want to do some complex or sophisticated processing, or plan to re-use the code that already exists, the external functions are the best choice for you. 4.4.3.1 Parameter styles in external UDFs You can specify several different parameter styles for an external function. On the external function invocation, DB2 UDB passes a number of parameters to the function in addition to those that you provide as input parameters. The number and type of extra parameters passed by DB2 UDB depends on the parameter style. You can specify the required parameter style at the time the function is created. DB2 UDB for AS/400 supports four parameter styles: • SQL • DB2SQL • GENERAL • GENERAL WITH NULLS The various parameters passed in each of the parameter styles are discussed in this section. Later, we provide examples for each of these parameter styles. SQL parameter style The required set of parameters for this parameter style are: ExternalUDF(IN arguments (repeated), OUT result, IN argument indicator variables (repeated), OUT result indicator, OUT sqlstate, IN function name, IN specific name, OUT diagnostic message) The elements of the parameters are explained in the following list: • Arguments: Input parameters. Passed in from database to UDF. • Result: Result value. Returned from the UDF to database. • Argument indicators: NULL indicator for each argument. If NULL was passed for the corresponding argument, the indicator variable contains -1. If a valid value was passed, the indicator variable contains 0. The function can The current sizes for all the arguments supported by the different parameter styles are defined in the sqludf.h include file found in QSYSINC library. There are also equivalent include files for RPG and Cobol. Note 96 DB2 UDB for AS/400 Object Relational Support test the value of an argument indicator. If the corresponding argument contains NULL or was truncated, it can take corrective action. These are input parameters. • Result indicator: NULL or mapping error indicator for each argument. This variable is examined by the invoking database process to check if the function returned a correct, NULL, or a truncated value. Set this parameter to -1 to indicate NULL, or 0 to indicate correct return value. This is an output variable. • SQL state: Corresponds to SQLSTATE in SQL. It is defined as CHAR(5). This value is set by the function to signal an error or warning to the database. It has one of the following values: – 00000: No errors – 01Hxx: Warning. It results in SQLCODE +462 from SQL. The last two characters, xx, are set by the function and can be anything you like. – 38xxx: Error occurred in UDF. It results in SQL -443. The last three characters, xxx, are set by the function and can be anything you like. When you set this error state the database interrupts the execution of the invoking SQL statement. In the Interactive SQL environment, the following message is displayed in this situation: Query cannot be run. See lower level messages. This is an output parameter. • Function name: A fully qualified function name. The fully qualified function name follows the SQL naming standard. This is an input parameter. • Specific name: The specific name of the function. This is an input parameter. • Diagnostic message: The message text to put into an SQL message. It corresponds to the sqlstate setting. When the function signals an error message to the database, it can set this parameter to a customized error message. This text is then embedded inside the second level message for the CPF503E, which is placed in the job log of the job running the SQL statement. Refer to 4.4.3.2, “Coding UDFs using the SQL parameter style” on page 97, for more details. This is an output parameter. DB2SQL parameter style All the parameters passed to a function for the SQL paramours style are also passed to a function with the DB2SQL heptameter style. However, DB2SQL parameter style allows additional parameters to be passed. The supported set of parameters for this parameter style are: externalUDF(IN arguments (repeated), OUT result, IN argument indicator variables (repeated), OUT result indicator, OUT sqlstate, IN function name, IN specific name, OUT diagnostic message, scratchpad, call type, dbinfo) The additional parameters, not covered in the previous section, are explained in the following list: User Defined Functions (UDFs) 97 • Scratchpad: The scratchpad if the SCRATCHPAD clause was specified in the CREATE FUNCTION statement. This can be used by the function as an area where it can save the results of the last call in between calls to the function. If the length of the scratchpad area required is not specified in the CREATE FUNCTION statement, the system reserves 100 bytes for the function by default. The maximum length that can be reserved for the scratchpad is 16,000,000 bytes. Each invocation of the function will be able to see the results stored by the last function invocation in the scratchpad. On the first call to the function, the contents of the scratchpad are initialized to all zeros. The data can be stored into the scratchpad area by a function only during the processing of a given SQL statement. No function can store data in the scratchpad area between SQL statements. This is an optional input and output parameter. • Call type: A parameter for the type of call if the FINAL CALL was specified on the CREATE FUNCTION statement. This can be one of three values: -1 First call to UDF 0 Normal call to UDF 1 Final call to UDF This parameter is normally used with the SCRATCHPAD parameter. On the first call, the scratchpad area is set up by the function and then used in subsequent normal calls. On the last call to the function, the scratchpad area is cleaned up. This is an optional input parameter. • dbinfo: A parameter for the dbinfo structure if the DBINFO clause is specified on the CREATE FUNCTION statement. Refer to the sqludf.h include found in the QSYSINC library for a detailed definition of this structure. General parameter style The supported set of parameters for this parameter style is: externalUDF(IN arguments (repeated)) For this parameter style, the result is the return value of the value returning function itself. 4.4.3.2 Coding UDFs using the SQL parameter style In this section, we look at examples on how to code external UDFs with the SQL parameter style. We also demonstrate how the parameters that DB2 passes to the function can be used within the function. Our test PRODMAST01 table contains the PRODUCT_PICTURE column. This column stores a picture of the product. The picture can be stored in this column in one of the widely accepted formats, such as GIF, BMP, JPG, and so forth. The The maximum number of parameters allowed in CREATE FUNCTION is 90. For external functions created with PARAMETER STYLE SQL, and for SQL functions, the input and result parameters specified and the implicit parameters for indicators, such as SQLSTATE, function name, specific name, and message text, as well as any optional parameters, are included. The maximum number of parameters is also limited by the maximum number of parameters allowed by the licensed program that is used to compile the external program or service program. Note 98 DB2 UDB for AS/400 Object Relational Support data type of the column is the PICTURE distinct type which, itself, is based on the base type BLOB(1M). Let us suppose you need to find out how many pictures are stored in this column with a specified file format. To accomplish this task, we implement two functions IsGif and IsBmp, which take the value of the PRODUCT_PICTURE column and determine whether its contents are in GIF or BMP format, respectively. If the contents are in the GIF format, the IsGif function returns 1. Otherwise, it returns 0. If the input to the IsGif function is NULL, it returns NULL. Similarly, the IsBmp function returns 1 if the input is in BMP format. Otherwise, the function returns 0. It returns a NULL if the input is NULL. Let us examine the CREATE FUNCTION statement for the IsGif function. The numbered sections are further explained in the list that follows: create function TEAMxx/ISGIF( PICTURE ) 1 returns INTEGER 2 language C 3 specific ISGIF00001 4 no sql 5 no external action 6 static dispatch 7 external name 'TEAMXX/PICTCHECK(fun_CheckPictureType)' 8 parameter style SQL; 9 CREATE FUNCTION statement notes 1. Here, you define the name of the function, the input parameters to the function, and their data types. Refer to 4.4.1.1, “Creating sourced UDFs as scalar functions” on page 78, for more information on this. 2. This is the RETURNS clause of the CREATE FUNCTION statement. Refer to 4.4.1.1, “Creating sourced UDFs as scalar functions” on page 78, for more information on this. 3. This is the LANGUAGE clause of the CREATE FUNCTION statement. The LANGUAGE clause specifies what language was used to implement the external UDF. In our case, it is written in ILE C/400. This information helps the database to pass parameters to the UDF in the format required by the programming language. You can write the UDFs in any of the following languages: • CL • COBOL • COBOLLE • PLI • RPG • RPGLE • SQL • C/C++ The LANGUAGE clause is optional. If it is not specified, the system tries to retrieve the attribute of the program object specified in the EXTERNAL NAME clause and set the language clause accordingly. If the program object does not exist, or if the attribute is not present, the language is defaulted to ILE C/400. 4. This is the SPECIFIC NAME clause of the CREATE FUNCTION statement. The specific name is checked for uniqueness and entered into the system catalogue. User Defined Functions (UDFs) 99 5. This is the NO / READS / MODIFIES / CONTAINS SQL DATA clause of the CREATE FUNCTION statement. Refer to 4.4.2, “Coding SQL UDFs” on page 85, for more information on this. 6. This is the EXTERNAL / NO EXTERNAL ACTION clause of the CREATE FUNCTION statement. Refer to 4.4.2, “Coding SQL UDFs” on page 85, for more information on this. 7. This is the STATIC DISPATCH clause of the CREATE FUNCTION statement. Refer to 4.4.2.1, “Passing LOBs and UDTs as parameters” on page 90, for more information on this. 8. This is the EXTERNAL NAME clause of the CREATE FUNCTION statement. This is the name of the external program that this function calls when it is invoked by the database. In this example, TEAMXX is the name of the library in which the program resides. PICTCHECK is the name of the service program that is to be executed, and fun_CheckPicture is the name of the ILE C/400 function inside the program that will be called when the function is invoked. The program does not need to exist at the time of the creation of the function, but it must be created before the function is invoked for the first time. This is an optional clause. If it is not specified, the system assumes that the name of the program to be executed is the same as the name of the function. 9. This is the PARAMETER STYLE clause of the CREATE FUNCTION statement. This can be one of four values: SQL, DB2SQL, GENERAL WITH NULLS, or GENERAL. DB2 UDB passes additional parameters, apart from the input arguments defined in the CREATE FUNCTION statement, based on the parameter style specified. Now let’s examine the external program PICTCHECK referred to in the CREATE FUNCTION statement above. We discuss what parameters DB2 sends to the program and how the program makes use of the parameters. The complete listing of the program is given in A.3, “PictCheck: External UDF” on page 218. This program also calls the fun_CheckHeader function. The source for this function is listed in A.4, “ChkHdr” on page 220. The PICTCHECK is used by both the IsGif and the IsBmp functions discussed earlier in this section. Depending on what function calls the program, its logic checks for the appropriate type of image. This leads to the reuse of the common code in the two functions. Both functions are defined with the parameter style SQL. The following code sample illustrates how a function with parameter style SQL is coded. The numbered areas are further explained in the list that follows: void SQL_API_FN fun_CheckPictureType( BLOB1M *str_ProductPicture, 1 SQLUDF_INTEGER *nmi_IsCorrect, 2 SQLUDF_NULLIND *nms_InputNullIndicator01, 3 SQLUDF_NULLIND *nms_OutputNullIndicator01, SQLUDF_CHAR sqludf_sqlstate[ SQLUDF_SQLSTATE_LEN + 1 ], 4 SQLUDF_CHAR sqludf_fname[ SQLUDF_FQNAME_LEN + 1 ], 5 SQLUDF_CHAR sqludf_fspecname[ SQLUDF_SPECNAME_LEN + 1 ], 6 SQLUDF_CHAR sqludf_msgtext[ SQLUDF_MSGTEXT_LEN + 1 ] ) 4 Code sample notes 1. The function named fun_CheckPictureType is the entry point in the ILE C service program. This entry point is referred to in the CREATE FUNCTION statement for the IsGif and the IsBmp functions as follows: external name 'TEAMXX/PICTCHECK(fun_CheckPictureType)' 100 DB2 UDB for AS/400 Object Relational Support If the reference is to an entry point in a service program, the external name is specified as lib.pgmname(entrypoint) or just pgmname(entrypoint). Note the use of the SQL_API_FN constant in the function declaration. This constant makes the function portable to multiple platforms. The value of this constant is set in an include file specific for a given platform, such as Windows NT, OS/2, or AIX. The value of this constant for the AS/400 system is defined in the header file sqlsystm.h found in the source file named H in the QSYSINC library. The IsGif or the IsBmp functions accept an input parameter of type PICTURE, which is a distinct type based on the base type BLOB(1M). When passed to an external program, a UDT is implicitly cast to its source type. In our case, we defined a structure called BLOB1M inside our program, which serves as a buffer for the picture object. The structure definition is shown here: typedef struct { unsigned long length; char data[ 1 ]; } BLOB1M; The function accepts one input parameter, which is the picture whose format we wish to determine. This is the first parameter to the ILE C function fun_CheckPictureType, which implements the UDF. 2. This is the value returned by the function. In the CREATE FUNCTION statement shown on page 98, it was defined as INTEGER. However, in the ILE C implementation, we defined it to be of type SQLUDF_INTEGER. We used this convention so that the function is portable across DB2 UDB platforms. All the basic data types on the AS/400 system have their counterparts under the DB2 UDB convention. These counterparts are defined in the header file sqludf.h. This file has to be included when you write an external program for a UDF. 3. The next two parameters to the fun_CheckPictureType function are the null input indicators for the input parameter and the return value. Whenever a null value is passed into the function on input, the input null indicator contains -1. If the value is correct, it contains 0. In our program, we check for null input, and if we get a null input, we return a null output. This is shown in the code sample here: if ( *nms_InputNullIndicator01 == -1 ) { *nms_OutputNullIndicator01 = -1; return; } If we want to pass a return value back to the database, we set the return variable, which in our case is nmi_IsCorrect, and set the return indicator to 0 as shown in the following code snippet: if ( ( nmi_CompareResult01 == 1 ) || ( nmi_CompareResult02 ==1)) { *nmi_IsCorrect = 1; *nms_OutputNullIndicator01 = 0; } else { User Defined Functions (UDFs) 101 *nmi_IsCorrect = 0; *nms_OutputNullIndicator01 = 0; } 4. The next two parameters, sqludf_sqlstate and sqludf_msgtext are used together. The sqludf_sqlstate contains the SQL state. This parameter can be used to signal an error or a warning condition on return to the database. The function can also set the message text parameter to a customized error message. However, the message text can only be set when sqludf_sqlstate is also set. Our program checks whether it was called by either the IsGif or the IsBmp function. If it is neither of these two, the program simply signals an error condition and returns it as in the following code example: *nms_OutputNullIndicator01 = -1; strcpy( sqludf_sqlstate, "38501" ); strcpy( sqludf_msgtext, "Unregistered function" ); return; 5. The parameter sqludf_fname contains the fully qualified name of the function that called this program. In our case, either the IsGif or the IsBmp functions can call the program. The program checks which function called it. If it was the IsGif function that made the call, the program checks the picture for GIF picture format; otherwise, it checks for the BMP picture format. This is implemented in the following code snippet: . #define GIF_FUNCTION "ISGIF" #define BMP_FUNCTION "ISBMP" ... void SQL_API_FN fun_CheckPictureType( ...... ) { ... char *chr_FunctionResolution; ... chr_FunctionResolution = strstr( sqludf_fname, GIF_FUNCTION ); if ( chr_FunctionResolution != NULL ) { ... } ... chr_FunctionResolution = strstr( sqludf_fname, BMP_FUNCTION ); if ( chr_FunctionResolution != NULL ) { ... } } 6. The parameter, sqludf_specname, is the specific name of the function that is passed by the database. Instead of using the function name, you can also use the specific name for comparisons. This is useful since UDFs can be overloaded. You can have more than one UDF with the same name calling the same program. Even if the function names were the same, the specific names would be unique. As mentioned earlier, the PICTCHECK program was created as a service program. The advantage of this approach is that the service program becomes active (if run in activation group *CALLER) when the function is resolved, therefore minimizing call overhead at IO. We used the following CL commands to compile and bind the PICTCHECK service program: CRTCMOD MODULE(TEAMXX/PICTCHECK) SRCFILE(TEAMXX/QCSRC) DBGVIEW(*SOURCE) CRTCMOD MODULE(TEAMXX/CHKHDR) SRCFILE(TEAMXX/QCSRC) DBGVIEW(*SOURCE) 102 DB2 UDB for AS/400 Object Relational Support CRTSRVPGM SRVPGM(TEAMXX/PICTCHECK) MODULE(TEAMXX/PICTCHECK TEAMXX/CHKHDR) EXPORT(*ALL) To invoke the IsGif function, use a SELECT statement, such as the following example: SELECT Product_Number, IsGif( Product_Picture ) from PRODMAST01; The results of the above query are shown in Figure 66. Figure 66. Running the IsGif external UDF with the SQL parameter style You would, similarly, run the IsBmp function. The output of the IsBmp function is shown in Figure 67. User Defined Functions (UDFs) 103 Figure 67. Running the IsBmp external UDF with the SQL parameter style 4.4.3.3 Coding external UDFs using the DB2SQL parameter style This section shows you how to code external UDFs using the DB2SQL parameter style. You learn how to use the SCRATCHPAD and the FINAL CALL parameters inside the UDF. The ORDER_TOTAL column in the ORDERHDR table contains the total of the customer’s order. The data type of this column is the distinct type MONEY, which is based on the built-in type DECIMAL(11,2). Suppose you wanted to find out the second, third, or the fifth best order by order total from the ORDERHDR table. One of the approaches might involve writing a program that calculates, for instance, the third best order total and writes it to a file. Then, your application would need to access this file and read the data from the file. We believe it would be much better to have a UDF that does this processing. The UDF could then be used inside a SELECT statement in any AS/400 interface that supports SQL. To accomplish this task, we coded an external UDF called Rating. The function takes in two parameters: a value of type MONEY from the ORDER_TOTAL column and an INTEGER, which specifies which rating you want to retrieve. The function scans the ORDER_TOTAL column and returns for each row the Nth best order total where N is the INTEGER that you specified. The CREATE FUNCTION statement for the function is shown in Figure 68 on page 104. 104 DB2 UDB for AS/400 Object Relational Support Figure 68. Creating the rating UDF with the DB2SQL parameter style Let us examine the CREATE FUNCTION statement. The CREATE FUNCTION statement is presented here. The numbered areas are explained in the list that follows: create function TEAMxx/RATING( MONEY, INTEGER ) returns MONEY language C specific RATING0001 no SQL no external action scratchpad 1 final call 2 static dispatch external name 'TEAMXX/RATING( fun_Rating )' parameter style DB2SQL; CREATE FUNCTION statement notes 1. This is the SCRATCHPAD clause of the CREATE FUNCTION statement. When you specify this clause, DB2 passes a scratchpad area to the function where the function can store results of the last call, and it will be available to the function the next time it is called. You can specify the required length for the scratchpad area if you want. This can be a maximum of 16,000,000 bytes. If not specified, system defaults the length of the scratch pad area to 100 bytes. In our example above, we did not specify the length of the scratchpad area. Therefore, the system will reserve 100 bytes of memory for scratchpad area and send the address of this area to the function program. 2. This is the FINAL CALL clause of the CREATE FUNCTION statement. When this clause is specified, DB2 UDB sends the type of call to the function every time the function is invoked. The value passed can be one of three values: 1 if this is the first call to the function, 0 if this is neither the first nor the last call to the function, and 1 if this is the last call to the function. This parameter is normally used along with the SCRATCHPAD clause. On the first call, the function sets up the scratchpad area. On a regular call, it accesses the scratchpad area. On the last call, the function cleans up the scratchpad area. User Defined Functions (UDFs) 105 Now let’s examine the contents of the Rating program. The complete listing of the source code is given in Appendix A.6, “Rating: External UDF using SCRATCHPAD” on page 221. We start with the function declaration for a function with the DB2SQL parameter style, concentrating on the most important parameters. The numbered areas are explained in the list that follows: void SQL_API_FN fun_Rating( decimal( 11, 2 ) *nmpd_InputMoneyValue, SQLUDF_INTEGER*nml_InputRequiredRank, decimal( 11, 2 )*nmpd_OutputMoneyValue, SQLUDF_NULLIND*nms_InputNullIndicator01, SQLUDF_NULLIND*nms_InputNullIndicator02, SQLUDF_NULLIND*nms_OutputNullIndicator01, SQLUDF_CHARsqludf_sqlstate[ SQLUDF_SQLSTATE_LEN + 1 ], 1 SQLUDF_CHARsqludf_fname[ SQLUDF_FQNAME_LEN + 1 ], SQLUDF_CHARsqludf_fspecname[ SQLUDF_SPECNAME_LEN + 1 ], SQLUDF_CHARsqludf_msgtext[ SQLUDF_MSGTEXT_LEN + 1 ], 1 SQLUDF_SCRATCHPAD*sqludf_scratchpad, 2 SQLUDF_CALL_TYPE*sqludf_call_type ) 3 Code sample notes 1. The sqludf_sqlstate is set by the function to indicate an error condition to the database on return from the function. In our function, we set this parameter if the required rank parameter is either null or less than zero. This is shown in the following code snippet: if ( ( *nms_InputNullIndicator02 != 0 ) || ( *nml_InputRequiredRank < 0 ) ) { strcpy( sqludf_sqlstate, "38601" ); strcpy( sqludf_msgtext, "Incorrect rank value specified" ); *nms_OutputNullIndicator01 = -1; return; } The function can also pass a custom message back to the database by setting the message text parameter sqludf_msgtext. 2. When a function is created as a scratchpad function, the database provides the function with a 100 byte scratchpad area. The function can store data in this area that it needs to preserve between function calls. Each invocation of the function can see the data stored by the last invocation of the function. The data in the scratchpad is stored only during the processing of a given SQL statement and not between SQL statements. The function is passed a pointer to the scratchpad area called sqludf_scratchpad. The scratchpad is initialized to zeros before the first call to the function. The following code snippets show how the scratchpad is implemented. First, we define our internal structure, called str_ScratchPad, that helps us keep track of different values stored in the ORDER_TOTAL column: typedef struct { decimal( 11, 2 ) *nmpd_LargeValue ; long nml_RequiredRating; long nml_ValuesStored; } str_ScratchPad; . . .. str_ScratchPad *str_SPad; str_ScratchPad **ptr_AlignmentPointer; . . .. /* Get the address of the scratchpad buffer passed by the DB2 UDB and align the pointer for the internal scratchpad structure at the 16 byte boundary */ ptr_AlignmentPointer = ( ( str_ScratchPad ** )( sqludf_scratchpad ) ) + 1; str_SPad = ( str_ScratchPad * ) ptr_AlignmentPointer; 106 DB2 UDB for AS/400 Object Relational Support In the previous code snippet, you see that a structure, called str_ScratchPad, has been declared. The variable, nmpd_LargeValue, is an array of packed decimals that is used to keep the list of values encountered so far. The variable, nml_RequiredRating, stores the rank that you wish to retrieve. The variable, nml_ValuesStored, stores the number of values stored so far in the packed decimal array. We declare a pointer to this structure called str_SPad. The scratchpad that is passed to the program itself is a structure of two elements. The following snippet gives the definition of the scratchpad structure as it is defined in the include file sqludf.h: SQL_STRUCTURE sqludf_scratchpad { unsigned long length; /* length of scratchpad data */ char data[SQLUDF_SCRATCHPAD_LEN]; /* scratchpad data, init. to all \0 */ }; In this program, you see that the data element of the scratchpad structure is cast to the str_scratchPad structure. In other words, we use the data element of the sqludf_scratchpad structure as a memory buffer for our internal str_ScratchPad structure. The method of casting, such as the one shown above, is used to align the str_SPad pointer on a 16-byte boundary. The AS/400 system requires that the memory addresses be placed on the 16-byte boundaries. If your code fails to align addresses properly, an exception is thrown at the run time, and the application is terminated. In the following code snippet, the scratchpad area that was sent to the function by the database is being put to work. The largest numbers are moved to the top of the array, the smaller ones follow them, and the required rating is then returned to the database from the array. This processing is performed on every invocation of the function: /* Check for regular function call */ if ( *nms_InputNullIndicator01 == 0 ) { /* Set the lowest value variable */ nmpd_LowestValue = *nmpd_InputMoneyValue; for ( nmi_Counter = 0; nmi_Counter < str_SPad->nml_ValuesStored; nmi_Counter++ ) { /* Exchange if the current lowest value is higher than the stored lowest */ /* value */ if ( str_SPad->nmpd_LargeValue[ nmi_Counter ] < nmpd_LowestValue ) { nmpd_Temp = nmpd_LowestValue; nmpd_LowestValue = str_SPad->nmpd_LargeValue[ nmi_Counter ]; str_SPad->nmpd_LargeValue[ nmi_Counter ] = nmpd_Temp; } /* Array not full then add the next element */ if ( str_SPad->nml_ValuesStored < str_SPad->nml_RequiredRating ) { str_SPad->nml_ValuesStored++; str_SPad->nmpd_LargeValue[ str_SPad->nml_ValuesStored - 1 ] = nmpd_LowestValue; } /* return NULL if required ranking not in the array*/ if ( str_SPad->nml_ValuesStored < str_SPad->nml_RequiredRating ) { *nms_OutputNullIndicator01 = -1; return; } /* Otherwise return the required ranking */ else { *nmpd_OutputMoneyValue = str_SPad->nmpd_LargeValue[ User Defined Functions (UDFs) 107 str_SPad->nml_RequiredRating - 1 ]; *nms_OutputNullIndicator01 = 0; return; } } } 3. The scratchpad parameter is normally used in conjunction with the FINAL CALL parameter. This is the last parameter in the fun_Rating function and is named sqludf_call_type. This parameter tells the function whether this is the first call, the last call, or a regular call. The following code snippets show how to use this parameter: if ( *sqludf_call_type == -1 ) { if ( ( *nms_InputNullIndicator02 != 0 ) || ( *nml_InputRequiredRank <0)) { strcpy( sqludf_sqlstate, "38601" ); strcpy( sqludf_msgtext, "Incorrect rank value specified" ); *nms_OutputNullIndicator01 = -1; return; } str_SPad->nml_RequiredRating = *nml_InputRequiredRank; str_SPad->nml_ValuesStored = 0; nml_Temp = *nml_InputRequiredRank * sizeof( decimal( 11, 2 ) ); str_SPad->nmpd_LargeValue = ( decimal( 11, 2 ) * )malloc( *nml_InputRequiredRank * sizeof( decimal( 11, 2 ) ) ); } First, a check is made to see if this is the first call. If so, at this point in time, the function must perform required initialization tasks. In our case, the program dynamically allocates the memory for storing the required number of values in the scratchpad using the ILE C/400 malloc function. This allocation is not done on the subsequent calls to the function that are considered to be regular calls. In the following snippet, you see that we also check if this is the final call: if ( *sqludf_call_type == 1 ) { free( str_SPad->nmpd_LargeValue ); } At this point in time, the function must perform any cleanup tasks that need to be performed. In our case, we allocated a piece of memory for our scratchpad using the malloc ILE C/400 function. This piece of memory needs to be freed. This is done by the free statement. To invoke this function, you could use a SELECT statement, such as the one shown here: SELECT Max( Decimal( Rating( Order_Total, 2) ) )from OrderHdr In the SELECT statement above, you ask the function to calculate the second best order total in the ORDERHDR table. Note the usage of the MAX built-in function. Our rating function is invoked for each row of the ORDERHDR table, and it produces a result for each row. In our example, the function shows the second best result for all the rows retrieved so far. We want to calculate the second best rating for all rows in the table, which explains the need for a MAX function. The result of the above query is shown in Figure 69 on page 108. 108 DB2 UDB for AS/400 Object Relational Support Figure 69. Using the rating external function with DB2SQL parameter style A more complex query can be given to find the number or the name of the customer with the second best order total. Figure 70 shows a sample query that does this. Figure 70. Finding the number and name of the customer using the rating function 4.5 Function resolution and parameter promotion in UDFs In this section, we demonstrate function resolution and parameter promotion. For concepts of function resolution, parameter promotion, and overloading, refer to 4.3, “Resolving UDF” on page 71. 4.5.1 An example of function resolution in UDFs Consider the following situation. Say there is a function, GetDescription, which accepts one parameter: A product number that is CHAR( 5 ) and returns the product description as a VARCHAR( 1024 ). This function operates on the User Defined Functions (UDFs) 109 PRODUCT_NUMBER column of the PRODMAST04 table. It returns the contents of the PRODUCT_DESCRIPTION column, which is of data type CLOB(50K). Now, another table, PRODMAST01, is created with the same columns and data as PRODMAST04. Here, the columns PRODUCT_NUMBER and PRODUCT_DESCRIPTION are based on distinct types SRLNUMBER and PRDDESC, respectively. The SRLNUMBER distinct type is based on the built-in type CHAR(5), and the PRDDESC column is based on the built-in type CLOB(50K). Now, you execute the following query: select Product_Number, GetDescription( Product_Number ) as Product_Description from ProdMast04; The GetDescription( CHAR5 ) function executes correctly. This is shown in Figure 71. Figure 71. Executing the GetDescription ( CHAR(5) ) function The system searched for a function called GetDescription that would accept an input parameter of data type CHAR(5) using the function selection algorithm described in 4.3.4, “The function selection algorithm” on page 76. It found one function that exactly matched the criteria. If there had been no function called GetDescription, accepting a CHAR(5 ) as input parameter, the system would have searched for the next best alternative: afunction called GetDescription, which accepts a VARCHAR as an input parameter. See 4.3.3, “Parameter matching and promotion” on page 74, for details. Now, we try to execute the same query on the PRODMAST01 table. This time the query fails. Figure 72 on page 110 shows the result of the query. 110 DB2 UDB for AS/400 Object Relational Support Figure 72. The query fails when it is run over the Prodmast01 table The query fails because the system could not find a function called GetDescription that accepts an input parameter of data type SRLNUMBER. Then, the data type precedence is checked to see if the parameter can be promoted to other data types. In this case, since the data type of the parameter is a distinct type, it cannot be promoted to anything other than itself. Since the parameter is not promotable, the system returns the following message: SQL0204 - GETDESCRIPTION in *LIBL type *N not found. To solve this problem, we need to overload the GetDescription function. Figure 73 shows the CREATE FUNCTION statement that we used to create a GetDescription function that accepts the SRLNUMBER distinct type as an input parameter. User Defined Functions (UDFs) 111 Figure 73. Creating the GetDescrption( SRLNUMBER ) sourced UDF Note that, instead of implementing the function from scratch, we reuse the existing implementation of the GetDesciption(char()) function. After creating the function, we run the query again. This time it works. The results of the query are shown in Figure 74. Figure 74. Running the GetDescription( SRLNUMBER ) UDF 112 DB2 UDB for AS/400 Object Relational Support This time, the system was able to find a function called GetDescription, which accepts SRLNUMBER distinct type as a parameter. The function is then executed. 4.5.2 An example of parameter promotion in UDF In this section, we will show you an example of parameter promotion. Consider the following scenario: The PRODMAST04 table has a PRODUCT_DESCRIPTION and a PRODUCT_NUMBER column. The data type of the PRODUCT_NUMBER column is CHAR(5), and the data type of the PRODUCT_DESCRIPTION column is CLOB(50K). The PRODUCT_DESCRIPTION column is a CLOB containing the description of the product, the size range of the product, and the color of the product. Suppose we wish to extract the size range from this column. We code a UDF, called GetSize, which accepts the product number and returns the size of the product. Let’s assume, for illustration purposes, that the type of the product number parameter is CLOB(50K). Please note that the actual data type of the PRODUCT_NUMBER column in the table is CHAR(5). The CREATE FUNCTION statement for the function is shown in Figure 75. Figure 75. The GetSize( CLOB(50K) )SQL UDF The data type of the value returned by the function is VARCHAR(1024). Note that we concatenate the character constant 'Function GetSize( CLOB(50K) )' with the return variable chs_ReturnValue. After the function was successfully created, we used it in a SELECT statement, such as the one shown here: select product_number, GetSize( product_number ) as SizeRange from prodmast04 User Defined Functions (UDFs) 113 The function GetSize( CLOB(50K ) ) is executed by the system. This is shown in Figure 76. Figure 76. Running the GetSize( CLOB(50K ) function Notice that the text 'Function GetSize( CLOB(50K) )' appears as part of the size range column. The input to the GetSize function was a value of type CHAR(5). The GetSize( CLOB(50K) ) function executed because of parameter promotion. The system searches the system catalog for all functions named GetSize that are located in the library list of the job executing the SELECT statement. A list of all such functions is compiled. Then, all selected functions that have more than one input parameter are eliminated. Now, for the remaining functions, a search is made for a function GetSize that accepts CHAR(5). The system finds no such function. The function’s parameter is now promoted to the next level. This is done by looking up the precedence list, as shown in Table 9 on page 76, and finding out which is the next datatype in the hierarchy for the CHAR data type. In our case, it is the VARCHAR data type. The product_number value, which we supplied to the GetSize function, is now cast to a VARCHAR data type, and the list is scanned to check for a function GetSize that accepts a VARCHAR as an input variable. Again, the system finds no such function and the precedence list is checked again to find the next data type higher in the hierarchy. In our example, it is CLOB. The product_number value is now cast to a CLOB, and the list of functions is again scanned to check for a function GetSize, which accepts a CLOB as an input parameter. This time the system finds the GetSize( CLOB( 50K ) ) function. Therefore, this function is currently the best fit for the function referenced in the SELECT statement. Therefore, this function is executed. Now, let’s create another GetSize function. This time the input parameter is VARCHAR(5). The CREATE FUNCTION statement is shown in Figure 77 on page 114. Notice that here the character constant 'Function GetSize( VARCHAR(5) )' is concatenated to the end of the return variable chs_ReturnValue. 114 DB2 UDB for AS/400 Object Relational Support Figure 77. Creating the GetSize( VARCHAR(5) )SQL UDF Now, we run our query again. This time, function GetSize( VARCHAR(5) ) is executed. The product_number value that we supplied to the GetSize function is now cast to a VARCHAR data type, and the list of selected GetSize functions is scanned to check for a function GetSize, which accepts a VARCHAR as an input variable. This time, the system finds the function with the signature GetSize (VARCHAR(5) ). The function GetSize( VARCHAR(5) ) is the best match for the function called in the SELECT statement. Figure 78 shows the result of the query. User Defined Functions (UDFs) 115 Figure 78. Running the GetSize( VARCHAR(5) ) SQL UDF Let’s now create a third GetSize function. This time, the data type of the input parameter is CHAR(5). Figure 79 shows the CREATE FUNCTION statement. Figure 79. Creating the GetSize( CHAR(5) ) SQL UDF 116 DB2 UDB for AS/400 Object Relational Support Again, the same query is run. This time, the system selects the function GetSize( CHAR(5) ) to be executed because it constitutes an exact match for the function called in the SELECT statement. Figure 80 shows the results of the query. Figure 80. Running the GetSize( CHAR(5) ) function. 4.6 The system catalog for UDFs The database manager provides a number of data dictionary facilities that can be used to keep track of User Defined Functions. In this section we see how to view UDF information using the SYSROUTINES catalog, the SYSPARAMS catalog, and the SYSFUNCS view. 4.6.1 SYSROUTINES catalog User Defined Functions are stored in the SYSROUTINES catalog. Refer to DB2 UDB for AS/400 SQL Reference, SC41-5612, for the detailed description of the catalog views. The following SQL statement displays SYSROUTINES information on User Defined Functions in our test TEAMXX library: The SYSROUTINES catalog contains details for both User Defined Functions and stored procedures. When you want to work only with UDFs you can use a view called SYSFUNCS. This view was created over the SYSROUTINES catalog with the following SQL statement: create view qsys2/sysfuncs as select * from qsys2/sysroutine where routine_type='FUNCTION' Note User Defined Functions (UDFs) 117 select * from sysroutines where routine_schema = 'TEAMXX' and routine_type = 'FUNCTION'; If we run this statement using the Operations Navigator Run SQL Scripts window, the query results viewer displays UDFs details as shown in Figure 81. Figure 81. Content of SYSROUTINES catalog Note that our catalog query shows both user created UDFs, as well as system generated cast functions needed for the UDT implementation. If you want to select only non-cast UDFs, try the following query: select * from sysfuncs where routine_schema = 'TEAMXX' and is_user_defined_cast = 'NO' 4.6.2 SYSPARMS catalog The SYSPARMS catalog contains one row for each parameter of an UDF created by the CREATE FUNCTION statement. Refer to DB2 UDB for AS/400 SQL Reference, SC41-5612, for the detailed description of the catalog views. Let’s suppose you want to retrieve the parameter details for all instances of the GETSIZE function located in the TEAMXX library. The following SQL statement can be run to display this information: select * from qsys2/sysparms where specific_schema = 'TEAMXX' and specific_name in (select specific_name from qsys2/sysfuncs where specific_schema = 'TEAMXX' and routine_name = 'GETSIZE'); Note that, due to function overloading, the TEAMXX library can contain several functions with the same routine name. Running this query produced the results shown in Figure 82 on page 118. The SYSPARMS catalog contains parameter detail for both User Defined Functions and stored procedures. Note 118 DB2 UDB for AS/400 Object Relational Support Figure 82. UDF parameter details in SYSPARMS catalog There are two instances of the GETSIZE function in the TEAMXX library. Their signatures differ since they accept an input parameter of type CHARACTER or CLOB, respectively. Note, also, that the result of a function is stored in the SYSPARMS catalog as an OUTPUT parameter. 4.7 Dropping UDFs To drop an UDF using the SQL interface, use the DROP FUNCTION statement. The DROP FUNCTION statement references the function by: • Name: For example, DROP FUNCTION myUDF. This is only valid if exactly one function of that name exists in that library. Otherwise, SQLSTATE 42854 ('More than one found') or SQLSTATE42704 ('Function not found') is signalled. • Signature (name and parameters): For example, DROP FUNCTION myUDF(int). The data type of the parameter(s) must match exactly those of the function found. Also, if length, precision, or scale are specified, they must match exactly the function to be dropped. SQLSTATE 42883 is signalled if a match to an existing function is not found. • Specific name: For example, DROP SPECIFIC FUNCTION myFun0001. Since the SPECIFIC name must be unique per library, this will find, at most, one function. If the function is not found, SQLSTATE 42704 ('Function not found') is signalled. To drop a UDF using Operations Navigator, you open the required library, right-click on the user defined function you wish to delete, and select Delete from the context menu. If there are no dependent functions, the right panel refreshes, and you should see that the UDF object has been removed from the library. Functions created implicitly by a CREATE DISTINCT TYPE statement cannot be explicitly dropped. They can only be deleted by dropping the type. Built-in functions, and those functions shipped with the database, cannot be deleted. When a DISTINCT TYPE is dropped, all functions that have one or more parameters of that type are implicitly dropped as well. This is accomplished by use of the SYSPARMS catalog. If a schema is not specified, the authorization ID (user lib) is used if SQL naming is specified. Otherwise, the library list is used. Note User Defined Functions (UDFs) 119 4.8 Saving and restoring UDFs This section describes how to save and restore UDFs and some of the considerations that apply. The save and restore of functions currently can only be performed by saving (and restoring) the QSYS2 library. Note that the you can save and restore the catalogs themselves, but this is not recommended. For external functions, enough information is saved with the external program such that, when it is saved and restored, the function is 're-created' on the restore. However, the external program should be implemented in one of the ILE languages, and it has to contain at least one embedded SQL statement Note that storing information in an external function is a bit tricky. The program may not exist at function creation and may be deleted/re-created/moved at any time. For this reason, saving the SQL information in the program occurs if: • The external program exists at the time the function is created. • The function is invoked at least once so that the SQL information can be added to program during the reference/use of it. As mentioned earlier, sourced and SQL UDFs are implemented as embedded SQL ILE C service programs. This implies that they have enough information stored in the program object such that the function can be re-created. On a restore of an external program of a function, the following is performed: • Function (signature) does not exist. In this case, add the function to the catalogs. • Function (signature) exists (may or may not have exactly the same attributes, but same signature). Do nothing. • If the function will be 'created' in QSYS2, do not create the function definition (to prevent user functions from being in QSYS2). 4.9 Debugging UDFs In this section, we show you how to debug UDFs. SQL UDFs are always created as service programs. We recommend that you create external functions as service programs. Therefore, we show you how to debug a service program here. The same technique needs to be used if you wish to debug a program object that is being referenced by an external UDF. In this example, we debug our IsGif External UDF. Debugging UDFs may be a bit tricky since they are run on the AS/400 system in secondary threads. The following steps outline the debug procedure: 1. Open two native AS/400 5250 sessions and sign on to both sessions. From here onwards, we refer to the first session as Session A and to the second session as Session B. 2. Switch to Session B, and type in the following command on the command line: STRSQL The interactive SQL session is started, and the SQL command line is displayed. 120 DB2 UDB for AS/400 Object Relational Support 3. Switch to Session A and type in the following command line: WRKACTJOB The Work with Active Jobs screen is displayed as shown in Figure 83. This screen displays a list of all jobs that are currently active on the system. The job in Session B will be listed as one among these. Figure 83. The Work with Active Jobs screen listing all currently active jobs. 4. Find the job started in Session B under the QINTER subsystem. This is done by looking for jobs under the QINTER subsystem that are started with the user ID you used to log on. In our case, it is TEAMxx. Then, locate the job that has the action named STRSQL under the column named Function. When this job is located, use option 5 to work with that job. This is shown in Figure 84. Work with Active Jobs AS400WS 10/07/99 10:26:47 CPU %: .0 Elapsed time: 00:00:00 Active jobs: 217 Type options, press Enter. 2=Change 3=Hold 4=End 5=Work with 6=Release 7=Display message 8=Work with spooled files 13=Disconnect ... Opt Subsystem/Job User Type CPU % Function Status ADMIN QTMHHTTP BCI .0 TIMW JERRY QTMHHTTP BCH .0 PGM-QZHBHTTP CNDW JERRY QTMHHTTP BCI .0 TIMW JERRY QTMHHTTP BCI .0 TIMW JERRY QTMHHTTP BCI .0 TIMW JERRY QTMHHTTP BCI .0 TIMW QINTER QSYS SBS .0 DEQW QPADEV0002 TEAMXX INT .0 CMD-STRSQL DSPW QPADEV0003 TEAMXX INT .0 MNU-MAIN DSPW More... Parameters or command ===> F3=Exit F5=Refresh F7=Find F10=Restart statistics F11=Display elapsed data F12=Cancel F23=More options F24=More keys User Defined Functions (UDFs) 121 Figure 84. Working with the job in Session B 5. The Work with Job screen is displayed. This screen displays the various actions that can be taken for this job. On the top of the screen, you see the following information: • Job: This is the name of the job with which you are working. • User: This is the name of the user profile that is using the job. • Number: This is the number assigned to the job you are working with. Every job on the AS/400 system is assigned a six digit unique job number. Write down your fully qualified name for the Session B job. In our case, it is: 044733/TEAMXX/QPADEV0002 Now, start a service job for the Session B job. Enter the following command on the command line: STRSRVJOB 044733/TEAMXX/QPADEV0002 6. Start a debug session for the service program used in the IsGif function. Type the following command on the command line: STRDBG UPDPROD(*YES) SRVPGM(TEAMXX/PICTCHECK) 7. The debug session appears on your screen with the source code loaded into the debugger. Enter a breakpoint for the first executable statement in the program. In our case, this is the following statement in the PICTCHECK program: if ( *nms_InputNullIndicator01 == -1 ). Work with Active Jobs AS400WS 10/07/99 10:26:47 CPU %: .0 Elapsed time: 00:00:00 Active jobs: 217 Type options, press Enter. 2=Change 3=Hold 4=End 5=Work with 6=Release 7=Display message 8=Work with spooled files 13=Disconnect ... Opt Subsystem/Job User Type CPU % Function Status ADMIN QTMHHTTP BCI .0 TIMW JERRY QTMHHTTP BCH .0 PGM-QZHBHTTP CNDW JERRY QTMHHTTP BCI .0 TIMW JERRY QTMHHTTP BCI .0 TIMW JERRY QTMHHTTP BCI .0 TIMW JERRY QTMHHTTP BCI .0 TIMW QINTER QSYS SBS .0 DEQW 5 QPADEV0002 TEAMXX INT .0 CMD-STRSQL DSPW QPADEV0003 TEAMXX INT .0 MNU-MAIN DSPW More... Parameters or command ===> F3=Exit F5=Refresh F7=Find F10=Restart statistics F11=Display elapsed data F12=Cancel F23=More options F24=More keys The job name will be different for you. Note 122 DB2 UDB for AS/400 Object Relational Support This can be done by placing your cursor on the line of code at which you wish to place the breakpoint and pressing the F6 key. The following message appears at the bottom of the screen: Breakpoint added to line 47 This is shown in Figure 85. Figure 85. Adding a breakpoint to the debug session 8. Press F12. This takes you back to the command line. Now, you need to invoke the UDF from the Interactive SQL run in Session B. 9. Switch to Session B and type in the following SQL statement on the SQL command line: select product_number, isgif( product_picture ) from prodmast01 The SELECT statement begins to execute. The IsGif( PICTURE ) UDF is invoked. This also means that the PICTCHECK program is invoked. The following message is displayed at the bottom of the screen: Query running. 3 records selected. Selection complete. This is shown in Figure 86. However, the results of the query do not show up. Instead, the session busy cross sign stays at the bottom of the screen. Display Module Source Program: PICTCHECK Library: TEAMXX Module: PICTTYPE 46 47 if ( *nms_InputNullIndicator01 == -1 ) 48 { 49 *nms_OutputNullIndicator01 = -1; 50 return; 51 } 52 53 chr_FunctionResolution = strstr( sqludf_fname, GIF_FUNCTION ); 54 55 if ( chr_FunctionResolution != NULL ) 56 { 57 nmi_CompareResult01 = fun_CheckHeader( str_ProductPicture->data 58 GIF_HEADER_LENGTH, 59 chr_GifHeader87 ); 60 nmi_CompareResult02 = fun_CheckHeader( str_ProductPicture->data More... Debug . . . F3=End program F6=Add/Clear breakpoint F10=Step F11=Display variable F12=Resume F17=Watch variable F18=Work with watch F24=More keys Breakpoint added to line 47. User Defined Functions (UDFs) 123 Figure 86. Invoking the IsGif( PICTURE ) external UDF 10.Now, switch back to Session A. You see the source code of the PICTCHECK service program displayed on the screen. The line of source code that is to be currently executed is highlighted in white on the screen. In our case, this is the line at which you set the breakpoint in step 8. This is shown in Figure 87 on page 124. Enter SQL Statements Type SQL statement, press Enter. Current connection is to relational database AS400WS. ===> select product_number, isgif( product_picture ) from prodmast01 Bottom F3=Exit F4=Prompt F6=Insert line F9=Retrieve F10=Copy line F12=Cancel F13=Services F24=More keys Query running. 3 records selected. Selection complete. In print, the line of source code to be executed is shown in bold. Note 124 DB2 UDB for AS/400 Object Relational Support Figure 87. Debugging the PICTCHECK service program 11.Press the F10 function key to execute the highlighted line of code. The line is executed and gets de-highlighted. The next line of code to be executed is highlighted. Each time you press the F10 key, the next line of code in sequence is executed. 12.You can check the value contained in any of the program variables. This can be done in two ways: • Pressing the F11 key after placing the cursor over the variable for which you wish to check the value. • Typing in the EVAL command on the debug command line. We now check the value of the program variable nmi_CompareResult01. Place your cursor over the variable and press F11. The value of the variable is displayed on the bottom of the screen. This is shown in Figure 88. Display Module Source Current thread: 00000020 Stopped thread: 00000020 Program: PICTCHECK Library: TEAMXX Module: PICTTYPE 43 int nmi_CompareResult01 = 0; 44 int nmi_CompareResult02 = 0; 45 46 47 if ( *nms_InputNullIndicator01 == -1 ) 48 { 49 *nms_OutputNullIndicator01 = -1; 50 return; 51 } 52 53 chr_FunctionResolution = strstr( sqludf_fname, GIF_FUNCTION ); 54 55 if ( chr_FunctionResolution != NULL ) 56 { 57 nmi_CompareResult01 = fun_CheckHeader( str_ProductPicture->data More... Debug . . . F3=End program F6=Add/Clear breakpoint F10=Step F11=Display variable F12=Resume F17=Watch variable F18=Work with watch F24=More keys Breakpoint at line 47 in thread 00000020 User Defined Functions (UDFs) 125 Figure 88. Checking the value of the program variables using the F11 key 13.Place the cursor on the debug command line and type the following command: EVAL *nmi_InputNullIndicator01 This time, the value of nmi_InputNullIndicator 01 is displayed on the bottom of the screen. Display Module Source Current thread: 00000020 Stopped thread: 00000020 Program: PICTCHECK Library: TEAMXX Module: PICTTYPE 43 int nmi_CompareResult01 = 0; 44 int nmi_CompareResult02 = 0; 45 46 47 if ( *nms_InputNullIndicator01 == -1 ) 48 { 49 *nms_OutputNullIndicator01 = -1; 50 return; 51 } 52 53 chr_FunctionResolution = strstr( sqludf_fname, GIF_FUNCTION ); 54 55 if ( chr_FunctionResolution != NULL ) 56 { 57 nmi_CompareResult01 = fun_CheckHeader( str_ProductPicture->data More... Debug . . . F3=End program F6=Add/Clear breakpoint F10=Step F11=Display variable F12=Resume F17=Watch variable F18=Work with watch F24=More keys nmi_CompareResult01 = 0 To display the value of pointer variables, you have to use the EVAL command on the debug command line. You can use the ILE C/400 pointer notation to display the information in pointer variables. This is shown in Figure 89 on page 126. Note 126 DB2 UDB for AS/400 Object Relational Support Figure 89. Displaying the information in pointer variables using the EVAL command. 14.Sometimes, you may want to display the content of a variable in hexadecimal format. This is especially useful when you work with BLOB variables. You will now display the contents of the str_ProductPicture variable. This variable contains the data from the PRODUCT_PICTURE column of the PRODMAST01 table. The PRODUCT_PICTURE column is based on the distinct type PICTURE which, in turn, is based on BLOB(1M). In our program, we declared the BLOB1M structure to accommodate the BLOB value. This structure is composed of two parts: the length and the data part. The data part of the variable actually contains the binary information passed to our function by the database. 15.Type in the following command on the debug command line: EVAL *str_ProductPicture->data:x 64 Since the data part of the str_ProductPicture variable is a string, we must use the pointer notation to display the contents of it. The :x after the variable name is used to display the contents of the variable in hexadecimal format. The value 64 instructs the system to display the first 64 bytes of the variable. The result is shown in Figure 90. Display Module Source Current thread: 00000020 Stopped thread: 00000020 Program: PICTCHECK Library: TEAMXX Module: PICTTYPE 43 int nmi_CompareResult01 = 0; 44 int nmi_CompareResult02 = 0; 45 46 47 if ( *nms_InputNullIndicator01 == -1 ) 48 { 49 *nms_OutputNullIndicator01 = -1; 50 return; 51 } 52 53 chr_FunctionResolution = strstr( sqludf_fname, GIF_FUNCTION ); 54 55 if ( chr_FunctionResolution != NULL ) 56 { 57 nmi_CompareResult01 = fun_CheckHeader( str_ProductPicture->data More... Debug . . . EVAL *nms_InputNullIndicator01 F3=End program F6=Add/Clear breakpoint F10=Step F11=Display variable F12=Resume F17=Watch variable F18=Work with watch F24=More keys *nms_InputNullIndicator01 = 0 User Defined Functions (UDFs) 127 Figure 90. Displaying the contents of a variable in hexadecimal format 16.Continue to press the F10 key until you step through the entire program. At any time, you can run the program to completion by pressing the F12 key. 17.Once debugging your code is finished, you return to the Work with Job screen. On the command line, type the following CL commands: ENDDBG ENDSRVJOB This ends the debug mode and the service job being run to debug the service program. 4.10 Coding considerations When coding UDFs, you should keep in mind some of the limitations and restrictions that apply to them. The following list contains important recommendations and hints for UDFs developers: • UDFs should not perform operations that take a long time (minutes or hours). • UDFs are invoked from a low-level in DB2 that holds resources (locks and seizes) for duration of the UDF execution. • If UDF doesn't finish in an allocated time, the SQL statement fails. You can override the system time out value with UDF_TIME_OUT parameter in the query option file QAQQINI. Refer to DB2 UDB for AS/400 SQL Programming, SC41-5611, for details. • Avoid inserts, updates, and delete operations on the same tables as the one referred to in the invoking statement. • A UDF runs in the same job as the invoking SQL statement, but runs in a separate system thread, so secondary thread considerations apply: Evaluate Expression Previous debug expressions nmi_CompareResult01 = 0 > EVAL nmi_CompareResult01 nmi_CompareResult01 = 0 > EVAL nms_InputNullIndicator01 nms_InputNullIndicator01 = SPP:E2F09C16E30011C0 > EVAL *nms_InputNullIndicator01 *nms_InputNullIndicator01 = 0 > EVAL *nms_InputNullIndicator01 *nms_InputNullIndicator01 = 0 > EVAL *str_ProductPicture->data:x 64 00000 47494638 39613601 C000F700 000B0B0B - åñã../..{.7..... 00010 427B9430 117F3AAB EC454480 43484234 - â#m..".¿ÖáàØäçâ. 00020 7BB56D4C C2D0CFB1 7C83BC22 18482F64 - #§_Environment. Look for PATH or CLASSPATH in the User Variables and System Variables. 5.1.2 Using a Blob object An SQL BLOB is mapped by the JDBC driver into a Java Blob object. You can access values of type Blob in the same way that you access traditional SQL92 built-in types. The interfaces ResultSet, CallableStatement, and PreparedStatement support methods getBlob and setBlob for a BLOB value. You can use these methods in the same way that you use getString and setString to manipulate a CHAR or VARCHAR value. The JDBC 2.0 specification defines Blob as an interface. The JDBC 2.0 driver provides a database specific class, which implements this interface. In case of the AS/400 Toolbox for Java driver, this class is called com.ibm.as400.access.AS400JDBCBlob. 5.1.2.1 Creating and materializing a Blob object The following short Java program illustrates how to use the AS/400 Toolbox for Java JDBC 2.0 driver to retrieve a BLOB from an AS/400 table. The ImageDisplayer class accepts one input parameter: Product_Number. It connects to the AS/400 system and retrieves the Product_Picture for the given Product_Number. After materializing the Product_Picture data on the workstation, the program uses Swing GUI to display the picture. The numbered sections of the source code are explained in the notes following the listD. import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.sql.*; /* This class displays an image retrieved from DB2 UDB for AS/400. */ public class ImageDisplayer extends JFrame { public static void main(String[] args) { Image image = db2getImage(args[0]); ImagePanel imagePanel = new ImagePanel(image); JFrame f = new JFrame("ImageDisplayer"); f.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); f.getContentPane().add(imagePanel, BorderLayout.CENTER); Programming alternatives for complex objects 131 f.setSize(new Dimension(200,200)); f.setVisible(true); } public static Image db2getImage (String productNumber) { String system = "AS400WS"; Connection connection = null; Image image = null; try { // Load the AS/400 Toolbox for Java JDBC driver. DriverManager.registerDriver(new com.ibm.as400.access.AS400JDBCDriver()); // Get a connection to the database. Since we do not // provide a user id or password, a prompt will appear. connection = DriverManager.getConnection ("jdbc:as400://" + system); PreparedStatement stmt = connection.prepareStatement( "SELECT product_picture " + "FROM teamxx.prodmast01 " + "WHERE PRODUCT_NUMBER = CAST(? AS SRLNUMBER)"); 1 stmt.setString(1, productNumber); 2 ResultSet rs = stmt.executeQuery(); while (rs.next()) { Blob pictblob = rs.getBlob(1); 3 long length = pictblob.length(); ImageIcon imageicon = new ImageIcon(pictblob.getBytes(0, (int) length)); 4 image = imageicon.getImage(); } } catch (Exception e) { System.out.println (); System.out.println ("ERROR: " + e.getMessage()); } return image; } } class ImagePanel extends JPanel { Image image; public ImagePanel(Image image) { this.image = image; } public void paintComponent(Graphics g) { super.paintComponent(g); //paint background //Draw image at its natural size. g.drawImage(image, 0, 0, this); } } Notes for ImageDisplayer.java 1. The Product_Number column in the PRODMAST01 table is of user defined type SRLNUMBER. Because the implicit casting is not supported in the WHERE clause, we need to explicitly cast the parameter marker to the SRLNUMBER UDT. 2. The setString method of the PreparedStatement class is used to set the parameter to the Product_Number passed by the invoking process. 3. The Blob object is created. At this time, the variable pictblob contains a logical pointer to the BLOB value stored in the Product_Picture column. Note that the UDT Picture was implicitly cast to its source type BLOB(1M) on the I/O operation. Therefore, no explicit casting is needed, and we can use getBlob method on the rs object. 4. We need to materialize the BLOB data before we can display it on the workstation. We use the getBytes method on the Blob object for this purpose. 132 DB2 UDB for AS/400 Object Relational Support The imageicon object now contains a copy of all of the bytes in the BLOB value. You can use the getBytes method on a BLOB object to materialize only a fragment of the BLOB object. The first argument of this method is used to specify the starting byte, while the second argument tells how many bytes should be returned. To compile the ImageDisplayer.java program, type the following command at the DOS prompt: javac ImageDisplayer.java To execute the program, type the following command: java ImageDisplayer 00001 Note, that the string value '00001' was passed as the Product_Number parameter. The results are shown in Figure 91. Figure 91. Using Java to display DB2 UDB for AS/400 BLOBs 5.1.2.2 Storing a Blob object in the database You can use the setBlob method on a BLOB object to store it in the DB2 UDB for AS/400 database. The following code snippet illustrates this approach: ... Blob pictblob = rs.getBlob("PRODUCT_PICTURE"); 1 ... // Prepare UPDATE statement. PreparedStatement stmt = connection.prepareStatement( "UPDATE teamxx.prodmast01" + " SET PRODUCT_PICTURE = ? WHERE PRODUCT_NUMBER = CAST( ? AS SRLNUMBER)"); // Set the first parameter marker to a blob object stmt.setBlob(1, pictblob); 2 // Set the second parameter marker to a String stmt.setString(2, productNumber); // Execute the SQL statement stmt.executeUpdate(); 3 Programming alternatives for complex objects 133 Notes on Blob object storage code 1. The Blob object is retrieved from the PRODMAST01 table. We can now use this object within our Java application. For example, we could crop the retrieved product picture. The next two steps demonstrate how to update the table with this changed object. 2. The pictblob object is passed as the input parameter to the prepared statement object stmt. 3. The Blob value pointed by pictblob is now stored in PRODMAST01 table. The pictblob Blob object must exist in your Java application before you can execute the setBlob method on it. The sql.java package defines the Blob as a public interface, so you cannot instantiate it in your application. Instead, you need to use getBlob method on ResultSet, CallableStatement, or PreparedStatement to get access to the Blob data or you can provide your own implementation. The setBlob method is capable of sending large amounts of data. You can also accomplish this task by setting a Blob parameter marker to a Java input stream. The following code example shows how to load Blob data into a AS/400 table using the setBinaryStream method. This approach is useful if you have to construct the BLOB object in your application and then upload it to the database for persistent storage. The LoadPicture program accepts two parameters: name of a file on the workstation that contains the product picture, and the product number for the given picture. The program reads the content of the file and stores it as a Blob object in the AS/400 database. import java.sql.*; import java.io.*; public class LoadPicture { public static void main (String[] args) { String system = "AS400WS"; Connection connection = null; try { File file = new File(args[0]); int fileLength = (int)file.length(); InputStream fin = new FileInputStream(file); 1 // Load the AS/400 Toolbox for Java JDBC driver. DriverManager.registerDriver(new com.ibm.as400.access.AS400JDBCDriver()); // Get a connection to the database. Since we do not // provide a user id or password, a prompt will appear. connection = DriverManager.getConnection ("jdbc:as400://" + system); DatabaseMetaData dmd = connection.getMetaData (); // Prepare UPDATE statement. PreparedStatement stmt = connection.prepareStatement( "UPDATE " + collectionName + dmd.getCatalogSeparator() + tableName + " SET PRODUCT_PICTURE = ? WHERE PRODUCT_NUMBER = CAST( ? AS SRLNUMBER)"); // Set the first parameter marker to a binary input stream stmt.setBinaryStream(1, fin, fileLength); 2 // Set the second parameter marker to a String stmt.setString(2, args[1]); // Execute the SQL statement stmt.executeUpdate(); 3 } catch (Exception e) { System.out.println (); System.out.println ("ERROR: " + e.getMessage()); } finally { // Clean up. try { if (connection != null) connection.close (); } 134 DB2 UDB for AS/400 Object Relational Support catch (SQLException e) { // Ignore. } } System.exit (0); } } Notes for LoadPicture.java 1. We use the instance of FileInputStream to obtain the content of the picture file located in the workstation’s file system. 2. The Blob parameter marker is set to input stream. 3. At the SQL statement execution, the JDBC driver repeatedly calls to the fin input stream to transmit the Blob content to the database. 5.1.3 Using a Clob object An SQL Clob is mapped by the JDBC driver into a Java Clob object. The interfaces ResultSet, CallableStatement, and PreparedStatement support methods getClob and setClob that can be used to manipulate the CLOB data. These interfaces also support setAsciiStream, and setCharacterStream methods that allow you to input a stream as a Clob value. Additionally, you can use getAsciiStream and getCharecterStream methods on a Clob object to materialize it as an input stream. 5.1.3.1 Creating and materializing a Clob object The following Java program shows how to retrieve a Clob value from an AS/400 table. The QueryClob class connects to the AS/400 using the AS/400 Toolbox for Java JDBC driver and retrieves two columns, Product_Number and Product_Description, from the PRODMAST01 table. Then, it iterates through all rows in the result set. For every row, it materializes the Product_Description data as a Clob object and then manipulates the object to retrieve the color of a product. import java.sql.*; public class ClobQuery { public static void main (String[] parameters) { String system = "AS400WS"; Connection connection = null; try { // Load the AS/400 Toolbox for Java JDBC driver. DriverManager.registerDriver(new com.ibm.as400.access.AS400JDBCDriver()); // Get a connection to the database. Since we do not // provide a user id or password, a prompt will appear. connection = DriverManager.getConnection ("jdbc:as400://" + system); // Allocate the statement and execute the query. Statement stmt = connection.createStatement (); ResultSet rs = stmt.executeQuery ( "SELECT Product_Number, Product_Description " + "FROM TEAMXX.PRODMAST01"); // Iterate throught the rows in the result set and output // the columns for each row. while (rs.next ()) { String prdnum = rs.getString(1); System.out.print(prdnum + " "); Clob prddesc = rs.getClob(2); 1 if (prddesc != null) { Programming alternatives for complex objects 135 long length = prddesc.length(); String desc = prddesc.getSubString(0, (int) length); 2 int startcolor = desc.indexOf((String) "Color:")+ 6; int stopcolor = desc.indexOf((String)"Best For:",startcolor); System.out.print(desc.substring(startcolor, stopcolor - 1)); } else { System.out.print("NULL"); } System.out.println (); } } catch (Exception e) { System.out.println (); System.out.println ("ERROR: " + e.getMessage()); } finally { // Clean up. try { if (connection != null) connection.close (); } catch (SQLException e) { // Ignore. } } System.exit (0); } } Notes for ClobQuery.java 1. A Clob object is created. The prddesc variable contains a logical pointer to the Clob value stored in the Product_Description column. Note that this column was specified with a user defined type PRDDESC. This UDT was implicitly cast to its source built-in type CLOB(50k) on the I/O operation. 2. The getSubString method can be used to materialize all or part of the Clob value as a String object. It was used to materialize the complete content of the Product_Description column. As mentioned earlier, you may also materialize the Clob value as a byte stream containing Unicode characters. The following code snippet illustrates how to use the getCharacterStream method on a Clob value to accomplish this task: ... File file = new File(args[0]); OutputStream fout = new FileOutputStream(file); 1 ... byte[] clobBytes = new byte[MAX_FILE_SIZE]; char[] clobData = new char[MAX_FILE_SIZE]; PreparedStatement stmt = connection.prepareStatement( "SELECT product_description FROM TEAMXX.PRODMAST01 " + "WHERE PRODUCT_NUMBER = CAST( ? as SRLNUMBER)"); String productNumber = new String(args[1]); stmt.setString(1, productNumber); ResultSet rs = stmt.executeQuery(); while (rs.next()) { Clob prddesc = rs.getClob(1); 2 Reader rin = prddesc.getCharacterStream(); 3 int max = rin.read(clobData); 4 for (int cnt = 0; cnt < max; cnt = cnt + 1) { clobBytes[cnt] = (byte)clobData[cnt]; 5 } fout.write(clobBytes); 6 } Code example notes 1. The FileOutputStream class is used to write the Clob data retrieved from the AS/400 system to a file on the workstation. 136 DB2 UDB for AS/400 Object Relational Support 2. The Clob object is created. The underlying UDT PRDDESC was implicitly cast to its source type CLOB(50k). 3. The Clob value is materialized as a stream of Unicode characters. 4. The read method reads the Unicode characters from the stream into a character array. The variable max contains the number of characters retrieved from the database (length of Clob). 5. We copy the description from the character array to the byte array to write the content out to the output stream. 6. We write the Clob data to a workstation file using the fout output stream. 5.1.3.2 Storing Clob in the database A PreparedStatement object supports the setClob method, which can be used to store the Clob data in the DB2 UDB for AS/400 database. The following code snippet illustrates this approach: ... Clob prddesc = rs.getClob("PRODUCT_PICTURE"); 1 ... // Prepare UPDATE statement. PreparedStatement stmt = connection.prepareStatement( "UPDATE teamxx.prodmast01" + " SET PRODUCT_DESCRIPTION = ? WHERE PRODUCT_NUMBER = CAST( ? AS SRLNUMBER)"); // Set the first parameter marker to a blob object stmt.setClob(1, prddesc); 2 // Set the second parameter marker to a String stmt.setString(2, productNumber); // Execute the SQL statement stmt.executeUpdate(); 3 Code sample notes 1. The Clob object is retrieved from the database. 2. The setClob method on the stmt object allows the Clob data to be passed as an input parameter. The setClob method requires an existing Clob object as the second parameter. We set this parameter to the Clob retrieved in step 1. 3. The Clob is now stored in the AS/400 table. The setClob method can be used to upload large amounts of data. The alternate approach is to load a large Clob object by setting a Clob parameter marker to a Java input stream. The following code snippet shows how to read a text file from the workstation and upload it to the AS/400 as a Clob. ... File file = new File(args[0]); int fileLength = (int)file.length(); InputStream fin = new FileInputStream(file); 1 ... // Prepare UPDATE statement. PreparedStatement stmt = connection.prepareStatement( "UPDATE TEAMXX.PRODMAST01 " + " SET PRODUCT_DESCRIPTION = ? WHERE PRODUCT_NUMBER = CAST( ? AS SRLNUMBER)"); // Set the first parameter marker to a binary input stream stmt.setAsciiStream(1, fin, fileLength); 2 // Set the second parameter marker to a String stmt.setString(2, args[1]); // Execute the SQL statement stmt.executeUpdate(); 3 Code sample notes 1. We use an instance of FileInputStream to read the product description from a workstation’s file. Programming alternatives for complex objects 137 2. The Clob parameter marker is set to an input stream. We need to cast the parameter marker to the appropriate UDT in the SQL statement. 3. The JDBC driver repeatedly calls to the fin input stream to transmit the Clob content to the database. 5.1.4 Using metadata Metadata is useful when you write programs that use advanced database features like complex object support. The JDBC defines two metadata interfaces: DatabaseMetaData and ResultSetMetaData. A DataBaseMetaData object provides comprehensive information about the database. A ResultSetMetaData object retrieves information about the columns in a ResultSet object. The following code example illustrates how to use the metadata interfaces to get the column information for our test table PRODMAST01. It also retrieves the descriptions of all UDTs defined in the TEAMxx collection. import java.sql.*; public class GetMetaData { public static void main(String args[]) { Connection con; Statement stmt; String system = "AS400WS"; String collectionName = "TEAMXX"; String tableName = "PRODMAST01"; try { DriverManager.registerDriver(new com.ibm.as400.access.AS400JDBCDriver()); con = DriverManager.getConnection ("jdbc:as400://" + system); DatabaseMetaData dmd = con.getMetaData (); 1 stmt = con.createStatement(); ResultSet rs = stmt.executeQuery("select * from " + collectionName + dmd.getCatalogSeparator() + tableName); ResultSetMetaData rsmd = rs.getMetaData(); 2 int numberOfColumns = rsmd.getColumnCount(); 3 for (int i = 1; i <= numberOfColumns; i++) { String colName = rsmd.getColumnName(i); String tblName = rsmd.getTableName(i); int type = rsmd.getColumnType(i); String name = rsmd.getColumnTypeName(i);4 boolean caseSen = rsmd.isCaseSensitive(i); boolean writable = rsmd.isWritable(i); System.out.println("Information for column " + colName); System.out.println(" Column is in table " + tblName); System.out.println(" Column type is " + type); System.out.println(" DBMS name for type is " + name); System.out.println(" Is case sensitive: " + caseSen); System.out.println(" Is possibly writable: " + writable); System.out.println(""); } int[] types = {Types.DISTINCT}; ResultSet rsUDT = dmd.getUDTs(null, collectionName, "%", types); 5 while (rsUDT.next()) { System.out.println("UDT catalog " + rsUDT.getString(1)); System.out.println("UDT schema " + rsUDT.getString(2)); System.out.println("Type name " + rsUDT.getString(3)); 6 System.out.println("Class name " + rsUDT.getString(4)); 7 System.out.println("Data type " + rsUDT.getString(5)); System.out.println("Remarks " + rsUDT.getString(6)); } stmt.close(); con.close(); } catch(SQLException ex) { System.err.println("SQLException: " + ex.getMessage()); 138 DB2 UDB for AS/400 Object Relational Support } System.exit (0); } } Notes for GetMetaData.java 1. We create a DatabaseMetaData object that contains information about DB2 UDB for AS/400. We use the getMetaData method on the Connection object for this purpose. 2. The rs object contains the data retrieved from the PRODMAST01 table with the SELECT statement. Now we can get information about the columns in the rs ResultSet by creating a ResultSetMetaData object. We use the getMetaData method on the rs object for this purpose. 3. The getColumnCount method on the ResultSetMetaData object created in step 2 is used here to find out how many columns the result set has. Our SELECT statement retrieved all of the columns in the PRODMAST01 table, so the value of the numberOfColumns variable is set to 5. 4. We iterate through the rsmd columns to print out the detailed metadata information about each particular column in the PRODMAST01 table. For instance, the getColumnTypeName method is used to find out a column’s data type name. The example data retrieved for the Product_Number column is shown here: Information for column PRODUCT_NUMBER Column is in table Column type is 1 DBMS name for type is CHAR Is case sensitive: true Is possibly writable: false Note, that the getColumnTypeName method reports the name of the source built-in data type name, rather than the UDT name for the Product_Number column. 5. The getUDTs method on the DatabaseMetaData object gets a description of the UDTs defined in a particular schema. This method accepts four parameters: • catalog: A string object representing a catalog name. Set this parameter to null for the DB2 UDB for AS/400 database. • schemaPattern: A string object representing a schema name pattern. We use TEAMxx to indicate that we want to retrieve the UDTs definitions from this particular schema (library). You can set this parameter to null to retrieve all UDTs without any schema name restrictions. • typeNamePattern: A string object representing type name pattern. We use % to indicate that we want to retrieve all UDTs definitions in the TEAMxx schema. • types[]: An array representing the data types to be retrieved. We set it to Types.DISTINCT to indicate that we want only user distinct types definitions. Other database platforms may support other values, such as Types.STRUCT. The rsUDT result set object contains one row for each UDT found in the TEAMxx schema. Each row of this ResultSet object has six columns containing a type catalog, type schema, UDT’s type name (as defined on the CREATE table statement), Java class name to represent given UDT, generic JDBC data type as defined in java.sql.Types, and remarks. Programming alternatives for complex objects 139 6. The third column of the rsUDT result set contains the SQL type name for a given UDT. 7. The fourth column of the rsUDT contains a String object giving a class name in the Java programming language for this UDT. The example data retrieved for the PRDDESC distinct type is shown here: UDT catalog AS400WS UDT schema TEAMXX Type name PRDDESC Class name com.ibm.as400.access.AS400JDBCClob Data type 2001 Remarks UDT sourced from CLOB(50K) Note that the Clob interface is implemented by the AS/400 Toolbox class called com.ibm.as400.access.AS400JDBCClob. 5.2 Using complex objects in CLI or ODBC In this section, we explain how to use complex objects with the DB2 Call Level Interface (CLI). Since the CLI specification is based on the ODBC, the discussion presented here should be relevant to the ODBC support. However, we didn’t test the code samples listed in this section with the AS/400 ODBC driver. 5.2.1 DB2 CLI application flow The DB2 Call Level Interface allows applications to access the data in the DB2 family of database management systems (DBMS) using Structured Query Language (SQL) as a standard for accessing data. Using this interface, a single application can access different DBMS. This allows the application developer to develop, compile, and ship an application without targeting the specific database. The DB2 Call Level Interface is an alternative to an embedded dynamic SQL. On the AS/400 system, this interface is available to any of the ILE languages. A DB2 CLI application can be broken down into a set of tasks. Each task may be composed of several lines of code and may use a number of DB2 CLI functions. The sample applications included in this section demonstrate only a small subset of all CLI functions available on the AS/400 system. Refer to DB2/400 Advanced Database Functions, SG24-4249, for more details on CLI programming. 5.2.2 Passing LOB to a stored procedure written in CLI The following C code illustrates how to pass a BLOB value as an input parameter to the CLI stored procedure. The BLOB is the first parameter passed to the RTVPRDNB3 procedure and is defined as INPUT. You could use this procedure as part of your Web store application, which presents online customers with a range of product pictures. Then, customers can click on the product they want to purchase. The stored procedure is then used to find out the product number for the item which was clicked. #include #include #include #include "sqlcli.h" 1 ... typedef struct { unsigned long length; char data[ 1048576 ]; 140 DB2 UDB for AS/400 Object Relational Support } BLOB1M; 2 BLOB1M bin_ProductPicture; 3 ... void main( int argc, char **argv ) { ... memcpy( ( void * )&bin_ProductPicture, argv[ 1 ], 1048580 ); 4 ... C code notes 1. To use DB2 CLI functions in your C programs, you must include the header file called “sqlcli.h”. This include file is contained in QSYSINC library. The OS/400 option Openness Includes needs to be installed on the AS/400 system for this library to be present. 2. The BLOB1M structure is declared. This structure has two elements, the current length of the BLOB object and the data buffer, which can contain up to 1 MB of binary data. 3. The bin_ProductPicture variable contains the picture passed to the stored procedure by the invoking process. 4. The content of the first parameter is copied into the bin_ProductPicture variable. Note that, in the C calling convention, the second argument passed to the program object constitutes the first parameter passed to the stored procedure. The first argument of the program, pointed by argv[0], is always set to the called program name, RTVPRDNB3 in this case. When copying the BLOB parameter into a variable, make sure that you copy both data length and data buffer. Once the parameters we passed and the initial CLI environment were successfully created, we can implement the business logic of the stored procedure. Let’s take a closer look at the fun_Process function, which is the core of the RTVPRDNB3 program. The most interesting (and tricky) part of this function is the code, which illustrates how to bind a BLOB parameter using the SQLBindParam function. Refer to A.7, “RtvPrdNbr3: External stored procedure written in CLI” on page 222, for a complete code listing. SQLRETURN fun_Process() { short Pictture_Ind = 0; printf( "Attempting to allocate handle to statement\n" ); nml_ReturnCode = SQLAllocStmt( nml_HandleToDatabaseConnection, &nml_HandleToSqlStatement ); 1 { printf( "Could not allocate handle to statement\n" ); fun_PrintError( SQL_NULL_HSTMT ); printf( "Terminating\n" ); return SQL_ERROR; } 2 strcpy( chs_SqlStatement01, "select product_number " ); strcat( chs_SqlStatement01, "from teamxx.prodmast01 " ); strcat( chs_SqlStatement01, "where " ); strcat( chs_SqlStatement01, "product_picture = " ); strcat( chs_SqlStatement01, " cast( ? as TEAMXX.PICTURE)") 3; nml_ReturnCode = SQLPrepare( nml_HandleToSqlStatement, chs_SqlStatement01, SQL_NTS ); 4 if ( nml_ReturnCode != SQL_SUCCESS ) { ... Programming alternatives for complex objects 141 } nmi_PcbValue = bin_ProductPicture.length; nml_ReturnCode = SQLBindParam( nml_HandleToSqlStatement, 1, SQL_BLOB, SQL_BLOB, sizeof( bin_ProductPicture ), 0, ( SQLPOINTER ) bin_ProductPicture.data, ( SQLINTEGER *) &nmi_PcbValue );5 if ( nml_ReturnCode != SQL_SUCCESS ) { ... } nml_ReturnCode = SQLExecute( nml_HandleToSqlStatement ); if ( nml_ReturnCode != SQL_SUCCESS ) { ... } nml_ReturnCode = SQLBindCol( nml_HandleToSqlStatement, 1, SQL_CHAR, ( SQLPOINTER ) chs_ProductNumber, sizeof( chs_ProductNumber ), ( SQLINTEGER * ) &nmi_PcbValue ); 6 if ( nml_ReturnCode != SQL_SUCCESS ) { ... } nml_ReturnCode = SQLFetch( nml_HandleToSqlStatement ); if ( nml_ReturnCode != SQL_SUCCESS ) { .... } else { return SQL_SUCCESS; } } Code listing notes 1. The SQL statement handle is allocated. This handle is used to pass SQL requests to the DB2 UDB for AS/400 database engine. 2. This a typical error-handling routine, which is used to catch SQL error conditions returned from the database. This routine is used after each execution of a CLI function to make sure that there are no pending SQL errors. 3. The text of the SQL request is assembled here. Note the use of the parameter marker. This marker is used to bind the BLOB value passed from the invoking process. We need to explicitly cast the parameter marker to the TEAMXX.PICTURE UDT, because the implicit casting is not supported in the WHERE clauses. 4. The SQL statement is prepared. Notice that the CLI uses dynamic SQL under the covers. 5. To bind application variables to parameter markers, the application must call SQLBindParam() or SQLSetParam(). Both functions are the same and are included for compatibility. The sample application provides the following parameters to the SQLBindParam function: • nml_HandleToSqlStatement: This is the handle to the SQL statement that contains the parameter markers. • 1: This is the number of the parameter marker to which you want to bind the application variable. We bind the chs_ProductNumber variable to the first (and only) parameter marker. If you have more parameter markers in your 142 DB2 UDB for AS/400 Object Relational Support SQL statement, you need to call the SQLBindParam function for each of them. The parameter markers are counted from left to right, starting with 1. • SQL_BLOB: This is the data type of the application variable as it is defined in C. This is the data type of the parameter passed by the invoking process. • SQL_BLOB: This is the SQL data type of the application variable. • sizeof( bin_ProductPicture ): This is the precision or length of the application variable. In the case of BLOB variables, this is the variable size in bytes. For this parameter you need to pass the size of the bin_ProductPicture structure. • 0: This is the scale of the application variable. In data types other than zoned packed decimals, this is unused. In case of packed and zoned decimals, this is the number of digits to the right of the decimal point. • ( SQLPOINTER ) bin_ProductPicture.data: This is a pointer to the buffer that actually contains the data to be used at the execution time. For this parameter, we pass the pointer to the data buffer containing the BLOB object. • ( SQLINTEGER *) &nmi_PcbValue: This is an integer pointer that, for the BLOB variable, points to a location containing the exact length of the BLOB data. The nmi_PcbValue was set to bin_ProductPicture.length just before the SQLBindParam was called. 6. After the SQL statement is successfully executed, we bind the value of the column returned by the run time to an application variable. The chs_ProductNumber variable contains the product number for the first item in the table, which has the same product picture as the picture passed by the invoking process as a search parameter. Note: The PRODUCT_NUMBER column was implicitly cast from the SRLNUMBER UDT to its underlying source type of CHARACTER(5). The DB2 CLI, like any other high level programing interface, is not aware of the UDTs, so UDTs are implicitly converted to their appropriate source data types during the INPUT/OUTPUT operations. The following CL command compiles our sample CLI stored procedure: CRTBNDC PGM(DPOBJECT/RTVPRDNBR3) SRCFILE(DPSOURCE/QCSRC) OUTPUT(*PRINT) DBGVIEW(*ALL) Since CLI is not using embedded SQL, the DB2 for AS/400 Development Kit is not required on your development machine. Once the program object is successfully created, we register the stored procedure with the following SQL statement: create procedure TEAMXX/RTVPRDNB3( IN ProductPicture BLOB(1M), OUT ProductNumber CHAR(5) ) 1 language C specific RTVPRD0003 deterministic external name DPOBJECT/RTVPRDNBR3 general; SQL statement note 1. The stored procedure is defined with two parameters. The BLOB object is passed by value. Programming alternatives for complex objects 143 For the external stored procedure, you can specify the input parameter as a locator to the value rather than the actual value. You can use the AS LOCATOR clause only if the input parameter has a LOB data type or a distinct type based on a LOB data type. The AS LOCATOR clause is not allowed for SQL procedures. 5.2.3 Calling the CLI stored procedure Once the RTVPRDNB3 external stored procedure is successfully registered in the system catalogs, it can be called from any interface that supports SQL CALL statement. The following embedded SQL code example illustrates how to call the procedure and how to pass LOB value as one of the parameters: #include #include #include EXEC SQL INCLUDE SQLCA; EXEC SQL BEGIN DECLARE SECTION; SQL TYPE IS BLOB(1M) bin_ProductPicture; char chs_ProductNumber[ 5 ]; EXEC SQL END DECLARE SECTION; void main( int argc, char **argv ) { EXEC SQL WHENEVER NOT FOUND GOTO badnews; EXEC SQL WHENEVER SQLERROR GOTO badnews; EXEC SQL DECLARE cur_Picture CURSOR FOR select Product_Picture from prodmast01; 1 EXEC SQL OPEN cur_Picture; do { EXEC SQL FETCH cur_Picture into :bin_ProductPicture; 2 EXEC SQL SET :chs_ProductNumber = ' '; EXEC SQL CALL RTVPRDNB3( :bin_ProductPicture, :chs_ProductNumber); 3 printf( "The product number - %s\n", chs_ProductNumber ); } while ( sqlca.sqlcode != 100 ); exit(0); badnews: EXEC SQL CLOSE cur_Picture; exit( 1 ); } Notes for CALLRPNBR3 C embedded SQL program 1. The SQL cursor is defined. We use this cursor to retrieve product pictures from the prodmast01 table. The PRODUCT_PICTURE column is of user defined type PICTURE. 2. A PRODUCT_PICTURE value is fetched from the table. The value is implicitly cast from the PICTURE UDT into the sourced data type (BLOB in this case) before it is assigned to the bin_ProductPicture host variable. 3. The retrieved value, now stored in bin_ProductPicture host variable, is passed by value to the stored procedure. 5.2.4 Retrieving LOBs in CLI In this section, we describe how to use the CLI to retrieve LOB data. We coded another stored procedure called RTVPRDNBR4. The procedure accepts two parameters: chs_ProductNumber as an INPUT parameter and bin_ProductPicture as an OUTPUT parameter. This time, we use the procedure to retrieve the product 144 DB2 UDB for AS/400 Object Relational Support picture for the given product number. The product number is passed by the invoking process. We focus our attention on the most important portion of the source code: typedef struct { unsigned long length; char data[ 1048576 ]; } BLOB1M; BLOB1M bin_ProductPicture; ... SQLRETURN fun_Process() { ... strcpy( chs_SqlStatement01, "select product_picture " ); strcat( chs_SqlStatement01, "from prodmast01 " ); strcat( chs_SqlStatement01, "where " ); strcat( chs_SqlStatement01, "product_number = cast (? as SRLNUMBER)" ); 1 nml_ReturnCode = SQLPrepare( nml_HandleToSqlStatement, chs_SqlStatement01, SQL_NTS ); if ( nml_ReturnCode != SQL_SUCCESS ) { ... } nml_ReturnCode = SQLBindParam( nml_HandleToSqlStatement, 1, SQL_CHAR, SQL_CHAR, sizeof( chs_ProductNumber ), 0, ( SQLPOINTER ) chs_ProductNumber, ( SQLINTEGER * ) &nmi_PcbValue ); 2 if ( nml_ReturnCode != SQL_SUCCESS ) { ... } nml_ReturnCode = SQLExecute( nml_HandleToSqlStatement ); if ( nml_ReturnCode != SQL_SUCCESS ) { ... } nml_ReturnCode = SQLBindCol( nml_HandleToSqlStatement, 1, SQL_BLOB, ( SQLPOINTER ) bin_ProductPicture.data, sizeof( bin_ProductPicture ), ( SQLINTEGER * ) &nmi_PcbValue ); 3 if ( nml_ReturnCode != SQL_SUCCESS ) { ... } nml_ReturnCode = SQLFetch( nml_HandleToSqlStatement ); if ( nml_ReturnCode != SQL_SUCCESS ) { ... } else { return SQL_SUCCESS; } } Notes for RTVPRDNBR4 CLI stored procedure 1. The SQL request is assembled here. The PRODUCT_NUMBER column is of user defined type SRLNUMBER, so we need to explicitly cast the parameter marker to the appropriate type. 2. We use SQLBindParam function to bind the parameter marker. Programming alternatives for complex objects 145 3. To bind a column to an application variable, the application must call the SQLBindCol function. The sample application provides the following parameters to this function: • nml_HandleToSqlStatement: This is the handle to the SQL statement that contains the column. • 1: We retrieve Product_Picture as the first and only column in the result set. • SQL_BLOB: This is the SQL data type of the application variable. • ( SQLPOINTER ) bin_ProductPicture.data: This is a pointer to the buffer where the retrieved picture is stored at the fetch time. • sizeof( bin_ProductPicture ): This is the size of the buffer that stores the data retrieved from the column. Note that, in case of BLOB data type, you need to pass the size of bin_ProductPicture structure. • ( SQLINTEGER * ) &nmi_PcbValue: This is an integer pointer that points to a location containing the length of the BLOB data returned at fetch time. 146 DB2 UDB for AS/400 Object Relational Support © Copyright IBM Corp. 2000 147 Chapter 6. DataLinks This chapter describes: • The role of DataLinks in applications and their use relative to LOBs • The generic components of DataLinks • The AS/400 operational environment to support the DataLinks components • The creation of DataLinks in DB2 Universal Database for AS/400 • The considerations for working with DataLinks in DB2 UDB for AS/400 • An overview of working with DataLinks in an heterogeneous environment • Backup/recovery considerations for DataLinks 6.1 A need for DataLinks Chapter 2, “Large object support in DB2 UDB for AS/400” on page 3, described the potential role that large objects can play in modern applications. In particular, with the growth of Internet-based applications, the desire for organizations to capture and retain the interest of potential customers is driving the need to include types of data beyond the simple structured interface presented by characters and numerics. This new breed of unstructured data includes images, sound recordings, video clips, and complex text. Large objects, in the form of BLOBs, CLOBS, and DBCLOBS, are now supported as data types for inclusion in DB2 Universal Database for AS/400 tables. Although the DB2 Universal Database architecture defines 2 GB as the maximum size of a LOB, the current OS/400 V4R4 implementation limits the size to 15 MB. While a majority of unstructured data that an application needs to use is likely to fall below the 2 GB, or even the 15 MB limit, some will undoubtedly be larger. Video recordings are a prime example of data that can be very large. These file objects will need to overcome that limit. As a further scenario, consider a user with thousands of file objects, for example, video recordings, images, or sound bites, stored on a hard drive of a PC server or in the Integrated File System of their AS/400. These files may simply be there for ease of storage, with hierarchical structure of file system directories being well suited to stream file management. Additionally, they may be currently used by PC based applications, such as audio and video players and graphics and drawing packages. New application requirements may then arise, which are best fulfilled by using an SQL table, to contain information about these file objects, for example, title, length, creation date, artist, and so forth. However, since the user already has the objects stored in a file directory, they may be reluctant to transfer them into the SQL table as LOB columns. Furthermore, it may not be feasible to move them from the file system if they need to be accessed by PC applications. The DataLink data type extends the types of data that can be stored in an SQL table. The principle behind a DataLink is that the actual data stored in the table column is only a pointer to an object residing in a file system on any file server that supports DataLinks. The file object can be any file type. The method used to resolve the file object in an application is to store this pointer in the form of a Uniform Resource Locator (URL). This URL can use any of the following formats: 148 DB2 UDB for AS/400 Object Relational Support • file: • http: • https: This means that a row in a table can be used to contain information about the file object in columns of traditional data types, and the object itself can be referenced using the DataLink data type. An application can use new SQL scalar functions to retrieve the name of the server on which the file object is stored and the path to it. The application can then hand control to software more appropriate in handling streaming data, for example a browser, to retrieve the object. This approach also has the advantage of deferring the physical movement of potentially very large objects from the server until needed by the client application. The access of such objects through the file system is also likely to provide better performance than through the relational database management system (RDBMS). However, there are a number of important considerations if the RDBMS is to be used to effectively manage unstructured data that is stored in a file system. The two major considerations are: • There has to be some relationship between the relational data and the file data. • This relationship must be managed, particularly in the areas of data integrity, data access control, and data backup/recovery to ensure high-application availability. Relational database management systems provide the robust environment that is lacking in file systems by applying that environment to the DataLinks. Figure 92 shows a relational table with the LOB data actually stored in columns within each row along with the traditional structured data columns. Figure 93 shows the same data, but the LOB data is stored as DataLinks within each row. Each DataLink column points to a file server, for example, the AS/400 Integrated File System, and a directory and file object within that server. Figure 92. Large objects in tables: The LOB approach SOLD ONHAND RATING ARTIST TITLE COVER VIDEO MUSIC SCRIPT 234 59 PG-13 Arnold The Exter minator 13 45 R Kevin Dancing with Bulls 1295 209 G Glenn 101 Doll Imitations 379 112 G Buzz Toy Glory DataLinks 149 Figure 93. Large objects in tables: The DataLink approach There are a number of additional benefits from the DataLinks approach. File systems, including the AS/400 Integrated File System (IFS), are able to store any type of stream file. The current scope includes all of the types referenced in Figure 93 and more. However, technological advances will, over time, no doubt give birth to new ways of storing complex unstructured data using new file types. In other words, using the file system approach to unstructured data storage provides a high degree of future proofing to applications. In summary, any application that could benefit from significant content management capabilities and robust and secure file management would be a candidate for deploying DataLinks. Examples include: • Web-based electronic commerce • Intranet applications • Applications with links to computer-aided design and manufacturing (CAD/CAM) • Library and asset management applications (for example, entertainment industry, medical applications using X-rays, and so on) SOLD ONHAND RATING ARTIST TITLE COVER VIDEO MUSIC SCRIPT 234 59 PG-13 Arnold The Exterminator file://AS400 WS/covers/ ext.jpg file://AS400 WS/videos/ ext.mpg file://AS400 WS/music/ ext.wav file://AS40 0WS/script /ext.lwp 13 45 R Kevin Dancing withBulls file://AS400 WS/covers/ dbull.jpg file://AS400 WS/videos/ dbull.mpg file://AS400 WS/music/ dbull.wav file://AS40 0WS/script /dbull.lwp 1295 209 G Glenn 101 Doll Imitations file://AS400 WS/covers/ di101.jpg file://AS400 WS/videos/ di101.mpg file://AS400 WS/music/ di101.wav file://AS40 0WS/script /di101.lwp 379 112 G Buzz Toy Glory file://AS400 WS/covers/ toyg.jpg file://AS400 WS/videos/ toyg.mpg file://AS400 WS/music/t oyg.wav file://AS40 0WS/script /toyg.lwp Directory: Music ext.w av dbull.w av di101.w av toyg.wav Directory: Covers ext.jpg dbull.jpg di101.jpg toyg.jpg Directory: Videos ext.mpg dbull.mpg di101.mpg toyg.mpg Directory: Script toyg.lw p dbull.lwp di101.lwp ext.lw p 150 DB2 UDB for AS/400 Object Relational Support 6.2 DataLinks components DataLink support on the AS/400 system is comprised of four major components: • The DataLink data type • The DataLink File Manager (DLFM) • The DataLink filter • DBMS/DLFM APIs Figure 94 summarizes the DataLinks components and the API interfaces they use to communicate. Figure 94. DataLinks components summary 6.2.1 DataLink data type The DataLink data type is new to DB2 Universal Database for AS/400 in V4R4 with the Database Fixpack. When you use Operations Navigator to create a table, the data type can be found in the drop-down list box when you insert a column as illustrated in Figure 95. RDBMS Manages file access requests from DataLinks Filter Applies Transaction Integrity to Link/Unlink actions Employee Table Name Dept Picture DATALINK type (URL) Applications SQL API Requests File API Requests DBMS / DLFM APIs Data Links File Manager (DLFM) Link/unlink Apply transaction consistency DataLinks Filter Referential integrity for file rename, move and delete Database access control for file open Images in External Files DataLinks 151 Figure 95. Inserting a column of data type DataLink The SQL statements that support the data type are CREATE TABLE and ALTER TABLE. The only default value that you can specify for a column of type DataLink is null. Because the DataLink is not compatible with any host variable data type, the only interface that allows access is SQL. The underlying format of the data in a DataLink column is character format, and you can use a number of SQL scalar functions to retrieve the Datalink value in this format. When you insert or update data in a DataLinks column, you must use the DLVALUE scalar function with SQL INSERT or UPDATE. 6.2.2 DataLink file manager The DataLink File Manager (DLFM) is the core component of the support for DataLinks on any platform. It controls and maintains the status of the links between the RDBMS tables and their associated file system objects. It does this by creating and maintaining metadata for each table and file. On the AS/400 system, this metadata is stored in a number of tables in the QDLFM collection (library). Figure 96 on page 152 shows the objects in the QDLFM library. 152 DB2 UDB for AS/400 Object Relational Support Figure 96. DLFM objects in library QDLFM The DLFM handles the linking and unlinking of files with tables. Because it is using DB2 Universal Database for AS/400 tables (in library QDLFM) for managing the environment, it can also manage the integrity of those links through commitment control by treating link and unlink actions as transactions. One of the most important aspects of the DataLinks architecture is that it is designed so that the DLFM can reside on a remote AS/400 system running V4R4 or higher. It achieves this by using a standard set of APIs between the RDBMS and DLFM components. This approach allows relational tables on one system to No explicit user interface is provided to these objects. We strongly recommend that you do not make any changes to their content. However, if you view the content of some of the tables, you will find useful information on the setup and state of the DataLink environment. Some examples are shown in 6.3.2.4, “Additional DataLink management interfaces” on page 161. Important DataLinks 153 link to files on the same or another system, either locally or remotely. This flexible approach allows the files to reside on the most appropriate system from an overall application standpoint. Such flexibility can also aid performance and minimize network costs by allowing file servers to be positioned close to the end users, enabling files to be delivered over shorter distances. Figure 97 shows an example of the type of DataLink environment that could be deployed. Relational DB2 Universal Database for AS/400 tables on the Rochester system are linked to: • Files in directories in its own Integrated File System • Files in directories on the London AS/400s Integrated File System A DLFM is running on both systems. Figure 97. Distributed heterogeneous DLFM environment 6.2.3 DataLink filter The DataLink filter is an internal function that is invoked whenever a program attempts operations, through a file system interface, on a file that is within a directory registered as containing linked files. It determines if the file is actually linked and, depending on the attempted operation, may also check if the user is authorized to access the file and open it. If it finds that the file is linked, it will impose a form of referential constraint and reject any attempt to move, rename, or delete the file. This aspect is covered in more detail in 6.4.6, “Using the DataLink access control token” on page 186. The DataLink Filter is invoked regardless of whether a file is linked or unlinked. Because invoking the DataLink Filter generates resource overhead, it is only executed when the file being accessed is in a registered directory or in a directory path below a registered directory. This is covered in more detail in 6.3.2.1, “Adding a prefix” on page 157. 6.2.4 APIs There are essentially three API interfaces in the DataLinks environment: • The interface to the relational table. This is through SQL and uses new scalar functions to work with the DataLink in the table rows. No OS/400 native I/O interface is provided to the DataLink data type. • The interface to objects in the file system from file API requests. Access to linked or unlinked files residing in a registered directory is intercepted by the Rochester AS400RCH London AS/400LON 154 DB2 UDB for AS/400 Object Relational Support DataLinks Filter. Access can be directly from file system programs and utilities or, in the case of the AS/400 IFS, from an AS/400 ILE C program. • The interface between the RDBMS and the DLFM. These APIs allow the RDBMS to communicate link and unlink activities to the DLFM, and the DLFM to communicate file access requests to the RDBMS if the option has been taken to use the RDBMS to control file access. 6.3 DataLinks system configuration A number of basic configuration tasks are necessary to enable the DataLinks environment to be defined. You must configure TCP/IP on all systems that you want to participate in the environment. That is, those that will host the SQL tables in which DataLink columns are created, and those that will host the file objects to be linked. In the case of a single AS/400 system where IFS files are going to be linked to DB2 Universal Database for AS/400 tables, the configuration is a single process. The URL in the DataLink column used to reference the file object contains the name of the file server. You must configure this name or register a TCP/IP name server. Enter the command: CFGTCP Then, enter option 10 as shown in Figure 98. Figure 98. Adding the TCP/IP server name Figure 99 shows the next screen displayed. If the system is not already configured, type 1 and the IP address on the top line, and press Enter to add a new entry. The next screen allows you to type in the name of the AS/400 server. If the IP address is configured, but the AS/400 system name you want to use in your DataLink columns is not, type 2 next to the appropriate IP address and press CFGTCP Configure TCP/IP System: R Select one of the following: 1. Work with TCP/IP interfaces 2. Work with TCP/IP routes 3. Change TCP/IP attributes 4. Work with TCP/IP port restrictions 5. Work with TCP/IP remote system information 10. Work with TCP/IP host table entries 11. Merge TCP/IP host table 12. Change TCP/IP domain information 20. Configure TCP/IP applications 21. Configure related tables 22. Configure point-to-point TCP/IP Selection or command ===> 10 F3=Exit F4=Prompt F9=Retrieve F12=Cancel DataLinks 155 Enter. The next screen allows you to enter an additional server name. In our case, this is AS400RCH. Figure 99. Adding the IP server name: IP address already configured Next, you must ensure that the AS/400 system that will host the relational tables with the DataLink columns has a relational database directory entry. You can define this system as *LOCAL in the system’s relational database directory by running the CL command: WRKRDBDIRE The screen shown in Figure 100 is displayed. Figure 100. Adding the relational database directory entry (WRKRDBDIRE) If there is no entry with a remote location name of *LOCAL, you must add this entry for the local AS/400 system. You should use the AS/400 system name that you used for the TCP/IP server as the relational database name. This enables the Work with TCP/IP Host Table Entries System: RCH Type options, press Enter. 1=Add 2=Change 4=Remove 5=Display 7=Rename Internet Host Opt Address Name 2 1.1.12.30 AS23 AS400WS 1.1.92.31 AS400LON 1.11.208.1 AS89 127.0.0.1 LOOPBACK LOCALHOST B F3=Exit F5=Refresh F6=Print list F12=Cancel F17=Position to Work with Relational Database Directory Entries Position to . . . . . . Type options, press Enter. 1=Add 2=Change 4=Remove 5=Display details 6=Print details Relational Remote Option Database Location Text AS400RCH *LOCAL Bottom F3=Exit F5=Refresh F6=Print list F12=Cancel (C) COPYRIGHT IBM CORP. 1980, 1999. 156 DB2 UDB for AS/400 Object Relational Support DLFM to communicate with DB2 Universal Database for AS/400 within the local AS/400 system. Note that the *LOCAL entry in the RDB directory is required only on the system where the tables reside. In a distributed environment, if the DLFM server is running on the system with no linked tables, there is no need for either the *LOCAL RDB entry or the remote entry for the system where the linked tables reside. 6.3.1 Initializing the DLFM server In 6.2.2, “DataLink file manager” on page 151, we explained how the DLFM manages the environment by keeping and maintaining metadata in a number of tables in the QDLFM collection. These tables must be set up and initialized. To do this, you must run the CL command INZDLFM as follows: INZDLFM *ALL The prompted command is shown in Figure 101. Figure 101. Initializing the DLFM tables (INZDLFM) The INZDLFM command with the *LNKSTS parameter clears the tables in the QDLFM library that contain the link status of DataLinks. You then need to relink all your files. Initialize DLFM (INZDLFM) Type choices, press Enter. Clear existing databases . . . . *all *LNKSTS, *ALL Bottom F3=Exit F4=Prompt F5=Refresh F12=Cancel F13=How to use this display F24=More keys DataLinks 157 6.3.2 DLFM configuration Once the generic DLFM environment has been initialized, you begin to customize it for your own application environment. This involves defining information to DLFM about your specific relational table and file system entities that will be included in the DLFM configuration. You should note that *IOSYSCFG special authority is needed to perform these administrative functions. 6.3.2.1 Adding a prefix DLFM needs to know the file system directories where it will find file objects to be linked and which will come under its management and control. For example, if you wanted to define the directory "Videos" as one containing files to be linked, you use the following CL command example: ADDPFXDLFM PREFIX('/videos') Figure 102 on page 158 shows it as a prompted command. You should use this command with caution. Under normal circumstances, its use should be viewed as a one-time exercise. If you run it again once the environment has been set up and Datalinks have been created, the system attempts to re-create the internal DLFM tables and delete any rows of data that they contain. You will then be faced with re-creating the entire environment and relinking your files. You are strongly advised to add the backup of the QDLFM library to your existing installation backup policies. If you should accidentally rerun the command, you will have to re-IPL the system. This is because DLFM mounts the file directories that are registered to it (refer to 6.3.2.1, “Adding a prefix” for more details) at IPL time, and rerunning the initialization causes the mount points to be lost. Attention 158 DB2 UDB for AS/400 Object Relational Support Figure 102. ADDPFXDLFM command prompt When rows containing DataLinks columns are inserted into a table, if the referenced files are to be linked, the DLFM checks to ensure that the files exist and that they are within a file directory that is a registered prefix or within a sub-directory of a registered prefix. For example, if the directory TEAMXX has been registered as follows: ADDPFXDLFM PREFIX('/teamxx') then files in any of the following paths are valid candidates for linking: • /teamxx • /teamxx/multimedia • /teamxx/multimedia/sound_bites To minimize the performance overhead incurred when the DLFM checks the registered prefixes, you should keep the number of prefixes to a minimum. For optimum manageability, you should keep files to be linked in sub-directories within the directories defined as prefixes, not within the registered directories themselves. This allows you to manipulate those sub-directories without affecting the mount points that have been set up at IPL. Therefore, using the above example, if you wanted to replace the complete set of sound bite files in the Add Prefix to DLFM (ADDPFXDLFM) Type choices, press Enter. Prefix: PREFIX Name . . . . . . . . . . . . . > '/videos' + for more values Source file . . . . . . . . . . SRCFILE Library . . . . . . . . . . . *LIBL Source member . . . . . . . . . SRCMBR Bottom F3=Exit F4=Prompt F5=Refresh F12=Cancel F13=How to use this display F24=More keys You may use the format '/videos' or '/videos/' for the PREFIX parameter, but you should be consistent in their usage. The directory that you are registering must exist at the time of registration. The SRCFILE and SRCMBR parameters allow you to pre-build the prefix names in a separately maintained source file member for input to the command. Each prefix name would occupy a line in the source member. Note DataLinks 159 sub-directory '/sound_bites', you could simply delete the complete sub-directory and restore the new version. Because '/sound_bites' is not a registered prefix, deleting it will not affect the file mount point. 6.3.2.2 Adding a host database DLFM needs to know the AS/400 systems and the libraries within those systems where relational tables will be found that need to link to files in a file system. Note that both the local AS/400 system and any remote AS/400 system that may generate link requests must be known to DLFM. For example, you have a local system, AS400RCH, and a remote system, AS400LON, with libraries as indicated in Table 10. Table 10. Host database registration example The local AS400RCH system tables link to files in the local IFS and the remote system’s IFS. The remote system tables only link to files in its own IFS. To register the necessary host database information on system AS400RCH, you use the following CL commands: ADDHDBDLFM HOSTDBLIB((MULTIM01)(MULTIM02)) HOSTDB(AS400RCH) On the AS400LON system, use the following command: ADDHDBDLFM HOSTDBLIB(IMAGMAST) HOSTDB(AS400LON) ADDHDBDLFM HOSTDBLIB((MULTIM01)(MULTIM02)) HOSTDB(AS400RCH) AS/400 system Libraries with tables to be linked AS400RCH MULTIM01 MULTIM02 AS400LON IMAGMAST There is a command to remove prefixes (see 6.3.2.4, “Additional DataLink management interfaces” on page 161). However, this would not be a commonly used function since prefixes can only be removed if there are no linked files anywhere in the directory path within and below the prefix directory. Note The value of the HOSTDB parameter must be set to the relational database name that you used for the *LOCAL RDB entry on the AS400RCH system. Note 160 DB2 UDB for AS/400 Object Relational Support Table 11. RDB entries on the AS400RCH system The RDB entries on the London system are shown in Table 12. Table 12. RDB entries on the AS400LON system The prompted ADDHDBDLFM command is shown in Figure 103. Figure 103. ADDHDBDLFM command prompt Relational database Remote location AS400RCH *LOCAL Relational database Remote location AS400LON *LOCAL London’s system will have link requests coming from Rochester (remote) and London (local). You need to register libraries from both systems. For the local system, you use the HOSTDB name, as specified for the *LOCAL RDB entry on the AS400LON machine. Similarly, for the remote system, you use the HOSTDB name, as specified for the *LOCAL RDB entry on the AS400RCH machine. In other words, to register libraries on the remote system, you need to know the name of the relational database for the *LOCAL entry on the remote system. Note also that, in this scenario, there is no need for the AS400RCH RDB entry on the AS400LON machine. However, this entry may be required for some other functionality, such as DRDA and/or DDM. To summarize, the RDB entries required by the DataLink interface on the Rochester system are shown in Table 11. Note Add Host Database to DLFM (ADDHDBDLFM) Type choices, press Enter. Host database library: HOSTDBLIB Name . . . . . . . . . . . . . > MULTIM01 Name . . . . . . . . . . . . . > MULTIM02 + for more values Host database instance . . . . . HOSTDBINST QSYS Host database . . . . . . . . . HOSTDB AS400RCH Source file . . . . . . . . . . SRCFILE Library . . . . . . . . . . . *LIBL Source member . . . . . . . . . SRCMBR Bottom F3=Exit F4=Prompt F5=Refresh F12=Cancel F13=How to use this display F24=More keys DataLinks 161 The SRCFILE and SRCMBR parameters allow you to pre-build the host database names in a separately maintained source file member for input to the command. The format of the input should be: HOSTDBLIB HOSTDBINST HOSTDB. Using Figure 103 as an example, the source file member would consist of the two following entries: MULTIM01 QSYS AS400RCH MULTIM02 QSYS AS400RCH 6.3.2.3 Additional configuration commands The functions of registering prefixes and host databases are both provided through CL commands. Sometimes, you may also want to remove registered prefixes. However, this administrative function is not accessed through CL commands but through the QShell interactive interface. The following example shows how to use the dfmadmin command in the QShell. To use the command, type the following statement into an OS/400 command prompt, and press Enter: QSH You are now presented with the QShell command interface. To remove the prefix '/teamzz,' which you accidentally mis-typed, run the following QShell command: dfmadmin -del_prefix Press Enter. When prompted, type: /teamzz Press Enter. Press Enter again to terminate the command. 6.3.2.4 Additional DataLink management interfaces Viewing the content of some of the database tables in the QDLFM library through the Operations Navigator Quick View function can be a useful way of determining the current state of the DataLink environment. The tables in QDLFM on which you should focus are: The ADDHDBDLFM command has an additional parameter, the host database instance (HOSTDBINST). This is always QSYS on the AS/400 system and does not need to be specified as the parameter defaults to this value. It is present for compatibility with DB2 Universal Database on other platforms which, unlike DB2 Universal Database for AS/400, supports multiple database instances. Note Exercise caution if using the QShell commands. Their use should be restricted to deleting inappropriate prefixes or host database names. For example, a particular directory prefix is no longer needed and it does not contain any linked files, or a library referenced in the host database entries is being replaced by a new library. Attention 162 DB2 UDB for AS/400 Object Relational Support DFM_DBID DFM_FILE DFM_PRFX From the Operations Navigator window, right-click on the DFM_DBID table icon, and select Quick View to display the rows in the table. You should not double-click on the table, since this opens it for update, exposing you to the danger of accidentally overwriting or deleting values in the table rows. You see a display similar to that in Figure 104. It contains one row for each library that has been registered with the DLFM and the name of the system on which that library resides. Figure 104. Table DFM_DBID in QDLFM library: Viewed with Operations Navigator Repeat the Quick View operation on the table DFM_FILE. The Results window should resemble that shown in Figure 105. This table has one row for each file that is linked and includes the directory path to the file. Figure 105. Table DFM_FILE in QDLFM library: Viewed with Operations Navigator Finally, repeat the Quick View operation on the table DFM_PRFX. You see a Results window similar to that shown in Figure 106. This has one row for each prefix that has been registered with the DLFM. Figure 106. Table DFM_PRFX in QDLFM library: Viewed with Operations Navigator DataLinks 163 6.3.3 Starting the DLFM server Once the generic DLFM environment has been initialized, you are ready to start the DLFM. It must be started on any systems that contain file objects to be linked. On the AS/400 system, the DLFM is, in fact, a TCP/IP server job. To start it, run the following CL command: STRTCPSVR SERVER(*DLFM) The screen shown in Figure 107 should be displayed. You will notice that this screen is not a conventional command display. The reason for this is that the DLFM server is started through the OS/400 QShell interface, and it is the interactive shell interface that is displayed. Once the DLFM server has started, you must press Enter to terminate the QShell terminal session and return to the OS/400 command interface. Once started, the DLFM would normally be permanently active. However, to terminate it in a controlled way, there is the following CL command: ENDTCPSVR SERVER(*DLFM) Once execution of this command has completed, you receive a the message: DLFM server ended Figure 107. Starting the DLFM server jobs When the DLFM has successfully started, there will be a number of jobs active in the OS/400 QSYSWRK subsystem. These are shown in Figure 108 and Figure 109 on page 164. Create detach session message queue. DLFM server started. Press ENTER to end terminal session. ===> F3=Exit F4=End of File F6=Print F9=Retrieve F17=Top F18=Bottom F19=Left F20=Right F21=User Window 164 DB2 UDB for AS/400 Object Relational Support Figure 108. DLFM server jobs in Operations Navigator Figure 109. DLFM server jobs in subsystem QSYSWRK 6.4 Using DataLinks with SQL Once you have registered the prefixes and host database names, and the DLFM server has been started, you can start to link to objects in the file system. You begin by defining and creating the tables you need in the libraries that have been registered to the DLFM. There are a number of options to be considered as part of the table creation process as you define the DataLinks columns. These are covered in detail in 6.4.1, “DataLink options: General” on page 165. The options you choose will be governed primarily by the nature of the applications that will be using the DataLinks. It is important to note that the DataLinks architecture defines a number of possible attributes for creating, processing, and managing linked files. V4R4 delivers the first stage of the implementation for DB2 Work with Active Jobs AS400WS 09/24/99 15:23:29 CPU %: .0 Elapsed time: 00:00:00 Active jobs: 197 Type options, press Enter. 2=Change 3=Hold 4=End 5=Work with 6=Release 7=Display message 8=Work with spooled files 13=Disconnect ... Opt Subsystem/Job User Type CPU % Function Status QZDFMCHD QSYS BCI .0 TIMW QZDFMCOD QSYS BCI .0 DEQW QZDFMCPD QSYS BCI .0 SIGW QZDFMDGD QSYS BCI .0 DEQW QZDFMGCD QSYS BCI .0 SIGW QZDFMRTD QSYS BCI .0 DEQW QZDFMSVR QSYS BCH .0 TIMW QZDFMUPD QSYS BCI .0 DEQW Bottom Parameters or command ===> F3=Exit F5=Refresh F7=Find F10=Restart statistics F11=Display elapsed data F12=Cancel F23=More options F24=More keys DataLinks 165 Universal Database for AS/400 and, therefore, delivers a subset of those attributes. 6.4.1 DataLink options: General The DataLinks architecture defines the following attributes that are summarized in Table 13 on page 167: • Linktype: The only link type currently defined is the URL. • Link Control: This is the basic attribute that defines whether file system objects will be linked to a DataLink row in an RDBMS table. The choice is between No Link Control and File Link Control: – No Link Control: When rows are inserted into the table, there would be no links established to the file objects referenced in the DataLink column. No check is made to verify that the file server can be accessed or that the file object being referenced even exists. However, the syntax of the URL is validated. While the No Link Control option still provides value in terms of new application potential, it does not enable you to benefit from the management and integrity control provided by the File Link Control option. – File Link Control: When a row is inserted into the table, the DLFM immediately attempts to establish a link to the referenced file object. The file server must be accessible, and the file object must exist. Once the link has been established, the DLFM maintains control of the link through its metadata. A file object may only be linked to one table row. However, a table row may contain multiple DataLink columns as long as each is linked to a different file object. Once a file has been linked, it may not be moved, deleted, or renamed. Deleting the table row unlinks the associated file. Updating the DataLink value in the table row causes the original referenced file to be unlinked while the new referenced file is linked. • Integrity: This attribute controls the level of data integrity between the database server and the file server. The two options are Integrity All and Integrity Selective: – Integrity All: Any linked file object referenced by a DataLink column is considered to be under the control of the RDBMS, and attempts to rename, delete, or move the file object from a file system interface are rejected. – Integrity Selective: Any linked file object referenced by a DataLink column is considered to be under the control of the RDBMS only if the file server has the DataLinks Filter installed. This option is not supported by V4R4 of DB2 Universal Database for AS/400. • Read Permission: This defines where file object read access is controlled. The choices are Read Permission FS and Read Permission DB: – Read Permission FS: The file system controls whether a user has the necessary authority to perform a read operation on a linked file system object. No prior access to the associated RDBMS table is required. – Read Permission DB: The RDBMS controls whether a user may perform a read operation on a linked file system object. Assuming the file system object has been given no public access authority, it can only be read by first accessing the DataLink value in the database table and retrieving an access control token. This is covered in more detail in 6.4.6, “Using the DataLink access control token” on page 186. 166 DB2 UDB for AS/400 Object Relational Support • Write Permission: This defines whether a user can write to the file object. The choices are Write Permission FS and Write Permission Blocked: – Write Permission FS: The file system controls whether a user has the necessary authority to perform a write operation to a linked file system object. No prior access to the associated RDBMS table is required. – Write Permission Blocked: A file system object cannot be written to through any interface because it is owned by the DLFM. V4R4 of DB2 Universal Database for AS/400 enforces this option if Read Permission DB has been selected. • Recovery: This attribute specifies whether point-in-time recovery of linked files will be supported. The two options are Recovery Yes and Recovery No: – Recovery Yes: Point-in-time recovery is achieved by the RDBMS ensuring that backup copies of the linked files are made as needed. It is only valid when Integrity All and Write Permission Blocked are also specified. This option is not supported by V4R4 of DB2 Universal Database for AS/400. – Recovery No: Point-in-time recovery is not supported. • On Unlink: This attribute determines the action to be taken when the RDBMS controls write operations to a linked file (Write Permission Blocked), and the file is unlinked either through the DataLink value in the associated table row being updated or the row being deleted. Note that updating a row’s DataLink value effectively deletes the current file link and replaces it with a new file link. The option is not applicable when write operations are controlled by the file system (Write Permission FS). The options are On Unlink Restore and On Unlink Delete: – On Unlink Restore: When a file is unlinked, this option will ensure that the file’s ownership and permissions are restored to their state at the time that the file was linked. If the owner no longer exists in the file system, a default owner may be established, but this action depends on the particular file system involved. Apart from only being a valid option when Write Permission Blocked is also specified, Integrity All is also a prerequisite. – On Unlink Delete: When a file is unlinked, it is automatically deleted. This option is only valid when Read Permission DB and Write Permission Blocked are also specified. DataLinks 167 Table 13. Architected DataLink attributes: Permissible combinations 6.4.2 DataLink options: DB2 Universal Database for AS/400 You can see from Table 13 that V4R4 of DB2 Universal Database for AS/400 supports a subset of the architected options. We now review how those options are defined and implemented. Tables that are to contain rows with DataLink columns can be created through the Operations Navigator or through a 5250 session and Interactive SQL. To use the Operations Navigator interface, you must right-click on a library object and select New->Table. The New Table dialog appears as shown in Figure 110. Figure 110. New table dialog Once you type the name of your new table and its optional description and click OK, the table definition can begin. You start inserting columns into the table, defining the appropriate data type for each column from the drop-down list box in the normal way. Figure 111 on page 168 shows a DataLink type column about to be inserted. Link control Integrity Read permission Write permission Recovery On unlink N/A N/A N/A N/A N/A N/A FILE ALL FS FS NO N/A FILE ALL FS BLOCKED NO RESTORE FILE ALL FS BLOCKED YES RESTORE FILE ALL DB BLOCKED NO RESTORE FILE ALL DB BLOCKED NO DELETE FILE ALL DB BLOCKED YES RESTORE FILE ALL DB BLOCKED YES DELETE FILE SELECTIVE FS FS NO N/A Note: • N/A means not applicable • The shaded rows indicate the combination of options that are supported by V4R4 of DB2 Universal Database for AS/400. 168 DB2 UDB for AS/400 Object Relational Support Figure 111. Inserting a DataLink column If you do not specify a length for the column, a default value of 200 is applied. Make sure that the specified length is sufficient to contain both the largest expected URL and any DataLink comment. The maximum length that can be specified is 32718. Once the DataLink column has been inserted, a number of options must be considered for that column, some of which are specific to the DataLink data type. These options could be grouped under the general description of "Link Control". The Link Control options you select determines if file system objects are linked to this table and how the links will be managed with regards to access control and integrity. Although a linked file cannot be referenced by more than one table row, a table row may contain more than one DataLink column. However, each of those columns must link to a different file. Figure 112 shows the state of the display after you have selected the DataLink data type and decided on its length. We now look at the remaining options for a DataLink column on the display. DataLinks 169 Figure 112. Create table: DataLink column display A DataLink column can be defined as not null. There are two valid default values: null and DLVALUE('','URL',''). The Length to allocate box has a value of 50. This specifies the default fixed-length space to be allocated for the DataLink column in each row. Column values with lengths less than or equal to the allocated length are stored in the fixed-length portion of the row. Column values with lengths greater than the allocated value are stored in the variable-length portion of the row. Column values stored in the variable-length portion of the row require additional input/output operations to retrieve. The allocated value may range from 0 to the maximum length of the string. The Link control check box can be left unchecked. This would result in the table being created, but when rows are inserted, there would be no links established to the file objects referenced in the DataLink column. In fact, the DLFM does not become involved, and no check is made to verify that the file server can be accessed or that the file object being referenced even exists. However, the syntax of the URL is validated. This option corresponds to the first row of attributes in Table 13 on page 167. While the 'No Link Control' option still provides value in terms of new application potential, it does not enable you to benefit from the management and integrity control provided by the File Link Control option. However, it allows a linked file to be referenced by a DataLink value in more than one table. If you now check the Link control check box, the display changes look like those shown in Figure 113 on page 170. 170 DB2 UDB for AS/400 Object Relational Support Figure 113. Create table: DataLink column link control Read FS/Write FS Refer to Figure 119 on page 175 for the equivalent SQL statement. When you specify Link control, the check box Allow read and write of the linked file through the file system is no longer grayed out and is checked by default. If you now create the table by pressing the OK button, it is created with the DataLink option READ PERMISSIONS FS/WRITE PERMISSIONS FS. This means that the file system controls access to the associated file objects. However, attempts to move, delete, or rename the file while it is linked are always denied because the data integrity is enforced. Attempts by a program to perform read and write operations directly on the file are allowed if all the appropriate authorities are in place. There is no requirement to retrieve an access control token from the database table (see 6.4.6, “Using the DataLink access control token” on page 186, for a detailed explanation). This option corresponds to the second row of attributes in Table 13 on page 167. However, if you un-check the Allow read and write of the linked file through the file system check box, the display appears as shown in Figure 114. DataLinks 171 Figure 114. Create table: DataLink column link control Read DB/Write Blocked The equivalent SQL statement looks like the following example: CREATE TABLE ProdMast02 (Product_Number FOR COLUMN PMNBR TEAMXX/SRLNUMBER NOT NULL WITH DEFAULT, Product_Name FOR COLUMN PMNAM CHAR(25) NOT NULL WITH DEFAULT, Product_Description FOR COLUMN PMDESC TEAMXX/PRDDESC, Product_Price FOR COLUMN PMPRIC TEAMXX/MONEY, Product_Picture_Link FOR COLUMN PMPICT DATALINK(200) LINKTYPE URL FILE LINK CONTROL INTEGRITY ALL READ PERMISSION DB WRITE PERMISSION BLOCKED RECOVERY NO ON UNLINK RESTORE); This indicates implicitly that you wish to create the table with the attributes READ PERMISSION DB/WRITE PERMISSION BLOCKED. This means that DB2 Universal Database for AS/400 controls access to the associated file objects. This is achieved by transferring ownership of each file object to the DLFM (user profile QDLFM) at the time that a table row is inserted and the link is established. However, attempts to move, delete, or rename the file while it is linked are always denied because the data integrity is enforced. Attempts by a program to perform write operations on the file are always rejected regardless of the permissions in place for the file. Attempts to perform read operations directly on the file will be honored if the user has sufficient permissions in place for that file. However, as the intention of this link option is to have the database control read access to the file objects, you should always ensure that the files to be linked have no public access permissions defined. Then, read operations are only successful if the program first obtains an access control token from the database by reading the 172 DB2 UDB for AS/400 Object Relational Support associated table row. Refer to 6.4.6, “Using the DataLink access control token” on page 186, for a detailed explanation. You can display the file permissions by using Operations Navigator to display the IFS files. Select a file, right-click on it, and select Permissions from the drop-down box. Figure 115 shows the ownership of a file in the AS/400 IFS before it has been linked. You see that it is owned by user TEAMXX. Figure 115. File ownership: Before linking Figure 116 shows the ownership of the same file after it has been linked to a table row where the table was created with the option Read Permission DB. DataLinks 173 Figure 116. File ownership: After linking You will see that the owner of the file is now QDLFM, the user profile of the DataLinks File Manager. However, when ownership is changed to QDLFM, details about the previous ownership are saved. Referring back to Figure 114 on page 171, the final check box option is the one labeled 'Delete file when unlinked'. If you place a check mark in this box, you establish the option ON UNLINK DELETE when the table is created. Note that the check box is grayed out if the file system is controlling authorities for read and write operations. This is because it is not logical for unlink actions caused by database activity to operate on file objects when the file system is managing write access to those objects. If you select On Unlink Delete when a table row is deleted, the associated file is unlinked and then deleted from the file system. The same action occurs when a table row is updated, because an update is executed as a delete of the existing row followed by an insert of the new row. This option corresponds to the sixth row of attributes in Table 13 on page 167. If you leave the check box empty, you are implicitly indicating that you wish to create the table with the option ON UNLINK RESTORE. When a file is unlinked, this option ensures that the file’s ownership and permissions are restored to their state at the time that the file was linked. If the owner no longer exists in the file system, ownership is given to the default owner, which is QDFTOWN on AS/400. This option corresponds to the fifth row of attributes in Table 13 on page 167. You must exercise caution if you use the On Unlink Delete option. We strongly advise that you use the On Unlink Restore option unless an application can significantly benefit from the delete action. For example, you may have a Web application that allows potential customers to listen to CDs and watch video clips from an online catalog. While the CD or video are popular, you are using the l integrity of DataLinks to prevent the CD sound bites and video clips from being deleted. However, you would want to maintain the catalog so that, when a CD or video is no longer current or popular, it is removed. The On Unlink Delete option 174 DB2 UDB for AS/400 Object Relational Support would ease the maintenance of the catalog by automatically deleting the CD sound bites and video clips when the row is deleted from the catalog table in the database. Figure 117 summarizes the V4R4 DB2 Universal Database for AS/400 link control options. Figure 117. Summary of DB2 Universal Database for AS/400 link control options When you create a table, there are a number of other table properties that can be defined. These properties include Key Constraints, Indexes, Referential Constraints, and so forth. DataLink fields have special considerations. They may not be used as key fields in an index. Consequently, they may not be used to define key constraints or referential constraints. Any attempt to define an index, key constraint, or referential constraint will result in an error message. Triggers may be defined for tables containing DataLinks columns. Because DataLink columns cannot be compared with other columns or literals, they cannot have check constraints defined on them. An attempt to define a check constraint results in the SQL0401 error message. Operations Navigator now provides a more complete interface than the 5250 interface for database management activities. However, for those who need to use the 5250 interface, the SQL constructs to enable tables to be created with DataLinks are shown in Figure 118 and Figure 119. For the sake of clarity, these are depicted using the Operations Navigator Run SQL Scripts interface. 123 124 125 126 Atomic B Atomic C Atomic D Atomic E URL URL URL URL boot4.jpg boot3.jpg boot2.jpg boot1.jpg NO LINK CONTROL 123 124 125 126 Atomic B Atomic C Atomic D Atomic E URL URL URL URL boot4.jpg boot3.jpg boot2.jpg boot1.jpg FILE LINK CONTROL 123 124 125 126 Atomic B Atomic C Atomic D Atomic E URL URL URL URL boot4.jpg boot3.jpg boot2.jpg boot1.jpg FILE LINK CONTROL READ PERMISSION FS WRITE PERMISSION FS PROGRAM PROGRAM READ PERMISSION DB WRITE PERMISSION BLOCKED ON UNLINK RESTORE/DELETE DataLinks 175 Figure 118. DataLink column with read permission DB/Write permission blocked Figure 119. DataLink column with read permission FS/Write permission FS Figure 120 on page 176 shows an alternative, shorthand definition to that in Figure 119. MODE DB2OPTIONS is used to define a default set of options and is functionally equivalent to: INTEGRITY ALL READ PERMISSION FS WRITE PERMISSIN FS RECOVERY NO • If the On Unlink Delete option is required, simply substitute ON UNLINK RESTORE with ON UNLINK DELETE. • LINKTYPE URL is currently the only link type supported by the architecture. Note 176 DB2 UDB for AS/400 Object Relational Support This notation is currently the only mode option that has been defined and is provided by DB2 Universal Database for AS/400 for compatibility with the other DataLink capable platforms. Figure 120. Create table with DataLinks: SQL (Mode DB2Options) If a table with a datalink column is created with File Link Control, that table must be journaled. This is because the link operation operates on two separate entities, the table and the file, and they are considered to be part of one transaction in order to maximize integrity. Because a table and its linked files could be on different physical servers, two-phase commitment control is exploited in order to extend that transaction integrity. If you attempt to insert data into a table with a DataLink that has been created with File Link Control, and you have failed to start journaling that table, you receive an SQL7008 error message (for example, SQL7008 - PICTU00001 in TEAMXX not valid for operation). It is worth remembering that placing your tables in a collection rather than a library will automate journaling for those tables. However, you must not forget the need to manage the journal receivers to prevent them from growing in an uncontrolled way. The journal entry for a DataLink column is written in the normal way with the row content appearing as characters as shown in Figure 121. DataLinks 177 Figure 121. Detailed journal entry: DataLink row insert V4R4 of Operations Navigator does not provide a function for viewing the link attributes of DataLink column within a table. However, the DSPFFD CL command has been updated to display the information in a 5250 session. The last page of the displayed output will look similar to the example shown in Figure 122 on page 178. Display Journal Entry Object . . . . . . . : PICTU00001 Library . . . . . . : TEAMXX Member . . . . . . . : PICTU00001 Sequence . . . . . . : 387 Code . . . . . . . . : R - Operation on specific record Type . . . . . . . . : PT - Record added Incomplete data . . : No Entry specific data Column *...+....1....+....2....+....3....+....4....+....5 00001 'A é00001URL 00043 FILE://AS400WS/teamxx/Fun' 00051 '_pictures/fish.gifThis is The Fish ' 00101 ' ' More... Null value indicators Field *...+....1....+....2....+....3....+....4....+....5 00001 >00< Bottom Press Enter to continue. F3=Exit F6=Display only entry specific data F10=Display only entry details F12=Cancel F24=More keys 178 DB2 UDB for AS/400 Object Relational Support Figure 122. DSPFFD output for a table with a DataLink column 6.4.3 Data manipulation examples Once you have created a table with one or more DataLink columns, you can use an SQL scalar function to insert or update data. Figure 123 shows an example of a table insert. DLVALUE is the scalar function. It is overloaded to accept one, two, or three parameters. Figure 123. Insert with DLVALUE DataLink scalar function Display Spooled File File . . . . . : QPDSPFFD Page/Line 1/47 Control . . . . . Columns 1 - 130 Find . . . . . . *...+....1....+....2....+....3....+....4....+....5....+....6....+....7....+....8 ....+....9....+....0....+....1....+....2....+....3 Alternative name . . . .. . . . . .. . : PRODUCT_PRICE User defined-type name . . . . . . . . . : MONEY User defined-type library name . . . . . : TEAMXX Allows the null value PMPICT DATALINK 200 224 71 Both PRODUCT_PICTURE_LINK Alternativename ............: PRODUCT_PICTURE_LINK Variable length field -- Allocated length : 50 Datalink link control . . . . . . . . . . : File Datalink integrity . . .. . . . . . . . : All Datalink read permission . .......: Database Datalink write permission . . . . . . . . : Blocked Datalink recovery . . . . . . . . . . . . : No Datalink unlink control . . . . . . . . . : Restore Allows the null value Default value . . ............: *NULL Coded Character Set Identifier . . . . . : 37 Bottom F3=Exit F12=Cancel F19=Left F20=Right F24=More keys DataLinks 179 The example shows all three parameters being passed to the function. These parameters are: • The data location, for example: 'file://as400ws/teamxx/Product_Pictures/boot1.jpg' • The link type, for example: 'URL' (currently only 'URL' is supported). This argument is optional. If not specified, it will be set to 'URL'. • A comment, for example: ’Atomic Betaflex 9.08’. The comment is optional. If it is not specified, it is set to an empty string. The full file path comprises the file server name, the registered prefix, the sub-directory path below the prefix, and the file name. The file must exist at the time the insert operation is executed if the table was created with file link control. Using the DataLink data from the example in Figure 123, other valid parameter combinations provided by function overloading of the DLVALUE scalar function are: • dlvalue('file://as400ws/teamxx/Product_Pictures/boot1.jpg') • dlvalue('', 'URL', 'Atomic Betaflex 9.08') In the case where only the link type (URL) and the comment are provided, the file path is defined as a zero-length string. The resulting row in the table would contain empty link attributes, and no file link would exist. This can be used, for example, to create rows in the table that are place-holders for files that, as yet, do not exist. Figure 124 shows an example of inserting a row into a table where the DataLink column does not specify a data location parameter. Using the Operations Navigator Quick View function, Figure 125 shows the contents of the table after the successful insert operation. The newly inserted row has an empty DataLink column. Figure 124. DLVALUE function overloading Figure 125. Table with empty DataLink column 180 DB2 UDB for AS/400 Object Relational Support However, there is one important consideration when inserting DataLink values into a table. A linked file cannot be referenced by more than one table row, that is, there is a one-to-one relationship between a file and the table to which it is linked. However, another table may include a linked file in its DataLink column value if that table was created with no link control. The Update statement works in the same way with the DLVALUE scalar function. However, an update to a row with a linked file is treated as a delete of the existing row followed by an insert of a new row. The effect on the linked file is to unlink the existing file and link the new file. In 6.4.1, “DataLink options: General” on page 165, the On Unlink Delete option is discussed in detail. However, to reiterate a word of caution, if On Unlink Delete is the option you choose for a table, the Update operation causes the file referenced by the row being updated to be deleted from the file system. Figure 126 shows an example of an Update operation. In this example file, ski12.mpg is linked to the Sports table immediately after the existing row has been deleted and the new row inserted. Figure 126. Update with DLVALUE DataLink scalar function When you insert a row with a DataLink into a table using the DLVALUE scalar function, the DataLink content that is actually stored is an encapsulated value. It contains a logical reference from the database to a file stored externally to the database within a file system. The encapsulated value is comprised of the following elements: • Link Type: Currently, only type URL is supported. • Scheme (Optional): For Link Type URL file:, http:, and https: are supported. Note that the scheme simply aids the DLFM in locating and validating the file object to be linked.There is no requirement for the presence of any particular Web server product. • File Server Name: The complete server address. • File Path: The directory and file name hierarchy within the file server Since the update is really a delete followed by an insert, you need to specify link type and comment values again. If you omit them in the update statement, they will be set to their respective default values. Note DataLinks 181 • Access Control Token: Generated dynamically (see 6.4.6, “Using the DataLink access control token” on page 186, for more details). • Comment (Optional): Up to 254 characters of description. Once you insert data into a table, you must use an SQL scalar function to retrieve data from the encapsulated DataLink value. The valid scalar functions are covered in 6.4.4, “DataLink SQL scalar functions” on page 182. Other common types of SQL data manipulation you may use include Group By and Order By. Neither grouping nor ordering is allowed based on a DataLink column. Figure 127 shows the error message you receive if you attempt Order By on a DataLink. Figure 127. Order by on DataLink column 182 DB2 UDB for AS/400 Object Relational Support 6.4.4 DataLink SQL scalar functions In addition to the DLVALUE scalar function, a number of others are provided in order to extract data from the encapsulated DataLink. They are summarized in Table 14. Table 14. DataLinks SQL scalar functions As an example, if you run the SQL statements from the Operations Navigator Run SQL Scripts window, as shown in Figure 128, the output appears similar to the example displayed in Figure 129 through Figure 132. Figure 128. DataLink SQL scalar functions script Figure 129. Result set from the DLURLCOMPLETE scalar function Scalar function name Data type returned Data returned DLVALUE DATALINK N/A (For Insert and Update) DLCOMMENT VARCHAR(254) Comment DLLINKTYPE VARCHAR(4) Link Type (Only URL currently supported) DLURLCOMPLETE VARCHAR Server Name+ Full Directory Path + Access Control Token DLURLPATH VARCHAR Full Directory Path + Access Control Token DLURLPATHONLY VARCHAR Full Directory Path DLURLSCHEME VARCHAR(20) FILE or HTTP or HTTPS DLURLSERVER VARCHAR Server name DataLinks 183 In Figure 129, as well as returning the file server name (AS400WS) and the full file directory path (/teamxx/Product_Pictures/boot1.jpg), you can also see the access control token immediately before the file name. Figure 130. Result set from the DLURLPATH scalar function Figure 130 shows that DLURLPATH omits the file server name, while Figure 131, DLURLPATHONLY, also omits the access control token. Figure 131. Result set from the DLURLPATHONLY scalar function Finally, Figure 132 shows the simple scalar functions, DLURLSCHEME and DLURLSERVER, that merely return the URL scheme (file:, http:, or https:) and the file server name, respectively. Figure 132. Result sets from DLURLSCHEME and DLURLSERVER scalar functions 6.4.5 Using the DataLink in dynamic Web pages To achieve better scalability of your Internet software solution, you usually split the application server running the Web server from the database server. For performance reasons, you also want to store the files referred in the Web pages on the Web server. Now, you may ask the question: How does the DataLink 184 DB2 UDB for AS/400 Object Relational Support support fit into this picture? In this section, we explain how to take advantage of the DataLinks for building dynamic Web pages. Let’s suppose that the database containing all the products we want to sell over the Internet reside in the library TEAMXX on the AS400RCH database server, and that the product picture files reside on the AS400LON Web server machine. The product picture files are linked to appropriate rows in the PRODMAST03 table on the AS400RCH machine. The following procedure outlines the major steps required to set up our application environment: 1. The PRODMAST03 table containing detailed product information was created with the following SQL statement: CREATE TABLE ProdMast03 (Product_Number FOR COLUMN PMNBR TEAMXX/SRLNUMBER NOT NULL WITH DEFAULT, Product_Name FOR COLUMN PMNAM CHAR(25) NOT NULL WITH DEFAULT, Product_Description FOR COLUMN PMDESC TEAMXX/PRDDESC, Product_Price FOR COLUMN PMPRIC TEAMXX/MONEY, Product_Picture_Link FOR COLUMN PMPICT DATALINK(200) LINKTYPE URL FILE LINK CONTROL INTEGRITY ALL READ PERMISSION FS WRITE PERMISSION FS RECOVERY NO); Note that we use file system permission for read and write options for the DataLink column. 2. The linked objects, which are product pictures in this case, were copied to the /teamxx/images/ IFS directory on the Web server system AS400LON. To enhance the Web server security, all files located in this directory have the PUBLIC permission set to *EXCLUDE. At the same time, we added the *RX permission for the QTMHHTTP profile so that the HTTP server jobs running on the AS400LON system can access the image files and serve them to the clients. 3. The DLFM environment was initialized on the AS400LON system with the INZDLFM command. The directory prefix was set up with the following CL command: ADDPFXDLFM PREFIX(('/teamxx/')) The host database was set up as follows: ADDHDBDLFM HOSTDBLIB((TEAMXX)) HOSTDB(AS400RCH) The DLFM server was started with the following CL command: STRTCPSVR SERVER(*DLFM) 4. The product details were inserted into the PRODMAST03 table on the database server AS400RCH. An example of the insert statement is shown as follows: Insert into teamxx/prodmast02 values('00001','Solomon X-scream Series', 'Description:A solid, reliable performer for experts. A sense of freedom and speed when turning. For playing with the terrain and improvising at high speed. Sizes:179 - 195 Color:yellow Best For:all but the gnarliest terrain', 730.00, dlvalue('file://as400lon/teamxx/images/xscr_pr.gif', 'URL', 'Solomon Xscream')); DataLinks 185 Note that the URL value in the DataLink column points to the remote system AS400LON. Now, our Web Shop application can generate dynamic HTML pages on the fly, fetching the required product data from the AS400RCH system. To retrieve a product picture file name for a given product number, we could use the following SQL statements: CONNECT TO AS400RCH 1 .... SELECT dlurlpath(Product_Picture_Link) INTO :src FROM prodmast03 WHERE Product_number = '00001' 2 SQL statement notes 1. Since the product database resides on the remote system, we can use DRDA to connect to the remote database. Note that, in this scenario, we need an RDB directory entry for the AS400RCH system on the AS400LON machine. Refer to DB2/400 Advanced Database Functions, SG24-4249, for details on setting up the DRDA environment. 2. The DLURLPATH scalar function is used to retrieve the full file directory path for a given product into the src host variable. We can now use this variable to generate an appropriate IMG HTML tag: Product Inline Image There are several advantages of using DataLinks in this scenario: • The product picture files on the Web server machine are safe. Nobody, even with QSECOFR authority, can move, rename, or delete linked files. Note that unlinked objects in the /teamxx/images/ directory can still be manipulated by a user who has proper authority. However, this is only true when the DLFM server is up and running. When the server is down, no manipulation of the objects in the prefixed directory is allowed, because the file system cannot verify whether any of these objects is linked. For example, deleting an object in the /teamxx/images/ directory could compromise the integrity of the PRODMAST03 file. • Although the image files logically belong to the PRODMAST03 table, they are physically stored on the machine where they are needed. • IFS APIs, rather than SQL, are used to serve potentially large objects to the client Web browser. Figure 133 on page 186 shows our example HTML page using linked image files. 186 DB2 UDB for AS/400 Object Relational Support Figure 133. Using linked image files in HTML pages 6.4.6 Using the DataLink access control token Section 6.4.1, “DataLink options: General” on page 165, provides detailed coverage of the link control options defined in the DataLinks architecture and those implemented in V4R4 of DB2 Universal Database for AS/400. In particular, Figure 114 on page 171 and Figure 118 on page 175 show the option for creating the table with the link option of Read Permission DB/Write Permission Blocked. You select this option when you want your application to control access to associated file objects. More specifically, you want your application to be able to read file system objects but not to write to or update them. However, if you define the PUBLIC file permissions or ownership properties of a file to allow read access, your application will bypass the database access control. Therefore, you should always ensure that the files to be linked have no public access permissions defined. Then, read operations will only be successful if the program first obtains an access control token from the database by reading the associated table row, and the DataLink Filter validates that token. The DLURLPATH scalar function may be used to retrieve the full directory path along with the control token. This section illustrates how to retrieve and use the token. We coded programs in C with embedded SQL to test both the Read Permission DB/Write Permission Blocked and the Read Permission FS/Write Permission FS environments. The programs also tested the integrity of both environments by attempting various operations on linked files. 6.4.6.1 READPM02 program The details are for program READPM02, Test Read Permission DB/Write Permission Blocked. The table is PRODMAST02 and the file boot1.jpg. The file was originally defined with no public authority. The DataLink column definition looks like the following example: DataLinks 187 Product_Picture_LinkFOR COLUMN PMPICTDATALINK(200) LINKTYPE URL FILE LINK CONTROL INTEGRITY ALL READ PERMISSION DB WRITE PERMISSION BLOCKED RECOVERY NO ON UNLINK RESTORE The program steps are: 1. Read file directly in the IFS. 2. Move the file to another directory. 3. Update the file (coded in the program as an append). 4. Delete the file. 5. Read the file after reading the table row to which it is linked and executing several scalar functions. Figure 134 shows the output from the program after running the first four steps. Figure 135 on page 188 shows the output from the program after executing step five. The numbered lines are explained in the notes that follow each figure. Figure 134. Executing program READPM02: Direct file operations on boot1.jpg Notes on READPM02 program 1. The direct read operation failed. It is because of Read Permission DB and no public read access for the boot1.jpg file, and no control token was passed on the open file request. 2. The move operation failed because the file is linked, and data integrity is enforced by the DataLink Filter. 3. The direct write operation failed because the DataLinks were created with Write Permission Blocked. 4. The delete operation failed because the file is linked, and data integrity is enforced by the DataLink Filter. DB2 Universal Database for AS/400 DataLink Test Program: TEAMXX/READPM02 Read Permission DB/Write Permission Blocked Hit Enter to continue... > Attempting file system operations on: /teamxx/Product_Pictures/boot1.jpg 1 Read failed: /teamxx/Product_Pictures/boot1.jpg: Permission denied. 2 Move failed: /teamxx/Product_Pictures/boot1.jpg -> /boot1.jpg: Improper link. 3 Append failed: /teamxx/Product_Pictures/boot1.jpg: Permission denied. 4 Delete failed: /teamxx/Product_Pictures/boot1.jpg: Object is a Datalink object. Hit Enter to continue... ===> F3=Exit F4=End of File F6=Print F9=Retrieve F17=Top F18=Bottom F19=Left F20=Right F21=User Window 188 DB2 UDB for AS/400 Object Relational Support Figure 135. Executing program READPM02: Read of boot1.jpg with control token 5. Various SQL scalar functions used to retrieve the DataLink value from the row in the PRODMAST02 table. 6. The SQL scalar function actually used in the program to retrieve the access control token, file directory path, and file name. The access control token value is highlighted. 7. Opening the file for read access succeeded because the access control token was passed to the file open operation. The following snippets of the program code highlight the most significant parts of the program with regards to working with the DataLinks. The full program listing can be found in Appendix A, “Source code listings” on page 215. 1/ Compile: CRTSQLCI OBJ(TEAMXX/READPM02) SRCFILE(TEAMXX/QCSRC) + / SRCMBR(READPM02) OPTION(*NOGEN) / CRTBNDC PGM(TEAMXX/READPM02) SRCFILE(QTEMP/QSQLTEMP) + / SRCMBR(READPM02) SYSIFCOPT(*IFSIO) Note 1: The comment lines show the method of program compilation. Note the SYSIFCOPT parameter, which directs the created object to use the IFS for stream I/O operations. 2{ exec sql include SQLCA; /* declare host variables */ exec sql begin declare section; char link_comment[255]; char link_type[5]; struct VARCHAR1 { short length; char data[200]; } link_url_complete; struct VARCHAR2 Selecting Product_Picture_Link from teamxx/prodmast02 where Product_Number = '00001' 5 dlcomment(Product_Picture_Link) = Atomic Betaflex 9.08 5 dllinktype(Product_Picture_Link) = URL 5 dlurlcomplete(Product_Picture_Link) = FILE://AS400WS/teamxx/Product_Pictures/SS3AYIS;JG2A;F.CC.;boot1.jpg 6 dlurlpath(Product_Picture_Link) = /teamxx/Product_Pictures/SS3AYIS;JG2A;F.CC.;boot1.jpg 5 dlurlpathonly(Product_Picture_Link) = /teamxx/Product_Pictures/boot1.jpg 7 Readok:/teamxx/Product_Pictures/SS3AYIS;JG2A;F.CC.;boot1.jpg10530bytesread Press ENTER to end terminal session. ===> F3=Exit F4=End of File F6=Print F9=Retrieve F17=Top F18=Bottom F19=Left F20=Right F21=User Window DataLinks 189 { short length; char data[200]; } link_url_path; struct VARCHAR3 { short length; char data[200]; } link_url_path_only; char where_value[6]; exec sql end declare section; char file_name[FILENAME_MAX]; char ren_file_name[FILENAME_MAX]; char mov_file_name[FILENAME_MAX]; exec sql whenever sqlerror go to sqlexit; exec sql set path teamxx; Note 2: Declaring the host variables. 3/* initialize the datalink file name */ strcpy(file_name, "/teamxx/Product_Pictures/boot1.jpg"); Note 3: Establishing the path and file name of the IFS file to be processed. Refer to the execution time results shown in Figure 136 on page 192. 4 /* read file */ file_read(file_name); /* move file to new location */ file_move(file_name, mov_file_name); /* update file */ file_append(file_name); /* delete file */ file_delete(file_name); Note 4: Attempting operations directly on the file. 5 exec sql select dlcomment(Product_Picture_Link), dllinktype(Product_Picture_Link), dlurlcomplete(Product_Picture_Link), dlurlpath(Product_Picture_Link), dlurlpathonly(Product_Picture_Link) into :link_comment, :link_type, :link_url_complete, :link_url_path, :link_url_path_only from teamxx/prodmast02 where Product_Number = srlnumber(:where_value); /* null terminate the varchar host variables */ link_url_path.data[link_url_path.length] = '\0'; Note 5: Retrieve DataLink values into host variables using scalar functions. 6 /* read file using access control token */ file_read(link_url_path.data); return 0; } 190 DB2 UDB for AS/400 Object Relational Support Note 6: Attempt to read the IFS file with the access control token. The host variable 'link_url_path' contains the value obtained from the DLURLPATH SQL scalar function. This value includes the access control token and must be passed to the file open operation. If no token is present, or the token is invalid (for example, it is a previously retrieved token that has expired), the file open fails. Refer to Figure 137 on page 193 for the execution time results. 7/*--------------------------------------------------------------------- / / Description: Read a file. Display number of bytes read. / / Usage: file_name name of the file to read / returns -1 on success / 0 on failure / */ int file_read(char* file_name) { FILE* read_file; char buf[BUF_SIZE+1]; int read_count; long read_total; char perror_message[FILENAME_MAX+128]; sprintf(perror_message, "Read failed: %s", file_name); read_total = 0; if ((read_file = fopen(file_name,"rb")) == NULL) { perror(perror_message); return 0; } while ((read_count = fread(buf, sizeof(char), BUF_SIZE, read_file)) > 0) { read_total += read_count; } if (fclose(read_file) == EOF) { perror(perror_message); return 0; } printf("Read ok: %s %ld bytes read\n", file_name, read_total); return -1; } Note 7: Set up the direct file read operation. 8/*--------------------------------------------------------------------- / / Description: Append EOF to a file. / / Usage: file_name name of the file to append EOF to / returns -1 on success / 0 on failure / */ int file_append(char* file_name) { FILE* append_file; char perror_message[FILENAME_MAX+128]; sprintf(perror_message, "Append failed: %s", file_name); /* make sure that the file exists first */ if ((append_file = fopen(file_name,"rb")) == NULL) { perror(perror_message); return 0; } fclose(append_file); DataLinks 191 if ((append_file = fopen(file_name,"ab")) == NULL) { perror(perror_message); return 0; } fputc(EOF, append_file); if (fclose(append_file) == EOF) { perror(perror_message); return 0; } printf("Append ok: %s\n", file_name); return -1; } Note 8: Set up the direct file update operation. 9/*--------------------------------------------------------------------- / / Description: Move a file. File only renamed if no or same path / supplied in dest_file_name. / / Usage: src_file_name old name of the file to move / dest_file_name new name of the file to move / returns -1 on success / 0 on failure / */ int file_move(char* src_file_name, char* dest_file_name) { char perror_message[FILENAME_MAX+FILENAME_MAX+128]; sprintf( perror_message, "Move failed: %s -> %s", src_file_name, dest_file_name); if (rename(src_file_name, dest_file_name)) { perror(perror_message); return 0; } printf("Move ok: %s -> %s\n", src_file_name, dest_file_name); return -1; } Note 9: Set up the direct file move operation. READPM03 program For the program READPM03, we used Test Read Permission FS/Write Permission FS. The table is PRODMAST03, and the file is boot4.jpg. The file was defined with *RWX public authority. The DataLink column definition is shown here: Product_Picture_Link FOR COLUMN PMPICTDATALINK(200) LINKTYPE URL FILE LINK CONTROL INTEGRITY ALL READ PERMISSION FS WRITE PERMISSION FS RECOVERY NO The program steps are: 1. Read file directly in the IFS. 2. Move the file to another directory. 3. Update the file (coded in the program as an append). 4. Delete the file. 192 DB2 UDB for AS/400 Object Relational Support Figure 136 shows the output from the program after executing the four steps. The numbered lines are explained in the notes that follow. Figure 136. Executing program READPM03: Direct file operations on boot4.jpg Notes on the READPM03 program 1. The direct read operation succeeded because the public file permissions for boot4.jpg are *RWX and the DataLink column attribute READ PERMISSION FS rather than READ PERMISSION DB. 2. The move operation failed because the file is linked, and data integrity is enforced by the DataLink Filter. 3. The direct write operation succeeded because the DataLinks were created with Write Permission FS, and the public file permissions for boot4.jpg are *RWX. 4. The delete operation failed because the file is linked, and data integrity is enforced by the DataLink Filter. The READPM03 program is identical to READPM02, except the code to access the database table and retrieve DataLinks values have been removed. The full program listing can be found in Appendix A, “Source code listings” on page 215. In summary, when a file has been linked, any attempt to move, delete, rename, or update that file is denied by the DataLink Filter. When a DataLink has been created with the option READ PERMISSIONS DB/WRITE PERMISSIONS BLOCKED, you are allowing the database to control access to associated file objects by transferring ownership of the files to the DLFM (user QDLFM). An attempt to read the file after first using an SQL scalar function to retrieve the access control token from the linked database table is permitted by the DataLink Filter. When a DataLink has been created with the option READ PERMISSIONS FS/WRITE PERMISSIONS FS, the file system controls access to the associated file objects. Attempts by a program to perform read and write operations directly DB2 Universal Database for AS/400 DataLink Test Program: TEAMXX/READPM03 Read Permission FS/Write Permission FS Hit Enter to continue... > Attempting file system operations on: /teamxx/Product_Pictures/boot4.jpg 1 Read ok: /teamxx/Product_Pictures/boot4.jpg 12094 bytes read 2 Move failed: /teamxx/Product_Pictures/boot4.jpg -> /boot4.jpg: Improper link. 3 Append ok: /teamxx/Product_Pictures/boot4.jpg 4 Deletefailed:/teamxx/Product_Pictures/boot4.jpg:ObjectisaDatalinkobject. Press ENTER to end terminal session. ===> F3=Exit F4=End of File F6=Print F9=Retrieve F17=Top F18=Bottom F19=Left F20=Right F21=User Window DataLinks 193 on the file are allowed if all the appropriate authorities are in place. There is no need to retrieve an access control token from the database table. The value of the access control token is not stored permanently in the DataLink value within the table row. It is generated dynamically when a scalar function is executed to retrieve it. Once retrieved, it eventually expires to prevent a user from storing it permanently for later use. Currently, the expiration time is set to two weeks. Figure 137 shows an example of retrieving the token for each of three table rows with the SQL scalar function DLURLPATH and then retrieving it again a few seconds later. Figure 137. Access control token: Dynamic generation Notice that the value of the tokens has changed in the short time it took to re-read the table rows. 6.5 Native interface considerations As previously stated, because the DataLink is not compatible with any host variable data type, the only interface that allows access is SQL. However, we conducted a number of tests to identify what native activities, if any, would be allowed with tables containing DataLink columns. Our conclusion is that, while DataLink columns cannot be used in applications using native I/O access, the tables in which they reside can be used by defining a logical file over the underlaying table that omits the DataLink columns. The tests were based on a table, SPORTS, which contains three columns of character data type and a single DataLink column. Figure 138 on page 194 shows the table properties. Both the table name and the column names have been kept short to simplify the native file and RPG program coding. The table was created with File Link Control and Read Permissions FS/Write Permissions FS, although these characteristics should have no bearing on the native interface capabilities. An RPG program, SPORTRPG1, was written to read a row from the SPORTS table, check the product season code column (PRDSEA) for the character 'W' and, if it is equal to 'W', add a row to the output table WINTER containing all the input columns, including a DataLink column. WINTER was created with the option No Link Control. 194 DB2 UDB for AS/400 Object Relational Support Figure 138. Table SPORTS for native tests The program was compiled, and the compilation listing is shown in here: 5769RG1 V4R4M0 990521 IBM RPG/400 TEAMXX/SPORTRPG1 10/06/99 15:56:28 Page 1 Compiler . . . . . . . . . . . . . : IBM RPG/400 Command Options: Program . . . . . . . . . . . . : TEAMXX/SPORTRPG1 Source file . . . . . . . . . . : TEAMXX/QRPGSRC Source member . . . . . . . . . : SPORTRPG1 Source listing options . . . . . : *SOURCE *XREF *GEN *NODUMP *NOSECLVL *NOSRCDBG *NOLSTDBG Generation options . . . . . . . : *NOLIST *NOXREF *NOATR *NODUMP *NOOPTIMIZE Source listing indentation . . . : *NONE Type conversion options . . . . : *NONE Sort sequence . . . . . . . . . : *HEX Language identifier . . . . . . : *JOBRUN SAA flagging . . . . . . . . . . : *NOFLAG Generation severity level . . . : 9 Print file . . . . . . . . . . . : *LIBL/QSYSPRT Replace program . . . . . . . . : *NO Target release . . . . . . . . . : *CURRENT User profile . . . . . . . . . . : *USER Authority . . . . . . . . . . . : *LIBCRTAUT Text . . . . . . . . . . . . . . : *SRCMBRTXT Phase trace . . . . . . . . . . : *NO Intermediate text dump . . . . . : *NONE Snap dump . . . . . . . . . . . : *NONE Codelist . . . . . . . . . . . . : *NONE Ignore decimal data error . . . : *NO Allow null values . . . . . . . : *NO Actual Program Source: Member . . . . . . . . . . . . . : SPORTRPG1 File . . . . . . . . . . . . . . : QRPGSRC Library . . . . . . . . . . . . : TEAMXX Last Change . . . . . . . . . . : 10/06/99 15:56:26 Description . . . . . . . . . . : RPG Program to Read PF with DataLink 5769RG1 V4R4M0 990521 IBM RPG/400 TEAMXX/SPORTRPG1 10/06/99 15:56:28 Page 2 SEQUENCE IND DO LAST PAGE PROGRAM DataLinks 195 NUMBER *...1....+....2....+....3....+....4....+....5....+....6....+....7...* USE NUM UPDATE LINE ID Source Listing H ***** 100 FSPORTS IF E DISK 10/06/99 200 F SPORTS KRENAMESPREC 10/06/99 RECORD FORMAT(S): LIBRARY TEAMXX FILE SPORTS. EXTERNAL FORMAT SPORTS RPG NAME SPREC 300 FWINTER O E DISK 10/06/99 400 F WINTER KRENAMEWINREC 10/06/99 RECORD FORMAT(S): LIBRARY TEAMXX FILE WINTER. EXTERNAL FORMAT WINTER RPG NAME WINREC A000000 INPUT FIELDS FOR RECORD SPREC FILE SPORTS FORMAT SPORTS. A000001 1 5 PRDID A000002 6 30 PRDDES A000003 31 31 PRDSEA 500 C NEXTR TAG 10/06/99 600 C READ SPREC 60 3 10/06/99 700 C *IN60 DOWEQ*OFF B001 10/06/99 800 C PRDSEA IFEQ 'W' B002 10/06/99 900 C WRITEWINREC 002 10/06/99 1000 C ENDIF E002 10/06/99 1100 C READ SPREC 60 3 001 10/06/99 1200 C ENDDO E001 10/06/99 1300 C SETON LR 1 10/06/99 B000000 OUTPUT FIELDS FOR RECORD WINREC FILE WINTER FORMAT WINTER. B000001 PRDID 5 CHAR 5 B000002 PRDDES 30 CHAR 25 * 6074 FIELD PRDLNK HAS A DATA TYPE OR ATTRIBUTE THAT IS NOT SUPPORTED. ***** END OF SOURCE ***** Additional Diagnostic Messages * 7086 100 RPG PROVIDES BLOCK OR UNBLOCK SUPPORT FOR FILE SPORTS. * 7150 RECORD SPORTS IN FILE SPORTS CONTAINS NULL-CAPABLE FIELDS. * 7154 IGNORED VARIABLE-LENGTH FIELDS IN RECORD SPORTS OF FILE SPORTS. * 7150 RECORD WINTER IN FILE WINTER CONTAINS NULL-CAPABLE FIELDS. * 7154 IGNORED VARIABLE-LENGTH FIELDS IN RECORD WINTER OF FILE WINTER. 5769RG1 V4R4M0 990521 IBM RPG/400 TEAMXX/SPORTRPG1 10/06/99 15:56:28 Page 3 Cross Reference File and Record References: FILE/RCD DEV/RCD REFERENCES (D=DEFINED) 01 SPORTS DISK 100D SPREC SPORTS 100D A000000 600 1100 02 WINTER DISK 300D WINREC WINTER 300D 900 B000000 Field References: FIELD ATTR REFERENCES (M=MODIFIED D=DEFINED) *IN60 A(1) 700 * 7031 NEXTR TAG 500D PRDDES A(25) A000002D B000002D PRDID A(5) A000001D B000001D PRDSEA A(1) A000003D 800 *OFF LITERAL 700 'W' LITERAL 800 Indicator References: INDICATOR REFERENCES (M=MODIFIED D=DEFINED) *IN 700 LR 1300M 60 600M 700 1100M ***** END OF CROSS REFERENCE ***** 5769RG1 V4R4M0 990521 IBM RPG/400 TEAMXX/SPORTRPG1 10/06/99 15:56:28 Page 4 Message Summary * QRG6074 Severity: 40 Number: 1 Message . . . . : Field data type from an externally-described file is not supported. The file is ignored. * QRG7031 Severity: 00 Number: 1 Message . . . . : The Name or indicator is not referenced. * QRG7086 Severity: 00 Number: 1 Message . . . . : RPG handles blocking function for file. INFDS updated only when blocks of data transferred. * QRG7150 Severity: 00 Number: 2 Message . . . . : The record format contains null-capable fields. * QRG7154 Severity: 00 Number: 2 Message . . . . : The record format contains variable length fields. Variable length fields ignored. ***** END OF MESSAGE SUMMARY ***** 196 DB2 UDB for AS/400 Object Relational Support 5769RG1 V4R4M0 990521 IBM RPG/400 TEAMXX/SPORTRPG1 10/06/99 15:56:28 Page 5 Final Summary Message Count: (by Severity Number) TOTAL 00 10 20 30 40 50 7 600010 Program Source Totals: Records . . . . . . . . . . : 13 Specifications . . . . . . : 13 Table Records . . . . . . . : 0 Comments . . . . . . . . . : 0 Compile stopped. Severity level 40 errors found in file. ***** END OF COMPILATION ***** You can see that the compilation failed because of the presence of a DataLink field in the output file. However, the DataLink field in the input file was ignored. Using another RPG program, SPORTRPG2, we tried to perform exactly the same processing as SPORTRPG1, except the program adds a row to a different table, WINTER2, which only has the Product Code (PRDID) and Product Description (PRDDES) columns defined. It does not have a DataLink column. The program was compiled, and the listing is shown in here: 5769RG1 V4R4M0 990521 IBM RPG/400 TEAMXX/SPORTRPG2 10/06/99 16:17:43 Page 1 Compiler . . . . . . . . . . . . . : IBM RPG/400 Command Options: Program . . . . . . . . . . . . : TEAMXX/SPORTRPG2 Source file . . . . . . . . . . : TEAMXX/QRPGSRC Source member . . . . . . . . . : SPORTRPG2 Source listing options . . . . . : *SOURCE *XREF *GEN *NODUMP *NOSECLVL *NOSRCDBG *NOLSTDBG Generation options . . . . . . . : *NOLIST *NOXREF *NOATR *NODUMP *NOOPTIMIZE Source listing indentation . . . : *NONE Type conversion options . . . . : *NONE Sort sequence . . . . . . . . . : *HEX Language identifier . . . . . . : *JOBRUN SAA flagging . . . . . . . . . . : *NOFLAG Generation severity level . . . : 9 Print file . . . . . . . . . . . : *LIBL/QSYSPRT Replace program . . . . . . . . : *NO Target release . . . . . . . . . : *CURRENT User profile . . . . . . . . . . : *USER Authority . . . . . . . . . . . : *LIBCRTAUT Text . . . . . . . . . . . . . . : *SRCMBRTXT Phase trace . . . . . . . . . . : *NO Intermediate text dump . . . . . : *NONE Snap dump . . . . . . . . . . . : *NONE Codelist . . . . . . . . . . . . : *NONE Ignore decimal data error . . . : *NO Allow null values . . . . . . . : *NO Actual Program Source: Member . . . . . . . . . . . . . : SPORTRPG2 File . . . . . . . . . . . . . . : QRPGSRC Library . . . . . . . . . . . . : TEAMXX Last Change . . . . . . . . . . : 10/06/99 16:17:41 Description . . . . . . . . . . : RPG Program to Read PF with DataLink 5769RG1 V4R4M0 990521 IBM RPG/400 TEAMXX/SPORTRPG2 10/06/99 16:17:43 Page 2 SEQUENCE IND DO LAST PAGE PROGRAM NUMBER *...1....+....2....+....3....+....4....+....5....+....6....+....7...* USE NUM UPDATE LINE ID Source Listing H ***** 100 FSPORTS IF E DISK 10/06/99 200 F SPORTS KRENAMESPREC 10/06/99 RECORD FORMAT(S): LIBRARY TEAMXX FILE SPORTS. EXTERNAL FORMAT SPORTS RPG NAME SPREC 300 FWINTER2 O E DISK 10/06/99 400 F WINTER2 KRENAMEWINREC 10/06/99 RECORD FORMAT(S): LIBRARY TEAMXX FILE WINTER2. EXTERNAL FORMAT WINTER2 RPG NAME WINREC A000000 INPUT FIELDS FOR RECORD SPREC FILE SPORTS FORMAT SPORTS. DataLinks 197 A000001 1 5 PRDID A000002 6 30 PRDDES A000003 31 31 PRDSEA 500 C NEXTR TAG 10/06/99 600 C READ SPREC 60 3 10/06/99 700 C *IN60 DOWEQ*OFF B001 10/06/99 800 C PRDSEA IFEQ 'W' B002 10/06/99 900 C WRITEWINREC 002 10/06/99 1000 C ENDIF E002 10/06/99 1100 C READ SPREC 60 3 001 10/06/99 1200 C ENDDO E001 10/06/99 1300 C SETON LR 1 10/06/99 B000000 OUTPUT FIELDS FOR RECORD WINREC FILE WINTER2 FORMAT WINTER2. B000001 PRDID 5 CHAR 5 B000002 PRDDES 30 CHAR 25 ***** END OF SOURCE ***** Additional Diagnostic Messages * 7086 100 RPG PROVIDES BLOCK OR UNBLOCK SUPPORT FOR FILE SPORTS. * 7086 300 RPG PROVIDES BLOCK OR UNBLOCK SUPPORT FOR FILE WINTER2. * 7150 RECORD SPORTS IN FILE SPORTS CONTAINS NULL-CAPABLE FIELDS. * 7154 IGNORED VARIABLE-LENGTH FIELDS IN RECORD SPORTS OF FILE SPORTS. * 7150 RECORD WINTER2 IN FILE WINTER2 CONTAINS NULL-CAPABLE FIELDS. 5769RG1 V4R4M0 990521 IBM RPG/400 TEAMXX/SPORTRPG2 10/06/99 16:17:43 Page 3 Cross Reference File and Record References: FILE/RCD DEV/RCD REFERENCES (D=DEFINED) 01 SPORTS DISK 100D SPREC SPORTS 100D A000000 600 1100 02 WINTER2 DISK 300D WINREC WINTER2 300D 900 B000000 Field References: FIELD ATTR REFERENCES (M=MODIFIED D=DEFINED) *IN60 A(1) 700 * 7031 NEXTR TAG 500D PRDDES A(25) A000002D B000002D PRDID A(5) A000001D B000001D PRDSEA A(1) A000003D 800 *OFF LITERAL 700 'W' LITERAL 800 Indicator References: INDICATOR REFERENCES (M=MODIFIED D=DEFINED) *IN 700 LR 1300M 60 600M 700 1100M ***** END OF CROSS REFERENCE ***** 5769RG1 V4R4M0 990521 IBM RPG/400 TEAMXX/SPORTRPG2 10/06/99 16:17:43 Page 4 Message Summary * QRG7031 Severity: 00 Number: 1 Message . . . . : The Name or indicator is not referenced. * QRG7086 Severity: 00 Number: 2 Message . . . . : RPG handles blocking function for file. INFDS updated only when blocks of data transferred. * QRG7150 Severity: 00 Number: 2 Message . . . . : The record format contains null-capable fields. * QRG7154 Severity: 00 Number: 1 Message . . . . : The record format contains variable length fields. Variable length fields ignored. ***** END OF MESSAGE SUMMARY ***** 5769RG1 V4R4M0 990521 IBM RPG/400 TEAMXX/SPORTRPG2 10/06/99 16:17:43 Page 5 Final Summary Message Count: (by Severity Number) TOTAL 00 10 20 30 40 50 6 600000 Program Source Totals: Records . . . . . . . . . . : 13 Specifications . . . . . . : 13 Table Records . . . . . . . : 0 Comments . . . . . . . . . : 0 PRM has been called. Program SPORTRPG2 is placed in library TEAMXX. 00 highest severity. Created on 10/06/99 at 16:17:45. ***** END OF COMPILATION ***** The DataLink field on the input file was ignored, and the compilation succeeded. 198 DB2 UDB for AS/400 Object Relational Support The next step was to execute the program, resulting in the error message shown in Figure 139 and Figure 140. Figure 139. Table with DataLink input to RPG program: Error Figure 140. Table with DataLink input to RPG program: Recovery Even though the program compiled successfully as a result of ignoring the DataLink column, as soon as an attempt was made to open the file that contained the DataLink, the program failed. We attempted to recompile the program with the option CVTOPT(*VARCHAR), but the compilation failed because the DataLink column was no longer ignored. Additional Message Information Message ID . . . . . . : CPF428A Severity . . . . . . . : 40 Message type . . . . . : Escape Date sent . . . . . . : 10/06/99 Time sent . . . . . . : 16:20:02 Message . . . . : Open of member SPORTS file SPORTS in TEAMXX failed. Cause . . . . . : Member SPORTS file SPORTS in library TEAMXX was not opened because of error code 2. The error codes and their meanings are: 1 -- The format for file SPORTS contains one or more large object fields and the open request did not indicate that large object fields could be processed by the user of the open. 2 -- The format for file SPORTS contains one or more data link fields and the open request did not indicate that data link fields could be processed by the user of the open. 3 -- The format for file SPORTS contains one or more user defined data type fields and the open request did not indicate that user defined data type fields could be processed by the user of the open. More... Press Enter to continue. F3=Exit F6=Print F9=Display message details F12=Cancel F21=Select assistance level Additional Message Information Message ID . . . . . . : CPF428A Severity . . . . . . . : 40 Message type . . . . . : Escape 4 -- A user-defined type for a field for the file does not exist. Recovery . . . : Either specify a different file, use the DSPFFD command to determine what user-defined type is missing, change the open request to indicate that the specified field type can be processed, or change the program to use embedded SQL to process the file. Then try your request again. These field types are fully supported only through SQL. Therefore, if you do not have the DB2 Query Manager and SQL Development Tool Kit for AS/400 product, your program may not be able to access file SPORTS. Bottom Press Enter to continue. F3=Exit F6=Print F9=Display message details F12=Cancel F21=Select assistance level DataLinks 199 In an attempt to avoid the DataLink problem, we created a Logical File, SPORTLF1, with a DataLink field defined. The following listing shows the CRTLF output: 5716SS1 V4R4M0 990521 Data Description TEAMXX/SPORTLF1 10/06/99 15:43:43 Page 1 File name . . . . . . . . . . . . . . . . . . . . . : SPORTLF1 Library name . . . . . . . . . . . . . . . . . . : TEAMXX File attribute . . . . . . . . . . . . . . . . . . : Logical Source file containing DDS . . . . . . . . . . . . : QDDSSRC Library name . . . . . . . . . . . . . . . . . . : TEAMXX Source member containing DDS . . . . . . . . . . . : SPORTLF1 Source member last changed . . . . . . . . . . . . : 10/06/99 15:43:31 Source listing options . . . . . . . . . . . . . . : *SOURCE *LIST *NOSECLVL *NOEVENTF DDS generation severity level . . . . . . . . . . . : 20 DDS flagging severity level . . . . . . . . . . . . : 00 File type . . . . . . . . . . . . . . . . . . . . . : *DATA Authority . . . . . . . . . . . . . . . . . . . . . : *LIBCRTAUT Replace file . . . . . . . . . . . . . . . . . . . : *NO Text . . . . . . . . . . . . . . . . . . . . . . . : Compiler . . . . . . . . . . . . . . . . . . . . . : IBM AS/400 Data Description Processor Data Description Source SEQNBR *...+....1....+....2....+....3....+....4....+....5....+....6....+....7....+....8 Date 100 R SPREC PFILE(TEAMXX/SPORTS) 10/06/99 200 A PRDID 10/06/99 300 A PRDDES 10/06/99 400 A PRDSEA 10/06/99 500 A PRDLNK 10/06/99 * CPD7426-***** ***** END OF SOURCE ***** 5716SS1 V4R4M0 990521 Data Description TEAMXX/SPORTLF1 10/06/99 15:43:43 Page 2 Expanded Source Field Buffer position SEQNBR *...+....1....+....2....+....3....+....4....+....5....+....6....+....7....+....8 length Out In 100 R SPREC PFILE(TEAMXX/SPORTS) 200 PRDID 5A B COLHDG('PRDID') 5 1 1 300 PRDDES 25A B COLHDG('PRDDES') 25 6 6 400 PRDSEA 1A B COLHDG('PRDSEA') 1 31 31 ***** END OF EXPANDED SOURCE ***** 5716SS1 V4R4M0 990521 Data Description TEAMXX/SPORTLF1 10/06/99 15:43:43 Page 3 Messages ID Severity Number * CPD7426 30 1 Message . . . . : Field length too large for data type. 5716SS1 V4R4M0 990521 Data Description TEAMXX/SPORTLF1 10/06/99 15:43:43 Page 4 Message Summary Total Informational Warning Error Severe (0-9) (10-19) (20-29) (30-99) 1 0 0 01 * CPF7302 40 Message . . . . : File SPORTLF1 not created in library TEAMXX. ***** END OF COMPILATION ***** The creation failed because the DataLink field was an unacceptable length, even though this had been defined as only 50. We then attempted to create the Logical File, SPORTLF2, over the SPORT table with the DataLink field omitted. The CRTLF listing is shown here: 5716SS1 V4R4M0 990521 Data Description TEAMXX/SPORTLF2 10/06/99 15:43:48 Page 1 File name . . . . . . . . . . . . . . . . . . . . . : SPORTLF2 Library name . . . . . . . . . . . . . . . . . . : TEAMXX File attribute . . . . . . . . . . . . . . . . . . : Logical Source file containing DDS . . . . . . . . . . . . : QDDSSRC Library name . . . . . . . . . . . . . . . . . . : TEAMXX Source member containing DDS . . . . . . . . . . . : SPORTLF2 Source member last changed . . . . . . . . . . . . : 10/06/99 15:43:41 Source listing options . . . . . . . . . . . . . . : *SOURCE *LIST *NOSECLVL *NOEVENTF DDS generation severity level . . . . . . . . . . . : 20 200 DB2 UDB for AS/400 Object Relational Support DDS flagging severity level . . . . . . . . . . . . : 00 File type . . . . . . . . . . . . . . . . . . . . . : *DATA Authority . . . . . . . . . . . . . . . . . . . . . : *LIBCRTAUT Replace file . . . . . . . . . . . . . . . . . . . : *NO Text . . . . . . . . . . . . . . . . . . . . . . . : Compiler . . . . . . . . . . . . . . . . . . . . . : IBM AS/400 Data Description Processor Data Description Source SEQNBR *...+....1....+....2....+....3....+....4....+....5....+....6....+....7....+....8 Date 100 R SPREC PFILE(TEAMXX/SPORTS) 10/06/99 200 A PRDID 10/06/99 300 A PRDDES 10/06/99 400 A PRDSEA 10/06/99 ***** END OF SOURCE ***** 5716SS1 V4R4M0 990521 Data Description TEAMXX/SPORTLF2 10/06/99 15:43:48 Page 2 Expanded Source Field Buffer position SEQNBR *...+....1....+....2....+....3....+....4....+....5....+....6....+....7....+....8 length Out In 100 R SPREC PFILE(TEAMXX/SPORTS) 200 PRDID 5A B COLHDG('PRDID') 5 1 1 300 PRDDES 25A B COLHDG('PRDDES') 25 6 6 400 PRDSEA 1A B COLHDG('PRDSEA') 1 31 31 ***** END OF EXPANDED SOURCE ***** 5716SS1 V4R4M0 990521 Data Description TEAMXX/SPORTLF2 10/06/99 15:43:48 Page 3 Message Summary Total Informational Warning Error Severe (0-9) (10-19) (20-29) (30-99) 0 0 0 00 * CPC7301 00 Message . . . . : File SPORTLF2 created in library TEAMXX. ***** END OF COMPILATION ***** The Logical File was successfully created. We then created an additional RPG program, SPORTRPG3, which defined the SPORTLF2 logical file as input and the WINTER2 table as output, in other words, no DataLink fields defined on input or output, but the underlying input table with a DataLink column. The compilation listing is shown here: 5769RG1 V4R4M0 990521 IBM RPG/400 TEAMXX/SPORTRPG3 10/06/99 18:14:21 Page 1 Compiler . . . . . . . . . . . . . : IBM RPG/400 Command Options: Program . . . . . . . . . . . . : TEAMXX/SPORTRPG3 Source file . . . . . . . . . . : TEAMXX/QRPGSRC Source member . . . . . . . . . : SPORTRPG3 Source listing options . . . . . : *SOURCE *XREF *GEN *NODUMP *NOSECLVL *NOSRCDBG *NOLSTDBG Generation options . . . . . . . : *NOLIST *NOXREF *NOATR *NODUMP *NOOPTIMIZE Source listing indentation . . . : *NONE Type conversion options . . . . : *NONE Sort sequence . . . . . . . . . : *HEX Language identifier . . . . . . : *JOBRUN SAA flagging . . . . . . . . . . : *NOFLAG Generation severity level . . . : 9 Print file . . . . . . . . . . . : *LIBL/QSYSPRT Replace program . . . . . . . . : *YES Target release . . . . . . . . . : *CURRENT User profile . . . . . . . . . . : *USER Authority . . . . . . . . . . . : *LIBCRTAUT Text . . . . . . . . . . . . . . : *SRCMBRTXT Phase trace . . . . . . . . . . : *NO Intermediate text dump . . . . . : *NONE Snap dump . . . . . . . . . . . : *NONE Codelist . . . . . . . . . . . . : *NONE Ignore decimal data error . . . : *NO Allow null values . . . . . . . : *NO Actual Program Source: Member . . . . . . . . . . . . . : SPORTRPG3 File . . . . . . . . . . . . . . : QRPGSRC Library . . . . . . . . . . . . : TEAMXX Last Change . . . . . . . . . . : 10/06/99 18:14:17 DataLinks 201 Description . . . . . . . . . . : RPG Program to Read PF with DataLink 5769RG1 V4R4M0 990521 IBM RPG/400 TEAMXX/SPORTRPG3 10/06/99 18:14:21 Page 2 SEQUENCE IND DO LAST PAGE PROGRAM NUMBER *...1....+....2....+....3....+....4....+....5....+....6....+....7...* USE NUM UPDATE LINE ID Source Listing H ***** 100 FSPORTLF2IF E DISK 10/06/99 RECORD FORMAT(S): LIBRARY TEAMXX FILE SPORTLF2. EXTERNAL FORMAT SPREC RPG NAME SPREC 200 FWINTER2 O E DISK 10/06/99 300 F WINTER2 KRENAMEWINREC 10/06/99 RECORD FORMAT(S): LIBRARY TEAMXX FILE WINTER2. EXTERNAL FORMAT WINTER2 RPG NAME WINREC A000000 INPUT FIELDS FOR RECORD SPREC FILE SPORTLF2 FORMAT SPREC. A000001 1 5 PRDID A000002 6 30 PRDDES A000003 31 31 PRDSEA 400 C NEXTR TAG 10/06/99 500 C READ SPREC 60 3 10/06/99 600 C *IN60 DOWEQ*OFF B001 10/06/99 700 C PRDSEA IFEQ 'W' B002 10/06/99 800 C WRITEWINREC 002 10/06/99 900 C ENDIF E002 10/06/99 1000 C READ SPREC 60 3 001 10/06/99 1100 C ENDDO E001 10/06/99 1200 C SETON LR 1 10/06/99 B000000 OUTPUT FIELDS FOR RECORD WINREC FILE WINTER2 FORMAT WINTER2. B000001 PRDID 5 CHAR 5 B000002 PRDDES 30 CHAR 25 ***** END OF SOURCE ***** Additional Diagnostic Messages * 7086 100 RPG PROVIDES BLOCK OR UNBLOCK SUPPORT FOR FILE SPORTLF2. * 7086 200 RPG PROVIDES BLOCK OR UNBLOCK SUPPORT FOR FILE WINTER2. * 7150 RECORD SPREC IN FILE SPORTLF2 CONTAINS NULL-CAPABLE FIELDS. * 7150 RECORD WINTER2 IN FILE WINTER2 CONTAINS NULL-CAPABLE FIELDS. 5769RG1 V4R4M0 990521 IBM RPG/400 TEAMXX/SPORTRPG3 10/06/99 18:14:21 Page 3 Cross Reference File and Record References: FILE/RCD DEV/RCD REFERENCES (D=DEFINED) 01 SPORTLF2 DISK 100D SPREC 100D A000000 500 1000 02 WINTER2 DISK 200D WINREC WINTER2 200D 800 B000000 Field References: FIELD ATTR REFERENCES (M=MODIFIED D=DEFINED) *IN60 A(1) 600 * 7031 NEXTR TAG 400D PRDDES A(25) A000002D B000002D PRDID A(5) A000001D B000001D PRDSEA A(1) A000003D 700 *OFF LITERAL 600 'W' LITERAL 700 Indicator References: INDICATOR REFERENCES (M=MODIFIED D=DEFINED) *IN 600 LR 1200M 60 500M 600 1000M ***** END OF CROSS REFERENCE ***** 5769RG1 V4R4M0 990521 IBM RPG/400 TEAMXX/SPORTRPG3 10/06/99 18:14:21 Page 4 Message Summary * QRG7031 Severity: 00 Number: 1 Message . . . . : The Name or indicator is not referenced. * QRG7086 Severity: 00 Number: 2 Message . . . . : RPG handles blocking function for file. INFDS updated only when blocks of data transferred. * QRG7150 Severity: 00 Number: 2 Message . . . . : The record format contains null-capable fields. ***** END OF MESSAGE SUMMARY ***** 5769RG1 V4R4M0 990521 IBM RPG/400 TEAMXX/SPORTRPG3 10/06/99 18:14:21 Page 5 Final Summary Message Count: (by Severity Number) TOTAL 00 10 20 30 40 50 202 DB2 UDB for AS/400 Object Relational Support 5 500000 Program Source Totals: Records . . . . . . . . . . : 12 Specifications . . . . . . : 12 Table Records . . . . . . . : 0 Comments . . . . . . . . . : 0 PRM has been called. Program SPORTRPG3 is placed in library TEAMXX. 00 highest severity. Created on 10/06/99 at 18:14:21. ***** END OF COMPILATION ***** The compilation was successful. Program SPORTRPG3 was then executed, and it also ran successfully. In summary, while DataLink columns cannot be used in applications using native I/O techniques, regardless of the programming language, the tables in which they reside can be used by defining a logical file over the underlying data that omits the DataLink column. To gain access to the DataLink columns, you have to use SQL interface. 6.6 DataLinks management considerations To use the DataLink environment in the most effective way, you are linking files in file systems with tables in the RDBMS. Most application requirements dictate that, in addition to maintaining the integrity of the environment, you also need to ensure the highest availability. Therefore, it is important that you pay attention to managing the DataLink environment and, in particular, the backup and restoration requirements. 6.6.1 Backup and recovery procedures Consider the AS/400-only environment. On the AS/400 system, you are dealing with two distinct data storage systems, each with its own support software. The relational tables reside in DB2 Universal Database for AS/400, while the file objects reside in the IFS. Each has its own set of CL commands to handle the save and restore of data. Currently, there is no direct linkage or communication between those two command sets. If you save a table using the SAVOBJ command, there is no facility to automatically save linked files with the SAV command. Therefore, you must manually manage the synchronization of backup copies of related table and file objects. DB2 Universal Database for AS/400 provides assistance when tables and their linked files are restored to the system. It tracks the status of the links through the DLFM metadata. It also helps with reconciling the links. We ran tests to cover the following scenarios where a table and a linked file have been deleted from the system and have to be restored from a backup copy: • Restore the table before restoring the linked files. • Restore the linked file before restoring the table. Note that it is not possible to delete linked files before the associated table has been dropped due to the integrity rules applied by the DataLinks Filter. To be able to manipulate any object residing in the prefixed directory, the DLFM server must be up and running. This also applies to save and restore activities. Important DataLinks 203 Two save files were created, one to receive the backup copy of the saved table and the other the backup copy of the linked file. Figure 141 shows the script used to run the first test. Figure 141. Script for save/restore exercise: Restore table before file The statements perform the following steps: 1. Clear the save file for the linked file. 2. Clear the save file for the table. 3. Save the table to the save file. 4. Save the linked file to the save file. 5. Drop the table from the system. 6. Delete the linked file from the system. 7. Restore the table. By running the DSPFD CL command for the table that has just been restored and paging down the resulting displays, you see a screen similar to the one shown in Figure 142 on page 204. This display is shown for a table called SAVETABLE in library TEAMXX. Look for the line "File is in link pending status". This shows that this table has at least one linked file object that is currently not present on the system. The DLFM has determined the link pending status from the metadata it maintains in the QDLFM library. As a result, it also marks the table as read-only. Any attempt to insert, update, or delete rows is rejected until the pending links are reconciled. 204 DB2 UDB for AS/400 Object Relational Support Figure 142. DSPFD of table: Link pending status after file restore A new CL command has been introduced in V4R4 of OS/400. This is the Work with Physical File DataLinks (WRKPFDL) command. When you run the following command for the same SAVETABLE table, you should see a display similar to the one shown in Figure 143: WRKPFDL FILE(TEAMXX/SAVETABLE) This shows that the field PICTU00001 is in Link Pending status. PICTU00001 is the system-derived short name for the DataLink column Picture_Link. This CL command displays the status of all DataLink columns defined for a table. Display Spooled File File . . . . . : QPDSPFD Page/Line 1/58 Control . . . . . Columns 1 - 130 Find . . . . . . *...+....1....+....2....+....3....+....4....+....5....+....6....+....7.... +....8....+....9....+....0....+....1....+....2....+....3 Allow delete operation . . . . . . . . . . : ALWDLT *YES Record format level check . . . . . . . . . : LVLCHK *YES Access path . . . . . . . . . . . . . . . . : Arrival Access path size . . . . . . . . . . . . . : ACCPTHSIZ *MAX1TB Maximum record length . . . . . . . . . . . : 225 File is currently journaled . . . . . . . . : Yes Current or last journal . . . . . . . . . . : TEAMXX_JRN Library . . . . . . . . . . . . . . . . . : TEAMXX Journal images . . . . . . . . . . . . . . : IMAGES *AFTER Journal entries to be omitted . . . . . . . : OMTJRNE *NONE Last journal start date/time . . . . . . . : 09/23/99 19:10:53 File is in link pending status . . . . . . : Yes Access Path Description Access path . . . . . . . . . . . . . . . . : Arrival Sort Sequence . . . . . . .........: SRTSEQ *HEX Language identifier . . . . . . . . . . . . : LANGID ENU Member Description Member . . . . . . . . . . . . . . . . . . : MBR SAVETABLE Member level identifier.........: 0990923190615 More... F3=Exit F12=Cancel F19=Left F20=Right F24=Morekeys DataLinks 205 Figure 143. WRKPFDL TEAMXX/SAVETABLE: Link pending If you type option 6 next to the SAVETABLE table and press Enter, you should see a display like the example shown in Figure 144. The only additional information displayed is the name of the RDBMS server. Figure 144. DataLink file attributes for TEAMXX/SAVETABLE With the table in link pending status, we attempted to perform a write operation on the table by trying to delete a row. The result was the error shown in Figure 145 on page 206. Work with Physical File DataLinks Type options, press Enter. 2=Reconcile 6=Display Link Opt File Library Field Pending SAVETABLE TEAMXX PICTU00001 YES Bottom Parameters for option 6 or command ===> F3=Exit F5=Refresh F9=Retrieve F12=Cancel F15=Sort by F16=Repeat position to F17=Position to Display Physical File Member File . . . . . . : QDL_000001 Library . . . . : QTEMP Member . . . . . : QDL_000001 Record . . . . . : 1 Control . . . . . Column . . . . . : 1 Find . . . . . . . *...+....1....+....2....+....3....+....4....+....5....+....6....+....7 Display DataLink File Attributes File name . . . . . . . . . . . . . . . : SAVETABLE Library name . . . . . . . . . . . . . . : TEAMXX Field name . . . . . . . . . . . . . . . : PICTU00001 Link pending . . . . . . . . . . . . . . : Yes Server names . . . . . . . . . . . . . . : AS400WS ****** END OF DATA ****** 206 DB2 UDB for AS/400 Object Relational Support Figure 145. Delete from table in link pending status: Error message Before the pending links could be reconciled, we restored the file object from the save file by using the RST CL command: RST DEV('/qsys.lib/teamxx.lib/linkedfile.file') OBJ(('TEAMXX/Save_Picture/hero.gif')) We then ran the following command once again: WRKPFDL FILE(TEAMXX/SAVETABLE) The display shown in Figure 146 appeared. This shows that field PICTU00001 is still in Link Pending status, even though the linked file has been restored. Figure 146. WRKPFDL TEAMXX/SAVETABLE: Link pending after file restore Work with Physical File DataLinks Type options, press Enter. 2=Reconcile 6=Display Link Opt File Library Field Pending SAVETABLE TEAMXX PICTU00001 YES Bottom Parameters for option 6 or command ===> F3=Exit F5=Refresh F9=Retrieve F12=Cancel F15=Sort by F16=Repeat position to F17=Position to DataLinks 207 We then entered option 2 (Reconcile) in the Opt field on the SAVETABLE line. Specifying the reconcile option does not actually perform the reconciliation at this stage. It simply marks the table as being eligible for reconciliation. Another new CL command has been provided in V4R4 of OS/400 to actually perform the reconciliation. This command is Edit DataLink File Attributes (EDTDLFA). Running this command resulted in a display like the example shown in Figure 147. This shows that the table SAVETABLE in library TEAMXX is in a "Link Pending" status and has been marked for reconciliation. It now provides you with an opportunity to actually perform the reconciliation. Figure 147. EDTDLFA display: Status LNKPND On this display, you over-type the value in the SEQ column with any value between 01 and 98 inclusive and press the Enter key. The display should now appear like the one shown in Figure 148 on page 208. EDIT DATALINK FILE ATTRIBUTES AS400WS 09/30/99 18:00:13 TYPE SEQUENCE, PRESS ENTER. SEQUENCE: 1-99, *HLD, *RMV DLFM SEQ STATUS FILE LIBRARY SERVER 99 LNKPND SAVETABLE TEAMXX BOTTOM F3=EXIT F5=REFRESH F11=DISPLAY DETAILS F12=CANCEL F15=SORT BY F16=REPEAT POSITION TO F17=POSITION TO F22=DISPLAY SERVER NAME 208 DB2 UDB for AS/400 Object Relational Support Figure 148. EDTDLFA display: Status READY The DLFM is ready to attempt to reconcile any pending links. The sequence number can be used to prioritize the order in which table reconciliation is executed when there are several tables to be processed that may have pending links to thousands of files. If you refresh the display, it should appear like the example in Figure 149. Figure 149. EDTDLFA display: Links reconciled EDIT DATALINK FILE ATTRIBUTES AS400WS 09/30/99 18:07:17 TYPE SEQUENCE, PRESS ENTER. SEQUENCE: 1-99, *HLD, *RMV DLFM SEQ STATUS FILE LIBRARY SERVER 98 READY SAVETABLE TEAMXX BOTTOM F3=EXIT F5=REFRESH F11=DISPLAY DETAILS F12=CANCEL F15=SORT BY F16=REPEAT POSITION TO F17=POSITION TO F22=DISPLAY SERVER NAME EDIT DATALINK FILE ATTRIBUTES ASM23 09/30/99 18:44:01 TYPE SEQUENCE, PRESS ENTER. SEQUENCE: 1-99, *HLD, *RMV DLFM SEQ STATUS FILE LIBRARY SERVER (No DataLinks to display) BOTTOM F3=EXIT F5=REFRESH F11=DISPLAY DETAILS F12=CANCEL F15=SORT BY F16=REPEAT POSITION TO F17=POSITION TO F22=DISPLAY SERVER NAME DataLinks 209 Figure 150. DSPFD of TEAMXX/SAVETABLE: Link pending status after reconciliation Rerunning the WRKPFDL command also confirmed that the DataLink column is no longer in Link Pending status as shown in Figure 151 on page 210. If you press F5 very quickly, you may see the Status field displayed as RUN. This indicates that the reconciliation is still in progress. Redisplaying the link pending status of the table by running the DSPFD command resulted in a display like the one shown in Figure 150. Note Display Spooled File File . . . . . : QPDSPFD Control . . . . . Find . . . . . . *...+....1....+....2....+....3....+....4....+....5....+....6....+....7....+....8 ... Allow delete operation . . . . . . . . . . : ALWDLT *YES Record format level check . . . . . . . . . : LVLCHK *YES Access path................: Arrival Access path size . . . . . . . . . . . . . : ACCPTHSIZ *MAX1TB Maximum record length . . . . . . . . . . . : 225 File is currently journaled . . . . . . . . : Yes Current or last journal . . . . . . . . . . : TEAMXX_JRN Library . . . . . . . . . . . . . . . . . : TEAMXX Journal images . . . . . . . . . . . . . . : IMAGES *AFTER Journal entries to be omitted.......: OMTJRNE *NONE Last journal start date/time . . . . . . . : 09/30/99 15:51:06 File is in link pending status . . . . . . : No Access Path Description Access path................: Arrival Sort Sequence . . . . . . . . . . . . . . . : SRTSEQ *HEX Language identifier............:LANGID ENU Member Description Member . . . . . . . . . . . . . . . . . . : MBR SAVETABLE Member level identifier . . . . . . . . . : 0990930154509 F3=Exit F12=Cancel F19=Left F20=Right F24=More keys 210 DB2 UDB for AS/400 Object Relational Support Figure 151. WRKPFDL TEAMXX/SAVETABLE: After link reconciliation We then ran the second test. This was identical to the first test except that the file was restored to the system before the table to which it was linked. Displaying the link pending status of the table with the DSPFD command immediately after it was restored resulted in the display shown in Figure 152. This shows that the table was restored, and its file links were automatically reconciled. Rerunning the WRKPFDL command also confirmed that the table was not in link pending status as shown in Figure 153. Work with Physical File DataLinks Type options, press Enter. 2=Reconcile 6=Display Link Opt File Library Field Pending SAVETABLE TEAMXX PICTU00001 NO Bottom Parameters for option 6 or command ===> F3=Exit F5=Refresh F9=Retrieve F12=Cancel F15=Sort by F16=Repeat position to F17=Position to DataLinks 211 Figure 152. DSPFD of TEAMXX/SAVETABLE: Link pending status after table restore Figure 153. WRKPFDL TEAMXX/SAVETABLE: No link pending The two tests show that the integrity of the DataLinks environment can be maintained by either restoring the tables or the linked files first. However, we strongly advise that you base your normal recovery policy on restoring the files first. This approach avoids placing the tables into the Link Pending status and, therefore, removes the need for the links to be reconciled. Display Spooled File File . . . . . : QPDSPFD Control . . . . . Find . . . . . . *...+....1....+....2....+....3....+....4....+....5....+....6....+....7....+....8. Allow delete operation . . . . . . . . . . : ALWDLT *YES Record format level check . . . ......:LVLCHK *YES Access path . . . . . . . . . . . . . . . . : Arrival Access path size . . . . . . . . . . . . . : ACCPTHSIZ *MAX1TB Maximum record length . . . . . . . . . . . : 225 File is currently journaled . . . . . . . . : Yes Current or last journal . . . . . . . . . . : TEAMXX_JRN Library . . . . . . . . . . . . . . . . . : TEAMXX Journal images . . . . . . . . . . . . . . : IMAGES *AFTER Journal entries to be omitted .......: OMTJRNE *NONE Last journal start date/time . . . . . . . : 09/30/99 15:51:06 File is in link pending status . . . . . . : No Access Path Description Access path . . . . . . . . . . . . . . . . : Arrival Sort Sequence . . . . . . . . . . . . . . . : SRTSEQ *HEX Language identifier . . . . . . . . . . . . : LANGID ENU Member Description Member . . . . . . . . . . . . . . . . . . : MBR SAVETABLE Member level identifier.........: 0990930154509 F3=Exit F12=Cancel F19=Left F20=Right F24=Morekeys Work with Physical File DataLinks Type options, press Enter. 2=Reconcile 6=Display Link Opt File Library Field Pending SAVETABLE TEAMXX PICTU00001 NO Bottom Parameters for option 6 or command ===> F3=Exit F5=Refresh F9=Retrieve F12=Cancel F15=Sort by F16=Repeat position to F17=Position to 212 DB2 UDB for AS/400 Object Relational Support There are other save/restore and copy considerations for tables with DataLinks columns. The save of such a table with a target release prior to OS/400 V4R4 is not supported. 6.7 Using DataLinks in a heterogeneous environment In 6.2.2, “DataLink file manager” on page 151, we described the DataLinks architecture and how it was designed in a way that allowed the DLFM to reside on any file server with a supporting operating system and RDBMS. Currently, support is provided by DB2 Universal Database for AS/400 V4R4 and by DB2 Universal Database V6 running on Windows NT or AIX. This permits the type of heterogeneous environment shown in Figure 154, where DB2 Universal Database tables on any of the three platforms can be linked to file objects residing in any of the three different file systems. Figure 154. The IBM heterogeneous DataLink server environment 6.7.1 DataLinks Manager for Windows NT and for AIX This section describes the different components that make up a database system that is using DB2 DataLinks Manager for Windows NT and for AIX. The Windows NT and the AIX versions are functionally identical except for where they interact with the underlying file systems, NT File System (NTFS) and Journaled File System (JFS) respectively. These components include the: At publication time, there were some known interopability issues and problems between the different IBM DB2 DataLink managers. Please check the following Web site for the latest status on these issues before implementing a cross-platform DataLink solution: http://www.as400.ibm.com/db2/dlinkinter.htm Disclaimer OS/400 IFS NTFS JFS DB2 UNIVERSAL DATABASE FOR AS/400 DB2 UNIVERSAL DATABASE FOR AIX DB2 UNIVERSAL DATABASE FOR WINDOWS NT DataLinks 213 • DataLinks Server • DB2 Universal Database Server • DB2 Client The DataLinks Server is comprised of the following components: • DataLinks File Manager (DLFM): The DLFM has identical functions to the DB2 Universal Database for AS/400 DLFM. It registers all the files on a particular DataLinks server that are linked to a DB2 database. It receives and processes link-file and unlink-file messages arising from SQL INSERT, UPDATE, and DELETE statements that reference a DATALINK column. For each linked file, the DLFM logically tracks the database instance, the fully qualified table name, and the column name referred to in the SQL statement. However, unlike DB2 Universal Database for AS/400, it also tracks previously linked files, if they were linked to a DATALINK column for which the RECOVERY=YES option was specified, during table creation. This allows DB2 to provide point-in-time roll-forward recovery for any file that is specified by a DATALINK column. The Recovery Yes option is not supported by V4R4 of DB2 Universal Database for AS/400. • Data Links Filesystem Filter (DLFF): Filter commands to ensure that linked files are not deleted, renamed, or the file’s attributes are not changed. Optionally, it also filters commands to ensure that proper access authority exists. • DB2 (Logging Manager): This is a Logging Manager that contains the DLFM_DB database. It provides equivalent function to the QDLFM library on the AS/400 system. This database contains registration information about databases that can connect to a Data Links server (equivalent to the Host Database entries in the AS/400 QDLFM table dfm_dbid), and the sharename of the drives that are managed by a DLFF (equivalent to the prefix entries in the AS/400 QDLFM table dfm_prfx). The DLFM_DB database also contains information about files that have been linked, unlinked, or backed up on a Data Links server (the AS/400 QDLFM library equivalent is the table dfm_file, except this does not track file backup activity). This database is created during the installation of DB2 Data Links Manager. Unlike V4R4 of DB2 Universal Database for AS/400, DB2 DataLinks Manager can provide point-in-time roll-forward recovery on the Data Links server (if the RECOVERY=YES option was specified during table creation) for any linked file that is specified by a DATALINK column. The files can be backed up on a disk or using ADSTAR Distributed Storage Manager (ADSM). The files that are linked via a DATALINK column are ensured to be backed up when your database is backed up. The DB2 Universal Database Server is the location of the main database where the DataLinks server is registered. It contains the table that includes the DATALINK data type. No sharing is required between a DB2 server and a DataLinks Server. All communication is done through a port reserved for communications. The remote DB2 Universal Database server can only be participating in a single-partitioned database system. Unlike DB2 Universal Database for AS/400s MultiSystem option, DB2 DataLinks Manager does not support interaction with partitioned database systems. A DB2 Client connects to a DB2 server as normal. In the case of Windows NT, a remote client can share a drive under the control of a DataLinks Filesystem Filter 214 DB2 UDB for AS/400 Object Relational Support that is installed on a DataLinks server. This way, the client can directly access the files on the DataLinks server. AIX provides this capability with a Network File System (NFS) mount of the file system under the control of the DataLinks Filesystem Filter. This is equivalent to the way that AS/400 provides simultaneous access to DB2 Universal Database for AS/400 tables and Integrated File System files through, for example, the C programming language. The DataLink environment and components for Windows NT are shown in Figure 155 and for AIX in Figure 156. Figure 155. DataLink environment for Windows NT Figure 156. DataLink environment for AIX DB2 UNIVERSAL DATABASE FOR WINDOWS NT DLFM DB2 UDB DataLink Filesystem Filter NTFS DB2 CLIENT Shared Directory Table SQL File DB2 UNIVERSAL DATABASE FOR AIX DLFM DB2 UDB DataLink Filesystem Filter JFS DB2 CLIENT NFS Mount Table SQL File © Copyright IBM Corp. 2000 215 Appendix A. Source code listings This appendix contains detailed example programs implementing functions and concepts covered in this redbook. The logic and programmimg techniques used in the programs listed here are thoroughly explained in the relevant sections of the redbook. A.1 UDTLABA: Using UDTs /*--------------------------------------------------------------------- / / File: UDTLABA / / Description: AS/400 DB2 UDT test program / / Usage: CALL TEAMXX/UDTLABA / / Author: Mark Endrei / / Complile: CRTSQLCI OBJ(TEAMXX/UDTLABA) SRCFILE(TEAMXX/QCSRC) + / SRCMBR(UDTLABA) COMMIT(*NONE) / CRTPGM PGM(TEAMXX/UDTLABA) MODULE(TEAMXX/UDTLABA) / / Copyright (c) 1999 IBM Corp. / All Rights Reserved. / */ #include #include /*--------------------------------------------------------------------- / / Description: Main program / / Usage: CALL TEAMXX/UDTLABA / returns -1 on success / 0 on failure / */ int main(int argc, char** argv) { exec sql include SQLCA; /* host variable declarations */ decimal(11,2) dec_price_in = 88.88d; decimal(11,2) dec_price_out = 0.00d; printf("\n"); printf("AS/400 DB2 UDB UDT Lab Test Program: %s\n", argv??(0??)); printf("\n"); printf( "/* host variable declaration */\n" \ "decimal(11,2) dec_price_in = 88.88d;\n" \ "\n" \ "/* implicit cast on assignment from decimal into money */\n" \ "exec sql\n" \ " update prodmast01 set product_price = :dec_price_in\n" \ " where product_number = srlnumber('00001');\n" \ "\n" \ These example programs have not been subjected to any formal testing. They are provided "as is"; they should be used for reference only. Please refer to the Appendix B, “Special notices” on page 229. Important information 216 DB2 UDB for AS/400 Object Relational Support "Use Operations Navigator to view current\n" \ "product_price for product_number 00001.\n" \ "\n" \ "Then hit Enter key to continue...\n"); getchar(); /* implicit cast on assignment from decimal into money */ exec sql update prodmast01 set product_price = :dec_price_in where product_number = srlnumber('00001'); if (SQLCODE != 0) { printf("SQL Error, SQLCODE = %d\n", SQLCODE); } printf( "SQL statement executed.\n" \ "\n" \ "Use Operations Navigator to view updated\n" \ "product_price for product_number 00001.\n" \ "\n" \ "Then hit Enter key to continue...\n"); getchar(); printf( "/* host variable declaration */\n" \ "decimal(11,2) dec_price_out = 0.00d;\n" \ "\n" \ "/* implicit cast on assignment from money into decimal */\n" \ "exec sql\n" \ " select product_price into :dec_price_out from prodmast01\n" \ " where product_number = srlnumber('00001');\n" \ "\n" \ "Hit Enter key to continue...\n"); getchar(); /* implicit cast on assignment from money into decimal */ exec sql select product_price into :dec_price_out from prodmast01 where product_number = srlnumber('00001'); if (SQLCODE != 0) { printf("SQL Error, SQLCODE = %d\n", SQLCODE); } printf( "SQL statement executed.\n" \ "\n" \ "value assigned to host variable :dec_price_out = %D(11,2)\n" \ "\n", dec_price_out); return -1; } A.2 UDTLABB: Casting UDTs /*--------------------------------------------------------------------- / / File: UDTLABB / / Description: AS/400 DB2 UDT test program / / Usage: CALL TEAMXX/UDTLABB / / Author: Mark Endrei / / Complile: CRTSQLCI OBJ(TEAMXX/UDTLABB) SRCFILE(TEAMXX/QCSRC) + / SRCMBR(UDTLABB) COMMIT(*NONE) / CRTPGM PGM(TEAMXX/UDTLABB) MODULE(TEAMXX/UDTLABB) / / Copyright (c) 1999 IBM Corp. / All Rights Reserved. / Source code listings 217 */ #include #include #define HOST_STRUCT_SIZE 10 /*--------------------------------------------------------------------- / / Description: Main program / / Usage: CALL TEAMXX/UDTLABB / returns -1 on success / 0 on failure / */ int main(int argc, char** argv) { exec sql include SQLCA; /* host variable declarations */ long int_price_in = 111; _Packed struct { char number??(5??); char name??(25??); long int_price_out; } product_rec??(10??); struct { short ind??(3??); } product_ind??(10??); int i; printf("\n"); printf("AS/400 DB2 UDB UDT Lab Test Program: %s\n", argv??(0??)); printf("\n"); printf( "/* host variable declaration */\n" \ "long int_price_in = 111;\n" \ "\n" \ "/* implicit cast on assignment from long integer into money */\n" \ "exec sql\n" \ " insert into prodmast01 (product_number, product_name, product_price)\n" \ " values( '00004', 'New product', :int_price_in);\n" \ "\n" \ "Hit Enter key to insert row...\n"); getchar(); /* implicit cast on assignment from long integer into money */ exec sql insert into prodmast01 (product_number, product_name, product_price) values( '00004', 'New product', :int_price_in); if (SQLCODE != 0) { printf("SQL Error, SQLCODE = %d\n", SQLCODE); } printf( "SQL statement executed.\n" \ "\n" \ "Hit Enter key to continue...\n"); getchar(); printf( "/* host variable declaration */\n" \ "_Packed struct {\n" \ " char number??(5??);\n" \ " char name??(25??);\n" \ " long int_price_out;\n" \ "} product_rec??(10??);\n" \ "struct { short ind??(3??); } product_ind??(10??);\n" \ "\n" \ "/* declare and open fetch cursor */\n" \ "exec sql\n" \ " declare c1 cursor for\n" \ " select product_number, product_name, product_price from prodmast01;\n" \ "exec sql open c1;\n" \ 218 DB2 UDB for AS/400 Object Relational Support "/* implicit cast on assignment from money into long integer */\n" \ "exec sql\n" \ " fetch c1 for 10 rows into :product_rec indicator :product_ind;\n" \ "\n" \ "Hit Enter key to continue...\n"); getchar(); /* declare and open fetch cursor */ exec sql declare c1 cursor for select product_number, product_name, product_price from prodmast01; exec sql open c1; /* implicit cast on assignment from money into long integer */ exec sql fetch c1 for 10 rows into :product_rec indicator :product_ind; if (SQLCODE != 0) { printf("SQL Error, SQLCODE = %d\n", SQLCODE); } printf( "SQL statement executed.\n" \ "\n" \ "values assigned to host variable array:\n" \ "\n"); for (i=0; i #include #include #include int fun_CheckHeader( char *, int, char * ); typedef struct { unsigned long length; char data??( 1 ??); } BLOB1M; void SQL_API_FN fun_CheckPictureType( BLOB1M *str_ProductPicture, SQLUDF_INTEGER *nmi_IsCorrect, SQLUDF_NULLIND *nms_InputNullIndicator01, Source code listings 219 SQLUDF_NULLIND *nms_OutputNullIndicator01, SQLUDF_CHAR sqludf_sqlstate??( SQLUDF_SQLSTATE_LEN + 1 ??), SQLUDF_CHAR sqludf_fname??( SQLUDF_FQNAME_LEN + 1 ??), SQLUDF_CHAR sqludf_fspecname??( SQLUDF_SPECNAME_LEN + 1 ??), SQLUDF_CHAR sqludf_msgtext??( SQLUDF_MSGTEXT_LEN + 1 ??) ) { char chr_GifHeader87??( GIF_HEADER_LENGTH ??) = { 0x47, 0x49, 0x46, 0x38, 0x37, 0x61 }; char chr_GifHeader89??( GIF_HEADER_LENGTH ??) = { 0x47, 0x49, 0x46, 0x38, 0x39, 0x61 }; char chr_BmpHeader??( BMP_HEADER_LENGTH ??) = { 0x42, 0x4D}; char *chr_FunctionResolution; int nmi_CompareResult01 = 0; int nmi_CompareResult02 = 0; if ( *nms_InputNullIndicator01 == -1 ) { *nms_OutputNullIndicator01 = -1; return; } chr_FunctionResolution = strstr( sqludf_fname, GIF_FUNCTION ); if ( chr_FunctionResolution != NULL ) { nmi_CompareResult01 = fun_CheckHeader( str_ProductPicture->data, GIF_HEADER_LENGTH, chr_GifHeader87 ); nmi_CompareResult02 = fun_CheckHeader( str_ProductPicture->data, GIF_HEADER_LENGTH, chr_GifHeader89 ); if ( ( nmi_CompareResult01 == 1 ) || ( nmi_CompareResult02 == 1 ) ) { *nmi_IsCorrect = 1; *nms_OutputNullIndicator01 = 0; } else { *nmi_IsCorrect = 0; *nms_OutputNullIndicator01 = 0; } return; } chr_FunctionResolution = strstr( sqludf_fname, BMP_FUNCTION ); if ( chr_FunctionResolution != NULL ) { nmi_CompareResult01 = fun_CheckHeader( str_ProductPicture->data, BMP_HEADER_LENGTH, chr_BmpHeader ); if ( nmi_CompareResult01 == 1 ) { *nmi_IsCorrect = 1; *nms_OutputNullIndicator01 = 0; } else { *nmi_IsCorrect = 0; *nms_OutputNullIndicator01 = 0; } return; } *nms_OutputNullIndicator01 = -1; 220 DB2 UDB for AS/400 Object Relational Support strcpy( sqludf_sqlstate, "38501" ); strcpy( sqludf_msgtext, "Unregistered function" ); return; } A.4 ChkHdr #define MAX_HEADER_SIZE 10 #include #include #include int fun_CheckHeader( char *chr_HeaderData, int nmi_HeaderLength, char *chr_HeaderFormat ) { char chr_HeaderString[ MAX_HEADER_SIZE ]; int nmi_CompareResult; memcpy( chr_HeaderString, chr_HeaderData, nmi_HeaderLength ); nmi_CompareResult = memcmp( chr_HeaderString, chr_HeaderFormat, nmi_HeaderLength ); if ( nmi_CompareResult != 0 ) { return 0; } else { return 1; } } A.5 RunGetPicture: Testing GetPicture UDF #include EXEC SQL INCLUDE SQLCA; EXEC SQL BEGIN DECLARE SECTION; SQL TYPE IS BLOB(1M) bin_ProductPicture; SQL TYPE IS CLOB(50K) chs_ProductDescription; char chs_ProductNumber??( 5 ??); char chs_Description??( 1024 ??); EXEC SQL END DECLARE SECTION; void main( int argc, char **argv ) { EXEC SQL WHENEVER NOT FOUND GOTO BadNews; strcpy( chs_ProductNumber, argv??(1 ??) ); printf( "The product number - %s\n", chs_ProductNumber ); EXEC SQL select Product_Description into :chs_ProductDescription from prodmast01 where product_number = SRLNUMBER( :chs_ProductNumber ); EXEC SQL DECLARE cur_Picture CURSOR FOR Select GetPicture( :chs_ProductDescription, Product_Description, Product_Picture ) from prodmast01; EXEC SQL open cur_Picture; bin_ProductPicture.length = 0; strcpy( bin_ProductPicture.data, " " ); Source code listings 221 EXEC SQL fetch cur_Picture into :bin_ProductPicture; while ( sqlca.sqlcode != 100 ) { printf( "\n" ); if ( bin_ProductPicture.length != 0 ) { printf( "Values returned by GetPicture( CLOB, PRDDESC, " ); printf( "PICTURE ): \n" ); printf( "The picture length - %d\n", bin_ProductPicture.length ); printf( "The picture data - %s\n", bin_ProductPicture.data ); } else { printf( "The GetPicture function( CLOB, PRDDESC, PICTURE ) " ); printf( "returned NULL\n" ); } bin_ProductPicture.length = 0; strcpy( bin_ProductPicture.data, " " ); EXEC SQL fetch cur_Picture into :bin_ProductPicture; } BadNews: EXEC SQL close cur_Picture; return; } A.6 Rating: External UDF using SCRATCHPAD #include #include #include #include #include typedef struct { decimal( 15, 5 ) *nmpd_LargeValue; long nml_RequiredRating; long nml_ValuesStored; } str_ScratchPad; void SQL_API_FN fun_Rating( decimal( 11, 2 ) *nmpd_InputMoneyValue, SQLUDF_INTEGER *nml_InputRequiredRank, decimal( 11, 2 ) *nmpd_OutputMoneyValue, SQLUDF_NULLIND *nms_InputNullIndicator01, SQLUDF_NULLIND *nms_InputNullIndicator02, SQLUDF_NULLIND *nms_OutputNullIndicator01, SQLUDF_CHAR sqludf_sqlstate[ SQLUDF_SQLSTATE_LEN + 1 ], SQLUDF_CHAR sqludf_fname[ SQLUDF_FQNAME_LEN +1 ], SQLUDF_CHAR sqludf_fspecname[ SQLUDF_SPECNAME_LEN + 1 ], SQLUDF_CHAR sqludf_msgtext[ SQLUDF_MSGTEXT_LEN + 1 ], SQLUDF_SCRATCHPAD *sqludf_scratchpad, SQLUDF_CALL_TYPE *sqludf_call_type ) { str_ScratchPad *str_SPad; str_ScratchPad **ptr_AlignmentPointer; decimal( 11, 2 ) nmpd_LowestValue, nmpd_Temp; int nmi_Counter; long nml_Temp; /* Get the address of the data part of the scratchpad and align the */ /* pointer for the scratchpad to the 16 byte boundary */ ptr_AlignmentPointer = ( ( str_ScratchPad ** )( sqludf_scratchpad ) ) + 1; str_SPad = ( str_ScratchPad * ) ptr_AlignmentPointer; if ( *sqludf_call_type == -1 ) { if ( ( *nms_InputNullIndicator02 != 0 ) || ( *nml_InputRequiredRank < 0 ) ) { strcpy( sqludf_sqlstate, "38601" ); strcpy( sqludf_msgtext, "Incorrect rank value specified" ); 222 DB2 UDB for AS/400 Object Relational Support *nms_OutputNullIndicator01 = -1; return; } str_SPad->nml_RequiredRating = *nml_InputRequiredRank; str_SPad->nml_ValuesStored = 0; nml_Temp = *nml_InputRequiredRank * sizeof( decimal( 15, 5 ) ); str_SPad->nmpd_LargeValue = ( decimal( 15, 5 ) * ) malloc( *nml_InputRequiredRank * sizeof( decimal( 11, 2 ) ) ); } if ( *sqludf_call_type == 1 ) { free( str_SPad->nmpd_LargeValue ); } if ( *sqludf_call_type < 1 ) { if ( *nms_InputNullIndicator01 == 0 ) { nmpd_LowestValue = *nmpd_InputMoneyValue; for ( nmi_Counter = 0; nmi_Counter < str_SPad->nml_ValuesStored; nmi_Counter++ ) { if ( str_SPad->nmpd_LargeValue[ nmi_Counter ] < nmpd_LowestValue ) { nmpd_Temp = nmpd_LowestValue; nmpd_LowestValue = str_SPad->nmpd_LargeValue[nmi_Counter]; str_SPad->nmpd_LargeValue[ nmi_Counter ] = nmpd_Temp; } } if ( str_SPad->nml_ValuesStored < str_SPad->nml_RequiredRating ) { str_SPad->nml_ValuesStored++; str_SPad->nmpd_LargeValue[str_SPad->nml_ValuesStored - 1] = nmpd_LowestValue; } } if ( str_SPad->nml_ValuesStored < str_SPad->nml_RequiredRating ) { *nms_OutputNullIndicator01 = -1; return; } else { *nmpd_OutputMoneyValue = str_SPad->nmpd_LargeValue[ str_SPad->nml_RequiredRating - 1 ]; *nms_OutputNullIndicator01 = 0; return; } } } A.7 RtvPrdNbr3: External stored procedure written in CLI #define SQL_MAX_PWD_LENGTH 10 #define SQL_MAX_STM_LENGTH 255 #include #include #include #include "sqlcli.h" #define SQL_MAX_UID_LENGTH 10 SQLRETURN fun_Connect( void ); SQLRETURN fun_DisConnect( void ); SQLRETURN fun_ReleaseEnvHandle( void ); Source code listings 223 SQLRETURN fun_ReleaseDbcHandle( void ); SQLRETURN fun_ReleaseStmHandle( void ); SQLRETURN fun_Process( void ); void fun_PrintError( SQLHSTMT ); typedef struct { unsigned long length; char data[ 1048576 ]; } BLOB1M; SQLRETURN nml_ReturnCode; SQLHENV nml_HandleToEnvironment; SQLHDBC nml_HandleToDatabaseConnection; SQLHSTMT nml_HandleToSqlStatement; SQLINTEGER nmi_PcbValue; SQLCHAR chs_SqlStatement01[ SQL_MAX_STM_LENGTH + 1 ]; SQLCHAR chs_ProductNumber[ 5 ]; BLOB1M bin_ProductPicture; void main( int argc, char **argv ) { SQLRETURN nml_ConnectionStatus; char chs_OrderNumber[ 5 ]; nml_ConnectionStatus = fun_Connect(); if ( nml_ConnectionStatus == SQL_SUCCESS ) { printf( "Connection Succeeded\n" ); } else { printf( "Connection Failed\n" ); exit( -1 ); } memcpy( ( void * )&bin_ProductPicture, argv[ 1 ], 1048580 ); nml_ConnectionStatus = fun_Process(); if ( nml_ConnectionStatus == SQL_SUCCESS ) { strncpy( argv[ 2 ], chs_ProductNumber, sizeof( chs_ProductNumber ) ); } nml_ConnectionStatus = fun_DisConnect(); if ( nml_ConnectionStatus == SQL_SUCCESS ) { printf( "DisConnect Succeeded\n" ); exit( 0 ); } else { printf( "DisConnect Failed\n" ); exit( -1 ); } } SQLRETURN fun_Connect() { SQLCHAR chs_As400System[ SQL_MAX_DSN_LENGTH ]; SQLCHAR chs_UserName[ SQL_MAX_UID_LENGTH ]; SQLCHAR chs_UserPassword[ SQL_MAX_PWD_LENGTH ]; printf( "Attempting to connect\n" ); nml_ReturnCode = SQLAllocEnv( &nml_HandleToEnvironment ); if ( nml_ReturnCode != SQL_SUCCESS ) { printf( "Error allocating environment handle\n" ); fun_PrintError( SQL_NULL_HSTMT ); printf( "Terminating\n" ); return SQL_ERROR; } printf( "Please enter the name of the As/400 system\n" ); gets( chs_As400System ); 224 DB2 UDB for AS/400 Object Relational Support printf( "Please enter User Id for Log On\n" ); gets( chs_UserName ); printf( "Please enter password for Log On\n" ); gets( chs_UserPassword ); nml_ReturnCode = SQLAllocConnect( nml_HandleToEnvironment, &nml_HandleToDatabaseConnection ); if ( nml_ReturnCode != SQL_SUCCESS ) { printf( "Error allocating databse connection handle\n" ); fun_PrintError( SQL_NULL_HSTMT ); nml_ReturnCode = fun_ReleaseEnvHandle(); printf( "Terminating\n" ); return SQL_ERROR; } nml_ReturnCode = SQLConnect( nml_HandleToDatabaseConnection, chs_As400System, SQL_NTS, chs_UserName, SQL_NTS, chs_UserPassword, SQL_NTS ); if ( nml_ReturnCode != SQL_SUCCESS ) { printf( "Could not connect to system %s\n", chs_As400System ); fun_PrintError( SQL_NULL_HSTMT ); nml_ReturnCode = fun_ReleaseDbcHandle(); nml_ReturnCode = fun_ReleaseEnvHandle(); printf( "Terminating\n" ); return SQL_ERROR; } else { return SQL_SUCCESS; } } SQLRETURN fun_Process() { short Pictture_Ind = 0; printf( "Attempting to allocate handle to statement\n" ); nml_ReturnCode = SQLAllocStmt( nml_HandleToDatabaseConnection, &nml_HandleToSqlStatement ); if ( nml_ReturnCode != SQL_SUCCESS ) { printf( "Could not allocate handle to statement\n" ); fun_PrintError( SQL_NULL_HSTMT ); printf( "Terminating\n" ); return SQL_ERROR; } strcpy( chs_SqlStatement01, "select product_number " ); strcat( chs_SqlStatement01, "from teamxx.prodmast01 " ); strcat( chs_SqlStatement01, "where " ); strcat( chs_SqlStatement01, "product_picture = " ); strcat( chs_SqlStatement01, "cast( ? as TEAMXX.PICTURE)" ); nml_ReturnCode = SQLPrepare( nml_HandleToSqlStatement, chs_SqlStatement01, SQL_NTS ); if ( nml_ReturnCode != SQL_SUCCESS ) { printf( "Could not prepare SQL statement\n" ); fun_PrintError( nml_HandleToSqlStatement ); nml_ReturnCode = fun_ReleaseStmHandle(); printf( "Terminating\n" ); return SQL_ERROR; } nmi_PcbValue = bin_ProductPicture.length; nml_ReturnCode = SQLBindParam( nml_HandleToSqlStatement, 1, SQL_BLOB, Source code listings 225 SQL_BLOB, sizeof( bin_ProductPicture ), 0, ( SQLPOINTER ) bin_ProductPicture.data, ( SQLINTEGER *) &nmi_PcbValue ); if ( nml_ReturnCode != SQL_SUCCESS ) { printf( "Could not bind SQL statement\n" ); fun_PrintError( nml_HandleToSqlStatement ); nml_ReturnCode = fun_ReleaseStmHandle(); printf( "Terminating\n" ); return SQL_ERROR; } nml_ReturnCode = SQLExecute( nml_HandleToSqlStatement ); if ( nml_ReturnCode != SQL_SUCCESS ) { printf( "Could not execute the SQL statement\n" ); fun_PrintError( nml_HandleToSqlStatement ); nml_ReturnCode = fun_ReleaseStmHandle(); printf( "Terminating\n" ); return SQL_ERROR; } nml_ReturnCode = SQLBindCol( nml_HandleToSqlStatement, 1, SQL_CHAR, ( SQLPOINTER ) chs_ProductNumber, sizeof( chs_ProductNumber ), ( SQLINTEGER * ) &nmi_PcbValue ); if ( nml_ReturnCode != SQL_SUCCESS ) { printf( "Could not bind columns of the cursor\n" ); fun_PrintError( nml_HandleToSqlStatement ); nml_ReturnCode = fun_ReleaseStmHandle(); printf( "Terminating\n" ); return SQL_ERROR; } nml_ReturnCode = SQLFetch( nml_HandleToSqlStatement ); if ( nml_ReturnCode != SQL_SUCCESS ) { printf( "Could not fetch from the SQL cursor\n" ); fun_PrintError( nml_HandleToSqlStatement ); nml_ReturnCode = fun_ReleaseStmHandle(); printf( "Terminating\n" ); return SQL_ERROR; } else { return SQL_SUCCESS; } } SQLRETURN fun_DisConnect() { printf( "Attempting to disconnect\n" ); nml_ReturnCode = SQLDisconnect( nml_HandleToDatabaseConnection ); if ( nml_ReturnCode != SQL_SUCCESS ) { printf( "Failed to disconnect\n" ); fun_PrintError( SQL_NULL_HSTMT ); printf( "Terminating\n" ); return 1; } else { printf( "Successfully disconnected\n" ); } nml_ReturnCode = fun_ReleaseDbcHandle(); nml_ReturnCode = fun_ReleaseEnvHandle(); return nml_ReturnCode; } 226 DB2 UDB for AS/400 Object Relational Support SQLRETURN fun_ReleaseEnvHandle() { printf( "Attempting to release handle to environment\n" ); nml_ReturnCode = SQLFreeEnv( nml_HandleToEnvironment ); if ( nml_ReturnCode != SQL_SUCCESS ) { printf( "Could not release handle to environment\n" ); fun_PrintError( SQL_NULL_HSTMT ); return SQL_ERROR; } else { printf( "Successfully released handle to environment\n" ); return SQL_SUCCESS; } } SQLRETURN fun_ReleaseDbcHandle() { printf( "Attempting to release handle to database connection\n" ); nml_ReturnCode = SQLFreeConnect( nml_HandleToDatabaseConnection ); if ( nml_ReturnCode != SQL_SUCCESS ) { printf( "Could not release handle to database connection\n" ); fun_PrintError( SQL_NULL_HSTMT ); return SQL_ERROR; } else { printf( "Successfully released handle to database connection\n" ); return SQL_SUCCESS; } } SQLRETURN fun_ReleaseStmHandle() { printf( "Attempting to release handle to SQL statement\n" ); nml_ReturnCode = SQLFreeStmt( nml_HandleToSqlStatement, SQL_CLOSE ); if ( nml_ReturnCode != SQL_SUCCESS ) { printf( "Could not release handle to SQL statement\n" ); fun_PrintError( nml_HandleToSqlStatement ); return SQL_ERROR; } else { printf( "Successfully released handle to SQL statement\n" ); return SQL_SUCCESS; } } void fun_PrintError( SQLHSTMT nml_HandleToSqlStatement ) { SQLCHAR chs_SqlState[ SQL_SQLSTATE_SIZE ]; SQLINTEGER nmi_NativeErrorCode; SQLCHAR chs_ErrorMessageText[ SQL_MAX_MESSAGE_LENGTH + 1 ]; SQLSMALLINT nmi_NumberOfBytes; nml_ReturnCode = SQLError( nml_HandleToEnvironment, nml_HandleToDatabaseConnection, nml_HandleToSqlStatement, chs_SqlState, &nmi_NativeErrorCode, chs_ErrorMessageText, sizeof( chs_ErrorMessageText ), &nmi_NumberOfBytes ); if ( nml_ReturnCode != SQL_SUCCESS ) { printf( "Could not retrieve error information\n" ); return; } Source code listings 227 printf( "SqlState - %s\n", chs_SqlState ); printf( "SqlCode - %d\n", nmi_NativeErrorCode ); printf( "Error Message:\n" ); printf( "%s\n", chs_ErrorMessageText ); } 228 DB2 UDB for AS/400 Object Relational Support © Copyright IBM Corp. 2000 229 Appendix B. Special notices This publication is intended to help programmers, analysts, and database administrators to implement DB2 UDB for AS/400. The information in this publication is not intended as the specification of any programming interfaces that are provided by DB2 UDB for AS/400. See the PUBLICATIONS section of the IBM Programming Announcement for DB2 UDB for AS/400, for more information about what publications are considered to be product documentation. References in this publication to IBM products, programs or services do not imply that IBM intends to make these available in all countries in which IBM operates. Any reference to an IBM product, program, or service is not intended to state or imply that only IBM's product, program, or service may be used. Any functionally equivalent program that does not infringe any of IBM's intellectual property rights may be used instead of the IBM product, program or service. Information in this book was developed in conjunction with use of the equipment specified, and is limited in application to those specific hardware and software products and levels. IBM may have patents or pending patent applications covering subject matter in this document. The furnishing of this document does not give you any license to these patents. You can send license inquiries, in writing, to the IBM Director of Licensing, IBM Corporation, North Castle Drive, Armonk, NY 10504-1785. Licensees of this program who wish to have information about it for the purpose of enabling: (i) the exchange of information between independently created programs and other programs (including this one) and (ii) the mutual use of the information which has been exchanged, should contact IBM Corporation, Dept. 600A, Mail Drop 1329, Somers, NY 10589 USA. Such information may be available, subject to appropriate terms and conditions, including in some cases, payment of a fee. The information contained in this document has not been submitted to any formal IBM test and is distributed AS IS. The information about non-IBM ("vendor") products in this manual has been supplied by the vendor and IBM assumes no responsibility for its accuracy or completeness. The use of this information or the implementation of any of these techniques is a customer responsibility and depends on the customer's ability to evaluate and integrate them into the customer's operational environment. While each item may have been reviewed by IBM for accuracy in a specific situation, there is no guarantee that the same or similar results will be obtained elsewhere. Customers attempting to adapt these techniques to their own environments do so at their own risk. Any pointers in this publication to external Web sites are provided for convenience only and do not in any manner serve as an endorsement of these Web sites. Any performance data contained in this document was determined in a controlled environment, and therefore, the results that may be obtained in other operating environments may vary significantly. Users of this document should verify the applicable data for their specific environment. 230 DB2 UDB for AS/400 Object Relational Support Reference to PTF numbers that have not been released through the normal distribution process does not imply general availability. The purpose of including these reference numbers is to alert IBM customers to specific information relative to the implementation of the PTF when it becomes available to each customer according to the normal IBM PTF distribution process. The following terms are trademarks of the International Business Machines Corporation in the United States and/or other countries: The following terms are trademarks of other companies: Tivoli, Manage. Anything. Anywhere.,The Power To Manage., Anything. Anywhere.,TME, NetView, Cross-Site, Tivoli Ready, Tivoli Certified, Planet Tivoli, and Tivoli Enterprise are trademarks or registered trademarks of Tivoli Systems Inc., an IBM company, in the United States, other countries, or both. In Denmark, Tivoli is a trademark licensed from Kjøbenhavns Sommer - Tivoli A/S. C-bus is a trademark of Corollary, Inc. in the United States and/or other countries. Java and all Java-based trademarks and logos are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and/or other countries. Microsoft, Windows, Windows NT, and the Windows logo are trademarks of Microsoft Corporation in the United States and/or other countries. PC Direct is a trademark of Ziff Communications Company in the United States and/or other countries and is used by IBM Corporation under license. ActionMedia, LANDesk, MMX, Pentium and ProShare are trademarks of Intel Corporation in the United States and/or other countries. UNIX is a registered trademark in the United States and other countries licensed exclusively through The Open Group. SET and the SET logo are trademarks owned by SET Secure Electronic Transaction LLC. Other company, product, and service names may be trademarks or service marks of others. AIX AS/400 AT C/400 COBOL/400 CT DB2 DRDA IBM® Netfinity Operating System/400 OS/2 OS/400 RPG/400 RS/6000 SP SQL/400 System/390 XT 400 © Copyright IBM Corp. 2000 231 Appendix C. Related publications The publications listed in this section are considered particularly suitable for a more detailed discussion of the topics covered in this redbook. C.1 IBM Redbooks publications For information on ordering these ITSO publications see “How to get IBM Redbooks” on page 233. • Building AS/400 Client/Server Applications with Java, SG24-2152 • DB2/400 Advanced Database Functions, SG24-4249 • DB2/400: Mastering Data Warehousing Functions, SG24-5184 • AS/400 Client Access Express for Windows: Implementing V4R4M0, SG24-5191 • Developing Cross-Platform DB2 Stored Procedures, SG24-5485 C.2 IBM Redbooks collections Redbooks are also available on the following CD-ROMs. Click the CD-ROMs button at http://www.redbooks.ibm.com/ for information about all the CD-ROMs offered, updates and formats. C.3 Other resources These publications are also relevant as further information sources: • IBM DB2 Universal Database Application Development Guide, SC09-2845 • DB2 UDB for AS/400 SQL Programming, SC41-5611 • DB2 UDB for AS/400 SQL Reference, SC41-5612 • White, Seth. JDBC API Tutorial and Reference, Second Edition. Addison-Wesley Publishing, Co., 1999 (ISBN: 0-2014332-81). CD-ROM Title Collection Kit Number System/390 Redbooks Collection SK2T-2177 Networking and Systems Management Redbooks Collection SK2T-6022 Transaction Processing and Data Management Redbooks Collection SK2T-8038 Lotus Redbooks Collection SK2T-8039 Tivoli Redbooks Collection SK2T-8044 AS/400 Redbooks Collection SK2T-2849 Netfinity Hardware and Software Redbooks Collection SK2T-8046 RS/6000 Redbooks Collection (BkMgr Format) SK2T-8040 RS/6000 Redbooks Collection (PDF Format) SK2T-8043 Application Development Redbooks Collection SK2T-8037 IBM Enterprise Storage and Systems Management Solutions SK3T-3694 232 DB2 UDB for AS/400 Object Relational Support C.4 Referenced Web sites These Web sites are also relevant as further information sources: • Visit the IBM Redbooks home page at: http://www.redbooks.ibm.com for announcements about upcoming redbooks, redpieces, and full redbook downloads and ordering information. • The reference tool Net.Data Administration and Programming Guide for OS/400 is available for download from the Web at: http://www.as400.ibm.com/products/netdata/docs/doc.htm • Modification 2 of the AS/400 Toolbox for Java is available for download from the Web at: http://www.ibm.com/as400/toolbox • For information regarding interopability issues and problems between the different IBM DB2 DataLink managers, and for DB2 information in general, check the following Web site: http://www.as400.ibm.com/db2/dlinkinter.htm © Copyright IBM Corp. 2000 233 How to get IBM Redbooks This section explains how both customers and IBM employees can find out about IBM Redbooks, redpieces, and CD-ROMs. A form for ordering books and CD-ROMs by fax or e-mail is also provided. • Redbooks Web Site http://www.redbooks.ibm.com/ Search for, view, download, or order hardcopy/CD-ROM Redbooks from the Redbooks Web site. Also read redpieces and download additional materials (code samples or diskette/CD-ROM images) from this Redbooks site. Redpieces are Redbooks in progress; not all Redbooks become redpieces and sometimes just a few chapters will be published this way. The intent is to get the information out much quicker than the formal publishing process allows. • E-mail Orders Send orders by e-mail including information from the IBM Redbooks fax order form to: • Telephone Orders • Fax Orders This information was current at the time of publication, but is continually subject to change. The latest information may be found at the Redbooks Web site. In United States Outside North America e-mail address usib6fpl@ibmmail.com Contact information is in the “How to Order” section at this site: http://www.elink.ibmlink.ibm.com/pbl/pbl United States (toll free) Canada (toll free) Outside North America 1-800-879-2755 1-800-IBM-4YOU Country coordinator phone number is in the “How to Order” section at this site: http://www.elink.ibmlink.ibm.com/pbl/pbl United States (toll free) Canada Outside North America 1-800-445-9269 1-403-267-4455 Fax phone number is in the “How to Order” section at this site: http://www.elink.ibmlink.ibm.com/pbl/pbl IBM employees may register for information on workshops, residencies, and Redbooks by accessing the IBM Intranet Web site at http://w3.itso.ibm.com/ and clicking the ITSO Mailing List button. Look in the Materials repository for workshops, presentations, papers, and Web pages developed and written by the ITSO technical professionals; click the Additional Materials button. Employees may access MyNews at http://w3.ibm.com/ for redbook, residency, and workshop announcements. IBM Intranet for Employees 234 DB2 UDB for AS/400 Object Relational Support IBM Redbooks fax order form Please send me the following: We accept American Express, Diners, Eurocard, Master Card, and Visa. Payment by credit card not available in all countries. Signature mandatory for credit card payment. Title Order Number Quantity First name Last name Company Address City Postal code Telephone number Telefax number VAT number Invoice to customer number Country Credit card number Credit card expiration date Card issued to Signature © Copyright IBM Corp. 2000 235 List of abbreviations CPU Central Processing Unit DBMS Database Management System CLI Call Level Interface DDL Data Definition Language DDS Data Definition Specification DML Data Manipulation Language IBM International Business Machines Corporation ILE Integrated Language Environment ITSO International Technical Support Organization LOB Large Object I/O Input/Output ODBC Open Database Connectivity OLAP On-line Analytical Processing OLTP On-line Transaction Processing RRA Relative Record Address RDBMS Relational Database Management System SEU Screen Edit Utility SLIC System License Internal Code SQL Structured Query Language UDF User Defined Function UDT User Defined Type 236 DB2 UDB for AS/400 Object Relational Support © Copyright IBM Corp. 2000 237 Index A activation group, *CALLER 101 AS LOCATOR clause 143 AS/400 Toolbox for Java 129 B bind, external UDFs 101 BLOB 5 using in Java 130 Blob code example in Java 130 parameter marker 133 Blob interface 130 Blob object creating and materializing 130 storing in the database 132 C Call Level Interface 139 casting functions 28 CL command ADDHDBDLFM 159 ADDPFXDLFM 157 CRTCMOD 101 CRTSRVPGM 101 DSPFD 203 DSPFFD 60 , 177 EDTDLFA 207 ENDTCPSVR 163 INZDLFM 156 STRTCPSVR 163 WRKPFDL 204 WRKRDBDIRE 155 CLASSPATH variable 130 CLI 139 code example 139 compile and bind 142 retrieving LOBs 143 stored procedure 139 CLOB 5 Clob object code example 135 creating and materializing 134 storing in the database 136 Unicode 135 using 134 column function 78 commitment control 12 , 18 compile CLI program 142 external UDFs 101 Java program 132 complex objects 1 , 129 control token 165 , 186 , 190 code example 186 CREATE FUNCTION statement 78 FINAL CALL clause 107 SCRATCHPAD clause 104 STATIC DISPATCH clause 90 CREATE PROCEDURE statement 142 D Data Links Filesystem Filter (DLFF) 213 data type precedence list 40 data type promotion 40 Datalink APIs 153 DataLink File Manager 151 Datalink Filter 153 DataLinks architecture 150 attributes 165 code examples 186 configuration 153 , 154 considerations 174 control token 165 , 186 code example 186 definition 147 delete ON UNLINK 166 in dynamic web pages 183 journal function 176 link control 165 link pending 205 ON UNLINK DELETE explained 173 read permission 165 reconcile pending link 206 save and restore 202 scalar function DLVALUE 178 SQL examples 175 SQL scalar functions 182 using as column type 168 write permission 166 DataLinks File Manager (DLFM) 213 DB2 (Logging Manager) 213 DB2SQL parameter style 96 coding example 104 DBCLOB 5 debugging 119 display pictures 130 DLFM 151 adding host database 159 adding prefix 157 initialize 156 on remote system 152 DLFM server job 156 checking the status 163 starting 163 stopping 163 DLURLCOMPLETE scalar function 182 DLURLPATH scalar function 183 DLURLPATHONLY scalar function 183 DLURLSERVER scalar function 183 DLVALUE scalar function 178 overloading example 179 238 DB2 UDB for AS/400 Object Relational Support dropping UDF 118 E error handling in UDF 96 explicit casting 35, 141 of parameter markers 131 external UDF 71, 95 error handling 101 null indicator 100 parameter styles 95 F FINAL CALL clause 107 full file path 179 function overloading 72, 179 code example 110 function parameters 90 function path 72 function resolution 71 code example 108 function selection algorithm 76 function signature 72 H HTTP 184 I IFS 149 file permission 172 mount points 158 implicit casting 38, 141 host variables 42 in Java 131 input stream in Java 136 input stream using in Java 133 Integrated File System 149 J Java 2 platfrom 129 Java input stream 133, 136 JDBC 2.0 129 JDK 1.2.2 130 join 45 L link pending status 205 LOB commitment control 18 comparing 19 compatibility of data types 8 definition 4 maximum size 6 native interface 22 passing as a parameter 143 supported built-in functions 21 triggers 25 using as column type 7 using in CLI 139 LOB file reference CCSID conversion 14 definition 12 file options 14 LOB locator commitment control 12 declaring 9 definition 8 LOBs using in Net.Data 25 M Metadata using in Java 137 metadata code example in Java 137 retrieving column information 137 N native I/O 202 native interface 22, 49, 193 Net.Data 25 O Operations Navigator 2, 28, 85, 150, 167 Run SQL Scripts utility 7 P parameter markers BLOB 141 Blob 133 casting 131 parameter matching 74 parameter promotion 74, 112, 113 parameter styles in external UDFs 95 pending link reconcilation 206 picture, load into database 133 precedence of data types 76 R RDB entry 155 RPG code example 202 Run SQL Scripts utility 78 S save and restore for UDTs 60 scalar function 78 scratchpad 104 code example 105 secondary thread 119 SET PATH statement 73 sourced UDF 70, 78 arithmetic operators 83 code example 79, 82, 84 239 column functions 82 scalar function 78 SQL naming convention 72 SQL parameter style 95 coding example 99 SQL UDF 70 , 85 code example 87 STATIC DISPATCH clause 90 strong typing 34 Swing GUI 130 system catalog SYSCOLUMNS 58 SYSPARMS 117 SYSROUTINES 113 , 116 SYSTYPES 57 system naming convention 72 T Toolbox for Java 129 triggers 25 U UDF code example 92 compile and bind 101 debugging 119 definition 69 dropping 118 error handling 96 external 71 , 95 function overloading 72 function path 72 function signature 72 LOB parameters 90 LOB return value 91 resolving 71 return value 91 save and restore 119 sourced 70 , 78 SQL 70 , 85 UDF_TIME_OUT parameter 127 UDT parameters 90 UDT return value 91 UDT casting functions 28 changing definition 34 comparing 44 creating 28 data type promotion 40 definition 27 dropping 64 explicit casting 35 implicit casting 38 joining on UDT columns 45 native I/O 49 , 54 native interface 49 save and restore 60 , 62 strong typing 34 system catalog 57 using as column type 31 , 33 using in CLI 142 using in Java 137 Unicode 135 240 DB2 UDB for AS/400 Object Relational Support © Copyright IBM Corp. 2000 241 IBM Redbooks evaluation DB2 UDB for AS/400 Object Relational Support SG24-5409-00 Your feedback is very important to help us maintain the quality of IBM Redbooks. Please complete this questionnaire and return it using one of the following methods: • Use the online evaluation form found at http://www.redbooks.ibm.com/ • Fax this form to: USA International Access Code + 1 914 432 8264 • Send your comments in an Internet note to redbook@us.ibm.com Which of the following best describes you? _ Customer _ Business Partner _ Solution Developer _ IBM employee _ None of the above Please rate your overall satisfaction with this book using the scale: (1 = very good, 2 = good, 3 = average, 4 = poor, 5 = very poor) Overall Satisfaction __________ Please answer the following questions: Was this redbook published in time for your needs? Yes___ No___ If no, please explain: What other Redbooks would you like to see published? Comments/Suggestions: (THANK YOU FOR YOUR FEEDBACK!) SG24-5409-00 Printed in the U.S.A. DB2 UDB for AS/400 Object Relational Support SG24-5409-00 ®

ibm.com/redbooks Front cover Clustering and IASPs for Higher Availability on the IBM iSeries Server Susan Powers Ellen Dreyer Andersen Sue Nee David Salmon Shashi Sethi Lee Walkky Moving the iSeries server beyond 99.9% availability Independent ASPs and other V5R1 high availabiity solutions Solutions for application and data resiliency International Technical Support Organization Clustering and IASPs for Higher Availability on the IBM ~ iSeries Server April 2002 SG24-5194-01 © Copyright International Business Machines Corporation 2000, 2002. All rights reserved. Note to U.S Government Users - Documentation related to restricted rights - Use, duplication or disclosure is subject to restrictions set forth in GSA ADP Schedule Contract with IBM Corp. Second Edition (April 2002) This edition applies to OS/400 Version 5, Release 1. Comments may be addressed to: IBM Corporation, International Technical Support Organization Dept. JLU Building 107-2 3605 Highway 52N Rochester, Minnesota 55901-7829 When you send information to IBM, you grant IBM a non-exclusive right to use or distribute the information in any way it believes appropriate without incurring any obligation to you. Take Note! Before using this information and the product it supports, be sure to read the general information in “Special notices” on page xv. © Copyright IBM Corp. 2000, 2002 iii Contents Contents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . iii Figures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ix Tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xiii Special notices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .xv IBM trademarks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xvi Preface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xvii The team that wrote this redbook. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xvii Notice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xix Comments welcome. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xix Summary of changes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxi April 2002, Second Edition. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxi Part 1. iSeries high availability fundamentals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 Chapter 1. Introduction. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 1.1 A brief overview about clustering . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 1.2 Defining availability . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 1.2.1 Factors impacting availability . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 Chapter 2. Downtime. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 2.1 Scheduled and unscheduled downtime . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 2.2 Example: Impact analysis of an outage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 2.3 Application architecture and downtime . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 Chapter 3. Availability technology. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 3.1 iSeries server hardware availability features. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 3.2 OS/400 and system software availability features . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 3.2.1 Clusters for high availability . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 3.3 Cluster with replication technology . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 3.4 Cluster with switched disk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 3.5 Shared disk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 3.6 Separate server. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 3.7 iSeries cluster middleware . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 Part 2. iSeries clusters and higher availability. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 Chapter 4. iSeries clusters explained . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 4.1 Cluster basics and definitions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 4.2 iSeries clustering. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 4.3 Why you want clustering . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 4.3.1 Hidden benefits of iSeries clusters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 4.4 OS/400 V5R1 clustering enhancements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 4.5 Prerequisites for iSeries clustering . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 4.6 Cluster Resource Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 4.6.1 OS/400 integrated cluster services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 iv Clustering and IASPs for Higher Availability on the iSeries Server 4.6.2 Cluster Resource Services structure. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40 4.7 Cluster components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42 4.7.1 Cluster nodes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 4.7.2 Cluster Resource Groups (CRG) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44 4.7.3 Recovery domains . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 4.7.4 Device domains . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46 4.7.5 Exit programs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47 4.8 Cluster implementation example. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48 4.8.1 Simple two-node cluster example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48 4.8.2 Four-node mutual takeover cluster example. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49 4.9 Resiliency . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50 4.9.1 Data resiliency in a simple two-node cluster example . . . . . . . . . . . . . . . . . . . . . 51 4.9.2 Application resiliency and IP address takeover example . . . . . . . . . . . . . . . . . . . 53 4.9.3 Managing application resiliency . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53 4.9.4 ClusterProven applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54 4.10 iSeries cluster solution components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54 4.11 iSeries clusters: Cluster architecture versus data replication . . . . . . . . . . . . . . . . . . . 56 Chapter 5. Implementing and managing clusters with IBM solutions . . . . . . . . . . . . . 59 5.1 Using the Operations Navigator GUI or commands, APIs to implement, manage iSeries clusters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60 5.2 Using the Operations Navigator GUI to implement and manage iSeries clusters. . . . . 61 5.2.1 Clustering configuration tasks. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63 5.2.2 Using the Simple Cluster Management GUI to create the cluster. . . . . . . . . . . . . 64 5.3 Using QUSRTOOL CL commands and OS/400 APIs to implement an iSeries cluster. 87 5.3.1 Using OS/400 cluster management APIs to implement a cluster . . . . . . . . . . . . . 93 5.3.2 Definitions revisited. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94 5.3.3 Cluster versions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96 Chapter 6. Independent ASPs explained . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99 6.1 What independent ASPs are. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100 6.2 Uses for IASPs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100 6.3 OS/400 IASP support and terminology . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102 6.3.1 OS/400 software options. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104 6.3.2 High Speed Link OptiConnect. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104 6.3.3 Configuration source and the IASP. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105 6.4 Considerations of switched disk and IASP use. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105 6.4.1 Advantages of using IASPs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106 6.4.2 Disadvantages of using IASP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106 6.5 Objects defining an IASP configuration. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107 6.5.1 Relationship of IASP configuration objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107 6.5.2 Device domain object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108 6.5.3 Device CRG object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109 6.5.4 IASPs, device domains, and device CRGs. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109 6.6 IASP configuration examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110 6.7 IASP application examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112 6.7.1 Domino and independent ASPs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112 6.7.2 Integrated xSeries Server and independent ASPs . . . . . . . . . . . . . . . . . . . . . . . 113 6.8 Configuring and managing IASPs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113 6.8.1 Creating a new disk pool. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114 6.8.2 Numbering new pools . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114 6.8.3 Selecting the disk units to add to a pool . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115 6.8.4 ASP unit numbering . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116 Contents v 6.8.5 Selecting All Disk Units to add to a pool . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117 6.9 IASP and security . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117 6.9.1 User profiles and IASPs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117 6.9.2 Accounting for space owned. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118 6.9.3 IASP and authorization lists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119 6.10 System operations with IASPs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121 6.10.1 IASP overflow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121 6.10.2 Switching IASPs between nodes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121 6.10.3 Reclaim Storage and IASPs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121 6.11 Positioning cluster middleware solutions with IASPs . . . . . . . . . . . . . . . . . . . . . . . . 122 6.12 iSeries IASP and other platform solutions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123 6.13 Reference material . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123 Chapter 7. Operations Navigator independent ASP GUI . . . . . . . . . . . . . . . . . . . . . . . 125 7.1 Prerequisite steps to create an IASP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126 7.1.1 Configuring the Service Tools adapter on the iSeries server . . . . . . . . . . . . . . . 126 7.1.2 Setting up Management Central . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127 7.2 The independent auxiliary storage pool GUI. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130 7.2.1 Creating a standalone independent auxiliary storage pool . . . . . . . . . . . . . . . . . 130 7.2.2 Creating a switchable independent auxiliary storage pool . . . . . . . . . . . . . . . . . 141 Chapter 8. ClusterProven for iSeries applications. . . . . . . . . . . . . . . . . . . . . . . . . . . . 161 8.1 ClusterProven components. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162 8.1.1 OS/400 Cluster Resource Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162 8.1.2 Data resiliency . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162 8.1.3 Cluster management. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163 8.1.4 Application resiliency . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163 8.2 ClusterProven defined. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163 8.2.1 The Advanced ClusterProven for iSeries Program . . . . . . . . . . . . . . . . . . . . . . . 164 8.3 Obtaining the ClusterProven trademark . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164 8.4 ClusterProven Domino for iSeries. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166 8.4.1 ClusterProven Domino customer benefits. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167 8.4.2 Comparing traditional Domino clustering support . . . . . . . . . . . . . . . . . . . . . . . . 168 Chapter 9. Making applications continuously available . . . . . . . . . . . . . . . . . . . . . . . 169 9.1 Defining critical objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170 9.1.1 Non-ClusterProven applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170 9.1.2 ClusterProven applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170 9.2 Cluster Resource Group exit program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171 9.2.1 Cluster Resource Group interface. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171 9.2.2 Input data area . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171 9.2.3 Output data area . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172 9.2.4 Returning from the exit program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172 9.2.5 Using the exit program to establish the environment . . . . . . . . . . . . . . . . . . . . . 172 9.2.6 Managing the environment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177 9.2.7 Rejoining or restarting the application. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180 Chapter 10. Sample cluster environment and applications . . . . . . . . . . . . . . . . . . . . 183 10.1 Example cluster configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184 10.1.1 Creating the sample clustering environment. . . . . . . . . . . . . . . . . . . . . . . . . . . 185 10.1.2 Sample setup of journaling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188 10.1.3 Journal environment to allow reverse remote backup. . . . . . . . . . . . . . . . . . . . 190 10.2 Sample RPG order entry application. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192 10.2.1 Original RPG application. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192 vi Clustering and IASPs for Higher Availability on the iSeries Server 10.2.2 Stage 1: Cluster application to use remote journals . . . . . . . . . . . . . . . . . . . . . 192 10.2.3 Stage 2: Cluster application to support a highly available environment . . . . . . 194 Chapter 11. Considerations when planning for iSeries clusters and recoverable applications. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195 11.1 Planning for iSeries clustering. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196 11.1.1 Measuring the impact of an outage to the business . . . . . . . . . . . . . . . . . . . . . 197 11.1.2 Determining the desired level of availability . . . . . . . . . . . . . . . . . . . . . . . . . . . 197 11.1.3 Understanding the required configuration of a cluster . . . . . . . . . . . . . . . . . . . 198 11.2 Making applications recoverable. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199 11.2.1 Application object inventory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199 11.2.2 Resilient data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199 11.2.3 Resilient applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200 11.2.4 Switchover . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200 11.2.5 Failover . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201 11.2.6 Job restart. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201 11.2.7 Application maintenance. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201 11.2.8 Database performance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205 11.3 Systems management . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206 11.3.1 Service level agreements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206 11.3.2 Operations management . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206 11.3.3 Problem and change management. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206 11.3.4 Capacity planning . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207 11.3.5 Performance planning. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207 11.3.6 Security and password considerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 208 11.4 Hardware considerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 208 11.4.1 Network planning . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209 11.5 Testing clusters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210 11.5.1 System management tests . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211 11.5.2 Cluster management tests . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211 11.6 Roles and responsibilities when implementing clustering . . . . . . . . . . . . . . . . . . . . . 211 11.6.1 The role of IBM and OS/400 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211 11.6.2 The role of a cluster middleware provider. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212 11.6.3 The role of an application developer. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212 Chapter 12. Problem determination for iSeries clustering . . . . . . . . . . . . . . . . . . . . . 215 12.1 Monitoring for problems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216 12.2 Problems with the status of a cluster . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217 12.2.1 Is my cluster up and running?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217 12.2.2 Why won’t my cluster start? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217 12.2.3 Why is my CRG hung up?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218 12.2.4 I cannot use the IBM Cluster Management GUI . . . . . . . . . . . . . . . . . . . . . . . . 218 12.2.5 I cannot use any new release functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219 12.2.6 How do I recover from a Cluster Resource Group job failure? . . . . . . . . . . . . . 219 12.2.7 Why do I have two clusters after fixing my cluster partition? . . . . . . . . . . . . . . 219 12.3 Recovering from a cluster partition state. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 220 12.3.1 Cluster partition error example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 220 12.3.2 Cluster partition tips . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222 12.3.3 Merging a cluster partition. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223 Part 3. Cluster middleware business partners. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 227 Chapter 13. DataMirror iCluster . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 229 13.1 Introduction to iCluster . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 230 Contents vii 13.2 Getting started with iCluster . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 230 13.3 Creating a cluster . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 231 13.3.1 Adding a node to the cluster . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 231 13.4 Creating and using Cluster Resource Groups . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233 13.4.1 Creating data CRGs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233 13.4.2 Selecting objects for a data CRG for high availability . . . . . . . . . . . . . . . . . . . . 235 13.4.3 Creating application CRGs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237 13.4.4 Creating device CRGs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237 13.4.5 Changing a CRG recovery domain . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 238 13.4.6 Activating or starting a data CRG . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239 13.4.7 De-activating or ending a data CRG . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239 13.4.8 Switching over a data CRG. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239 13.4.9 Problem solving . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 240 13.5 DataMirror ClusterProven applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243 13.5.1 Setting up a resilient application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243 13.5.2 Selecting objects to a resilient application . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245 13.5.3 Changing or updating a resilient application . . . . . . . . . . . . . . . . . . . . . . . . . . . 245 13.5.4 Changing a resilient application’s recovery domain . . . . . . . . . . . . . . . . . . . . . 245 13.5.5 Activating or starting a resilient application. . . . . . . . . . . . . . . . . . . . . . . . . . . . 246 13.5.6 De-activating or ending a resilient application. . . . . . . . . . . . . . . . . . . . . . . . . . 246 13.5.7 Switching over a resilient application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246 13.6 Removing the cluster and its components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246 13.6.1 Removing a resilient application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246 13.6.2 Removing a data CRG . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246 13.6.3 Removing a node from the cluster . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 247 13.6.4 Removing the entire cluster . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 247 13.7 Using iCluster commands to access Cluster Services operations . . . . . . . . . . . . . . 247 13.8 For more information. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 248 Chapter 14. Lakeview Technology MIMIX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 249 14.1 MIMIX Cluster Server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 249 14.1.1 Implementing clustering with the MIMIX Cluster Server . . . . . . . . . . . . . . . . . . 251 14.1.2 Technical support . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 252 14.2 MIMIX FastPath . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 252 14.2.1 Resilient objects for clustering . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253 14.2.2 MIMIX FastPath services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253 14.2.3 MIMIX FastPath support . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253 14.2.4 MIMIX FastPath Professional Services. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253 Chapter 15. Vision Solutions Vision Suite . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 255 15.1 Vision Solutions OMS/400 Cluster Manager. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 256 15.1.1 Implementation goals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 256 15.2 Getting started with OMS/400 Cluster Manager . . . . . . . . . . . . . . . . . . . . . . . . . . . . 256 15.2.1 Installing the client . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 256 15.2.2 Starting the product. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 257 15.2.3 Defining host systems. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 257 15.2.4 Auto-detecting clustered nodes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 257 15.2.5 IP interface selection. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 258 15.2.6 Working with ClusterProven applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 258 15.3 OMS/400 Cluster Manager sample displays. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259 15.3.1 Working with clusters and CRGs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259 15.3.2 Creating new clusters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260 15.3.3 Viewing cluster information . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260 viii Clustering and IASPs for Higher Availability on the iSeries Server 15.3.4 Adding a node to the cluster . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 261 15.3.5 Activating and de-activating nodes in the cluster . . . . . . . . . . . . . . . . . . . . . . . 262 15.3.6 Creating and using Cluster Resource Groups . . . . . . . . . . . . . . . . . . . . . . . . . 262 15.3.7 Changing a CRG recovery domain . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263 15.3.8 Activating or starting a data or application CRG . . . . . . . . . . . . . . . . . . . . . . . . 263 15.3.9 De-activating or ending a data or application CRG. . . . . . . . . . . . . . . . . . . . . . 264 15.3.10 Creating an application CRG recovery domain. . . . . . . . . . . . . . . . . . . . . . . . 264 15.3.11 Removing a data or application CRG . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 265 15.3.12 Removing a node from the cluster . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 266 15.3.13 Removing the entire cluster . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 266 15.4 Working with applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 267 15.4.1 ISV data area contents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 267 15.4.2 Creating ISV data areas for application CRGs . . . . . . . . . . . . . . . . . . . . . . . . . 267 15.4.3 Changing or updating data areas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 268 15.4.4 Changing a resilient application’s data area contents. . . . . . . . . . . . . . . . . . . . 268 15.4.5 Working with object specifiers. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269 15.4.6 Object selection results. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 270 15.4.7 Creating a list of objects for high availability . . . . . . . . . . . . . . . . . . . . . . . . . . . 270 15.4.8 Viewing OMS/400 links and statistics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 271 15.5 Enhancements for OS/400 V5R1 functionality . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 271 Part 4. Appendices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 273 Appendix A. Advanced clusters explained. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 275 A.1 Underlying technologies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276 A.2 Peer cluster node design . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276 A.2.1 Heartbeat and cluster communication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276 A.2.2 Distributed activities . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 277 A.2.3 Job structure for Cluster Resource Services . . . . . . . . . . . . . . . . . . . . . . . . . . . 278 A.2.4 Cluster engine services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 279 A.2.5 Cluster partition state . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 279 A.2.6 Cluster versions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 281 Appendix B. Referenced lists. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 283 B.1 Clustering data area layout. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 284 B.2 Unpacking and creating QUSRTOOL APIs and commands. . . . . . . . . . . . . . . . . . . . 285 B.3 Cluster APIs and related QUSRTOOL commands . . . . . . . . . . . . . . . . . . . . . . . . . . . 286 B.3.1 Cluster Control APIs and QUSRTOOL commands . . . . . . . . . . . . . . . . . . . . . . 286 B.3.2 Cluster Resource Group APIs and QUSRTOOL commands . . . . . . . . . . . . . . . 287 B.4 Object specifier file layout. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 288 Appendix C. iSeries cluster resources . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 291 Related publications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 293 IBM Redbooks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 293 Other resources . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 293 Referenced Web sites . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 293 How to get IBM Redbooks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 294 IBM Redbooks collections. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 294 Glossary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 295 Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 297 © Copyright IBM Corp. 2000, 2002 ix Figures 1-1 Elements impacting downtime . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 2-1 Causes of unplanned downtime. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 2-2 Estimated costs of downtime . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 2-3 Typical multi-tier Web application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 3-1 iSeries server hardware availability features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 3-2 iSeries software availability features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 3-3 Basic cluster. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 3-4 Switched disk cluster . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 3-5 Shared disk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 3-6 Separate server cluster . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 3-7 Cluster created by logical partitioning . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 4-1 OS/400 integrated cluster services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 4-2 Cluster Resource Services structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40 4-3 Components of clustering . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 4-4 Cluster nodes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44 4-5 Cluster Resource Group . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44 4-6 Recovery domain. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46 4-7 Device domain . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47 4-8 Exit program. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47 4-9 Simple two-node cluster. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49 4-10 Four-node mutual takeover cluster . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50 4-11 Data resiliency in a simple two-node cluster . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 4-12 Failure in a simple two-node cluster . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 4-13 Application resiliency and IP address takeover in a simple two-node cluster . . . . . . 53 4-14 Application resiliency and IP address takeover after a failure . . . . . . . . . . . . . . . . . . 54 4-15 iSeries cluster solution components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 5-1 iSeries cluster implementation open architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . 59 5-2 Operations Navigator initial window. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65 5-3 Creating a new cluster . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66 5-4 Starting the New Cluster wizard. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66 5-5 New Cluster Wizard welcome window. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 5-6 Cluster prerequisites . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68 5-7 Naming the cluster. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69 5-8 Specifying a system to be the primary node . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 5-9 Specifying the IP address of primary node . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71 5-10 Cluster primary node completion display. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72 5-11 Specifying the name and IP address of backup node . . . . . . . . . . . . . . . . . . . . . . . . 73 5-12 Signing on to the backup node . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 5-13 Switchable software. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75 5-14 Network attribute to allow clustering . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76 5-15 Creating a cluster. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77 5-16 Cluster creation complete . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78 5-17 The cluster is created. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79 5-18 New cluster appears in Management Central . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79 5-19 System groups created . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80 5-20 The cluster creation log . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81 5-21 Managing a cluster with Operations Navigator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82 5-22 Adding switchable software . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82 x Clustering and IASPs for Higher Availability on the iSeries Server 5-23 Adding the application CRG. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83 5-24 Entering the name of the exit program. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83 5-25 Application added . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84 5-26 Starting the application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84 5-27 CRG started. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85 5-28 Switching the application to a backup system . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85 5-29 Confirming the switch of the application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86 5-30 Node changed to backup. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86 5-31 Create Cluster QUSRTOOL command . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88 5-32 Add Cluster Node Entry QUSRTOOL command . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89 5-33 Add Device Domain Entry QUSRTOOL command . . . . . . . . . . . . . . . . . . . . . . . . . . 90 5-34 Create CRG QUSRTOOL command . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91 5-35 Start Cluster Resource Group command. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92 5-36 End Cluster Resource Group QUSRTOOL command. . . . . . . . . . . . . . . . . . . . . . . . 93 5-37 Create Cluster specifying previous cluster version . . . . . . . . . . . . . . . . . . . . . . . . . . 97 6-1 ASPs at V5R1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103 6-2 Additional ASP terminology . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103 6-3 Switchable IASP object relationship . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108 6-4 IASPs, device domains, and device CRGs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110 6-5 IASP configuration: Examples 1 and 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111 6-6 IASP configuration: Examples 3 and 4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111 6-7 Domino using IASP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112 6-8 Integrated xSeries Server or Direct Attached xSeries Server using IASP. . . . . . . . 113 6-9 Creating a disk pool using the GUI interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114 6-10 IASP pool number is assigned by the system . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115 6-11 Unit numbering for IASPs and disks in the IASP . . . . . . . . . . . . . . . . . . . . . . . . . . . 117 6-12 IASPs and user profiles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118 6-13 Accounting for space used. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119 6-14 IASPs and authorization lists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120 7-1 Adding a service table entry on the iSeries server. . . . . . . . . . . . . . . . . . . . . . . . . . 126 7-2 View of Operations Navigator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127 7-3 Access Application Administration in Operations Navigator . . . . . . . . . . . . . . . . . . 128 7-4 Application Administration window. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128 7-5 Host Applications tab . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129 7-6 Enabling disk unit access. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129 7-7 Non-switchable independent ASP with Integrated xSeries Adapters (IXA) attached 130 7-8 Signing on to DST . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131 7-9 New Disk Pool . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131 7-10 Welcome panel of the New Disk Pool Wizard . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132 7-11 Specifying the disk pool type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133 7-12 Protecting a disk pool. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134 7-13 Selecting the disk units . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135 7-14 Balancing the disk pools . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135 7-15 Summary of the disk configuration. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136 7-16 New Disk Pool Status window . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136 7-17 Disk pool created . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137 7-18 Disk pool visible to Operations Navigator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137 7-19 Varying on the IASP. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138 7-20 Confirming to make the disk pool available . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138 7-21 Vary on completed. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139 7-22 IASP visible on the Integrated File System . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140 7-23 PC files on the IASP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140 7-24 Displaying IFS files with WRKLNK. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141 Figures xi 7-25 Simple two-node cluster using a switchable IASP. . . . . . . . . . . . . . . . . . . . . . . . . . 142 7-26 Creating a new switchable hardware group. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143 7-27 The Welcome panel. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143 7-28 Selecting the primary node . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144 7-29 Specifying a group name . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145 7-30 Specifying the disk pool name . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146 7-31 New Group – Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147 7-32 Add Disk Pool wizard. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148 7-33 Selecting the disk units . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149 7-34 Units selected . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150 7-35 Balance Disk Pools . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151 7-36 Disk pool summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152 7-37 Creating disk pool . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153 7-38 Successful creation message . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154 7-39 Group summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155 7-40 Start New Hardware Group . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156 7-41 IASP before switch. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156 7-42 Switching the IASP group . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157 7-43 Switch confirmation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157 7-44 Disks attached to the backup system . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158 7-45 WRKDSKSTS shows disks attached to primary node. . . . . . . . . . . . . . . . . . . . . . . 159 7-46 Disks are not visible after the switch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159 7-47 IASP attached to backup node . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160 8-1 IBM logo for ClusterProven applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161 8-2 iSeries cluster partnership . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162 8-3 ClusterProven Domino for iSeries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167 8-4 Domino replication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168 9-1 Scenario A: Creating a data CRG exit program example (EXITPGM). . . . . . . . . . . 174 9-2 Scenario A: Creating the application CRG exit program example (EXITPGMAPP) 175 9-3 Scenario B: Starting the CRG Data exit program example (EXITPGM) . . . . . . . . . 175 9-4 Scenario B: Starting the CRG application exit program example (EXITPGMAPP) . 176 9-5 Scenario C: Switchover CRG data exit program example (EXITPGM) . . . . . . . . . . 179 9-6 Scenario C: Switchover CRG application exit program example (EXITPGMAPP) . 180 10-1 Application cluster CLUSTERA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184 10-2 Assignment of IP addresses in cluster CLUSTERA. . . . . . . . . . . . . . . . . . . . . . . . . 185 10-3 Example cluster setup (Part 1 of 3) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186 10-4 Example cluster setup (Part 2 of 3) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187 10-5 Example cluster setup (Part 3 of 3) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188 10-6 Sample journal setup (Part 1 of 3) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189 10-7 Sample journal setup (Part 2 of 3) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189 10-8 Sample journal setup (Part 3 of 3) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190 10-9 Resilient data from System A to B . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191 10-10 Resilient data from System B to A . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191 10-11 Definition of the StatusLog file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193 11-1 Application maintenance in a cluster (Part 1 of 3) . . . . . . . . . . . . . . . . . . . . . . . . . . 203 11-2 Application maintenance in a cluster (Part 2 of 3) . . . . . . . . . . . . . . . . . . . . . . . . . . 204 11-3 Application maintenance in a cluster (Part 3 of 3) . . . . . . . . . . . . . . . . . . . . . . . . . . 205 11-4 Redundant network connections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209 11-5 Cluster test scenario . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210 12-1 Recovery action for clustering error message . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216 12-2 Cluster partition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 220 12-3 Possible merge operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 224 12-4 Primary-secondary merge operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 224 xii Clustering and IASPs for Higher Availability on the iSeries Server 12-5 Secondary-secondary merge operation. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 225 13-1 The DataMirror iCluster Administrator main window . . . . . . . . . . . . . . . . . . . . . . . . 231 13-2 The iCluster Administrator Add Node input dialog . . . . . . . . . . . . . . . . . . . . . . . . . . 232 13-3 The iCluster Administrator cluster nodes display. . . . . . . . . . . . . . . . . . . . . . . . . . . 232 13-4 Cluster with a single primary node and three backup nodes . . . . . . . . . . . . . . . . . . 233 13-5 The iCluster Administrator Add Group input dialog . . . . . . . . . . . . . . . . . . . . . . . . . 234 13-6 The iCluster Administrator Group window . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 235 13-7 The iCluster Administrator Select/Add Object Specifier input dialog . . . . . . . . . . . . 236 13-8 iCluster GUI Administrator Object Specifiers in PAYROLL group . . . . . . . . . . . . . . 237 13-9 iCluster Add node display . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 238 13-10 DM Add Resource Group display . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 238 13-11 iCluster GUI Event Viewer Change Filter display . . . . . . . . . . . . . . . . . . . . . . . . . . 241 13-12 iCluster GUI Event Viewer Detailed Message display . . . . . . . . . . . . . . . . . . . . . . . 242 13-13 iCluster GUI Event Viewer Export Log dialogue . . . . . . . . . . . . . . . . . . . . . . . . . . . 242 13-14 iCluster GUI Add Resilient Application input dialogue . . . . . . . . . . . . . . . . . . . . . . . 244 13-15 The iCluster Resilient Applications window . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 244 14-1 Cluster enable with MIMIX. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251 15-1 OMS Welcome page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 257 15-2 Auto-detecting nodes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 258 15-3 OMS Cluster Manager . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259 15-4 Creating a cluster window . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260 15-5 Cluster information windows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 261 15-6 Adding a node . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 261 15-7 Cluster activation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262 15-8 Creating CRGs with iCluster . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262 15-9 Changing a recovery domain. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263 15-10 Activating CRG . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263 15-11 Stopping Resource Group Services. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264 15-12 Switching over CRG. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264 15-13 Creating an application CRG . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 265 15-14 Takeover IP address . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 265 15-15 Removing CRGs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 265 15-16 Removing a node from a cluster . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 266 15-17 Removing the cluster . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 266 15-18 QCSTHAPPI contents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 267 15-19 Creating QCSTHAPPI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 268 15-20 Changing QCSTHAPPI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 268 15-21 Updating QCSTHAPPI contents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269 15-22 Object specifier list. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269 15-23 Working with object specifiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 270 15-24 Object selection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 270 15-25 Creating a resilient object list. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 271 15-26 Viewing OMS/400 links and statistics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 271 A-1 Relay nodes in heartbeat protocols . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 277 A-2 Example job structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 278 A-3 Cluster partitions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280 © Copyright IBM Corp. 2000, 2002 xiii Tables 1-1 Availability percentage translated to potential business downtime . . . . . . . . . . . . . . . 6 2-1 ERP disaster recovery options by level . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 2-2 Business impact advantages by level . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 5-1 Clustering functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61 6-1 Type and quantity of ASP support by OS/400 release . . . . . . . . . . . . . . . . . . . . . . 102 6-2 Independent ASP rankings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115 6-3 Comparison of cluster middleware replication and IASP switched disk. . . . . . . . . . 122 8-1 ClusterProven for iSeries criteria . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165 9-1 Action code and exit programs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173 12-1 Cluster Control API partition restrictions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221 12-2 Cluster Resource Group API partition restrictions . . . . . . . . . . . . . . . . . . . . . . . . . . 221 13-1 Mapping Cluster Services operations to iCluster commands . . . . . . . . . . . . . . . . . 248 13-2 Mapping Cluster Resource Group operations to iCluster commands . . . . . . . . . . . 248 A-1 CRG operations allowed in LPAR partition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 281 B-1 QCSTHAAPPI data area . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 284 B-2 QCSTHAAPPO data area . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 285 B-3 Cluster Control API and QUSRTOOL command descriptions. . . . . . . . . . . . . . . . . 286 B-4 CRG Group API and command descriptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 287 B-5 Record format of object specifier file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 288 xiv Clustering and IASPs for Higher Availability on the iSeries Server © Copyright IBM Corp. 2000, 2002 xv Special notices References in this publication to IBM products, programs or services do not imply that IBM intends to make these available in all countries in which IBM operates. Any reference to an IBM product, program, or service is not intended to state or imply that only IBM's product, program, or service may be used. Any functionally equivalent program that does not infringe any of IBM's intellectual property rights may be used instead of the IBM product, program or service. Information in this book was developed in conjunction with use of the equipment specified, and is limited in application to those specific hardware and software products and levels. IBM may have patents or pending patent applications covering subject matter in this document. The furnishing of this document does not give you any license to these patents. You can send license inquiries, in writing, to the IBM Director of Licensing, IBM Corporation, North Castle Drive, Armonk, NY 10504-1785. Licensees of this program who wish to have information about it for the purpose of enabling: (i) the exchange of information between independently created programs and other programs (including this one) and (ii) the mutual use of the information which has been exchanged, should contact IBM Corporation, Dept. 600A, Mail Drop 1329, Somers, NY 10589 USA. Such information may be available, subject to appropriate terms and conditions, including in some cases, payment of a fee. The information contained in this document has not been submitted to any formal IBM test and is distributed AS IS. The use of this information or the implementation of any of these techniques is a customer responsibility and depends on the customer's ability to evaluate and integrate them into the customer's operational environment. While each item may have been reviewed by IBM for accuracy in a specific situation, there is no guarantee that the same or similar results will be obtained elsewhere. Customers attempting to adapt these techniques to their own environments do so at their own risk. Any pointers in this publication to external Web sites are provided for convenience only and do not in any manner serve as an endorsement of these Web sites. xvi Clustering and IASPs for Higher Availability on the iSeries Server IBM trademarks The following terms are trademarks of the International Business Machines Corporation in the United States and/or other countries: e (logo)® AIX® AS/400® AS/400e™ Balance® ClusterProven™ DB2® DB2 Universal Database™ DFS™ e (logo)® Enterprise Storage Server™ IBM® iSeries™ MQSeries® Netfinity® Operating System/400® OS/400® Parallel Sysplex® PartnerWorld® Perform™ pSeries™ Redbooks™ RS/6000® S/390® Service Director™ SP™ SP1® SP2® System/38™ TCS® Tivoli® xSeries™ Lotus® Domino™ Redbooks (logo)™ Other company trademarks The following terms are trademarks of other companies: C-bus is a trademark of Corollary, Inc. in the United States and/or other countries. Java and all Java-based trademarks and logos are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and/or other countries. Microsoft, Windows, Windows NT, and the Windows logo are trademarks of Microsoft Corporation in the United States and/or other countries. PC Direct is a trademark of Ziff Communications Company in the United States and/or other countries and is used by IBM Corporation under license. ActionMedia, LANDesk, MMX, Pentium and ProShare are trademarks of Intel Corporation in the United States and/or other countries. UNIX is a registered trademark in the United States and other countries licensed exclusively through The Open Group. SET, SET Secure Electronic Transaction, and the SET Logo are trademarks owned by SET Secure Electronic Transaction LLC. Other company, product, and service names may be trademarks or service marks of others. © Copyright IBM Corp. 2000, 2002 xvii Preface With OS/400 V5R1, IBM ~ iSeries servers support two methods of clustering. Replication technology is one method. The other method is switchable disk technology, which is referred to as independent auxiliary storage pools (IASPs) on the iSeries server. This IBM Redbook presents an overview of cluster and switched disk technology available at OS/400 Version 5 Release 1. It explains the concepts and architecture surrounding iSeries clusters. It introduces you to the ~ brand initiative – ClusterProven for iSeries – and explains how it applies to iSeries customers and independent software vendors. Application resiliency can be delivered by exploiting OS/400 cluster technology and cluster management services such as those provided by IBM High Availability Business Partners. It is available through IBM cluster middleware providers. Considerations for this application design are also introduced in this redbook. This redbook is written for IBM customers, technical representatives, and Business Partners who plan business solutions and systems that are continuously available. You should use this book to gain a broad understanding of the cluster architecture available with OS/400 Version 5, Release 1, where clustering is viable. You should also use it to learn how to plan and implement clustering and independent ASPs. The team that wrote this redbook This redbook was produced by a team of specialists from around the world working at the International Technical Support Organization, Rochester Center. Susan Powers is a Senior I/T Specialist at the International Technical Support Organization, Rochester Center. Prior to joining the ITSO in 1997, she was an AS/400 Technical Advocate in the IBM Support Center with a variety of communications, performance, and work management assignments. Her IBM career began as a Program Support Representative and Systems Engineer in Des Moines, Iowa. She holds a degree in mathematics, with an emphasis in education, from St. Mary’s College of Notre Dame. Ellen Dreyer Andersen is a Certified IT Specialist in IBM Denmark. She has 22 years of experience working with the AS/400 and System/3x platforms. Since 1994, Ellen has specialized in AS/400e Systems Management with a special emphasis on performance, ADSTAR Distributed Storage Manager for AS/400, and high availability solutions. Note: This redbook discusses high availability solutions beyond a single-system iSeries solution. Solutions for single-system availability are discussed in The System Administrator's Companion to AS/400 Availability and Recovery, SG24-2161. xviii Clustering and IASPs for Higher Availability on the iSeries Server Sue Nee currently works in the ~ Executive Briefing Center for the iSeries in Rochester, Minnesota. She has had a variety of assignments in IBM, starting in the field working with IBM customers. She has worked in Competitive Marketing, focusing on the midrange server marketplace and has managed AS/400 data center operations for AS/400 Support Family Services: Performance Management/400, AS/400 Alert, and AS/400 Support Line. Her area of expertise in the Briefing Center is systems management and high availability computing. David Salmon is a Senior I/T Availability Professional in IBM Global Services, Australia. He has 27 years experience in IBM. He began his career began as a hardware Customer Engineer on midrange systems, moving into the software area after 15 years to serve as a Branch Program Support Representative specializing in System/38 and AS/400 systems. Working as a Systems Consultant, David is experienced in Client Access/400 and in recovering customer systems. His current assignment is as an iSeries and AS/400 System Consultant in the Business Continuity and Recovery Services Centre in Sydney. Shashi Sethy works for IBM Global Services out of Rochester, Minnesota, USA. He has over 20 years of consulting experience in the IT industry, the last ten years of which have been spent at IBM Rochester. He consults with many large corporations around the world in diverse areas of the iSeries server. As the iSeries server has evolved over the years, so have his areas of specialization. Currently, he is an active iSeries specialist in three areas – Clustering and IASP on the iSeries, iSeries performance including Application design and SQL optimization, and finally the use of MQSeries on the iSeries platform. Lee Walkky works for the IBM ~ Executive Briefing Center in Rochester, Minnesota, where he specializes in high availability and systems management. He has been there since June 2001. He began his career with IBM in OS/400 development for Common Data Management. In 1997, he left IBM and joined Lakeview Technology, where he worked in development and eventually became a High Availability Services Consultant. In 1999, Lee returned to IBM Global Services to implement the high availability environment for IBM Server Group Manufacturing. Lee has a degree in Computer Information Systems from Winona State University. Thank you to the following people for their invaluable contributions to this project: Michael Brinker Bob Gintowt Vicki Morey Amartey Pearson Ron Peterson George Romano IBM Rochester team Mike Snyder, Lead Architect for iSeries Clustering IBM Rochester Laboratory Preface xix Sue Baker Eric Hess Chuck Stupca IBM Rochester Technical Services R. L. (Bob) Blanscett IBM UNIX Executive Briefing Center - Austin Mike Warkentin, Senior Product Sales Specialist Ilze Valdmanis, Senior Product Developer DataMirror Corporation Mary Lieser, Manager of Product Development Glenn Van Benschoten, Product Marketing Director Lakeview Technology Dave Brown, Chief Scientist Johannes Grobler, Chief Engineer Vision Solutions, Inc. Notice This publication is intended to help system administrators understand the availability, backup, and recovery techniques for a high availability solution on iSeries servers. The information in this publication is not intended as the specification of any programming interfaces that are provided by high availability vendors, such as DataMirror Corporation, Lakeview Technology, and Vision Solutions, Inc. See the PUBLICATIONS section of the IBM Programming Announcement for OS/400 (5722-SS1) for more information about what publications are considered to be product documentation. Comments welcome Your comments are important to us! We want our Redbooks to be as helpful as possible. Send us your comments about this or other Redbooks in one of the following ways:  Use the online Contact us review redbook form found at: ibm.com/redbooks  Send your comments in an Internet note to: redbook@us.ibm.com  Mail your comments to the address on page ii. xx Clustering and IASPs for Higher Availability on the iSeries Server © Copyright IBM Corp. 2000, 2002 xxi Summary of changes This section describes the technical changes made in this edition of the book compared to the first edition. This edition may also include minor corrections and editorial changes that are not identified. Summary of Changes for SG24-5194-01 for Clustering and IASPs for Higher Availability on the iSeries Server as created or updated on April 16, 2002. April 2002, Second Edition The second edition of this redbook reflects the addition, deletion, and modification of new and changed information in iSeries clustering and availability technology. The original publication, AS/400 Clusters: A Guide to Achieving Higher Availability, SG24-5194-00, is based on OS/400 V4R4. The current edition is based on clustering and availability functions added in OS/400 V4R5 and V5R1. New information Several chapters (and appendices) are added in the second edition of this redbook to address new functions added since OS/400 V4R4. The new chapters include:  Chapter 5, “Implementing and managing clusters with IBM solutions” on page 59 This chapter discusses solutions provided by IBM to implement and manage clusters. These include the Operations Navigator Simple Cluster Management GUI, APIs, and commands available in QUSRTOOL library.  Chapter 6, “Independent ASPs explained” on page 99, and Chapter 7, “Operations Navigator independent ASP GUI” on page 125 These chapters describe the “what”, “why”, and “how” of the new iSeries switched disk functionality introduced with OS/40 V5R1.  Chapter 9, “Making applications continuously available” on page 169 This chapter describes an application view of continuously available. It also provides simple programming examples.  Chapter 10, “Sample cluster environment and applications” on page 183 This chapter illustrates a cluster configuration and describes program examples to support program resiliency.  Appendix A, “Advanced clusters explained” on page 275 This chapter is directed for the reader interested in more technical description of iSeries clustering architecture, or a deeper discussion than what is provided in other sections of the redbook.  Appendix B, “Referenced lists” on page 283 To improve the readability of the redbook, several lists and tables are moved to this appendix.  Appendix C, “iSeries cluster resources” on page 291 The education and services available from IBM is listed in this appendix. xxii Clustering and IASPs for Higher Availability on the iSeries Server Changed information Much of the original redbook is revised with this current edition. In general, the redbook is changed from an executive overview of clustering functions, to an implementor’s view of the tasks involved to implement and support a higher availability clustering solution on the iSeries server. © Copyright IBM Corp. 2000, 2002 1 Part 1 iSeries high availability fundamentals The iSeries server is proven to be one of the most reliable servers in the marketplace. However, reliability is not availability. Unplanned downtime does happen – hardware failures can occur, operators do make errors, applications may fail, and power can give out. Unplanned downtime happens. Yet the largest share of downtime can be due to foreseeable, yet unavoidable tasks, such as system backups, software upgrades, and application and database management, maintenance or reorganization that require planned downtime to complete. Clustering builds on the solid foundation of iSeries single-system high availability. An iSeries clustering solution is designed to address the problems caused by downtime and further enhance system availability. This part introduces the reader to availability topics as a basis to understand iSeries solutions for higher availability. Part 1 2 Clustering and IASPs for Higher Availability on the iSeries Server © Copyright IBM Corp. 2000, 2002 3 Chapter 1. Introduction Clustering is designed as a high availability solution. Clustering involves a primary and backup system (or systems) linked together in a network. It supports switching from one server to another in the event of a system outage (planned and unplanned). High availability computing can be achieved with an iSeries clustering implementation. This redbook focuses on clustering as a means to achieve high availability with an iSeries implementation. This chapter provides fundamental information about availability and the clustering architecture for the iSeries server. It serves as an introduction to the remainder of the redbook. 1 4 Clustering and IASPs for Higher Availability on the iSeries Server 1.1 A brief overview about clustering Clustering technology has been in the computing industry for years. It is used for high availability computing, horizontal scalability, and load balancing. Most of the early cluster solutions are designed to solve a problem with limited scalability of the server. Coupling servers in a cluster provides a means to scale horizontally and grow capacity as business needs require. With the scalability of servers available in the computing industry today, the need to cluster for horizontal growth is less. The new imperative is high availability. High availability drives the need to cluster. Globalization of business, server consolidation, and Web based computing – these are the dynamics that bring server availability to the forefront of IT strategic planning. These factors place demand in an environment where the server must be available nearly 24 X 7 for business transaction processing or Web serving. The users of a business’ I/T infrastructure extend beyond its employees. A server outage potentially affects not only employees of the business, but also trading partners, customers, and perhaps the public at large. The visibility of a computing system outage is magnified. In this era of e-commerce, information availability is of the utmost importance for business survival. With these dynamics as a backdrop, high availability computing is no longer viewed as applicable to only the largest, most sophisticated businesses. Cluster architecture provides support for customers who want to make their businesses continuously available. The level of availability required in today’s I/T environment can only be achieved by building redundancy into critical I/T resources, especially servers. Server redundancy is achieved through clustering. The primary goal of iSeries clustering is to achieve unprecedented system availability approaching 99.999% and beyond. You may wonder, “Clustering is not new to the iSeries. The iSeries servers support dual systems with failover capability using data replication products from DataMirror, Lakeview Technology, and Vision Solutions. So what’s new about iSeries and clustering that did not exist in the past?” What is new is that clustering functionality is built right into the system, something that did not exist in the past. This new clustering support for the iSeries provides:  A “heartbeat” monitor for systems in a cluster through a function in OS/400 called Cluster Services. If a failure occurs in one of the nodes, Cluster Services posts an error to an exit program to begin preparation for failover. This sophistication of the management of failover was not present prior to V4R4, when clustering was first introduced as part of OS/400.  A GUI interface makes it easier to setup and manage cluster implementation.  Application recoverability via an API interface that maintains a program’s state when switching between nodes in a cluster.  Device resiliency, which allows disk devices to be switched between nodes in a cluster and run applications on a different node. This redbook provides an overview of this new clustering support for the iSeries introduced at V4R4 and that has been enhanced at V5R1. It also guides you through the steps required to set up replication-based clustering and clustering using independent auxiliary storage pools (IASPs). Cluster management and problem determination are also outlined. Chapter 1. Introduction 5 1.2 Defining availability An outage is a period when the information system is not available. During a scheduled outage, the system is planned to be made unavailable to users. Scheduled outages are used to run batch work, save the system, or apply program temporary fixes (PTFs). An unscheduled outage is usually caused by a failure of some type. Unscheduled outages typically cannot be predicted. Clustering technologies and solutions are implemented to minimize the impact of outages. Availability solutions are designed for differing levels of system availability. There is no industry standard to define precisely what high availability is. Different vendors and solution providers apply different meanings to terms like “continuous operations,” high availability,” and “continuous computing”. This redbook uses these definitions of the terms to discuss the availability levels offered by iSeries servers and clustering:  High availability: Systems that reduce or eliminate unplanned outages.  Continuous operations: Systems that reduce or eliminate planned outages.  Continuous availability: Systems that reduce or eliminate both planned and unplanned outages. The iSeries server can achieve all three levels of availability. 1.2.1 Factors impacting availability A component’s availability rating impacts the potential downtime of the solution. Availability decreases as more components are added to the I/T environment. The downtime numbers identified in Figure 1-1 illustrate this point. Note: These availability definitions are consistent with the usage in the redbook The System Administrator's Companion to AS/400 Availability and Recovery, SG24-2161. This book is commonly referred to as “the companion redbook” and describes availability for a single-system iSeries (AS/4000e) implementation. Important: Server availability is just one component of a critical business process. For an effective high availability implementation, consider all of the elements involved, such as the wide area network (WAN) and local area network (LAN) resources, connections to other servers, and design for resiliency. 6 Clustering and IASPs for Higher Availability on the iSeries Server Figure 1-1 Elements impacting downtime Table 1-1 correlates the availability ratings of 90 through 99.9999% to the equivalent duration of an outage measured in time. Table 1-1 Availability percentage translated to potential business downtime A 10% difference in availability rating makes a difference of seconds, minutes, hours, and indeed days. To illustrate this reality, consider this scenario. For this example, we assume:  A server supports a critical business process.  The server is available 99% of the time.  An application running on that server uses a network connection through a router.  The availability of router is 95%. To measure the availability for this critical business process, consider each component separately. The combined availability of the server and the router factors calculate to be 94%, which means a probability of 21 days of downtime per year. In contrast, if only the server’s 99% availability is factored in, downtime is only 3.5 days per year. If a probability of 21 days downtime per year cannot be tolerated by the business, the availability of the router must be improved. With 95% availability, the router is the weak link in the chain of factors contributing to availability. Availability percentage Total outage per year 99.9999 32 seconds 99.999 5 minutes 99.99 53 minutes 99.9 8.8 hours 99 87 hours (3.6 days) 90 876 hours (36 days) 14 components @ 99% each = 86% System Availability (SA) 51 days downtime per year 13 components @ 99% each and 1 at 100% = 87% SA 47 days downtime per year 13 components @ 99% each and 1 at 95% = 82% SA 65 days downtime per year Wide area Server or controller Local area Desktop Environment Hardware Operating System Application Utility Power Human Error Site Loss © Copyright IBM Corp. 2000, 2002 7 Chapter 2. Downtime In larger companies, planning for downtime has been an inherent part of the I/T structure for many years. Recovery models would focus primarily on hot or cold sites, or redundant computer centers. With a large initial investment, many companies would elect to improve single system availability rather than buy into redundant systems. As hardware and software costs have declined, specifically processors, memory, disk, and communication bandwidth, entry into the recovery market is now more feasible for smaller companies. The purpose of high availability is to avoid downtime. High availability implementation requires a business investment. Although iSeries servers hold some of the highest reliability and availability ratings of any server in the marketplace, iSeries customers still need to prepare for the possibility of downtime. (See Chapter 3, “Availability technology” on page 15, for information on single-system availability.) This chapter discusses the implications of downtime from a business viewpoint, with an approach to analyze the impact of downtime, and how downtime can be affected by application design. The topics in this chapter apply to all platforms. 2 8 Clustering and IASPs for Higher Availability on the iSeries Server 2.1 Scheduled and unscheduled downtime Downtime – whether planned or unplanned – is, at the very least, an inconvenience to a business. With business’ relying on their I/S infrastructure almost 24x7 today, managing downtime becomes a primary focus of I/T organizations. Clustering provides a means to reduce or eliminate downtime. Planned downtime is more of a known entity. Although it is an inconvenience at times, business operations can adjust to accommodate the outage. A business must ask itself, “How long can we tolerate an unplanned outage without significantly impacting business?” The answer determines what I/T infrastructure investment is required to manage unplanned downtime. If the answer is “for several days“, then a high availability solution involving clustering for fast failover and recovery to a backup system probably is not required. But if the answer is “not for very long”, then a further investment in high availability solutions is required. The business impact of downtime is measured in terms of lost worker productivity, lost sales, lost manufacturing time, or customer satisfaction. These impacts are tangibly quantified as business costs. To determine what investment in high availability is required, a business must weigh the costs of system downtime against the costs associated with implementing a high availability solution to reduce or avoid an outage. An example of this business impact analysis is presented in 2.2, “Example: Impact analysis of an outage” on page 9. With current technology, most system outages are planned; that is, the system is down for a planned activity such as maintenance. Other system outages are unplanned, caused primarily by these factors as illustrated in Figure 2-1:  Application failure  Operator errors  Hardware, power, operating system, disaster Figure 2-1 Causes of unplanned downtime If a business builds a plan to address the scheduled outages, it addresses the unscheduled outages. Application failure Operator errors Hardware, power, operating system, disaster Chapter 2. Downtime 9 If a business builds a plan to address the impact of scheduled outages, it addresses some of the unscheduled outages. Figure 2-2 lists the estimated hourly costs of downtime experienced by businesses in several industries. Figure 2-2 Estimated costs of downtime Downtime can be costly. High availability computing is a form of insurance. The higher the cost an outage is to a business, the easier it is to cost justify the insurance that a high availability solution provides. 2.2 Example: Impact analysis of an outage This section presents a summary of an analysis of the impact to a business of the worst type of system outage – a site disaster. The business described is a worldwide manufacturing company that has implemented an ERP package across all its locations. The name of the company is not revealed. The numbers are real. The analysis takes into account three levels of recovery implementation, the business impact to one business unit and the entire company, and the costs (in dollars) associated with implementing only the physical infrastructure. The costs associated with manual processes, employee inefficiencies, lost sales, any lost market value of the company, the restart of applications, and synchronization with a manual system are not included. The levels of recovery implementation considered to develop the business impact model are:  Level 1: No infrastructure is in place to initiate the restore of data from backup tapes. Agreements are in effect to have hardware shipped in a timely manner if a disaster event is declared. The business impact at Level 1, over a three-week period, represents a loss of approximately 2.5% of the gross revenue of the company. Business Operation Average Hourly Impact Airline Reservation Center $89,500 ATM Service Fees $14,500 Brokerage Operations $6.45 million Catalog Sales Center $90,000 Cellular Service Activation $41,000 Credit Card Authorizations $2.6 million Home Shopping Channels $113,750 On-line Network Fees $25,250 Package Shipping Services $150,250 10 Clustering and IASPs for Higher Availability on the iSeries Server The factors in level 1 take into account the amount of time to recover all server platforms, the operating systems and data. The time required to perform a system re-test and to resynchronize the application is considered for the ERP application only.  Level 2: A minimum infrastructure is in place to allow a faster start to restore data from backup tapes. There is major transaction loss. Data is restored after the failure. The business impact at Level 2, over a ten day period, represents a loss of approximately 1.7% of the gross revenue of the company.  Level 3: Continuous availability. There is no transaction loss and little impact to the business. The impact of 30 minutes or less of application outage is rated as minimal. The costs to achieve this minimized business risk are not cost prohibitive when compared to Level 2. For a more complete determination of the cost of a business outage due to a site disaster, quantify the cost of these consequences:  Problems with data integrity  A loss of productivity due to inconsistent access to data and applications  A loss of business as a result of lost sales  The affects to the company image Other potential negative impacts to the business due to an outage that are not included in this example cost analysis are:  A consequential loss of external business  A loss in market value Table 2-1 identifies the recovery time, the impact of the duration of the recovery in terms of costs, and the cost of the business investment for the three levels of recovery implementation that were assessed. Table 2-1 ERP disaster recovery options by level While the cost to the business of moving to recovery Level 2 appears high, compare this amount to a potential loss of $100 million, which is less than one percent of the potential loss. It is a small price to pay for the business to survive. As such, a continuously available solution is a relatively small cost. Business managers should plan to reach Level 3, rather than stay on recovery Level 2. Option Description Recovery time Single business unit lost revenue * Business impact lost revenue ** Disaster recovery implementation Level 1 React at the time of disaster 3 weeks Over 1 million 150 million None Level 2 Minimum infrastructure build today; data restored after disaster 10 days $750,000 100 million $775,000 Level 3 Continuous availability 30 minutes or less Minimum Minimum Level 2 costs plus $150,000 * Source: Single business unit ** Source: Cumulative Financial Impacts and Exposures. These numbers represent the losses for all global business units. Chapter 2. Downtime 11 The implementation time differs for Level 2 and Level 3. When a business is serious about availability, Level 2 is viewed as a tactical business solution. Level 2 recovery can provide protection until the more complex options at Level 3 are implemented. Studies have shown that a loss of data and impact to business are:  43% of companies experiencing disasters never re-open. 29% close within two years (McGladrey and Pullen)  One out of 500 data centers has a severe disaster each year (McGladrey and Pullen)  A company that experiences a computer outage which lasts more than ten days never fully recovers financially.  50% of the businesses experiencing a computer loss are out of business within five years. For more information, refer to Disaster Recovery Planning: Managing Risks and Catastrophe in Information Systems by Jon Toigo. The advantages far outweigh the disadvantages and risk represented at each availability level. Table 2-2 illustrates the impact to the business for each level of availability. Table 2-2 Business impact advantages by level While the initial expenditure for a highly available system is viewed as prohibitive, the resulting savings is even greater. 2.3 Application architecture and downtime Modern applications are typically multitiered and involve edge (cache) servers, Web servers, application servers, and database servers, as illustrated in Figure 2-3. This component approach to application design introduces a higher probability of failure and subsequent potential for downtime. Level Advantage Cost to implement Disadvantage Cost to business Risk protection* 1 None None Lost revenue Can destroy company None 2 Significant benefit Some downtime Large investment Substantial loss of revenue Annual maintenance and cost of support Low 3 High customer satisfaction Automated processes No downtime for system upgrades Higher cost than Level 2 Highest cost Not significantly higher than Level 2 Extremely high * Insurance coverage 12 Clustering and IASPs for Higher Availability on the iSeries Server Figure 2-3 Typical multi-tier Web application Today’s application environment has evolved over time and is driven by the introduction of industry standards for databases, programming languages, communication protocols, messaging services, and other key technology components. These standards provide an application framework to build very flexible solutions with a lot of interconnections. New standards continue to emerge. For example, XML provides for a whole new type of client to access server resources through wireless devices. With wireless access, users are not restricted to their office or home to make a connection to a server. They can carry their server access with them. This sort of pervasive computing adds pressure to I/T staff and solutions, to reduce or eliminate downtime altogether. Application recoverability can be a large component to address unscheduled downtime. In the event of an unscheduled outage, if an application does not have good recoverability characteristics, transactions are lost or partially completed. This compromises the integrity of the database. The time it takes to sort out partially completed transactions and missing database records can considerably lengthen the overall recovery process. In a high availability environment, an application must be designed with recoverability as part of the overall objective. Include commitment control in the design to allow a partially completed transaction to be rolled back. Adding commitment control to an existing application is a task that many businesses are reluctant to do, in spite of the recoverability benefits that are to be gained. Often an application is developed over time and the original program designers are no longer available. It becomes a challenge to undertake any major changes because how long it takes, or the potential impact of the changes, is unknown. A benefit of the clustering support introduced with OS/400 V4R4 for the iSeries server is that clustering provides a framework to provide better recoverability for applications. This framework supports several levels of application recoverability, starting simply with the use of an exit program to record which screen or step an application is executing when the system fails, and sending the application state information to the secondary system when the primary fails. This allows an application to resume at a known point when it starts up on the secondary system. Intranets or traditional networks Firewall Web Browsers Database Server network Internet Database Server Database Server Web Server+- Edge or Cache Server Chapter 2. Downtime 13 This level of application recoverability can be accomplished without making changes to the application itself. Therefore, iSeries clustering architecture allows an improvement to the application’s recoverability without being intrusive to the application. Application design and recoverability are explained further in Chapter 9, “Making applications continuously available” on page 169. Important: Full transaction level recovery still needs to be addressed with commitment control. 14 Clustering and IASPs for Higher Availability on the iSeries Server © Copyright IBM Corp. 2000, 2002 15 Chapter 3. Availability technology iSeries servers earn some of the highest reliability and availability ratings of any server in the market place today. There are many availability features inherent within OS/400 and iSeries hardware. From its inception onward, the iSeries server is designed to run applications to support core business processes. The iSeries is built for business. Because it is built to support business, features are designed to avoid unscheduled system downtime whenever possible and to quickly restore the system to an operational state should a failure occur. The impact of an unscheduled outage of the iSeries server components can be minimized, because many operations can continue while error reporting occurs. The errors logged allow maintenance to be deferred and scheduled for maintenance at a less disruptive time. System backups are the most frequent cause for scheduled downtime on a system. For scheduled outages, the philosophy and design of the iSeries server are to provide tools, utilities, processes, and hardware resources to make a scheduled outage as brief as possible. Examples of this include support for fast tape technology (3590 and Linear Tape Output (LTO) devices), and leveraging OS/400’s multi-threading capability by initiating multiple save jobs in parallel to more than one tape drive. These features reduce the time it takes to backup a system. OS/400 itself maintains message logs, job logs, and the system history log to ensure they do not become too large and perhaps impact system performance or operations. OS/400 reclaims virtual addresses and temporary disk space used by system jobs and applications to reduce the requirement of a system IPL to reclaim and clean up resources. The limit of what can be achieved in a single system environment is reached between a 99.9% and 99.99% availability. Achieving higher availability (99.999% and above) is only possible using a multiple system approach. With the iSeries server’s implementation of clustering, availability tends to move closer to the 100% target. This chapter describes the availability technology built into the iSeries server. It supplements the information found in the redbook The System Administrator's Companion to AS/400 Availability and Recovery, SG24-2161, which explains iSeries availability from a single system perspective. 3 16 Clustering and IASPs for Higher Availability on the iSeries Server 3.1 iSeries server hardware availability features Figure 3-1 identifies the availability features built into the iSeries server hardware. These features are described in more detail in this section. Figure 3-1 iSeries server hardware availability features  Power subsystem –Redundant power supplies, cooling fans, dual line cords Redundant power supplies and cooling fans are options available for iSeries servers. Some models of the system can be ordered with dual line cords. These features allow power to be supplied from more than one source, with one power source acting as a backup in the event of a disruption to the alternate power source. –Dedicated UPS interface The iSeries server provides a program interface to monitor and manage the switch to a Uninterruptible Power Supply (UPS) source in the event of a power outage. The system sends a message (that can be monitored for) when it detects power loss. A power handling program can monitor for power-related messages and manage the switchover to a UPS.  Disk subsystem –Device parity protection (RAID-5) Device parity protection (RAID-5) is a hardware availability function that protects data from loss due to a disk unit failure or because of damage to a disk. The overall goal of device parity protection is to provide high availability and to protect data as inexpensively as possible. To protect data, the disk controller or input/output processor (IOP) calculates and saves a parity value for each bit of data. Conceptually, the disk controller or IOP computes the parity value from the data at the same location on each of the other disk units in the device parity set. When a disk failure occurs, the parity value and values of the bits in the corresponding locations on the other disks are used to reconstruct the data. The system continues to run while the data is reconstructed. Power Subsystem Disk Subsystem I/O Subsystem Memory Hardware Service Redundant power supplies Dual line cords Redundant cooling fans Dedicated UPS Monitoring Interface RAID 5 protection Mirroring protection Concurrent maintenance Add disk concurrently "Chip kill" technology Error detection & correction Memory scrubbing Hot pluggable PCI cards Dynamic hardware resource reallocation (Vary cmd) Redundant HSL loops IOP reset Automatic Failure Notification Chapter 3. Availability technology 17 – Mirrored protection Mirrored protection is an availability function that protects data from being lost due to failure or because of damage to a disk-related component. Data is protected because the system keeps two copies of data on two separate disk units. When a disk-related component fails, the system continues to operate without interruption. The mirrored copy of the data is used until the failed component is repaired. Mirroring can be extended to include mirroring the disk IOPs and the busses that the disk units are attached to so the disk subsystem can continue to function even if a disk IOP or a bus fails. – Concurrent maintenance The iSeries disk subsystem allows maintenance to be performed on a disk drive that is part of a mirrored pair or a RAID-5 set while the system remains operational. Disks can be added concurrently, meaning disk capacity can be increased without disruption to system operations. Because the system manages storage automatically, newly added drives are immediately available for use. There is no requirement to partition the drives or move data to them in order for the system to utilize the drives. The system manages all space as one virtual address. Other than configuring the disks as new hardware devices, special setup is not required to make a new disk operational.  I/O subsystem –Hot pluggable PCI cards Hot plugging is made possible by the existence of a power control to individual cards slots. PCI IOPs or IOAs can be added, removed, or replaced while the system remains active. –Dynamic hardware resource reallocation Each hardware device on the iSeries server has a device description associated with it. The description contains the name of the specific hardware component that the hardware resource is associated with. If a hardware device fails and there is a backup device for it installed in the system, the device description can be modified to point to the backup device. It can then be substituted for the failing device. –Redundant HSL loops High Speed Link (HSL) is a new fibre bus structure introduced for iSeries servers. HSL is a 1 Gigabyte per second bus that includes a redundant path capability. If a system bus cable is broken or unplugged, I/O traffic is routed through an alternate path, therefore, avoiding a system outage. –IOP reset The iSeries I/O architecture uses intelligent I/O processors (IOPs) to control hardware adapters. Should a failure occur in one of these IOPs, it can be reset (or “re-booted”) with the system VARY command. This avoids the need to IPL the system to recover from an I /O error.  Memory iSeries memory represents “Chip Kill” technology. If a segment of memory fails, the iSeries simply makes unavailable the range of addresses, including the defective address or addresses. A message is sent to the system operator and the hardware error logs are updated with data related to the failure. Therefore, the system can remain active should a part of main storage fail. Maintenance can be deferred, which allows the system to tolerate memory failures without bringing the system down. 18 Clustering and IASPs for Higher Availability on the iSeries Server The system also performs a background “scrub” of memory, to detect and correct single and double bit errors.  Hardware service –Hardware failure notification With iSeries Service Director, the system “phones home” to a service machine when it detects key hardware component failures. A customer can optionally choose to have a repair engineer dispatched automatically when a hardware failure is logged. There are many cases recorded where a service engineer comes to a customer’s premises in response to a hardware problem detected by Service Director, and the customer is not even aware of the problem because the system was able to continue operations. 3.2 OS/400 and system software availability features This section provides additional detail about the availability features built into the iSeries server software. The features that are addressed are listed in Figure 3-2. Figure 3-2 iSeries software availability features  Database – DB2 Universal Database for iSeries –Journaling iSeries journaling was initially introduced to record changes made to database files. In the event of a system outage, the journal is used to reconstruct the file based on changes recorded in the journal receiver. Database Storage Management Save/Restore Journaling: Tables (files) Data Areas Data Queues IFS (stream files) Remote journaling SMAPP Commitment control ASPs, iASPs HSM Automated Storage Management Online disk balancing Save While Active Save Changed Objects Parallel Save & Restore Multiple objects, multiple tape drives BRMS - backup/recovery & tape automation Online Domino backup TCP/IP Security System Software Maintenance Virtual IP Route fault tolerance Inbound/outbound load balancing Immediate PTF apply - no IPL required No interfaces to OS kernel highly virus resistant Security auditing Chapter 3. Availability technology 19 iSeries journaling has evolved over time, as has the style of computing that the system supports. Journaling support is enhanced to include byte stream files (Integrated File System files), data areas, and data queues. Remote journaling was introduced to the system at V4R2. With remote journaling, journal receiver entries are replicated to a backup or remote system. Remote journaling can be setup to run in synchronous or asynchronous mode. When remote journaling is synchronous, a database update for the source system is not completed until the target system makes the journal entry in its receiver. Remote journaling can be used in conjunction with database replication for high availability. You can find more information about remote journaling in the redbook AS/400 Remote Journal Function for High Availability and Data Replication, SG24-5189. The system also provides a journal for security auditing purposes, as described under the bullet “Security” on page 21. –Commitment control Some applications involve multi-step transactions to update the database. It is imperative that you complete all steps within the transaction before you commit the database update. The iSeries provides commitment control for this transaction environment. Commitment control is an application-level function that defines the transaction boundary. It is used in conjunction with database journaling. In the event of a system failure, commitment control uses journal entries to “roll back” an entire transaction. Therefore, a partial update to database files is avoided. An example of the need for commitment control is a financial application that moves funds between accounts. In order for the transaction to be considered complete, the debit and credit of the accounts involved must both be reflected in the database.  Storage management –Auxiliary storage pools (ASP) iSeries single level storage treats all storage as one large virtual address space (this includes main store memory as well as disk). There is no concept of a disk volume or data set partition. However, the system provides the capability to separate this contiguous address space into smaller disk “pools” to make system backup and recovery faster and to provide Hierarchical Storage Management facilities. These pools are called auxiliary storage pools. Conceptually, each ASP on the system is a separate pool of disk units for single-level storage. The system spreads data across the disk units within an ASP. If a disk failure occurs, you need to recover only the data in the ASP that contains the failed unit. The user of ASPs can reduce system backup time. To do this, create ASP to include individual applications and data. A single ASP can then be backed up without impacting business operations while other applications that operate from different ASPs stay online. Introduced with V5R1, independent ASPs (IASPs) take the concept of ASPs further by making the ASP switchable between systems in a cluster. At V5R1, IASPs can contain only IFS objects. iSeries intends to support database objects in IASPs in the future. –Hierarchical Storage Management Hierarchical Storage Management (HSM) is a set of APIs supplied with OS/400. Beginning with V4R4, the iSeries Backup Recovery Media Services (BRMS) licensed program offers an HSM component. BRMS provides automated backup and recovery support for database and IFS files. It also provides automation for system recovery. 20 Clustering and IASPs for Higher Availability on the iSeries Server HSM moves data across a hierarchy of storage, allowing data that is not heavily used to move to less costly storage. Retrieval of the data is transparent to users and programs. When the object is referenced, BRMS retrieves it for the user or program. HSM also helps reduce system back up time, as seldom used data is moved out of the system ASP and can be saved outside the backup window used for daily saves of critical business data. –Automated storage management The iSeries server has long been known for its low cost of ownership. A contributing factor is that the iSeries server does not need a database administrator (DBA) to track storage utilization and worry about moving data around to balance or enhance disk subsystem performance. Automated storage management is also an availability feature in that the database does not need to be made unavailable to perform this type of maintenance. OS/400 storage management automatically spreads data across all available disk arms to balance disk arm utilization. It also automatically allocates additional storage as files, libraries, and other objects grow. There is no need to take the database or a file offline to extend its size. –Online disk balancing If a large number of disk drives are added at once, run the Start ASP Balance (STRASPBAL) CL command to redistribute data across the disk arms and rebalance arm utilization. There is no need to partition data sets or to move data between volumes as required with other databases to balance performance.  Save and restore OS/400 provides a very comprehensive set of save and restore capabilities. These capabilities include: –Save-while-active Save-while-active provides a means to save an object to tape while the system remains active. Any application using a file or library being saved while the system is active must temporarily stop processing before the save can occur. Save-while-active then establishes a checkpoint image of the object and begins the save to tape while the application resumes execution. An advantage to save-while-active is that the entire system does not need to be brought down for back up. We recommend that you end all subsystems to ensure any database updates are written from memory to disk before the save is initiated. –Save changed objects OS/400 keeps a description for every object that exists on the system. Within this description, there is a time stamp that records the last time the object is changed and when it is last backed up. OS/400 save commands use this time stamp to provide the ability to save only objects that have been changed since the last save to tape. This reduces the amount of data saved and the time required to perform a system backup. –Parallel save and restore OS/400 allows parallelism within the system save commands. A system with multiple tape drives can initiate several save commands in parallel. Use the include and omit parameters to direct saves for specific libraries to different tape drives. Use this same approach to restore system objects using the restore procedures. Chapter 3. Availability technology 21 –Backup Recovery and Media Services (BRMS) BRMS provides an automated means to manage tape libraries and to set up system save policies. Save policies can be setup for daily, weekly, and other schedules to ensure critical enterprise data is saved to tape media. BRMS tracks which system objects are saved and the date of the save, and reports objects that are not saved in the operation. BRMS creates a “recovery report”, which lists the steps required to restore a system in the event of an outage where the system must be recovered from backup media. BRMS uses the parallel save and restore support provided in OS/400.  TCP/IP iSeries servers support a full function TCP/IP communications stack. The support is built into TCP/IP to facilitate high availability computing in a network environment. A description of these functions follows. –Virtual IP iSeries support for virtual IP allows the system to assign an IP address without designating it to a physical hardware device. All IP traffic can be routed through this virtual address. Each virtual address can have more than one physical communications adapter and/or system behind it. This way, if a physical card adapter or system fails, traffic can be rerouted to maintain availability. A client can be transparently re-routed. There is no need to re-establish or reconfigure the link to the alternate system. Virtual IP can also be used for load balancing and to direct sessions across communications adapters in a system. This helps to evenly distribute traffic for workload management.  Security – With the well-known instances today of viruses and server hacking, to have a secure server that is not vulnerable to attack is a key component of availability. OS/400 has no open interfaces to the system kernel, which means the iSeries is highly resistant to hacking and viruses. The iSeries provides security auditing and uses system journaling support to log security entries. System security auditing can log activities with user profiles, objects on the system, and jobs.  System Software Maintenance – To achieve higher levels of availability when applying PTFs, the iSeries adopts a philosophy to apply PTFs immediately (if possible), and not require a system IPL for the PTF to take effect. 3.2.1 Clusters for high availability When business demands a system to be operational 24 hours a day, 365 days a year (24 x 365), a continuous availability solution is required. A viable solution for iSeries customers involves Cluster Resource Services (CRS). Cluster Resource Services is part of the OS/400 operating system and runs on each system in the cluster. CRS provides failover and switchover capabilities for systems used as database servers or application servers. When a system outage or a site loss occurs, the functions provided on a clustered server system can be switched over to one or more designated backup systems that contain a current copy (replica) of the critical resource. The failover can be automatic. Or the operator can control how and when the transfer takes place by initiating a manual switchover. Figure 3-3 shows a basic cluster. There are four node systems, A though D. The nodes are connected through a network. Systems A, B, and C are local to each other, and System D is at a remote location. 22 Clustering and IASPs for Higher Availability on the iSeries Server Figure 3-3 Basic cluster The cluster management tool controls this cluster from anywhere in the network. End users work on servers in the cluster without knowing or caring from which server their application executes. In the event of a failure, Cluster Resource Services provides a switchover. The switch causes minimal impact to the end user or applications running on a server system. Data requests are automatically rerouted to the new primary system. Multiple data replications of the same data are easily maintained. Clusters contain more than two nodes. A system's resilient data (replicated data) can be grouped together to allow different systems to act as the backup system for each group's resilient data. Multiple backup systems are supported. If a system fails, Cluster Resource Services provides the means to automatically re-introduce or rejoin systems to the cluster and to restore their operational capabilities. Hardware and software requirements for clusters Any iSeries model that can run OS/400 Version 4 Release 4 or later is compatible for cluster implementation. OS/400 V4R4 or later must be installed, and Transmission Control Protocol/Internet Protocol (TCP/IP) must be configured on iSeries servers to implement clustering. Purchase a cluster management package from a cluster middleware business partner to provide the required replication functions and cluster management capabilities. See Part 3, “Cluster middleware business partners” on page 227, for information on business partner solutions. 3.3 Cluster with replication technology Replication technology is the database’s ability to make a synchronized copy of data and objects from one system to another. On the iSeries server, this is achieved with journaling and commitment control. Customers who understand the need for highly available systems implement these features on their systems and in their applications. Cluster Management Remote location System D System C End-user System A System B Network Chapter 3. Availability technology 23 Journaling is the cornerstone of the high availability middleware provided by IBM HABPs. Journaling allows changes in the database to be recorded and stored. These changes can be transferred to the backup system by a communications method or using tape media. Commitment control is implemented at an application level. It provides transaction boundary points. When a point is reached, the transaction is committed to the database. In the event of a failure, any incomplete transactions can be rolled back to the last complete transaction. Incomplete transactions still need to be re-keyed on the backup machine, but this scenario considerably adds to the recoverability of the application. A few application providers have implemented commitment control in their applications. This position changes as the application providers deliver continuously available applications. 3.4 Cluster with switched disk Disk drives can be switched from one system to another (see Figure 3-4). Local access to the data is only available from the owning system. Figure 3-4 Switched disk cluster Some operating systems implement switched disk technology to improve the reliability from the single system model. Microsoft Cluster Services implements switched disk technology. With switched disk technology, if the processor fails, another processor complex takes over the disk and the associated database. This model is less expensive than dual systems because there is no duplication of disk units (DASD) and adapters. However, unless the hardware is unreliable, there is no significant difference between this and the single system model. What happens to the business transactions in the switched disk model? In general, the following actions occur:  The applications fail  A switch is made  The applications are restarted System B Processor System A Processor In the event of a processor failure, one processor takes over the other processor's disk unit. 24 Clustering and IASPs for Higher Availability on the iSeries Server If a switched system has on-line transaction processing (OLTP) applications and a failure occurs, there can be transactions that are only partially complete. To maintain database integrity, roll back the incomplete database transactions and restart the application. Re-key the incomplete transactions after the roll back completes. For non-OLTP based applications, whether standalone or server-based, there can be less of a problem, depending on when the user last saved their work. For example, there is less of an impact to the database for a typical word processor or spreadsheet user, because their transactions typically only affect their open files. Disruptions to OLTP applications are typically more pervasive and require additional capabilities in database functionality. The iSeries server implemented switched disk with OS/400 V5R1 technology. Refer to Chapter 4, “iSeries clusters explained” on page 31, for a further discussion. 3.5 Shared disk In a shared disk setup, disk drives are attached to multiple systems simultaneously. Local access is available from all systems sharing the disk. Figure 3-5 illustrates a shared disk cluster. The first design of shared disk technology allows every server to access every disk. This requires expensive cabling and switches, plus specialized operating system functions and specialized applications. Figure 3-5 Shared disk With today’s standards, such as small computer systems interface (SCSI), the need for expensive cabling and switches is eliminated. However, shared disk still requires specially modified applications. System B Processor System C Processor System A Processor Shared disk Lock Manager controls all of the system's access to disk blocks Chapter 3. Availability technology 25 In Figure 3-5, Systems A, B, and C are writing to and reading from the same disk. To manage this, the three systems have a form of DASD block management code. This code controls who has current access to a block of storage. In this example, System A currently has a lock on block 123. Then System B requests block 123 on the shared DASD. The lock manager asks System A to give up block 123. When System A gives up the block, the lock manager changes the ownership of block 123 to System B. System B now has control of the block and can write all over it. At any time, Systems C or A can request the block back or can compete for other blocks. The lock manager can reside on any or all of the three systems. IBM S/390 Parallel Sysplex successfully uses shared disk technology. This function has developed over time, with a significant investment in the system and applications to manage this function. The iSeries server does not implement true shared disk functions. Single level storage and symmetric multi-processing (SMP) have some analogies to shared disk, where multiple applications run on multiple processors and in one storage pool. The user does not have to be concerned about where the data resides. The system takes care of managing the data, spreading the data across all the disks. OS/400 also takes care of object lock and task management. There are more examples of the underlying iSeries functions that provide such high single system availability, largely taken for granted for many years. 3.6 Separate server In a separate server cluster or dual system environment, data and objects are replicated from one system to another (as illustrated in Figure 3-6). Figure 3-6 Separate server cluster The primary resources in the iSeries server are its processors, memory (main storage), I/O buses, and IOPs. Each logical partition represents a division of these resources in the iSeries server. Each partition is logical (as opposed to physical), because the division of resources is virtual. The sharing of resources offered in a cluster that is made-up of logical partitions is illustrated in Figure 3-7. Memory card Memory card LAN Adapter Card (redundant) LAN Adapter Card (active) Processor Card Memory card Memory card LAN Adapter Card (redundant) LAN Adapter Card (active) Processor Card Network System B Processor System A Processor Mirrored disks Mirrored disks 26 Clustering and IASPs for Higher Availability on the iSeries Server Figure 3-7 Cluster created by logical partitioning OS/400 is licensed once for the entire system by its normal processor group, regardless of the number of partitions defined. License management across partitions is not supported in OS/400 V4R4. Install OS/400 on each partition. Releases prior to V4R4 are not supported in a logical partition. Each logical partition operates as an independent logical system. Each partition shares a few physical system attributes such as the system serial number, system model, and processor feature code. All other system attributes can vary among partitions. For example, each partition has dedicated processors, main storage, and I/O device hardware. An LPAR solution does not offer a true failover capability for all partitions. If the primary partition fails, all other partitions also fail. If there are multiple secondary partitions backing each other up, a failover can occur between partitions. The secondary partitions are nodes and are a cluster solution. They are not a separate server implementation. An LPAR solution cannot provide the same level of availability as a two or more node cluster solution. 3.7 iSeries cluster middleware Cluster middleware is the name given to the group of applications that provide the replication and management of application data between iSeries servers and that provide cluster management utilities. The following cluster middleware providers offer data resiliency tools. Beginning with OS/400 V4R4, they are developing application resiliency offerings. Multiple LPAR Partitions OS/400 Primary Partition OS/400 OS/400 LAN IOP y IOP z Tape IBM SP MFIOP x Load Source IBM Tape CD IOP y LAN IOP z LAN CD IOP xyz Load Source Load Source IOP xyz Virtual OptiConnect* Secondary Partition Secondary Partition Node 1 Node 2 Tape Multiple Cluster Node 3 Nodes Chapter 3. Availability technology 27  DataMirror  LakeView Technology  Vision Solutions Refer to the Cluster Management GUI described in Part 3, “Cluster middleware business partners” on page 227, to learn more about the cluster middleware solutions that are available for the iSeries server. 28 Clustering and IASPs for Higher Availability on the iSeries Server © Copyright IBM Corp. 2000, 2002 29 Part 2 iSeries clusters and higher availability During the 1990s, the focus of information technology was server high availability and data resiliency. Data resiliency is when applications handle a copy of the data together with information about the currency of the data. While mirroring and RAID-5 increase the availability of the data source, data replication tools serve to enable a data resilient solution. However, solutions that focus only on data availability cannot be available every hour of the day. The focus must include the application and the data together. That is why clustering technology was introduced in V4R4. Switching between systems in a cluster requires application resiliency and transaction signalling, as well as data availability. Part 2 describes the components involved in the comprehensive solution for higher availability called iSeries clustering. Part 2 30 Clustering and IASPs for Higher Availability on the iSeries Server © Copyright IBM Corp. 2000, 2002 31 Chapter 4. iSeries clusters explained To explore the implementation of iSeries clustering, it is important to first understand iSeries clustering technology and capabilities. This chapter provides information that is fundamental to understanding what clustering is. It outlines the available methods to implement clustering and the reasons to invest in clustering. For those of you who are looking for a deeper understanding of clustering, the underlying technology is described in Appendix A, “Advanced clusters explained” on page 275. 4 32 Clustering and IASPs for Higher Availability on the iSeries Server 4.1 Cluster basics and definitions A cluster can be defined as a configuration or a group of independent servers that appear on a network as a single machine. Stated another way, a cluster is a collection of complete systems that work together to provide a single, unified computing resource. The cluster is managed as a single system or operating entity. It is designed specifically to tolerate component failures and to support the addition or subtraction of components in a way that is transparent to users. The major benefits that clustering offers a business are:  Continuous or high availability of systems, data, and applications  Simplified administration of servers by allowing a customer to manage a group of systems as a single system or single database  Increased scalability and flexibility by allowing a customer to seamlessly add new components as business growth develops Attributes normally associated with the concept of clustering include:  High availability and continuous availability  Simplified single system management  Scalability and flexibility  High-speed interconnect communication  Shared resources  Workload balancing  Single system image Sometimes horizontal support is referred to as load balancing. When a client job addresses a server in a cluster to get some work done, it is automatically directed to the server with less workload running at that time. Some application software packages running on the iSeries server can also accomplish load balancing. An example is SAP. 4.2 iSeries clustering OS/400 technologies provide a firm foundation for iSeries architecture. Clustering is the latest OS/400 improvement in iSeries technology for high availability. The clustering technology introduced with OS/400 V4R4 builds on legacy AS/400 availability support for single-systems, such as journaling, commitment control, mirroring, and OptiConnect. iSeries high availability is offered with clustering support, for example:  Peer relationships between cluster nodes help ensure no cluster-wide outage.  Heartbeat monitoring and efficient cluster communications provide low overhead internode processing and early detection of potential node outages. Important: It is important to note that there are several implementations or interpretations of what a cluster is. Different computer manufacturers have different cluster solutions. Most of these cluster solutions were designed to solve a limited horizontal growth in distributed systems. The design concept for iSeries clustering is that a number of systems closely coupled together can provide the capacity required for a growing business. Chapter 4. iSeries clusters explained 33  The distributed activity groups are used to synchronize activities and objects across cluster nodes.  Cluster engine services provide reliable, ordered messaging, and group membership services.  The job structure of Cluster Resource Services (CRS), interjob communications, and internode communications provide a single, consistent view of cluster nodes, and cluster resource status.  Through cluster partition handling, the system determines the difference between many failure and partition conditions without user intervention. The explanation of these concepts comprises the content of this redbook. OS/400 V5R1 provides key features to build the foundation for clustering support, as highlighted in 4.4, “OS/400 V5R1 clustering enhancements” on page 35. OS/400 clustering delivers a standard for transferring applications, and their associated data, programs, and users, from one iSeries to another. An iSeries clustering solution offers continuous availability to meet the operational business demands 24 hours a day, 365 days a year (24 x 365). The foundation for this solution, called OS/400 Cluster Resource Services, is part of the OS/400 operating system. CRS provides failover and switchover capabilities for iSeries servers that are used as database servers or application servers. If a system outage or a site loss occurs, the functions that are provided on a clustered server system can be switched over to one or more designated backup (idle standby) systems that contain a current copy (replica) of the critical resource. If a system failure should happen, the failover can be automatic. Or an operator can control how and when the transfer takes place by manually initiating a switchover. The iSeries cluster uses a separate server, as well as a shared-nothing model. That is, cluster resources are not physically shared between multiple systems, or critical resources can be replicated between nodes. The resource is accessible from other nodes by shipping function requests to the system that is currently hosting the resource of interest. At any given moment, each resource is owned, or hosted, by a single system. See Chapter 3, “Availability technology” on page 15, for a discussion of single-system availability options. 4.3 Why you want clustering Small outages, tolerated just a few years ago, can now mean a significant loss of revenue and of future opportunities for a business. The most important aspect of clustering is high availability, that is, the ability to provide businesses with resilient processes. A well-managed iSeries cluster can provide the highest levels of availability of any individual server in the industry. Clusters are a very effective solution for continuous availability requirements on an iSeries server, providing fast recovery for the widest range of outages possible, with minimal cost and overhead. 34 Clustering and IASPs for Higher Availability on the iSeries Server The concept of high availability in the sense of disaster recovery is an important consideration. However, disasters are not the only reason why high availability is so important. Disasters or unplanned outages account for only 20% of all outages. The majority of outages consists of planned ones, such as a shutdown to perform an upgrade or complete a total system backup. A relatively straightforward action, like the backup of databases and other objects, actually accounts for 50% of all planned outages. Some of you may think that a backup of the server is not an outage. But iSeries users are not interested in such technicalities. If access to their data on the system is not possible, the user is most concerned about when the system is available again so that work can continue. Actually, in many environments, any downtime creates a problem. According to one IBM study, the iSeries server averages 61 months between hardware failures. However, even this stellar record can be cause for availability concerns. Stated another way, 61 months between hardware failures means that nearly 67 percent of all iSeries servers can expect some type of hardware failure within the first five years. Such industries as health care and banking invest in redundant hardware and high-availability software solutions that minimize downtime by replicating the production environment on a backup system (an idle standby system). High availability of the system is also a big concern for e-business and Web-based solutions. Regardless of what causes an outage and whether it is a planned or an unplanned one, the users – or in some cases, the customers – only see the system as unavailable, with all of the consequences to the business that this can have. 4.3.1 Hidden benefits of iSeries clusters Clusters can be an efficient solution to availability issues, and in some situations, for server capacity and performance issues. Depending upon the availability requirements of a business, the backup iSeries server in a cluster can serve in an idle or an active mode:  Idle backup iSeries server As an idle backup, the only active workload on the backup iSeries server is the cluster middleware product. The idle backup server provides data replication and cluster management. In the event of an outage, the backup server stands ready for a switchover, to assume primary iSeries production processing responsibilities. Backup mode typically provides for the fastest recovery in the event of an outage on the primary iSeries server, since no time is required to manage or end the workload on the backup iSeries server.  Active backup iSeries server As an active backup, other work takes place on the backup iSeries server in addition to the cluster middleware. The active backup is productive throughout the day. By using replicated databases on the backup iSeries, “read only” types of workloads can be relocated to the backup iSeries to use the backup server’s available CPU and system resources. It is important that only “read only” work is performed against the replicated databases to avoid interference with the data replication processes. Functions that impact the availability, capacity, and performance of the primary iSeries server are candidates to be moved to the backup iSeries server. Chapter 4. iSeries clusters explained 35 For example, the active backup iSeries server can serve to: – Provide query, reporting, and inquiry capabilities at any time of the day Ad hoc queries, reporting, Web-enabled customer inquiry, and Business Intelligence can have an impact on the primary (production) iSeries server performance. You should move these types of jobs to the backup iSeries server to use its processing power and replicated databases, without impacting the primary iSeries server. – Perform system maintenance When the iSeries server is in a backup server role, system maintenance can be done without impacting business production. Examples of system maintenance include: • Nightly saves Even with fast, multiple tape drives and OS/400 save options, such as save-while-active, backup windows that require quiescing production work can become a problem. Use the data replicated to the backup iSeries so that the backup activity itself can be relocated to the backup server. This reduces the planned downtime on the primary iSeries server. • Perform PTF maintenance The backup iSeries server is available to assume production work, while the primary iSeries has regular PTFs applied. Return production work to the primary iSeries server once PTF maintenance is complete. This allows a minimal interruption to business. • Perform release updates or system upgrades The backup iSeries server can assume production work while the primary iSeries has its software (such as OS/400 and other licensed programs) upgraded to a new release, or when a hardware upgrade is performed. The data replication method of clustering supports a wide variety of versions and releases between systems, which can virtually eliminate the possibility that both systems must be upgraded at the same time. • Eliminate development and testing from the production iSeries server Periodically, an outage can occur due to application development and testing on the primary (production) iSeries server. Whether it is a planned or unplanned outage (such as accidental alteration or deletion of production data), it can be an outage that the business cannot tolerate. Assign application development and testing to the backup iSeries, where an outage does not immediately impact availability. The ability to use a backup iSeries server in a cluster for the capabilities mentioned in this section depends on the availability requirements, configurations, spare capacity, and performance of the backup iSeries server, and the training of operations staff on the clustering solution. You should work closely with a cluster middleware consultant or an IBM Integrated Technology Services (ITS) consultant during the design phase of the cluster to ensure that failover and switchover capabilities meet the objectives of the business. 4.4 OS/400 V5R1 clustering enhancements Clustering is an iSeries availability solution offered with OS/400 V4R4 and later. The functions and support added with V5R1 are listed in this section. 36 Clustering and IASPs for Higher Availability on the iSeries Server  Switchable independent auxiliary storage pools Independent auxiliary storage pools (IASP), also known as “switchable disk”, are described fully in Chapter 6, “Independent ASPs explained” on page 99.  Resilient cluster device A resilient cluster device is represented by a system object. It is a hardware resource that can be switched between systems in the event of a planned system outage or a unplanned system failure. The resilient cluster device available with OS/400 V5R1 is the IASP.  Device domain A device domain is a subset of cluster nodes across which a set of resilient devices can be “shared”. A device domain prevents conflicts that could cause resilient device switching to fail. The Resilient Cluster Device IASP can be active on one system at a time.  Simple Cluster Management GUI A Simple Cluster Management GUI interface is accessible through Operations Navigator. It is offered as Option 41 of OS/400. Use the IBM Simple Cluster Management GUI to create and manage a two-node, switched disk cluster. The GUI allows the user to create and manage a cluster that uses switchable IASPs to ensure data availability. Simple Cluster Management features a wizard that steps the user through the creation of a simple, two-node cluster. Additional cluster management can be accomplished using the Simple Cluster Management GUI to perform tasks such as to: – Add a node to an existing one-node cluster – Add a switchable hardware group to a cluster – Add a switchable software product to a cluster – Change the cluster description – Change the exit program name – Change the takeover IP address for a switchable software product – Delete a cluster – Start a cluster – Stop a clustering – Switch cluster resources from the primary node to the backup node – View messages relative to cluster activity Cluster performance tuning APIs are available for basic tuning of cluster operations, such as allowing the user to set the tuning parameters to a predefined set of values identified for high, low, and normal time-out and messaging intervals. Distribute Information The Distribute Information (QcstDistributeInformation) API provides a mechanism to send information from one node in the CRG recovery domain to other nodes in the recovery domain. This can be a useful mechanism to communicate application activity or to send small amounts of information related to the application to affected nodes. Cluster versioning A cluster version represents the level of function available on the cluster. Versioning is a technique that allows the cluster to contain systems at multiple release levels and fully interoperate by determining the communications protocol level to use. Chapter 4. iSeries clusters explained 37 See 5.3.3, “Cluster versions” on page 96, and A.2.6, “Cluster versions” on page 281, for a further discussion. Cluster partition improvements Improved handling and recovery for cluster partitions is offered with OS/400 V5R1. In addition to better detection of some failover conditions, Cluster Resource Services provides an easier way to change the status of partition nodes to failed. See A.2.5, “Cluster partition state” on page 279, for a further discussion. Example commands and exit program A set of example commands are provided in QUSRTOOL that can be used to create and manage a cluster in some environments. An example application CRG exit program is also included in the QUSRTOOL library. The sample source code can be used as the basis for writing an exit program. The tools in QUSRTOOL are meant for customers who want to create switchable applications and some advanced cluster functions. To create a simple cluster with switchable disks, the Simple Cluster Management GUI interface is sufficient. See 5.3, “Using QUSRTOOL CL commands and OS/400 APIs to implement an iSeries cluster” on page 87, for a further discussion. 4.5 Prerequisites for iSeries clustering The base functions for clustering are provided in V4R4 hardware. Clustering with switched disk support requires OS/400 V5R1 hardware. Therefore, the prerequisites for an iSeries clustering solution depend on IASPs and the type of IASPs that are to be implemented. Specifically, the prerequisites for clustering are:  Hardware – Two or more V4R4 systems or a logically partitioned system with a minimum of two partitions. For a logically partitioned system, each partition participating in the cluster must be at V5R1. – To support a switchable IASP in a standalone disk tower, V5R1 HSL adapter cards are required. Examples of adapters that support clustering include: • #7002 HSL Enabler • #2739/#9749 Optical Bus Adapter • #9691 Bus Adapter  Software – TCP/IP Connectivity Utilities (5722-TC1) – Client Access Express (5722-XE1) – OS/400 HA Switchable Resources (Option 41 of 5722-SS1) to support the Operations Navigator GUI or switched disks Note: Member TCSTINFO in the QUSRTOOL/QATTINFO file has more information on the cluster management commands. The TCSTAPPEXT member in the QATTSYSC file has an example exit program written in ILE C. 38 Clustering and IASPs for Higher Availability on the iSeries Server These prerequisites are identified in a Help panel of Operations Navigator clustering, as shown in Figure 5-6 on page 68. 4.6 Cluster Resource Services Cluster Resource Services is a component of OS/400. The functions provided by CRS are:  Tools to create and manage clusters, the ability to detect a failure within a cluster, and switchover and failover mechanisms to move work between cluster nodes for planned or unplanned outages.  A common method for setting up object replication for nodes within a cluster. This includes the data objects and program objects necessary to run applications that are cluster enabled.  Mechanisms to automatically switch applications and users from a primary to a backup node within a cluster for planned or unplanned outages. The iSeries clustering framework is built around a set of system APIs, system services, and exit programs. This clustering architecture calls for teamwork between IBM and Business Partners to provide the total solution. IBM clustering initiatives include alliances with cluster middleware business partners and independent software vendors (ISVs) and the development of standards for cluster management utilities. See Chapter 8, “ClusterProven for iSeries applications” on page 161, to understand these standards. 4.6.1 OS/400 integrated cluster services This section discusses the Cluster Resource Services provided within OS/400, as illustrated in Figure 4-1. Note: HSL OptiConnect (Option 23 of 5722-SS1) is not required for clustering or IASPs. It is required for system-to-system communication, for example, Distributed Data Management (DDM). Chapter 4. iSeries clusters explained 39 Figure 4-1 OS/400 integrated cluster services Message function The message function of Cluster Resource Services keeps track of each node in a cluster and ensures that all nodes have consistent information about the state of cluster resources. Reliable messaging uses retry and time-out values that are unique to clustering. These values are preset and can be changed with an API. The values are used to determine how many times a message is sent to a node before a failure or partition situation is signaled. For a local area network (LAN), the amount of time it takes to go through the number of retries before a failure or partition condition is signaled is approximately 45 seconds. For a remote network, more time is allowed to determine whether a failure or partition condition exists. Estimate approximately four minutes and 15 seconds for a remote network. See A.2.2, “Distributed activities” on page 277, for further information. Heartbeat monitoring Heartbeat monitoring ensures that each node is active. When the heartbeat for a node fails, the condition is reported so the cluster can automatically fail over resilient resources to a backup node. A heartbeat message is sent every three seconds from every node in the cluster to its upstream neighbor. In a network, the nodes expect acknowledgment to their heartbeat from the upstream node as well as incoming heartbeats from the downstream node, thus creating a heartbeat ring. By using routers and relay nodes, the nodes on different networks can monitor each other and signal any node failures. If a node fails or a break occurs in the network, heartbeat monitoring tries to re-establish communications. If communications cannot be reestablished within a designated time, heartbeat monitoring reports the failure to the rest of the cluster. See A.2.1, “Heartbeat and cluster communication” on page 276, for further information. Messages Heartbeat 9.99.99.01 9.99.99.01 IP takeover Services 40 Clustering and IASPs for Higher Availability on the iSeries Server IP takeover IP takeover is the ability of a backup system to take over the IP address of a primary system in case of a failure on the primary system. OS/400 cluster service jobs Cluster service jobs are a set of multithreaded jobs supplied with OS/400. When clustering is active on an iSeries, the jobs run in the QSYSWRK subsystem. The jobs run using the QDFTJOBD job description. Should any Cluster Resource Services job fail, no job log is produced. In order to provide a job log, change the LOG parameter of the job description to a logging level that produces job logs. See A.2.3, “Job structure for Cluster Resource Services” on page 278, and A.2.4, “Cluster engine services” on page 279, for further information. 4.6.2 Cluster Resource Services structure On the iSeries server, the clustering infrastructure is called Cluster Resource Services. Figure 4-2 shows the key elements of OS/400 Cluster Resource Services and their relationship. Figure 4-2 Cluster Resource Services structure The two boxes labeled Cluster Control and Cluster Resource Group Manager in Figure 4-2 represent OS/400 services that provide APIs. The APIs enable business partners, independent software vendors, and application providers to deliver a cluster management utility, data resilience through replication, and resilient (highly available) applications. The APIs are documented in System API Reference, SC41-5801, which is available from the iSeries Information Center at: http://publib.boulder.ibm.com/pubs/html/as400/onlinelib.htm Cluster Management Utilities Highly Available Applications Data Replication Applications APIs Cluster Control (CCTL) Cluster Resource Group Manager (CRGM) Cluster Engine (CLUE) Cluster Communications/Cluster Topology Services (CC/CTS) MI Chapter 4. iSeries clusters explained 41 Cluster control Cluster control provides configuration, activation, and management functions for the cluster and the nodes in the cluster. The cluster definition, configuration, and state information is maintained in a persistent internal object called a cluster information object. This object exists on each node in the cluster. Upon request, cluster control starts clustering on a node and coordinates the process of joining that node into the cluster. This process ensures that all nodes are equally aware of the action and have the same content in their cluster information object. Cluster control also manages the merging of cluster partitions. For further information, see A.2.5, “Cluster partition state” on page 279. Cluster Resource Group Manager Cluster Resource Group Manager provides object management functions to create, delete, and modify CRG objects. A CRG is an OS/400 object that defines and controls the behavior for a group of cluster resources across a recovery domain. Conceptually, the CRG is a distributed object. It exists on all nodes in the defined recovery domain. Each node in the recovery domain has a defined role of primary, backup, or replicate. The nodes in the recovery domain and their respective roles are defined in the CRG object. When a cluster event occurs that affects that CRG, a user-specified exit program is called on every active node in the recovery domain. A cluster event can add a node to the cluster, change a recovery domain, or cause a node to go offline. The CRG exit program is identified in the *CRG object. Since the exit program provides resource-specific processing for the cluster event, it can be considered the resource manager for the group of resources associated with that CRG. There can be many CRGs on a node, each potentially with a different recovery domain. The cluster control and Cluster Resource Group manager components use lower-level system services (OS/400 Licensed Internal Code) to ensure consistency, such that:  The content of all control objects are logically identical across the affected nodes.  Cluster activity is coordinated across the affected nodes. The two boxes labeled Cluster Engine and Cluster Communications/Cluster Topology Services in Figure 4-2 identify the functions that provide these system services. The Cluster Engine provides reliable group communications for the distributed processing needed by the other cluster components to achieve coordinated, distributed, and synchronized activity across multiple cluster nodes. The cluster engine services include group membership services and group messaging services. Most of the cluster engine is implemented below the Machine Interface (MI) to achieve high efficiency, better performance, and better integration with other communication components in the streams stack. See A.2.4, “Cluster engine services” on page 279, for further information. Cluster communications Cluster communications provides low-level internode communications support for the rest of the Cluster Resource Services. It implements the reliable first in, first out (FIFO) ordered multicast message that takes advantage of the IP multicast support of the underlying network when it is available. 42 Clustering and IASPs for Higher Availability on the iSeries Server This component guarantees that a multicast message is eventually delivered to all its targets, except in the case of failures. When cluster communications fails to deliver a message to a target (after exhausting all retry attempts and alternative paths), it considers the target node unreachable (failed or disconnected). In the case where the local node fails before completing a multicast message, there are no guarantees that all targets receive the multicast message. In addition to multicast messages, cluster communications also supports unreliable unordered messaging, reliable FIFO point-to-point messaging, and unreliable point-to-point messaging. The components used can define many multicast groups, dynamically modify membership of each multicast group, and refer to each multicast group via an identifier (for example, when sending messages). This allows cluster communications to plan message distribution and to maximize parallelism for processing unrelated multicast messages sent in the cluster. Cluster communications is implemented in the streams stack below the MI to achieve high efficiency, better performance, and better integration with other communication components. Cluster topology services Cluster topology services provides a cluster view over existing IP network connectivity. It maintains the knowledge of currently active cluster nodes and cluster nodes known to be partitioned. Two paths can be defined to each node in the cluster. The first path to the node specified on the cluster control API is considered the preferred (primary) path. A partition is the situation where the connection between nodes is lost, but none of the nodes fail. This situation is described in more detail in A.2.5, “Cluster partition state” on page 279. Cluster topology services continuously checks connectivity of the various network paths and allows a seamless switch to the alternative path when the preferred path is not available. It also allows a seamless switch back to the preferred path when it becomes available again. Cluster topology services periodically checks connectivity to partitioned nodes to see if connectivity is re-established. When successful, cluster topology services notifies cluster control and the cluster engine, which then attempt to merge partitions back into the cluster. Part of the continuous check performed by cluster topology services is heartbeating, which performs periodic checks on liveness and connectivity of the locally reachable cluster nodes and delivers failure notifications. When a previously connected node becomes unreachable, cluster topology services notifies the cluster engine. The cluster engine then removes the node from the locally visible cluster or declares a partition. For an in-depth discussion of the structure of OS/400 cluster services, refer to A.1, “Underlying technologies” on page 276. 4.7 Cluster components A cluster is made of these elements:  Cluster nodes  Cluster resources  Recovery domains  Cluster management support and clients These elements are illustrated in Figure 4-3 and explained in the following sections. Chapter 4. iSeries clusters explained 43 Figure 4-3 Components of clustering 4.7.1 Cluster nodes A cluster node is any iSeries server or partition that is a member of a cluster. Cluster nodes must be interconnected on an IP network. A cluster node name is an eight-character cluster node identifier. Each node identifier is associated with one or more Internet Protocol (IP) addresses that represent an iSeries server. Any name can be given to a node. However, for simplicity, make the node name the same as the system name. Cluster communications that run over IP connections provide the communications path between cluster services on each node in the cluster. The set of cluster nodes that are configured as part of the cluster are referred to as the cluster membership list. A cluster consists of a minimum of two nodes. The environment can be extended to a cluster with a maximum of 128 nodes. A node of a cluster can fill one of three possible roles within a recovery domain, as shown in Figure 4-4. The roles and associated functions are:  Primary node – Point of access for resilient device – Contains principal copy of any replicated resource – Current owner of any device resource – All CRG objects fail over to a backup node  Backup node – Can take over the role of primary access at failure of the current primary node – Contains copy of cluster resource – Copies of data are kept current via replication Cluster Resources Recovery Domains N o d e A A A Nodes Resources Recovery domains Management support and clients Cluster management Cluster 44 Clustering and IASPs for Higher Availability on the iSeries Server  Replicate node – Has copies of cluster resources – Unable to assume the role of primary or backup (typically used for functions such as data warehousing) Figure 4-4 Cluster nodes 4.7.2 Cluster Resource Groups (CRG) A Cluster Resource Group is an OS/400 external system object that is a set or grouping of cluster resources. The Cluster Resource Group (and replication software) is a foundation for all types of resilience. See Figure 4-5 for an illustration. Figure 4-5 Cluster Resource Group N o d e 3 possible roles for a node: Primary Backup Replicate node CRG A CRG A CRG A CRG B CRG B CRG B CIO CIO CIO CIO CIO Cluster Resource Group Single resource view across nodes Data Resilient CRG (type-1) Application Resilient CRG (type-2) Device Resilient CRG (type-3) Chapter 4. iSeries clusters explained 45 Resources that are available or known across multiple nodes within the cluster are called cluster resources. A cluster resource can conceptually be any physical or logical entity (database, file, application, device, and so forth). Examples of cluster resources include iSeries objects, IP addresses, applications, and physical resources. The objects labeled CRG A and CRG B in Figure 4-5 represent cluster resources. When a cluster resource persists across an outage, that is any single point of failure within the cluster, it is known to be a resilient resource. As such, the resource is resilient to outages and accessible within the cluster even if an outage occurs to the node currently “hosting” the resource. Cluster nodes that are grouped together to provide availability for one or more cluster resources are called the recovery domain for that group of cluster resources. A recovery domain can be a subset of the nodes in a cluster, and each cluster node may actually participate in multiple recovery domains. Resources that are grouped together for purposes of recovery action or accessibility across a recovery domain are known as a Cluster Resource Group. The Cluster Resource Group defines the recovery or accessibility characteristics and behavior for that group of resources. A CRG describes a recovery domain and supplies the name of the Cluster Resource Group exit program that manages cluster-related events for that group. One such event is moving the users from one node to another node in case of a failure. There are three Cluster Resource Group object types that are used with Cluster Services at V5R1:  Data resilient: A data resilient CRG enables data resiliency, so that multiple copies of data can be maintained on more than one node in a cluster.  Application resilient: An application resilient CRG enables an application (program) to be restarted on either the same node or a different node in the cluster.  Device resilient: A device resilient CRG enables a hardware resource to be switched between systems. The device CRG is represented by a (device) configuration object as a device type of independent ASP (IASP). Device resilient CRGs are supported with OS/400 V5R1. Each CRG definition object specifies the cluster exit program to be called. The exit program is responsible for handling the action codes passed to it by the Cluster Resource Group Manager. Action codes are managed in the APIs that interact with the applicable CRG. And the Cluster Resource Group exit program manages the movement of the access point of a resilient resource. Exit programs are written or provided by high availability business partners and by cluster-aware application program business partners. See 4.7.5, “Exit programs” on page 47, for a further discussion. 4.7.3 Recovery domains A recovery domain is a subset of nodes in the cluster that are grouped together in a Cluster Resource Group for purposes such as performing a recovery action. Each Cluster Resource Group has a recovery domain that is a subset of the nodes in the cluster. See Figure 4-6 for an illustration. 46 Clustering and IASPs for Higher Availability on the iSeries Server Figure 4-6 Recovery domain Here are some facts about recovery domains:  The nodes within a recovery domain participate in any recovery actions for the resources of the domain.  Different CRGs may have different recovery domains.  As a cluster goes through operational changes (for example nodes end, nodes start, nodes fail), the current role of a node may change. Each node has a preferred role that is set when the CRG is created.  A recovery domain can be a subset of the nodes in a cluster, and each cluster node may participate in multiple recovery domains. 4.7.4 Device domains The construct known as a device domain (Figure 4-7) is a subset of cluster nodes that share a set of resilient devices. A resilient device might be an independent ASP. A function of a device domain is to prevent conflicts that would cause the failure of an attempt to switch a resilient device between systems. Resources involved in a device domain include the structures used to identify and manage the content of the structures across the multiple systems involved in the domain. These structures are described in Chapter 6, “Independent ASPs explained” on page 99. CRG A CRG A CRG A CRG B CIO CIO CRG B CIO CRG B CIO CIO Recovery Domains Chapter 4. iSeries clusters explained 47 Figure 4-7 Device domain 4.7.5 Exit programs The main purpose of exit programs (Figure 4-8) is to “tell” each node in the cluster what to do in case of a failure on the primary system. Figure 4-8 Exit program Direct Attached Switchable Disk IASP iSeries iSeries ? ? ? Called when changes occur in the recovery domain Specify which action to take on the other nodes Exit program 48 Clustering and IASPs for Higher Availability on the iSeries Server When a change occurs in the recovery domain, the exit program associated with the CRG is called on all the active nodes in the recovery domain. Changes range from a system failure to a planned switchover from one system to another, to the addition of a new node to the recovery domain. The exit program is also called when other events happen, such as when the CRG is started or ended or when an exit program fails. When an exit program is initiated, OS/400 passes the program an action code indicating the event that caused the program call. Exit programs with data CRGs An exit program associated with a data CRG must ensure that as much data as possible (for example, any final journal entries) is transferred to the backup system in the event of a switchover. On the backup system (the new primary system), all outstanding journal entries must be applied. Any other objects must be synchronized as well. When a new node is added to a recovery domain, the exit program may handle the initial data replication. For example, when a switchover is initiated for a data CRG, the cluster middleware software for data replication writes any remaining journal entries to the backup system. (Remote journaling eliminates this step). Then, when the exit program is called on the backup system (changing its role to primary), the cluster middleware software applies any outstanding journal entries and synchronizes the non-database objects. The software establishes tasks to replicate data from the new primary system to the next backup node, if necessary. Cluster middleware providers are committed to enhancing their products to use the new clustering support (for example, to call the appropriate functions from the exit program), which lets them take advantage of system services such as heartbeat monitoring. In most cases, a cluster middleware provider supplies data CRG exit programs that take care of all the functions mentioned previously. This means that when a customer wants OS/400 functions combined with data replication, the link between these is already provided. Exit programs with application CRGs Exit programs associated with application CRGs are particularly critical, because the application must be restarted on the backup system. OS/400 supplies the exit program with information about the node status change, but all application-specific details, such as current users, record pointers, and even which programs are active, must be handled by the application developer. 4.8 Cluster implementation example To illustrate the concepts described in this chapter thus far, this section provides examples of cluster implementation: a simple two-node cluster and a four-node cluster. 4.8.1 Simple two-node cluster example For this simple cluster example, there is a cluster named WINTER with two cluster nodes, named SNOW and COLD. See Figure 4-9 for an illustration. Note: It is not mandatory for a device CRG to have an associated exit program. It is for application and data CRGs. Chapter 4. iSeries clusters explained 49 Figure 4-9 Simple two-node cluster Node SNOW operates as the primary node for two Cluster Resource Groups called CRG A and CRG D. CRG A is an application Cluster Resource Group. CRG D is a data Cluster Resource Group. Node COLD is the first (and only) backup for both of the luster resource groups. Data that is associated with CRG D and pertinent application information associated with CRG A are replicated from the node named SNOW to the node named COLD. If Node SNOW fails or needs to be taken down for administrative reasons, then Node COLD becomes the primary node for both Cluster Resource Groups CRG A and CRG D. Node COLD takes over the Internet Protocol address defined for CRG A. 4.8.2 Four-node mutual takeover cluster example A four node example shows the additional flexibility that is possible with an iSeries cluster. In this example, there are two Application Cluster Resource Groups (CRG A1 and CRG A2) and two Data Cluster Resource Groups (CRG D1 and CRG D2). The data associated with CRG D1 is the critical data for the application associated with CRG A1. The data associated with CRG D2 is the critical data for the application associated with CRG A2. See Figure 4-10 for an illustration. Note: While Node SNOW is down, system availability is exposed because there is no backup if Node COLD also fails. When Node SNOW recovers and rejoins the cluster, it becomes the backup for both Cluster Resource Groups. At that time, replication is from the node named COLD to the node named SNOW. To make SNOW the primary node, perform an administrative switchover. SNOW COLD One way replication and failover. Two-tier environment. Applications and data move together. Backup used for off line processing of data. CRG D CRG A CRG A CRG D WINTER 50 Clustering and IASPs for Higher Availability on the iSeries Server Figure 4-10 Four-node mutual takeover cluster Because this is a three-tier environment, the applications exist on the second tier (Node SNOW and Node COLD) and the data is separated into the third tier (Node RAIN and Node WIND). For CRG A1, Node SNOW is the primary and Node COLD is the backup. At the same time, Node COLD is the primary for CRG A2 and Node SNOW is its backup. For CRG D1, Node WIND is the primary and Node RAIN is the backup. Also, Node RAIN is the primary for Data CRG D2 and Node WIND is its backup. This enables mutual take over capability at both the application and data levels. All four nodes are used for normal production. The nodes are also used to back up other systems in the cluster. The two applications and their associated data would always be available in this cluster. The outage of any single node does not disrupt availability. In addition, the simultaneous outage of a node at the application level with a node at the data level does not disrupt availability. You can find further examples in Chapter 10, “Sample cluster environment and applications” on page 183. 4.9 Resiliency To achieve continuous availability, more than robust system availability is needed. Critical data and critical applications must also be resilient to outages. A complete resiliency solution is achieved when the critical data and the critical applications are made to be resilient resources and are always available. Two-way replication and failover; three-tier environment. Applications and data move independently. Backup used for normal production of different workloads. COLD CRG A1 CRG A2 CRG D1 CRG D2 CRG D1 CRG D2 CRG A1 SNOW CRG A2 RAIN Application Data Four production systems WIND Chapter 4. iSeries clusters explained 51 Clustering depends on two interrelated concepts: data resiliency and application resiliency. Both must be accessible across the cluster even when the normal hosting system for the resource fails Data resiliency ensures that the backup system has all the information necessary to run critical production jobs when control is transferred from the primary system. Data resiliency requires synchronizing objects across the nodes in the Cluster Resource Group. Cluster middleware business partners have many tools to deliver iSeries data resiliency. IBM supports the business partner tools rather than to create a contending data resiliency solution. Existing high-availability solutions synchronize data files, programs, and related objects such as data areas, job queues, and user profiles. The cluster middleware solutions use a combination of custom applications and OS/400 functions (for example, remote journaling). All these functions are needed to support clustering. A solution that focuses only on data cannot be available 24 x 365. Switching between systems requires application resiliency and transaction signalling. This is why clustering technology was introduced at V4R4 and why the focus is now expanded to include the application and the data together in a comprehensive solution called the cluster. Application resiliency ensures that the services provided by the application are accessible to end users of the cluster. Resilience is provided through an IP address takeover and a restart of the application on the backup system. Application resiliency can be defined as the ability to run an application on more than one node in a cluster. Ideally, when an application switches from one node to another, the user experiences no disruption at all and is not even aware that the job has been switched to a different server. Realistically, the disruption the user experiences can range from a slight delay to an extensive application restart. The user may have to sign on to the new server, restore or resynchronize data, restart the application, and re-enter any partially completed transactions. The more resilient an application is, the more this disruption is minimized. For a full discussion of application resiliency, see Chapter 8, “ClusterProven for iSeries applications” on page 161. 4.9.1 Data resiliency in a simple two-node cluster example Figure 4-11 shows an example of a cluster with two nodes: SNOW and COLD. SNOW is the primary machine. The Data CRG “D” represents data resiliency. Data objects are replicated between the two systems. 52 Clustering and IASPs for Higher Availability on the iSeries Server Figure 4-11 Data resiliency in a simple two-node cluster Figure 4-12 illustrates what happens in the event of a failure at Node SNOW. Figure 4-12 Failure in a simple two-node cluster When Node SNOW encounters a failure, Node COLD must take over as the primary node. Note: In either instance, the cluster runs exposed in that some cluster resources are not replicated while a node is down. Resolve this by having more than one backup for any critical cluster resource. SNOW COLD CRG D CRG D Data Data CRGs represent data resiliency Data objects are replicated between systems Data Replicated objects SNOW COLD CRG D CRG D When SNOW becomes inactive, COLD must assume a current node role of primary No replication takes place Replicated objects Assume that SNOW encounters a failure Chapter 4. iSeries clusters explained 53 4.9.2 Application resiliency and IP address takeover example Figure 4-13 shows an example of a cluster with two nodes. The WINTER_cluster has data resiliency, meaning that data is available at both systems. In this case, production jobs can run on the backup system (COLD) in case of a failure at the primary system (SNOW). The level of resiliency beyond data resiliency is application resiliency. Application resiliency means that the application can transfer the user to the backup system in case of a failure in the primary system. An important feature in application resiliency is IP takeover. Figure 4-13 illustrates a setup for an IP address takeover. The client uses an IP address associated with an application CRG. The IP address specified in the CRG must not be in use on any other node in the cluster. In this example, the TCP/IP interface with the same address as that of Node SNOW is inactive on Node COLD, the backup system. The IP address is started on the node that has the current role of primary for the application CRG. Figure 4-13 Application resiliency and IP address takeover in a simple two-node cluster 4.9.3 Managing application resiliency Figure 4-14 illustrates what happens to the user in case of a failure at the System (Node) named SNOW. This is an example of application resiliency and IP takeover after failover processing is complete. Node SNOW fails, and Node COLD assumes the role of primary. The TCP/IP interface 1.3.22.114 is now active on Node COLD, and the users are switched to Node COLD. When Node SNOW is back up again, objects are replicated from Node COLD (temporarily the primary system) back to Node SNOW. WINTER (Cluster)   1.3.22.406 1.3.22.407 1.3.22.322 1.3.22.323 SNOW COLD 1.3.22.114 (Inactive) IP Address Takeover 1.3.22.114 (Active) Note: In this case, the risk involved in a failure at Node COLD is a concern, because it has no backup and no data is being replicated from Node COLD to another backup machine. 54 Clustering and IASPs for Higher Availability on the iSeries Server Figure 4-14 Application resiliency and IP address takeover after a failure Once replication is finished to the point where the two nodes are in sync, another cluster node operation can switch the users back to run on the node named SNOW, to again become the current primary. 4.9.4 ClusterProven applications A ClusterProven application is one that allows the user be switched automatically to the backup system in case of a failure on the primary system. It also lets the user resume work in the same screen the user was working in at the primary machine. To understand ClusterProven applications for the iSeries server, refer to Chapter 8, “ClusterProven for iSeries applications” on page 161. 4.10 iSeries cluster solution components The infrastructure of clustering support is comprised of several functions. These universal functions involve:  Support to enable the base means of clustering, to define the: – Cluster – Cluster membership list – Means to access each cluster node Important: Application resiliency is important. It is equally important to recognize that in order to obtain continuous availability, the applications have to be designed in a way that allows them to return to their previous known failure state. In other words, the job state and the application state have to be maintained. WINTER (cluster)   1.3.22.406 1.3.22.407 1.3.22.322 1.3.22.323 Node SNOW Node COLD SNOW Active COLD Active Internal Object SNOW Inactive COLD Active Internal Object BLIZZARD ACTIVE PRIMARY SHOVEL ACTIVE PRIMARY 1.3.22.114 (Active) Chapter 4. iSeries clusters explained 55  Support for groups of nodes to: – Define groups of cluster resources – Manage groups of cluster resources – Ensure node accessibility – Determine when an outage occurs – Distribute information or messages across groups of cluster nodes  Support for the infrastructure of clustering to: – Ensure that internal cluster information and external objects are synchronously updated across all affected cluster nodes Figure 4-15 illustrates the components of an iSeries total cluster solution. Figure 4-15 iSeries cluster solution components For a total iSeries clustering solution, note these points:  Data resiliency is provided by data replication solutions from cluster middleware providers or switched disk technology.  Application resiliency is provided by highly available ClusterProven™ applications from ISVs.  Cluster management is performed with a GUI management interface from a cluster middleware provider or within IBM in OS/400 V5R1.  Cluster Resource Services are provided by IBM in OS/400. Notice the inclusion in Figure 4-15 of various cluster middleware business partners. The interdependent relationships between IBM, cluster middleware providers, and application developers are central to the rollout of clustering with OS/400. Each participant's role is clearly defined in 11.6, “Roles and responsibilities when implementing clustering” on page 211. Base OS/400 Cluster Functions Highly Available ClusterProvenTM Applications from ISVs Cluster Resource Services Cluster Management Data Resiliency Application Resiliency APIs Data or Device CRGs Application CRGs Architected Relationship Switched Disk Technology GUI Management Interface tools Data Replication Technology from Cluster Middleware Providers or 56 Clustering and IASPs for Higher Availability on the iSeries Server 4.11 iSeries clusters: Cluster architecture versus data replication Although it is possible to build a “cluster like” environment without taking advantage of the ClusterProven Architecture and ClusterProven Applications, it is much more difficult. For example, when building the business clustering environment, you must: 1. Select a tool to replicate critical data from the production system to the backup system. Replication tools are available from one of the IBM cluster middleware business partners, DataMirror, Lakeview Technology, or Vision Solutions. See Part 3, “Cluster middleware business partners” on page 227, for a discussion of these solutions. 2. Assuming the physical environment is prepared (that is, a backup server is installed and connectivity is established), determine what needs to be replicated to the backup system. This requires a thorough knowledge of the application design. This can be a very complex task that can take a long period of time. In fact, often times it is a work in progress as time goes on. Because of this, the integrity and reliability of the High Availability environment can be jeopardized. Do not be fooled. This is a part of the project that can take weeks, even months, to complete. 3. Ensure that everything to be replicated is journaled. If not, create the journal environment and begin journaling on those files and objects. With journaling, the cluster middleware product knows what objects to replicate, based on the changes made. 4. Synchronize data between the systems. 5. Replicate the data. The project is not done at this point. There is plenty more to do to create a “cluster like” environment. For example, you need to perform these tasks:  With data replicated to the backup system, in both planned and unplanned situations, programs are needed to switch the users from the production system to the backup system.  Programs are needed to restart the application following a switch.  In an unplanned scenario, a manual process must be in place to determine what transactions are lost and never make it to the backup system.  Depending on the application, some manual steps can be needed to restart the application and to determine where certain processes should begin.  Implement monitors for the production system to alert the operator of a failure of the system. The operator can then determine if a switch is necessary. A clustering solution with replication services has the architecture for automatic failovers. Use replication services to avoid a need for operator (manual) intervention for a switchover. Therefore, as described, it is possible to create a “cluster like” environment. However, to build the final solution around the data replication involves a lot of work. That is the fundamental difference between a “cluster like” environment and iSeries clusters. iSeries cluster architecture takes the tasks that otherwise would be built and maintained in-house, and makes them part of the architecture. That is:  An application that is ClusterProven provides the cluster middleware providers with all of the objects the application needs replicated. Chapter 4. iSeries clusters explained 57  Functions to monitor the cluster are provided.  There is a GUI environment to manage the clusters in the entire enterprise rather than switching between character-based screens on each system.  All of the processes to restart the application are provided via application CRG exit programs. Stated another way, IBM works with the cluster middleware providers and ISVs to make a customer’s HA environment more reliable by moving critical function out of user-written high-level language (HLL) programs and into OS/400. These relationships will continue to grow to enhance and strengthen the cluster architecture, which in turn, makes the HA environment more manageable and reliable. 58 Clustering and IASPs for Higher Availability on the iSeries Server © Copyright IBM Corp. 2000, 2002 59 Chapter 5. Implementing and managing clusters with IBM solutions IBM and IBM Cluster Middleware Business Partners team together to provide state-of-the-art Cluster Resource Services functions, along with a graphical user interface (GUI) for cluster management. This relationship is illustrated in Figure 5-1 and further described in this chapter. Figure 5-1 iSeries cluster implementation open architecture OS/400 Cluster Resource Services (CRS) provides a set of integrated capabilities to maintain cluster topology, perform heartbeating, and create and administer cluster configuration and Cluster Resource Groups (CRGs). CRS provides reliable messaging functions that keep track of each node in the cluster, and ensure that all nodes have consistent information about the state of cluster resources. In addition, Cluster Resource Services provides a set of application program interfaces (APIs) and facilities that can be used by iSeries application providers and customers to enable cluster architecture and enhance application availability. A set of clustering commands is provided in the QUSRTOOL library. QUSRTOOL library is shipped as part of OS400 V5R1. For each clustering API available with OS/400, there is a corresponding cluster command available in the QUSRTOOL library. 5 OS/400 Cluster Resource Services OS/400 APIs Cluster Middleware Replication Services ISV Application 60 Clustering and IASPs for Higher Availability on the iSeries Server The QUSRTOOL cluster commands are most useful in simple clustering environments. With the commands available in QUSRTOOL, a customer can easily set up a cluster to test cluster enabled applications. This chapter describes the steps necessary to create and manage clusters. The discussion covers the IBM-supplied methods available with OS/400 V5R1 – the GUI that is part of Operations Navigator and the cluster APIs and commands that are provided in the QUSRTOOL library. 5.1 Using the Operations Navigator GUI or commands, APIs to implement, manage iSeries clusters Either the Operations Navigator GUI, or commands and OS/400 APIs, can be used to implement and control iSeries clusters. Each method has its positive and negative aspects. Consider these points to help determine the better solution for clusters on the iSeries server:  The Simple Cluster Management GUI is the easiest interface to create simple clusters. A two-node cluster can be created with the Operations Navigator GUI. Switchable resources can be added to the cluster and the resources can be managed. The status of a cluster can be determined with minimum effort with the GUI. And the GUI supports a switchover function.  The clustering APIs and the commands supplied with QUSRTOOLS are more effective when clustering needs extend beyond a simple two-node cluster environment. Consider the Cluster APIs or commands supplied with QUSRTOOL library when clustering needs are more complex. The APIs and QUSRTOOL commands allow the user to create up to 128 nodes and create and manage CRGs. Device domains can have resilient switchable devices.  Use a high availability business partners clustering implementation when cluster requirements and the configuration are more complex. Managing a complex cluster can be time consuming. The more complex the cluster configuration and requirements are, the more high availability replication is warranted. The cluster middleware providers offer sophisticated cluster management tools to create and manage a complex multi-node cluster with less effort than using APIs and commands, or GUI. Refer to Part 3, “Cluster middleware business partners” on page 227, for a description of the cluster middleware providers offerings for cluster management on the iSeries server. For a quick comparison, the basic functions of cluster support are listed in Table 5-1. Note: Cluster middleware solutions are the preferred method to implement a more advanced clustering solution. Note: For more information, you can find a cross-reference of the QUSRTOOL command name with the corresponding clustering API in B.3, “Cluster APIs and related QUSRTOOL commands” on page 286. Chapter 5. Implementing and managing clusters with IBM solutions 61 Table 5-1 Clustering functions In effect, API usage is not for the ordinary user. A GUI interface is necessary to manage IASPs. And the best solution when data and application resiliency are the goal, is to either develop code in-house, or implement an application business partner offering. If a simple two-node cluster is created with the Simple Cluster Management GUI, continue using the GUI for all activity related to that cluster. Do not attempt to use the APIs and QUSRTOOL commands to further enhance the cluster. Similarly, if the APIs or QUSRTOOL commands are used to create a more complex cluster, do not attempt to manage or enhance the cluster using the Simple Cluster Management GUI. The GUI tool often combines multiple steps completed with a simple click of a mouse. Many functions are “hidden” by the IBM GUI actions. If a business partner solution is selected, do not attempt to manage or enhance the cluster using the Simple Cluster Management GUI or the QUSRTOOL commands. Unpredictable results can occur when mixing the GUI with cluster APIs and QUSRTOOL commands. IBM does not provide support for problems encountered in this circumstance. 5.2 Using the Operations Navigator GUI to implement and manage iSeries clusters When switched disk is used, the GUI interface of Operations Navigator is the recommended interface to manage a cluster of two iSeries’ servers. The other supported interface is described in 5.3, “Using QUSRTOOL CL commands and OS/400 APIs to implement an iSeries cluster” on page 87, and 5.3.1, “Using OS/400 cluster management APIs to implement a cluster” on page 93. The basic steps to implement a simple cluster using Operations Navigator GUI are: 1. Complete the environment plan. 2. Set up the communications environment for the cluster. 3. Start Management Central. 4. Create the cluster. Clustering function OS/400 cluster APIs Operations Navigator cluster GUI Create cluster Yes Yes Add application CRG Yes Yes Add data CRG Yes No Add device CRG (switchable hardware) Yes Yes Manage clusters Limited Application and device management. Not data. Extensive help text No Yes Managed nodes 128 2 Wizards No Yes Important: Whatever option is selected to implement a clustering solution, do not mix methods. 62 Clustering and IASPs for Higher Availability on the iSeries Server The steps are explained in this section. You can find more details on step 3 in “IBM Simple Cluster Management GUI considerations” on page 64. You can also find more information on step 4 in 5.2.2, “Using the Simple Cluster Management GUI to create the cluster” on page 64. Completing the environment plan To develop a plan to prepare the environment for clustering, consider these success factors:  Clearly state the objectives of clustering. Make sure that there is a well-defined plan to implement the cluster.  Identify which nodes are to be in the cluster.  Be certain that the required prerequisite software is loaded on both systems to be in the cluster. Refer to 4.10, “iSeries cluster solution components” on page 54, to understand the software requirements for an iSeries clustering solution.  Ensure that user profiles exist on all nodes that are to be in the cluster. The user profile must incorporate *IOSYSCFG authority. Setting up the communications environment for the cluster Prior to implementing a cluster solution, document all system names and IP addresses of the nodes to participate in the cluster. To set up the communications environment for the cluster, follow these steps: 1. Start the TCP/IP servers Internet Daemon (*INETD) and Management Central server (*MGTC). 2. Change the Allow Add to Cluster (ALWADDCLU) network attribute to *ANY or *RQSAUT. Starting Management Central To enable cluster management from Management Central, you must complete these actions: 1. Change the Central System in Management Central to be one of the nodes to participate in the cluster. 2. Use Operations Navigator to define both nodes as valid connections. Using the Simple Cluster Management GUI to create the cluster Follow these steps: 1. Proceeding through the GUI, read all screens carefully and fully. 2. If error screens are encountered, click the Details button. 3. Follow the suggestions mentioned in the error text. Errors are typically easily fixed and a “try again” option is provided after the error is answered. Note: *ANY means that any other system is allowed to add this system as a node in a cluster. *RQSAUT means that after an exchange of digital certificates is done to validate the cluster add request, another system is allowed to add this system as a node in a cluster. Note: The central system is typically the primary node in the cluster, but is not required to be so. Chapter 5. Implementing and managing clusters with IBM solutions 63 5.2.1 Clustering configuration tasks To prepare for configuring simple clusters with the Operations Navigator GUI, it is helpful that certain conditions exist in the iSeries setup and configuration. Prior to creating a cluster, make sure the tasks in these checklists are completed. TCP/IP requirements __1.TCP/IP must be started on every node chosen to be in the cluster (STRTCP). __2.Configure the TCP loopback address of 127.0.0.1. It must show a status of Active. Use the Network Status command (NETSTAT) to verify this on every node in the cluster. __3.The IP addresses used for clustering to a given node must show a status of Active. Use NETSTAT to verify this on the status of the subject node. __4.All cluster IP addresses must be defined with contiguous-bit subnet masks. The subnet address must be the same for each node of the cluster. That is, each IP address participating in the cluster must have the same subnet mask. __5.The status of the QUSER user profile must be enabled. __6.TCP Server *INETD must be active on all nodes in the cluster (STRTCPSVR *INETD). Verify this by checking for a presence of a QTOGINTD (user QTCP) job in the Active Jobs list on the subject node. *INETD provides a port in the TCP connection list that “listens” for various clustering functions. __7.The local and any remote nodes must be able to PING using the IP addresses used for clustering to ensure network routing is active. __8.Ports 5550 and 5551 are reserved for IBM clustering and must not be used by other applications. Use the NETSTAT command to view the port usage. Port 5550 is opened by clustering and is in a “Listen” state once *INETD is started. Resilient device requirements __1.If resilient devices are to be switched between logical partitions on a system, enable Virtual OptiConnect for the partitions. This is done at the Dedicated Service Tools (DST) signon. __2.If a tower on an HSL loop is switched between two systems, and one of the systems has logical partitions, enable HSL OptiConnect for the partitions. This is done at the Dedicated Service Tools (DST) signon. __3.When switching resilient devices between logical partitions that are on a system bus, configure the bus as “own bus shared” by one partition. Configure all other partitions that participate in the device switching as “use bus shared”. __4.When switching a tower on a HSL loop between two different systems, configure the tower as switchable. __5.When a tower is added to an existing HSL loop, all systems on that same loop must be restarted. __6.Install OS/400 Option 41 (HA Switchable Resources) on all cluster nodes to be in the device domain. __7.A valid license key must exist on all cluster nodes to be in the device domain. Note that any use of the IBM Simple Cluster Management GUI requires this option. Security requirements __1.The Allow Add to Cluster (ALWADDCLU) network attribute must be appropriately set on the target node if trying to start a remote node. Set ALWADDCLU to *ANY or *RQSAUT depending on the environment. 64 Clustering and IASPs for Higher Availability on the iSeries Server __2.If ALWADDCLU is set to *RQSAUT, install OS/400 Option 34 (Digital Certificate Manager) and a Cryptographic Access Provided Product (5722-AC2 or AC3). __3.The user profile invoking the Cluster Resource Services APIs must exist on all cluster nodes and must have IOSYSCFG authority. __4.The user profile to run the exit program for a CRG must exist on all recovery domain nodes. Job considerations __1.Jobs can be submitted by the Cluster Resource Services APIs to process requests. The jobs either run under the user profile to run the exit program specified when creating the CRG, or under the user profile that requested the API (for varying on devices in a Device Resiliency CRGs only). The user must ensure that the subsystem which services the job queue associated with the user profile is configured as *NOMAX for the number of jobs that can be run from that job queue. __2.Jobs are submitted to the job queue specified by the job description that is obtained from the user profile defined for a CRG. The default job description causes the jobs to be sent to the QBATCH job queue. Since this job queue is used for many user jobs, the exit program job may not run in a timely fashion. Consider using a unique job description with a unique user queue. The number of maximum programs should be set to a value greater than one. __3.The value of the routing data supplied in the job description determines in which main storage pool, and with what run time attributes, the exit program executes. The default job description values result in jobs that execute in a pool with other batch jobs with a run priority of 50. The default options may not produce the desired performance for exit programs of clustering jobs. The subsystem initiating the exit program jobs (which is the same subsystem that is using the unique job queue) should assign the exit program jobs to a pool that is not used by other jobs initiated by the same subsystem or other subsystems. In addition, assign a run priority of 15 so that the exit program jobs run before most user jobs. IBM Simple Cluster Management GUI considerations __1.Install OS/400 Option 41 (HA Switchable Resources) on all cluster nodes to be in the device domain. __2.A valid license key must exist for each cluster node in the device domain. __3.Start all host servers. Use this command: STRHOSTSVR SERVER(*ALL) __4.Start the Management Central server (*MGTC). Use this command: STRTCPSVR SERVER(*MGTC) Follow these steps to work with the clusters function in Management Central: 1. Open the main Operations Navigator window by clicking Start-> Programs-> IBM AS/400 Client Access Express-> AS/400 Operations Navigator. 2. Expand Management Central. 3. Select Clusters. 5.2.2 Using the Simple Cluster Management GUI to create the cluster The IBM Simple Cluster Management GUI is provided as part of Operations Navigator. Use it to create a simple two-node cluster. Chapter 5. Implementing and managing clusters with IBM solutions 65 Considerations when using the IBM Simple Cluster Management GUI include:  The Operations Navigator GUI appears as a special Management Central system group against which cluster functions can be performed.  It provides system-by-system functions.  It supports a maximum of two nodes in the cluster.  Only application and device CRGs are supported with Operations Navigator GUI. Data CRGs are not supported. Follow these steps to create a cluster using the Simple Cluster Management GUI: 1. Sign on to Management Central on the system that is to be the managing system. The Operations Navigator initial window is displayed in Figure 5-2. Figure 5-2 Operations Navigator initial window 2. Right-click Clusters and select New Cluster from the drop-down menu. This is the starting point for creating a cluster. See Figure 5-3. Note: The managing system does not have to be one of the systems that participates in the cluster. Note: You may experience a short delay as the Wizard is loaded from the iSeries server. 66 Clustering and IASPs for Higher Availability on the iSeries Server Figure 5-3 Creating a new cluster 3. On the New Cluster window, select Start the New Cluster Wizard and then click OK as shown in Figure 5-4. Figure 5-4 Starting the New Cluster wizard 4. The new cluster dialogue box (Figure 5-5) reminds you that there are requirements for the cluster to be created. Click Details to see the prerequisites. Chapter 5. Implementing and managing clusters with IBM solutions 67 Figure 5-5 New Cluster Wizard welcome window As illustrated in Figure 5-6, hardware and software prerequisites are listed. Do not proceed until these prerequisites are met: – Hardware: It is necessary to have either two V5R1 systems, or a logically partitioned system with a minimum of two partitions, where each partition is at V5R1. If you plan to create a Switchable IASP in a standalone disk tower, install an HSL adapter card. – Software: The TCP/IP Connectivity Utilities product (5722-TC1) is required, as is Client Access Express (5722-XE1) and OS/400 HA Switchable Resources (Option 41 of 5722-SS1). HSL OptiConnect (Option 23 of 5722-SS1) is not required for clustering or IASPs. It is required for system-to-system communication, for example, Distributed Data Management (DDM). 68 Clustering and IASPs for Higher Availability on the iSeries Server Prerequisites are identified in a Help panel of Operations Navigator clustering, as illustrated in Figure 5-6. For a further discussion on prerequisites for clustering, see 4.5, “Prerequisites for iSeries clustering” on page 37. Figure 5-6 Cluster prerequisites Chapter 5. Implementing and managing clusters with IBM solutions 69 5. As shown in Figure 5-7, enter the name of the cluster. Choose a descriptive name; it should be no more than ten characters in length. Figure 5-7 Naming the cluster 70 Clustering and IASPs for Higher Availability on the iSeries Server 6. Specify which system is to be the primary node in the cluster. Use the Browse button to select a system. The server selected does not have to appear in the select list to be a valid node in the cluster. See Figure 5-8. Figure 5-8 Specifying a system to be the primary node Chapter 5. Implementing and managing clusters with IBM solutions 71 7. Specify the IP address of the Primary Node. Enter the IP address directly or select it from the drop-down dialogue box. See Figure 5-9. Figure 5-9 Specifying the IP address of primary node Hint: If the IP address does not appear in the dialogue box, there may be a problem with the Host table. When the system name is entered, its address is retrieved from the Domain Name Server (DNS). Enter the IP address as the system name to bypass this check. 72 Clustering and IASPs for Higher Availability on the iSeries Server Figure 5-10 shows the completed display. Figure 5-10 Cluster primary node completion display Note: A secondary IP address can be specified for redundancy. This allows a secondary IP path to the system in the event that the primary interface is unavailable. Chapter 5. Implementing and managing clusters with IBM solutions 73 8. The next window (Figure 5-11) allows you to select the Backup Node and IP address in the same way that the primary node is selected. Figure 5-11 Specifying the name and IP address of backup node asm15 74 Clustering and IASPs for Higher Availability on the iSeries Server 9. You are then prompted to sign on to the Backup Node. See Figure 5-12. Figure 5-12 Signing on to the backup node Important: The user profile entered must exist on both nodes in the cluster. asm15 Chapter 5. Implementing and managing clusters with IBM solutions 75 10.After a search of the systems, you are informed whether “Switchable” software is installed as shown in Figure 5-13. Adding Switchable Software is described starting in Step 16 of this procedure. Figure 5-13 Switchable software Note: Switchable software is any server software that is automatically started on the backup node if the primary node is unavailable. An example of switchable software is Lotus Domino for iSeries, which is ClusterProven and therefore switchable. See Chapter 8, “ClusterProven for iSeries applications” on page 161, for a further description of ClusterProven. 76 Clustering and IASPs for Higher Availability on the iSeries Server An error message may appear that indicates that there is a problem with the network attributes as shown in Figure 5-14. Figure 5-14 Network attribute to allow clustering Note: Both systems need to have the Allow Add to Cluster (ALWADDCLU) network attribute set to *ANY or *RQSAUT. Change Network Attributes (CHGNETA) Type choices, press Enter. HPR path switch timers: Network priority . . . . . . . *SAME 1-10000, *SAME, *NONE High priority . . . . . . . . *SAME 1-10000, *SAME, *NONE Medium priority . . . . . . . *SAME 1-10000, *SAME, *NONE Low priority . . . . . . . . . *SAME 1-10000, *SAME, *NONE Allow add to cluster . . . . . . *SAME *SAME, *NONE, *ANY, *RQSAUT Modem country ................................................................ : Allow add to cluster (ALWADDCLU) - Help : : : : *NONE: No other system can add this system as a node : : in a cluster. : : : : *ANY: Any other system can add this system as a node : : in a cluster. : : : : More... : : F2=Extended help F10=Move to top F12=Cancel : F3=Exit F4= : F13=Information Assistant F20=Enlarge F24=More keys : F24=More keys : : :..............................................................: Chapter 5. Implementing and managing clusters with IBM solutions 77 11.The cluster is created. The status bar appears on the Creating Cluster display (Figure 5-15) to indicate the progress. Figure 5-15 Creating a cluster 78 Clustering and IASPs for Higher Availability on the iSeries Server 12.When the cluster is created successfully, a completion message is displayed. See Figure 5-16. Figure 5-16 Cluster creation complete Chapter 5. Implementing and managing clusters with IBM solutions 79 13.The New Cluster - Summary display (Figure 5-17) shows a summary of the created cluster. The nodes in the cluster are shown, as well as any switchable hardware or software that may be present. Figure 5-17 The cluster is created 14.Refresh the Operations Navigator screen (F5). You now see the new cluster under the Cluster in Management Central as shown in Figure 5-18. Figure 5-18 New cluster appears in Management Central Asm15 Asm01 Asm15 Asm24 80 Clustering and IASPs for Higher Availability on the iSeries Server Note that two system groups are created by the process – one for each node in the cluster. See Figure 5-19. Figure 5-19 System groups created Chapter 5. Implementing and managing clusters with IBM solutions 81 15.Right-click the cluster name and select Cluster Log. This allows you to look at the cluster creation log, which is shown in Figure 5-20. Figure 5-20 The cluster creation log Note: The GUI calls the cluster APIs. The following actions transpire with the GUI function:  The QcstCreateCluster API is called, which is equivalent to the CRTCLU command.  The ADDDEVDMNE command calls the QcstAddDeviceDomainEntry API.  The ADDCLUNODE command calls the QcstAddClusterNodeEntry API.  The QcstStartClusterNode API starts the cluster node. This is equivalent to using the STRCLUNOD command. Asm15 82 Clustering and IASPs for Higher Availability on the iSeries Server You can make other changes to the cluster with this drop-down menu, such as to Collection Services, Inventory, or Fixes. See Figure 5-21. Figure 5-21 Managing a cluster with Operations Navigator 16.The cluster is created. To add Switchable Software to the cluster, click the + (plus sign) to expand Clusters. Click Switchable Software. Then right-click and select Add Product. See Figure 5-22. Figure 5-22 Adding switchable software Note: The Cluster starts by default. Use Operations Navigator to stop or start the cluster. Chapter 5. Implementing and managing clusters with IBM solutions 83 17.On the Add Product window (Figure 5-23), enter the cluster name, primary node, and the takeover IP address for the application. Figure 5-23 Adding the application CRG 18.Click the Exit Program tab (Figure 5-24). Enter the exit program name and library, the user under which the job will run, and the name of the job. Then, click OK. Figure 5-24 Entering the name of the exit program Note: The exit program used here is the example shipped in QUSRTOOL. 84 Clustering and IASPs for Higher Availability on the iSeries Server 19.Refresh the Operations Navigator window (F5). The new software appears under Switchable Software a shown in Figure 5-25. Figure 5-25 Application added 20.The status of the Software is Stopped. Right-click the software and select Start (Figure 5-26). Figure 5-26 Starting the application 21.Refresh the Operations Navigator window (F5). The status changes to Started (Figure 5-27). Chapter 5. Implementing and managing clusters with IBM solutions 85 Figure 5-27 CRG started 22.To switch the software to the backup system, right-click the software and select Switch (Figure 5-28). Figure 5-28 Switching the application to a backup system 23.Click Yes to confirm the switch (Figure 5-29). 86 Clustering and IASPs for Higher Availability on the iSeries Server Figure 5-29 Confirming the switch of the application 24.Refresh the Operations Navigator window (F5). The active node has changed to the backup system (Figure 5-30). Figure 5-30 Node changed to backup Common problems As with operations of any type, problems can be encountered when using the Operations Navigator GUI to create a simple cluster. Some of the typical errors encountered are listed in this section. Use the command that is identified to correct the problem.  The Allow Additional Cluster (ALWADDCLU) network attribute is not set to *ANY or *RQSAUT. Use either of the following commands: CHGNETA ALWADDCLU(*ANY) CHGNETA ALWADDCLU(*RQSAUT)  Host Servers are not started: STRHOSTSVR *ALL  The user profile does not have correct authority: CHGUSRPRF user_profile SPCAUTH(*IOSYSCFG *ALLOBJ *SERVICE) Chapter 5. Implementing and managing clusters with IBM solutions 87  TCPIP Internet Daemon is not started: STRTCPSVR *INETD  The user profile of the user creating the cluster should be the same on all nodes in the cluster 5.3 Using QUSRTOOL CL commands and OS/400 APIs to implement an iSeries cluster The pairing of OS/400 APIs and CL commands is one of two supported interfaces when full clustering is not required. The other supported interface for simple clustering is described in 5.2, “Using the Operations Navigator GUI to implement and manage iSeries clusters” on page 61. To use CL commands to create a non-complex iSeries cluster, follow these seven easy steps: 1. Perform these functions on each node in the cluster: a. Change the network attributes to allow a cluster: CHGNETA ALWADDCLU(*ANY) b. Activate TCP using: STRTCP This command also starts the INETD server job (QTOGINTD). c. Verify the connection to the system: PING system-name Record the TCP/IP address. d. Make sure the controlling subsystem can handle more than one batch job: DSPSYSVAL QCTLSBSD WRKSBSD ctl-sbs i. Select option 6 (Job queue entries). Note the value for Max Active for the job queue listed. If it is not *NOMAX or a value greater than 1, a cluster can appear to be hung as batch jobs execute. ii. If job queue is not *NOMAX or a value greater than 1, enter: CHGJOBQE SBSD(lib-name/subsystem-name) JOBQ(lib-name/job-queue-name) MAXACT(*NOMAX) 2. Create the cluster, using either of the following commands: CRTCLU (QUSRTOOL) CRTCLU CLUSTER(cluster-name) NODE('ip-address'/system-name) Notes:  The commands described in this section (and chapter) are part of the QUSRTOOL library that is shipped with OS/400 V5R1. OS/400 native commands do not support iSeries clustering at this time. You can find a list of the commands and APIs available in the QUSRTOOL library in B.3, “Cluster APIs and related QUSRTOOL commands” on page 286.  In the following steps, both of the commands offered in QUSRTOOL and base OS/400 commands are illustrated. You may choose to use one or the other. 88 Clustering and IASPs for Higher Availability on the iSeries Server See Figure 5-31 for an illustration. Figure 5-31 Create Cluster QUSRTOOL command Create Cluster (CRTCLU) Type choices, press Enter. Cluster . . . . . . . . . . . . > CLUSTER1 Name Node: Node identifier . . . . . . . > SYSTEM1 Name IP address . . . . . . . . . . > '10.10.10.1' Node identifier . . . . . . . > SYSTEM2 Name IP address . . . . . . . . . . > '10.10.10.2' + for more values Start indicator . . . . . . . . *YES *NO, *YES Cluster version . . . . . . . . *CUR *PRV, *CUR Bottom F3=Exit F4=Prompt F5=Refresh F12=Cancel F13=How to use this display F24=More keys Note: The Cluster version parameter in the Create Cluster command allows the user to specify whether this cluster is to be a type 2 cluster (V5R1) or a type 1 cluster (V4R4 and V4R5). *CUR indicates type 2, and *PRV indicates type 1. This fact is important if the type 1 nodes are to be added to the cluster. Chapter 5. Implementing and managing clusters with IBM solutions 89 3. Add another node to the cluster from the active cluster node: ADDCLUNOD (QUSRTOOL) Use the IP address from the ping operation completed in step 1, for example: ADDCLUNOD CLUSTER(cluster-name) NODE('ip-address'/system-name) See Figure 5-32 for an illustration. Figure 5-32 Add Cluster Node Entry QUSRTOOL command Add Cluster Node Entry (ADDCLUNODE) Type choices, press Enter. Cluster . . . . . . . . . . . . > CLUSTER1 Name Node: Node identifier . . . . . . . > SYSTEM3 Name IP address . . . . . . . . . . > '10.10.10.3' Start indicator . . . . . . . . *YES *NO, *YES Bottom F3=Exit F4=Prompt F5=Refresh F12=Cancel F13=How to use this display F24=More keys 90 Clustering and IASPs for Higher Availability on the iSeries Server 4. Define the device domains. When you are using APIs or QUSRTOOL commands, device domains must be created manually. (The Simple Cluster Management GUI conceals this step.) Use either of the following commands: ADDDEVDMNE(QUSRTOOL) ADDDEVDMNE CLUSTER(cluster-name) DEVDMN(choose-a-name-for-the-device-domain) NODE(system-name) See Figure 5-33 for an illustration. Figure 5-33 Add Device Domain Entry QUSRTOOL command Add Device Domain Entry (ADDDEVDMNE) Type choices, press Enter. Cluster . . . . . . . . . . . . > CLUSTER1 Name Device domain . . . . . . . . . > DD1 Name Node . . . . . . . . . . . . . . > SYSTEM1 Name Bottom F3=Exit F4=Prompt F5=Refresh F12=Cancel F13=How to use this display F24=More keys Chapter 5. Implementing and managing clusters with IBM solutions 91 5. Create the Cluster Resource Group, using the command: CRTCRG For example, to create a Device CRG, enter: CRTCRG CLUSTER(cluster-name) CRG(crg-name) CRGTYPE(*dev) TEXT(TEXT) EXITPGMDTA(*NONE) USERPRF(*NONE) RCYDMN((system-name *prim) (system-name *back1)) CFGOBJL((iasp-devd-name)) See Figure 5-34 for an illustration. Figure 5-34 Create CRG QUSRTOOL command Create Cluster Resource Group (CRTCRG) Type choices, press Enter. Cluster . . . . . . . . . . . . > CLUSTER1 Name Cluster resource group . . . . . > CRG1 Name Resource group type . . . . . . > *DEV *DATA, *APP, *DEV Exit program . . . . . . . . . . > *NONE Name, *NONE Library . . . . . . . . . . . Name, *CURLIB User profile . . . . . . . . . . > USER1 Name, *NONE Exit program data . . . . . . . *NONE Text description . . . . . . . . DI user queue . . . . . . . . . *NONE Name, *NONE Library . . . . . . . . . . . Name More... F3=Exit F4=Prompt F5=Refresh F12=Cancel F13=How to use this display F24=More keys 92 Clustering and IASPs for Higher Availability on the iSeries Server 6. Start the CRG using the command: STRTCRG Consider this example: STRCRG CLUSTER(cluster-name) CRG(crg-name) See Figure 5-35 for an example. Figure 5-35 Start Cluster Resource Group command Start Cluster Resource Group (STRCRG) Type choices, press Enter. Cluster . . . . . . . . . . . . > CLUSTER1 Name Cluster resource group . . . . . > CRG1 Name Exit program data . . . . . . . *SAME Bottom F3=Exit F4=Prompt F5=Refresh F12=Cancel F13=How to use this display F24=More keys Chapter 5. Implementing and managing clusters with IBM solutions 93 7. End the CRG using the command: ENDCRG Consider this example: ENDCRG CLUSTER(cluster-name) CRG(crg-name) See Figure 5-36 for an illustration. Figure 5-36 End Cluster Resource Group QUSRTOOL command Additional CL commands are available to further enhance the cluster by adding nodes, devices, remove domains and nodes, and print information. You can find a list of QUSRTOOL commands in B.3, “Cluster APIs and related QUSRTOOL commands” on page 286. 5.3.1 Using OS/400 cluster management APIs to implement a cluster OS/400 APIs are part of one of the two supported interfaces when full iSeries clustering support is not required. The APIs provided with OS/400 support developing code for the management and creation of a simple cluster environment. The other supported interface is described in 5.2, “Using the Operations Navigator GUI to implement and manage iSeries clusters” on page 61. To configure a cluster, you need to understand the attributes for each node of the cluster:  What nodes are in the cluster (what are the iSeries servers that make up the cluster)  What the current cluster version is  What the cluster resources (the resilient objects and resilient applications) are  What the policies related to failover or switchover for the cluster policies are  What the required CRGs are  Obtain IP addresses for each application CRG; the IP addresses must not be used by other applications  Decide the level required level for cluster messaging End Cluster Resource Group (ENDCRG) Type choices, press Enter. Cluster . . . . . . . . . . . . > CLUSTER1 Name Cluster resource group . . . . . > CRG1 Name Exit program data . . . . . . . *SAME Bottom F3=Exit F4=Prompt F5=Refresh F12=Cancel F13=How to use this display F24=More keys Note: Since APIs are designed to be used within a custom application, example coding is not provided in this redbook. 94 Clustering and IASPs for Higher Availability on the iSeries Server You can find a list of APIs that support clustering in B.3, “Cluster APIs and related QUSRTOOL commands” on page 286. 5.3.2 Definitions revisited Using the APIs and commands requires a good knowledge of cluster definitions and how they relate to one another. Before we look at cluster creation using the cluster APIs, it is important that you understand the terminology that is related to clusters. A definition and brief description of the terms that are important to understand iSeries clustering are provided in this section. Each term is described in more detail in the remainder of this redbook.  Cluster node: Cluster node is any iSeries server that is a member of a cluster. Any name can be used. However, it can be simplest if the node name is the same name as is used for either the host name or the system name. The cluster node name is associated with one or more Internet Protocol (IP) addresses that represent an iSeries server. Cluster communications makes use of the TCP/IP protocol suite to provide the communications paths between cluster services on each node in the cluster. The set of cluster nodes that are configured as part of the cluster is referred to as the cluster membership list.  Cluster Resource Group: A Cluster Resource Group is an OS/400 system object that is a set or grouping of cluster resources. The group describes a recovery domain and supplies the name of the CRG exit program that manages cluster-related events for that group. One such event is moving an access point from one node to another node. CRG objects are defined as data resilient, application resilient, or device resilient. Data resiliency enables multiple copies of data to be maintained on more than one node in a cluster and enables the point of access to be changed to a backup node. Application resiliency enables an application (program) to be restarted on either the same node or a different node in the cluster. Device resiliency enables a device resource to be moved (switched) to a backup node. Every Data and Application CRG has a CRG exit program associated with it. The exit program is optional for resilient Device CRGs.  Replication: Replication involves copying objects from one node in a cluster to one or more other nodes in the cluster. Replication makes a copy of objects in real time. Replication makes and keeps the objects on the clustered servers identical. A change to an object on one node in a cluster is replicated to other nodes in the cluster. Replication can be done through the use of journaling. For more information on how journaling works, see iSeries Backup and Recovery, SC41-5304.  Resilient resource: Resilient resources are highly available with clustering implemented on the systems of the cluster. These system resources can be resilient: – Cluster node – CRG – Replicated data – Resilient applications – Switchable Internet Protocol (IP) address – Resilient device Chapter 5. Implementing and managing clusters with IBM solutions 95 If the primary access point for a particular set of resilient resources in a cluster node incurs an outage, another cluster node that is defined as the backup for that set of resources becomes the access point. The definition of the relationship between the nodes associated with a set of resilient resources is found in the CRG object. CRGs are replicated and coordinated across the nodes in the cluster through Cluster Resource Services.  Recovery domain: A recovery domain is a subset of nodes in the cluster that are grouped together in a CRG for a common purpose, such as performing a recovery action. A domain represents those nodes of the cluster from which a cluster resource can be accessed. The subset of cluster nodes that is assigned to a particular CRG supports either the primary point of access, secondary (backup) point of access, or the replicate. Each node in the recovery domain has a role with respect to the current operational environment of the cluster. This is known as its current role in the recovery domain. As the cluster goes through operational changes, such as when nodes end, start, or fail, the node's current role is changed accordingly. Each node in the recovery domain has a role with respect to the preferred or ideal cluster environment. This is known as its preferred role in the recovery domain. The preferred role is a static definition that is initially set when the CRG is created. As the cluster environment changes, the preferred role is not changed.  Device domain: A device domain is a collection of cluster nodes that share resources. More specifically, nodes in a device domain can participate in a switching action for a collection of resilient device resources. Device domains are identified and managed through a set interface that allows the user to add a node to a device domain or remove a node from a device domain. Device domains are used to manage certain global information necessary to switch a resilient device from one system to another. All systems in the device domain use this information to ensure that conflicts do not occur when devices are switched. For example, for a collection of switchable IASPs, the IASP identification, disk unit assignments, and virtual address assignments must be unique across the entire device domain. A cluster node can belong to at most one device domain. A node must first be as a member of a device domain before a node can be added to a recovery domain for a device CRG. All nodes that are to be in the recovery domain for a resilient device CRG must be in the same device domain. Install Option 41 of OS/400, HA Switchable Resources, on the system to create and manage device domains. A valid license key must exist for this option. For more details on managing device domains, refer to the Add Device Domain Entry (QcstAddDeviceDomainEntry) and Remove Device Domain Entry (QcstRemoveDeviceDomainEntry) APIs.  Failover and switchover: A failover is when the system automatically switches over to one or more backup systems in the event of a system failure. A switchover involves a manual switch to switch the access from one system to another. A switchover is done, for example, to perform system maintenance, such as applying program temporary fixes (PTFs), installing a new release, or upgrading the system. When multiple CRGs are involved in a failover action, the system processes the device CRGs first, the data CRGs second, and the application CRGs next. For an administrative switchover of multiple CRGs, consider the relationships between the CRGs when specifying their order. For example, if an application CRG depends on data associated with a device CRG, the steps of an ordered switchover are: 96 Clustering and IASPs for Higher Availability on the iSeries Server a. Stop the application on the old primary (to quiesce changes to the data) b. Switch the device CRG to the new primary c. Switch the application CRG to the new primary d. Restart the application on the new primary  Cluster version: A cluster version represents the level of clustering function available on the system. Functions are improved and added in each release of OS/400. Versioning is a technique that allows the cluster to contain systems at multiple release levels. The systems fully interoperate by determining the communications protocol level to be used. Refer to the “Glossary” on page 295 for a list of additional definitions of terms that relate to clustering on the iSeries server. 5.3.3 Cluster versions There are two cluster version levels:  Potential cluster version represents the more advanced level of cluster function that is available for a given node. With this level, the node is capable of communicating with the level of each of the other cluster nodes.  Current cluster version represents the version actually used for all cluster operations. This level facilitates the nodes to communicate within the cluster. The potential cluster version increments with each OS/400 release that has significant function not available in earlier cluster versions. If the current cluster version is less than the potential cluster version, then that function cannot be used since some nodes cannot recognize or process the request. To take advantage of such new function, each system in the cluster must be at the same potential cluster version. Set the cluster version to that level. When a node attempts to join a cluster, its potential cluster version is compared against the current cluster version. If the value of the potential cluster version is not the same as current version (N) or not equal to the next version level (N+1), then the node is not allowed to join the cluster. The current cluster version is initially set by the first node defined in the cluster, using the value specified on the create cluster function. See the Create Cluster API (QcstCreateCluster) for more information. For example, to have OS/400 V4R4 and V4R5 nodes exist with V5R1 nodes, you need to perform one of the following steps:  Create the cluster on a V4R4 or V4R5 system and add in the V5R1 node.  Create the cluster on a V5R1 system. Specify “Allow previous nodes to be added” to the cluster. Then add V4R4 and V4R5 systems to the cluster. See Figure 5-37. Chapter 5. Implementing and managing clusters with IBM solutions 97 Figure 5-37 Create Cluster specifying previous cluster version In a mixed release cluster, cluster protocols are run at the lowest node release level (N). The protocol is defined when the cluster is first created. N can be set either to the potential node version running on the node that originated the create cluster request, or one cluster version previous to the originators potential node version. Nodes in the cluster can differ by at most one cluster version level. Once all systems in the cluster are upgraded to the next release, upgrade the cluster version so that new functions are available. Use the adjust cluster version function for this purpose. See the brief description of the Adjust Cluster Version (QcstAdjustClusterVersion) API Table 5-1 on page 61 to relate this API with other Cluster APIs. Create Cluster (CRTCLU) Type choices, press Enter. Cluster . . . . . . . . . . . . CLUSTER cluster1 Node: NODE Node identifier . . . . . . . system1 IP address . . . . . . . . . . 10.10.10.1 + for more values Start indicator . . . . . . . . STARTIND *YES Cluster version . . . . . . . . VERSION *prv Bottom F3=Exit F4=Prompt F5=Refresh F12=Cancel F13=How to use this display F24=More keys 98 Clustering and IASPs for Higher Availability on the iSeries Server © Copyright IBM Corp. 2000, 2002 99 Chapter 6. Independent ASPs explained An independent ASP (IASP) is a configuration of multiple disk storage units into one group. The group can include all the disk units in one I/O tower, a subset of the disk units in an I/O tower, or disk units from two or more I/O towers. This chapter presents information on the concepts, objectives, architecture, and design of independent ASPs. This information is useful not only to understand IASPs, but to market and strategically plan for an IASP implementation. 6 100 Clustering and IASPs for Higher Availability on the iSeries Server 6.1 What independent ASPs are Auxiliary storage pools (ASPs) have been part of the iSeries architecture since the announcement of the AS/400 in 1988, and of the System/38 before it. System ASPs and user ASPs enable a division of the total disk storage on the system into logical groups. One or more applications or data objects can then be isolated onto one or more ASPs, to support improvements for backup and recovery, performance, and more. What are independent ASPs (IASPs)? IASPs are like user ASPs (described in 6.3, “OS/400 IASP support and terminology” on page 102). The “I” in the acronym IASP stands for “independent”, which makes a significant difference. Independent ASPs can be used on a single system, or switched between multiple systems or LPAR partitions. When used on a single system (as a standalone IASP), the IASP can be dynamically turned on or off. The IASP, and therefore, its contents – application and data – are dynamically made available or unavailable to the system. When used across multiple systems, the IASP, and therefore, its contents – application and data – can be switched between those systems. The ability to be turned off or on, or to be switched between systems, is what differentiates IASPs from regular ASPs and provides IASPs the independent characteristics. The characteristic for an IASPs to be varied off or on, or attached and detached, can be done without performing a system IPL. This increases the flexibility offered by IASPs. Clustering support is required to switch IASPs across multiple systems. Cluster Management is used to switch the IASP across systems in the cluster. At any one time, the IASP can be used from one of the clustered systems. The IASP cannot be used simultaneously from multiple systems. The ability for one iSeries server to pickup or inherit the disks of another iSeries server with all its contents, without a system IPL, is a revolutionary concept. As a result, it is expected that IASPs will open up many useful application possibilities for iSeries customers. 6.2 Uses for IASPs A predictable question for any new function in OS/400 is: What do I use it for? This section identifies some of the uses for IASPs. Independent ASP supports objects in the Integrated File System (User Defined File System (UDFS)). Therefore, most of the uses in OS/400 V5R1 relate to applications that use the IFS. Some of the more apparent uses of independent ASPs at V5R1 are:  To use independent ASPs to store anything that resides in the Integrated File System (IFS), for example: – Web pages – Domino data directories Domino’s use of independent ASPs for its data directory is described in 6.7.1, “Domino and independent ASPs” on page 112. – Linux file system  Storage for Integrated xSeries Server for iSeries (Integrated Netfinity Server)  Tivoli Storage Manager storage Chapter 6. Independent ASPs explained 101  Applications that use the Integrated File System, such as: – MQSeries – Applications ported from other systems which utilize the IFS for storage, for example UNIX or Windows NT – Data mining and business intelligence data if the application uses the Integrated File System  To store separate applications and their associated data on separate IASPs For example, store Domino data on one IASP, and store HTTP Server data on another IASP.  To store separate instances of data related to a specific application on separate IASPs For example, store Domino data for one customer on one IASP, and store Domino data for a second customer on a different IASP.  System upgrades It is believed that the IASP can be used for system hardware and software upgrades. That is, switch the IASP to the backup system and upgrade the primary system while the backup system keeps production operation. After the upgrade, switch back to the primary system. Note that at the time of writing this redbook, this use had not been tested and therefore is not supported by IBM. Although the more “glamorous” or high profile use of an IASP is as an ASP that can be switched between systems, there are other valid uses for a standalone IASP, for example:  In a single system environment, an independent ASP can be used to store certain data offline except for the periods when it is actually needed. The isolation provided by storing data offline means that there is less work necessary for certain functions such as IPL, reclaim storage, and some save operations.  A single system IASP can be a stepping stone for the more complex usage of the switchable IASP. Some of these uses are discussed within this chapter. Other uses for an IASP are expected to evolve over time. It is anticipated that applications will look to store journal receivers on an IASP once that support is available. Look for the redbook Moving Applications to Switchable Independent ASPs, SG24-6802, which is scheduled for publication later in the second half of 2002. Note: An Enterprise Storage Server (commonly known as Shark) that is attached to a switchable IASP tower switches when the IASP switches. However, individual Logical Unit Number (LUN) sets of the Shark cannot be switched. The Shark must switch as an entity. Attention: IBM has released a statement of direction that other objects, such as libraries, database files, and journals and journal receivers, will be supported on the IASP in a later release. The statement says: In a future release, IBM intends to enhance OS/400 support for switching the ownership of objects between primary and secondary servers through the use of independent ASPs and switchable disk technologies by extending the list of possible switched objects beyond the IFS files. Additions would include objects associated with the DB2 UDB for iSeries and other OS/400 library-based objects. 102 Clustering and IASPs for Higher Availability on the iSeries Server 6.3 OS/400 IASP support and terminology The types and quantity of ASPs supported on the iSeries servers depend upon the release of OS/400 installed on the system. Table 6-1 summarizes these characteristics. Table 6-1 Type and quantity of ASP support by OS/400 release Other characteristics of ASPs include:  System ASP The system ASP contains SLIC and OS/400 code. It can contain objects of any object type.  User ASP User ASPs are any ASP other than the system ASP. The additional 16 user ASPs supported with V5R1 have the same characteristics as the traditional ASP numbers 2 through 16 originally available with the AS/400 system.  Independent ASPs Independent ASPs are user ASPs that can be varied offline or varied online independent of the rest of the server storage. IASPs can be switched between iSeries servers (and partitions). Independent ASPs are known to the system by both names and numbers (33 through 99). The preferred user interface is by name. In many cases, the user interface does not support a reference by IASP number. The iSeries Machine Interface (MI) recognizes both names and numbers. A machine instruction associates an IASP name with its number. Figure 6-1 further illustrates the V5R1 supported characteristics of ASPs. Type of ASP OS/400 release supported ASP number Maximum quantity supported on the system System ASP All ASP 1 1 User ASP* V5R1 ASP 02 - ASP 32 31 User ASP* V4R5 and earlier ASP 02 - ASP 16 15 Independent ASP V5R1 ASP 33 - ASP 99 67 * Also known as Basic ASP Chapter 6. Independent ASPs explained 103 Figure 6-1 ASPs at V5R1 With V5R1 the user interface for the iSeries is graphical, using Operations Navigator. Within the GUI tools, the term disk pool is used for ASPs. The terms disk pool and auxiliary storage pool (ASP) are synonymous. The term basic disk pool also refers to the traditional user ASP. In pre-V5R1 terms, basic refers to pools 2 through 15. The scope of this definition is now expanded to include ASPs 2 through 32. Figure 6-2 illustrates the relationship of ASPs using this disk pool terminology. Figure 6-2 Additional ASP terminology System ASP (1) Independent ASPs 33-99 User ASPs (Basic) 2-32 Pre-V5R1: User ASPs 2-16 User ASPs 2-16 User ASPs 2-16 Auxiliary Storage Pools (Disk Pools) Independent ASPs - IASPs (Independent Pools 33-99) Traditional User ASPs (Basic Pools 2-32) System ASP (Disk Pool 1) User ASPs (Disk Pools 2-99) 104 Clustering and IASPs for Higher Availability on the iSeries Server 6.3.1 OS/400 software options Option 41 of the OS/400 is the High Availability Switchable Resources feature. This feature is required to enable the Cluster Management wizard in Operations Navigator and to enable switching of resilient devices, such as a switchable IASP. There can be confusion regarding the requirement of OptiConnect and the use of IASPs. To configure and use a switchable IASP, HSL hardware connectivity supported with V5R1 is required. OptiConnect over HSL is a viable option for high speed system-to-system I/O. It is a useful option for applications, such as replication. Enable OptiConnect by installing Option 23 of OS/400. It is a separately purchased feature. 6.3.2 High Speed Link OptiConnect This section covers the HSL requirements and some of the clustering constructs that are necessary to create an IASP. HSL technology is introduced with OS/400 V4R5 as the means to attach I/O towers to the base system unit. HSL fabric is useful for high-speed server-to-server interconnect, since it can run ten times faster than SPD OptiConnect at V4R5. HSL is a pre-requisite for creating and using switchable IASPs. HSL is not required for a standalone IASP. HSL OptiConnect replaces the SPD connection. This support does not require additional hardware. Each iSeries model announced in April 2001 (Models 270 through 840) is shipped with the appropriate HSL port that can be used for HSL OptiConnect and for the new switching IASP support. The V4R5 iSeries 830 and 840 models (available before April 2001) use the older HSL port. However, these models can upgrade to the new HSL hardware. The V4R5 iSeries 270s and 820s cannot have the newer technology port installed on their system, because they use the same boards to drive the processor or processors and HSL. A customer with a pre- April 2001 270 or 820 must order or upgrade to a new April 2001 270 or 820 processor to use the new HSL hardware. HSL limitations are fully described in AS/400e to IBM ~ iSeries Migration: A Guide to System Upgrades at V4R5 and V5R1, SG24-6055. Note: OS/400 Option 41 is not required to configure a standalone IASP. Attention: To clarify the relationship of Option 23 and switched disks, remember OptiConnect over HSL (OS/400 Option 23) is not required to use a switchable or standalone IASP. Note: IBM plans to bring the Power4 microprocessor technology to the iSeries in the second half of 2002. IBM does not intend for the planned Power 4 iSeries servers to support non-PCI (SPD-based) I/O controllers and adapters. Chapter 6. Independent ASPs explained 105 6.3.3 Configuration source and the IASP Since an IASP can switch between systems, certain configuration information of the IASP is stored on the IASP itself to make it self contained. The configuration information of the disks on which the IASP is contained in the configuration source (sometimes referred to as load stone) on the IASP itself. When the IASP switches, the IASP configuration information switches with it. In general, the load source of the system keeps information on all ASPs on the system, including the independent ASPs. Detailed information for the basic ASPs is kept in the load source. Limited information for the independent ASPs is kept on the load source. Detailed configuration information of the IASP is contained in the configuration source of the IASP. This is a key concept to remember to understand switching disks. 6.4 Considerations of switched disk and IASP use When planning an iSeries availability solution, consider the characteristics of IASPs, as well as their advantages and disadvantages. For example, consider these statements regarding switched disk or IASPs when determining their value in an availability solution:  The time to vary on an IASP during the switching process depends on the number of objects on the IASP, and not the size of the objects. If possible, keep the number of objects small.  For a quicker vary on or off, keep the User-ID Number (UID) and Group-ID Number (GID) of user profiles that own objects on the IASP the same between nodes of the cluster. Having different UIDs lengthens the vary on time.  All the disk units within a tower are switched as an entity. When a tower containing the IASP is switched, all other I/O devices on that tower (if any), such as tape drive, CD ROM, printers, etc., are also switched to the other node.  The number of devices in a tower affects the switchover time. The devices in a switchover are reset as part of the switchover process.  The devices within a tower that is switched can autoconfigure. This can result in different resource names on the switched-to node. Manually configure the devices on the node that the tower is switched to so that the resource names match on both systems.  In an LPAR environment, the IOP controlling the disks is switched between the partitions. Make sure that the console is not on that IOP. Otherwise the console is switched with the IOP. Without the console, the primary partition is inaccessible.  Objects in an IASP cannot be journaled. Since replication uses journals, objects in an IASP cannot be replicated to a backup system at V5R1.  Library-based objects are not supported in the IASP at V5R1. The rules regarding HSL differ dependent upon the model of the iSeries server. For example, the following information varies by system model:  How many entities can be on an HSL loop  How many of these entities can be switched 106 Clustering and IASPs for Higher Availability on the iSeries Server Refer to AS/400e to IBM ~ iSeries Migration: A Guide to System Upgrades at V4R5 and V5R1, SG24-6055, to understand these requirements. Example configurations to illustrate some of these implementation rules are outlined in 6.6, “IASP configuration examples” on page 110, and 6.7.2, “Integrated xSeries Server and independent ASPs” on page 113. 6.4.1 Advantages of using IASPs Improvements to iSeries availability are enabled through the use of IASPs, beyond the capabilities of replication solutions. This section discusses the advantages of IASP use:  For disk drives in the IASP, device parity protection can be stopped or started from within OS/400. For regular ASPs, stopping and starting device parity protection is a Dedicated Service Tools (DST) function.  For disk drives in the IASP, mirroring can be turned on and off from within OS/400. For regular ASPs, stopping and starting mirroring is a DST function.  IASPs enable a higher level of availability without the need to buy a duplicate set of disks for the backup system. In a sense, IASPs are the poor man's option for higher availability.  The contents of a switchable IASP can be made available to the backup system without any kind of replication.  It is not necessary to maintain multiple copies of data, programs, and other objects. Multiple copies of objects is a function of replication.  There is minimal additional system overhead with IASP. Replication requires more CPU cycles when replicating to a backup system.  There is no network traffic associated with IASP. Replication across a LAN or WAN involves network traffic.  There is less work for system functions such as IPL, reclaim storage, and some save operations. In a single system environment, an independent ASP can be used to store certain data offline except for the periods when it is actually needed. The isolation provided by storing data offline means that there is less work necessary for system functions.  Objects are not “in flight” in the event of a failure. With replication, it is possible that journal entries become “trapped” on the source system at the time of failure and do not arrive at the target machine. 6.4.2 Disadvantages of using IASP There can be disadvantages to the system if IASPs are utilized, for example:  IASPs represent a single point of failure in the system. If the disks in the IASP are permanently damaged and the data is unrecoverable, data is available only up to the last backup copy. IASPs protect the iSeries server against system failures, not against disk failure.  Because of loop limitations with HSL, the systems must be within 250 meters using optical HSL cables or 15 meters with copper cables. The production and backup systems can be several thousand kilometers apart when replication is used. IASPs are, therefore, not useful as a disaster recovery solution. Chapter 6. Independent ASPs explained 107  If the IASP configuration involves an HSL loop, a V5R1 supported HSL port card is required (such as HSL port features #2754, #2755, #2758, #2759, #2774, and #2777). HSL port cards available prior to V5R1 do not work with IASPs. However, systems with original HSL hardware can be replaced by newer HSL port cards.  The IASP works with only one system at any one time. The IASP cannot be used for balancing workload. Typically customers use their backup system for read-only types of activities, such as creating or printing reports, running batch applications, and running queries. This helps spread workload to the backup system and thereby helps performance of the production system. 6.5 Objects defining an IASP configuration A cluster, device domain, device CRG, and device description are configuration objects used to implement independent ASPs or clusters. This section introduces these structures. Implementation details are offered in Chapter 7, “Operations Navigator independent ASP GUI” on page 125. 6.5.1 Relationship of IASP configuration objects Several object types are required to set up a switchable IASP:  Cluster  Device domain  Device CRG  Device description The inter-relationship of each IASP and cluster configuration object is illustrated in Figure 6-3. 108 Clustering and IASPs for Higher Availability on the iSeries Server Figure 6-3 Switchable IASP object relationship There is an enforced relationship between the resilient device CRG object and the switchable IASP physical resources. This relationship is enabled through OS/400 Option 41 - HA Switchable Resources. Option 41 is an additional cost, licensed option of OS/400. A standalone IASP does not require a cluster definition. To set up a standalone IASP, use the GUI tool or the green screen interface to:  Create a device description (using the Create Device ASP (CRTDEVASP) command)  Assign the disks to the IASP  Populate the IASP with data 6.5.2 Device domain object A device domain is the first of the cluster constructs to be defined when creating a switchable IASP. It is a logical construct within Cluster Resource Services that is used to ensure that there are no configuration conflicts that prevent a switchover or failover. The device domain is a subset of cluster nodes. The set of configuration resources associated with a collection of resilient devices can be switched across the nodes in the device domain. Resource assignments are negotiated to ensure that no conflicts exist. The configuration resources assigned to the device domain must be unique within the entire device domain.Therefore, even though only one node can use a resilient device at any given time, that device can be switched to another node and brought online. These cluster resources are negotiated across a device domain to ensure there are no conflicts: Note: Switchable IASPs can only be created using the IBM Operations Navigator GUI tool. Cluster Collection of iSeries servers Device Domain Collection of cluster nodes that share resources (switchable DASD towers) Manages assignment of common IASP ID, disk unit and virtual addresses across domain Device CRG Cluster Control object for a set of I-ASPs (switchable towers) Device Description (CRTDEVASP) Logical control name for varying on/off an IASP IASP Defines a physical set of switchable drives Prerequisite: cluster Drives Drives Prerequisite: Cluster, device description and license for OS/400 feature 41 Prerequisite: Cluster and license for OS/400 feature 41 Prerequisite: TCP/IP connectivity to all nodes, V5R1 HSL port hardware, I/O Tower or DASD on LPAR shared bus Chapter 6. Independent ASPs explained 109  IASP number assignments IASPs are automatically assigned a number to correlate the name of the IASP. The user chooses the resource name. The system manages the assigned IASP numbers, which may not be in numerical order. The order depends on a number of factors, including the creation date and the creation of IASPs on other nodes in the device domain.  DASD unit number assignments To keep from conflicting with the permanently attached disk units of each node, all IASP unit numbers begin with a four. IASP disk unit numbers start with the number 4001. Section 6.8.2, “Numbering new pools” on page 114, discusses DASD unit numbers in more detail.  Virtual address assignments The cluster configuration determines the virtual address space required for the IASP. Virtual address assignments (the cluster configuration) are ensured not to conflict across all nodes in the device domain. 6.5.3 Device CRG object A device CRG is the second clustering construct used to define and create a switchable IASP. Device CRGs or CRGs define the recovery domain for the switchable IASP. They provide the control for switching the IASP and for managing other aspects of the IASP. Switched disks enable a storage tower that is connected via High Speed Link (HSL) OptiConnect to two local iSeries servers, to be switched to the server used for recovery in event of a failure of the primary server. As entries in the device list, device CRGs support objects that are IASP devices only. Integrated File System objects only are allowed within the IASP at V5R1. Releases to follow OS/400 V5R1 will support database objects. In V5R1, resilient device CRGs support these features:  Are comprised of one or more IASPs  Can be manually or automatically switched to a secondary node. Cluster interfaces to support a resilient device CRG include functions to:  Manage a device CRG  Add or remove a resilient device list entry  Call a CRG exit program There can be one or more IASPs in a device list for a specific device CRG. 6.5.4 IASPs, device domains, and device CRGs Figure 6-4 illustrates the relationship between the device domain and device CRG when IASPs are implemented in a clustered environment. Note: With the Operations Navigator GUI wizard, the device domain, and the device CRG are created automatically by the wizard. Note: A CRG exit program is optional. For simple clustering support offered in V5R1, the exit program is not required. The support for a CRG exit program is primarily to support high availability business partners. 110 Clustering and IASPs for Higher Availability on the iSeries Server Figure 6-4 IASPs, device domains, and device CRGs For this example, there are four systems: A, B, C, and D. An independent ASP, named IASP4, is defined for System C. Another IASP, called IASP3, is defined for System D. Neither of these IASPs are intended to be switched to other systems. Consequently, there is no need for any system other than the owning system to be aware of their existence. IASP1 is defined as switchable between Systems A and B. IASP2 is defined as switchable between Systems B and C. Therefore, Systems A and B contain configuration information about IASP1, and Systems B and C contain configuration information about IASP2. The definition of the resilient devices named IASP1 and IASP2 results in an interrelationship between Systems A, B, and C. These systems form part of a device domain. Actually there are two device domains in this example: one for IASP1 that includes Systems A and B, and the other for IASP2 that includes Systems B and C. 6.6 IASP configuration examples An independent ASP is a method of configuring multiple disk storage units into one group. The group can include all the disk units in one I/O tower, a subset of the disk units in an I/O tower, or disk units from two or more I/O towers. To illustrate this concept, this section describes four of the possible IASP configurations. The first example is an IASP configuration that is made up of all the disk units in a tower. This is shown in the diagram on the left side of Figure 6-5 (labeled as IASP33). Device Domain System A System B System C System D IASP 4 IASP 3 Switchable Tower or IOP (LPAR only) IASP 2 RD 2 RD 2 IASP 1 RD 1 RD 1 Device CRGs Chapter 6. Independent ASPs explained 111 The second example illustrates an IASP configuration with two IASPs in the same tower. This is shown in the diagram on the right side of Figure 6-5. Independent IASPs numbered 38 and 39 each define a subset of the disks of the tower. Note that when the tower is switched, both IASPs are switched to the second system. Figure 6-5 IASP configuration: Examples 1 and 2 The third example illustrates a three IASP configuration that uses two towers. See the diagram on the left side of Figure 6-6 for an illustration. Independent ASPs numbered IASP51 and IASP53 are made up of a subset of disks of their individual towers. IASP52 spans the two towers. It is made up of disks from both of the towers. Note that, practically speaking, IASP52 does not represent an optimum configuration. This is because when IASP52 is switched, IASP51 or IASP53 is forced to switch with it. A better configuration is for IASP52 to be fully contained within one of the towers. Then IASP51 and IASP53 can share the second tower. The fourth example illustrates that an IASP configuration (IASP45) can span two towers. See the diagram on the right side of Figure 6-6. Figure 6-6 IASP configuration: Examples 3 and 4 IASP33 SCSI IOA Tape device I/O bus interface Combined function IOP Disk Unit Disk Unit Disk Unit Disk Unit Communications IOA Communications IOA Disk Unit Disk Unit Disk Unit Disk Unit Disk Unit Disk Unit Disk Unit Disk Unit Communications IOP iASP38 iASP39 I/O bus Interface Disk Unit Disk Unit Disk Unit Disk Unit Disk Unit Disk Unit Disk Unit Disk Unit Disk Unit Disk Unit Disk Unit Disk Unit I/O bus interface Disk Unit Disk Unit Disk Unit Disk Unit Disk Unit Disk Unit Disk Unit Disk Unit Disk Unit Disk Unit Disk Unit Disk Unit iASP51 I/O bus interface Disk Unit Disk Unit Disk Unit Disk Unit Disk Unit Disk Unit Disk Unit Disk Unit Disk Unit Disk Unit Disk Unit Disk Unit iASP53 iASP52 I/O Bus Interface Disk Unit Disk Unit Disk Unit Disk Unit Disk Unit Disk Unit Disk Unit Disk Unit Disk Unit Disk Unit Disk Unit Disk Unit I/O Bus Interface Disk Unit Disk Unit Disk Unit Disk Unit Disk Unit Disk Unit Disk Unit Disk Unit Disk Unit Disk Unit Disk Unit Disk Unit IASP45 112 Clustering and IASPs for Higher Availability on the iSeries Server While all devices packaged in a single I/O tower are switched from one iSeries server to another, clustering support allows for configuration and management of the IASPs using the disk units in the tower only. The non-ASP devices, such as, printers, tape drives, CD-ROM drive, etc., are usable by the iSeries server that now owns the tower. The user is responsible for performing the necessary device configuration, for example, varying on of the non-disk devices. Specifically, the #5074 I/O tower is an enclosure commonly used to house the components of disk units, and therefore an IASP. Although the #5074 I/O tower can house devices other than disk units, only IASPs (switched disks) are supported by clustering in V5R1. The #5079 tower is a hardware package that behaves the same as a #5074 tower, but contains twice as many disk units. In terms of clustering, the #5079 tower can be thought of as two #5074s. 6.7 IASP application examples iSeries applications can readily benefit from the availability and recovery advantages offered by independent ASPs. This section briefly describes the use of IASPs in two application settings: Domino and the Integrated xSeries Server for iSeries. 6.7.1 Domino and independent ASPs A Domino server can be defined on more than one system. Its data directory can reside on a switchable IASP. This allows a Domino server's data to be switched from one iSeries server to another. The same Domino server can be started on another iSeries server and access the data directory on the IASP. See Figure 6-7 for an illustration. Figure 6-7 Domino using IASP For a detailed discussion on complete Domino for iSeries clustering capabilities, refer to: http://www.ibm.com/eserver/iseries/domino CLUSTER #5074Tower* Domino Server A's data directory SYS1 SYS2 App. CRG Domino Server A App. CRG Domino Server A *IASP Chapter 6. Independent ASPs explained 113 6.7.2 Integrated xSeries Server and independent ASPs Windows disks support an independent ASP. For example, if a server named Server A runs with the Integrated xSeries Server for iSeries, or a direct attached xSeries Server, the steps to switch the disk are: 1. Take iSeries Server A offline. The disk tower switches to iSeries Server B. 2. Manually link network server descriptions (NWSDs) to iSeries Server B resource names. 3. Reboot the Windows servers. Windows servers are back online on iSeries Server B. See Figure 6-8 for an illustration. Figure 6-8 Integrated xSeries Server or Direct Attached xSeries Server using IASP 6.8 Configuring and managing IASPs The simplest method to configure and manage an IASP is with the Operations Navigator interface. A “green-screen” DST interface can be used to configure ASPs. However, with V5R1, if a function is supported with Operations Navigator, a GUI is the recommended interface. This section highlights the aspects of creating an IASP using the Operations Navigator. Detailed step-by-step instructions for creating the IASPs using the Operations Navigator are covered in Chapter 7, “Operations Navigator independent ASP GUI” on page 125. Note: The xSeries servers must have the same configuration. Integrated xSeries Server for iSeries A IASP Storage Spaces Windows 2000 Server #1 C, D, E, F NWSD A Integrated xSeries Server for iSeries B NWSD Disk Tower B HSL Loop HSL Loop Windows, Applications, and Data Windows 2000 Server #2 C, D, E, F NWSD NWSD Direct attached xSeries Server A Direct attached xSeries Server B 114 Clustering and IASPs for Higher Availability on the iSeries Server 6.8.1 Creating a new disk pool One of the disk functions available in the hardware path of the Configuration and Service function of Operations Navigator is to create a disk pool. This section explains Operations Navigator initial steps to create a disk pool. Access to the disk functions is controlled via the Service Tools User Profiles, a function of SST introduced at V5R1. Once signed into the Service Tools functions, select the option for disk pools (auxiliary storage pool). In our example, the user selects the “New Disk Pool” option. A “retrieving data” message is displayed to notify the user that the request is being processed. From this starting point, follow the Disk Pool Wizard to create the disk pool. See Figure 6-9 for an illustration. Figure 6-9 Creating a disk pool using the GUI interface Note: Only one Disk Pool Creation task can be run at any one time. 6.8.2 Numbering new pools When creating independent disk pools, the user has the opportunity to name the disk pool. The system assigns the pool number. The user is not given an option to select a number for the pool. Figure 6-10 illustrates the cautions displayed to the user regarding IASP pool number assignment. Chapter 6. Independent ASPs explained 115 Figure 6-10 IASP pool number is assigned by the system 6.8.3 Selecting the disk units to add to a pool When creating the IASP using the Operations Navigator interface, the GUI wizard looks at all the disks in the system and assigns them a suitability rank for use with an IASP. The suitability rank indicates how appropriate the disk unit is to add to the specific disk pool. The lower the number, the more appropriate the match. A number 0-99 indicates the ranking of the most suitable disk, as illustrated in Table 6-2. Select the disk units for inclusion in the IASP based on the rankings. Table 6-2 Independent ASP rankings Important: In V5R1, there are cases when the GUI does not display the correct number when creating the pool. There is no method for the system to unmistakably know the number until the pool is actually created. The present implementation is to not show any number for the independent pool until it is fully created. This is a known restriction that is addressed in a later release. Independent pool creation user names pool system responsible for assigning pool number V5R1 incorrect number may be displayed during creation process correct number is assigned at end of process Rank Description 2 Disk pool and disk are nonswitchable. 53 Disk pool and disk are switchable. 100-199 Valid disks, but not most suitable. 102 Disk pool and disk are nonswitchable, but disk can be made switchable. 151 Disk pool and disk are switchable. The disk's switchable entity is in the same Cluster Resource Group. 116 Clustering and IASPs for Higher Availability on the iSeries Server Find a full list of rankings in the help text associated with the Operations Navigator function. 6.8.4 ASP unit numbering The system selects the ASP number for IASPs. The numbers range from 33 through 99. Use ASP numbers range from 2 through 32. Across an IASP device domain, numbers assigned to ASPs are unique and conform to these standards:  User ASP numbers range from two through 2047.  System ASP is number 1.  IASPs are assigned numbers in the range of 4001 through 6047. The separate ranges provide additional disk unit numbers with these limits:  Each node in the IASP device domain can have up to 2047 units in its system and user ASPs.  The entire IASP device can have up to 2047 units in IASPs. The ASP numbers are in separate ranges to avoid a conflict when user ASPs are added to an IASP device domain within a node. Figure 6-11 shows the IASP pool number and disk unit numbers assigned by the system to an IASP. The disk units in this example are in the range 4001 through 4007. The IASP number is 33. 153 Disk pool is switchable. Disk is switchable, but its switchable entity has no disks in any disk pool in the disk pool's CRG. 200-299 Unlikely disks, and should not be used unless absolutely necessary. 202 Disk pool is nonswitchable. Disk is switchable and its switchable entity already has disks in a switchable disk pool. 300-399 Invalid disks. Cannot be used in the Disk Pool. Rank Description Chapter 6. Independent ASPs explained 117 Figure 6-11 Unit numbering for IASPs and disks in the IASP 6.8.5 Selecting All Disk Units to add to a pool An alternate path available to create IASPs on a system is to select the All Disk Units path. The Select path described in 6.8.1, “Creating a new disk pool” on page 114, is the path most users take to create an independent pool. In this path, there is no option to create more than one disk pool. For a new system or new environment, select the All Disk Units path to work with more than one pool in the same operation. Follow this alternative GUI path to create disk pools. 6.9 IASP and security This section discusses the characteristics of user profiles and authorization lists as they relate to the security of an IASP. 6.9.1 User profiles and IASPs User profile information is stored in the system ASP. Each user profile object is an object type of *USRPRF. Copies of *USRPRF objects are not in any independent pool. However, some user profile information must be maintained on the IASP itself. Each object in an IASP requires this user profile information:  The owner of the object  The primary group of the object  The private authority entries for the object IASPs system assigns disk unit numbers 4001 - 6047 system assigns pool numbers 33 - 99 Unit # Pool # 118 Clustering and IASPs for Higher Availability on the iSeries Server See Figure 6-12 for an illustration. Figure 6-12 IASPs and user profiles Additional storage (above that consumed by objects) is required for these system security structures. This is necessary to make the independent ASP self-contained. These structures consume a maximum of 10% of the disk space within the IASP. The percentage varies and depends on the size of the objects referenced by these structures. SLIC is responsible for storing, retrieving, changing, or deleting the authority information stored on an IASP. OS/400 security interfaces accommodate the SLIC changes. When creating independent disk pools in a multiple (clustered) system environment, it is assumed the content of any user profiles is synchronized across the cluster in which the user profile exists. 6.9.2 Accounting for space owned The total storage attributed to an individual user profile is the sum of the storage used:  In each online IASP  By the user in the local system user ASPs Use the Display User Profile (DSPUSRPRF) CL command to display the total value of this storage. If an IASP is brought online, some user profiles can have the value of their total storage increase dramatically. In some cases, the total amount of storage to which they are authorized is exceeded. To prevent disruptions to a system, the limit for the maximum amount of auxiliary storage that can be allocated by a user profile is not enforced when bringing an IASP online. That is, if bringing an IASP online causes a user profile to exceed its storage limit, the storage limit is allowed to exceed the specified amount. Subsequent requests for additional storage cause a “User Profile Storage Limit Exceeded” exception. *USRPRFs AAA BBB *AUTLs GHI XYZ *USRPRFs AAA BBB *AUTLs GHI XYZ b Independent Pool UDFS STMFs DIRs Ownership Info obj owner primary group private auths Chapter 6. Independent ASPs explained 119 Consider this example to help illustrate this concept. An IASP starts in an offline status. User AAA has a maximum storage (MAXSTG) value of 1000. 500 objects are in the local system and user pools. Similarly, user BBB has a MAXSTG of 1500 with 1200 in use. The IASP contains objects HJK and RST, which represent 950 units of total storage. Figure 6-13 illustrates this situation. Figure 6-13 Accounting for space used Then the IASP is brought online. User profile AAA is updated to a value of 750, which is still below its MAXSTG value of 1000. However, BBB now exceeds its MAXSTG value of 1500. That is, the addition of HJK brings the value owned to 1900. User profile BBB is not allowed to own any additional objects. 6.9.3 IASP and authorization lists Authorization lists are used to secure access to objects in a system, irrespective of ASP boundaries. An authorization list (similar to a user profile) is implemented as a distributed object. That is, it can secure objects within the system ASP, user ASPs, and any IASPs. There remains one copy of each authorization list (*AUTL) object in the system ASP. Copies of *AUTL objects are not kept on IASPs. However, when an object on an IASP is secured by an authorization list, the name of that list is kept on the IASP. This concept is illustrated in Figure 6-14. Authorization lists AUTL111 and AUTL222 are stored in the IASP, because the objects HJK and RST are secured by these lists. There is no reference on the IASP itself to the authorization list AUTL333 because the object LHR is not stored on the IASP. SYS1 IASP off-line AAA is OK BBB is OK User Space Space Local Max AAA 500 1000 BBB 1200 1500 b Independent Pool Obj Size Owner HJK 700 BBB RST 250 AAA IASP on-line AAA is OK BBB is MAX+ 120 Clustering and IASPs for Higher Availability on the iSeries Server Figure 6-14 IASPs and authorization lists As with user profiles, the Licensed Internal Code (LIC) is responsible for handling this function. The user interface does not change for storing, retrieving, changing, or deleting the authorization list information on an IASP. Switching IASPs and *AUTLs The effect of switching an IASP when at *AUTL is implemented as described in this section. For this description, these are the assumptions, activities, and results:  Assumptions – An IASP has been switched from one system to another. – A user attempts to access an object in the IASP. – The object in the IASP is secured by an authorization list.  Activity – LIC accesses the IASP and retrieves the name of the authorization list. LIC attempts to connect to the authorization list on the newly attached system. – If an authorization list with that name is found on this system, authority checking proceeds as normal. – If an authorization list with that name is not found on this system, the attempted access to the object is handled the same as if the authorization list is damaged.  Results – Any authority check that is satisfied before the authority list is tested works as expected. – When an authority check tries to access the missing authorization list, the result is an “object damaged” failure. – The Display Authority (DSPAUT) command displays blanks for the authorization list name. Objects ADL HKG RST ORD Objects not secured by authorization list ADL ORD SYS1 AUTL on SYS1 AUTL111 HKG AUTL222 RST AUTL333 LHR Chapter 6. Independent ASPs explained 121 – The user can change the authorization list name using the Change Authority (CHGAUT) command. 6.10 System operations with IASPs An IASP can be brought online and made active at any time during IPL or after the system is IPLed. The IASP is brought online by the system during IPL if the device description of the IASP specifies *YES for the Online at IPL parameter (ONLINE(*YES)). Once the IASP is online and active, the objects within the IASP are accessible and usable. An IASP that is online on one system can be varied offline by that system. This can be done explicitly by user request or it can be done implicitly by system termination. 6.10.1 IASP overflow There is a difference between ASPs and independent ASPs as it relates to the action when an ASP overflows. That is:  An overflow of a basic ASP occurs when the ASP fills. The excess data spills into the system ASP.  IASPs are designed so that they cannot overflow; otherwise, they would not be switchable. When there is insufficient space available for a requested allocation of storage in an IASP, Auxiliary Storage Management either signals a new exception (ASP Storage Limit Exceeded) or returns an error code. 6.10.2 Switching IASPs between nodes The process of switching IASPs between nodes within a domain is performed by cluster software. If the IASP is to be switched between LPAR partitions, then the disk units can be either internal or external components. If the IASPs are to be switched between machines (that is, separate CECs), then the disk units must be external, such as those in a switchable tower or a Storage Area Network (SAN). A logical SPCN related question to ask is: When the SPCN node of a switchable tower has a failure, what happens to the tower? The answer is that Cluster Management handles this. Even though the SPCN node of the switchable tower fails, Cluster Management instructs the tower to remain on. The tower does not power down. Cluster Management then switches the tower to the other system and the other system then has access to the tower. 6.10.3 Reclaim Storage and IASPs With the introduction of IASPs comes the capability to run Reclaim Storage (RCLSTG) on an IASP while the rest of the system keeps running. This implies that multiple IASP RCLSTG processes can execute simultaneously. Important: An IASP can go offline and yet the remainder of the system remains functional. However, once an IASP is offline, the objects that it contains are no longer visible to, accessible from, or usable by the system where it was previously online and active. 122 Clustering and IASPs for Higher Availability on the iSeries Server V5R1 functional changes to the RCLSTG command added to support IASPs are:  *SYSBAS values If the *SYSBAS value is specified for the ASP device, the Reclaim Storage operation runs as it does on systems prior to V5R1. The reclaim operation is performed on the system and on traditional user-defined ASPs. If the value specified is an ASP device name, then that ASP is reclaimed.  Reclaim Storage for an ASP device (that is, an IASP) can be run without the system being in restricted state. Multiple jobs can be submitted, each performing RCLSTG on a different ASP device. Multiple ASP devices can be reclaimed in parallel. 6.11 Positioning cluster middleware solutions with IASPs With the introduction of IASPs on the iSeries server, the questions arise:  Are cluster middleware solutions needed?  Can an IASP solution support high availability for the business? To understand the fit of IASPs, it is important to understand the requirements of the business. Use the information in Table 6-3 to compare the needs of the business to the functions available with a replication solution and that offered by an IASP switched disk solution. Table 6-3 Comparison of cluster middleware replication and IASP switched disk While it is true that IASPs provide a new means of high availability on the iSeries server, it does not replace business partner solutions. Independent ASPs co-exists with these solutions. Note: Reclaiming an auxiliary storage pool device requires that there are no active users of the ASP device that is the subject of the reclaim. Cluster middleware replication solution IASP switched disk solution Number of systems in cluster Tens of systems Two systems Single Point of Failure None Disk subsystem Cost factors Additional disk capacity. Replication software. Switchable I/O expansion tower Performance factors Replication overhead Negligible Typical failover time hours Around 15 minutes Typical switchover time Around 30 minutes Around 5 minutes Real time coverage Objects journaled Objects in IASP Objects supported A very large set IFS only (except QSYS.LIB) Geographic dispersion Unlimited Limited distance to attach (250 meters maximum) Disaster Recovery Protection Yes No Concurrent backup Yes No Setup Replication environment. What to replicate. Requires Clustering support on the two systems. Chapter 6. Independent ASPs explained 123 Consider these characteristics of IASP and replication solutions:  Replication solutions provide geographical dispersal of the data. The production and backup systems can be several thousand kilometers apart. This is an important factor for effective disaster recovery.  With an IASP solution, the systems must be within 250 meters of each other because of the limitations of the HSL Loop. With some V5R1 configurations, the distance is limited to 15 meters.  Customers who simply want high availability at a lower cost can use independent ASPs without adding disks for the backup system.  A replication solution provides switchover capability between two systems. The level of monitoring between systems can be primitive. However, the approach for switchover and failover is complex. Monitoring is performed at a high level. In comparison, using switchable IASP with clustering provides a means to handle a complex requirement in a relatively simple way. The heartbeat monitoring that is implemented with IBM clustering is very sophisticated. Once properly setup, the switchover or failover to the backup system can be nearly seamless. 6.12 iSeries IASP and other platform solutions Non-iSeries platforms (such as UNIX and Windows NT systems) have offered switched disk solutions for high availability for several years. Given earlier limitations and the exposures of a switched disk solution, these platforms have now added replication technology to their suite of high availability offerings. For example, the high availability product on the IBM ~ pSeries (RS/6000) servers is High Availability Cluster Multi-Processing for AIX (HACMP). This product has been around for many years. HACMP provides the switched disk solution for high availability. A newer product called HACMP GSO is now available to provide replication technology for the pSeries customer. iSeries enabled these two functions in the reverse order. The iSeries offerings started with a replication technology solution and have now added switched disk technology with V5R1. The important point to note is that both replication and switched disk solutions are needed. Indeed, they must co-exist. This is evident for non-iSeries as well as iSeries platforms. 6.13 Reference material You can find useful sources of further information on independent ASPs and related topics at:  InfoCenter: http://publib.boulder.ibm.com/html/as400/infocenter.html  High Availability: http://www.iseries.ibm.com/ha  iSeries Backup and Recovery, SC41-5304 124 Clustering and IASPs for Higher Availability on the iSeries Server © Copyright IBM Corp. 2000, 2002 125 Chapter 7. Operations Navigator independent ASP GUI Configuring a cluster, configuring a hardware group (a resilient device CRG), and performing a switch are done from the primary node of a cluster (the central server). The central server is used to activate the cluster objects, but the disk pool (the IASP) is managed from the specific system. There are two types of IASPs: standalone and switchable. This chapter describes the steps necessary to create each type of independent auxiliary storage pool (IASP) using the GUI that is part of Operations Navigator in OS/400 V5R1. This method creates a system group that is coupled tightly with the cluster. 7 126 Clustering and IASPs for Higher Availability on the iSeries Server 7.1 Prerequisite steps to create an IASP Before you can create any IASPs, there are some prerequisite steps within Operations Navigator that you must complete. These steps have to do with configuring the adapter used by Service Tools on the iSeries server and setting up Management Central so that disk devices can be managed. 7.1.1 Configuring the Service Tools adapter on the iSeries server A service table entry is required to use the disk functions of Operations Navigator. The steps to add a service table entry and submit a job to reclaim TCP on the iSeries servers that is to be used with the IASP are illustrated in this section. Use the Add Service Table Entry (ADDSRVTBE) command and fill in the parameters as shown in Figure 7-1 to add a service table entry named ‘as-sts’. Figure 7-1 Adding a service table entry on the iSeries server Press Enter to continue. The service table entry added in this step does not become effective until TCP is ended and started again. Use the ENDTCP and STRTCP commands to end and start TCP. Add Service Table Entry (ADDSRVTBLE) Type choices, press Enter. Service . . . . . . . . . . . . 'as-sts' Port . . . . . . . . . . . . . . 3000 lowercase Protocol . . . . . . . . . . . . 'tcp' Text 'description' . . . . . . . 'Service tool adapter' Additional Parameters Aliases . . . . . . . . . . . . AS-STS UPPERCASE + for more values Bottom F3=Exit F4=Prompt F5=Refresh F12=Cancel F13=How to use this display F24=More keys Tip: Enter the value for the Service and Protocol parameters:  In lowercase letters  Enclosed in single quotes If the entries do not follow these rules, and Additional Parameters is selected, the Protocol value becomes uppercase letters, which causes an error to occur. Chapter 7. Operations Navigator independent ASP GUI 127 7.1.2 Setting up Management Central Configure the Management Central function in Operations Navigator. The necessary setup steps are illustrated in this section: 1. Start with Operations Navigator as shown in Figure 7-2. Figure 7-2 View of Operations Navigator Tip: The connection to the system is broken when ENDTCP is issued from a TCP-connected terminal. Also, commands (including STRTCP) cannot be entered from any TCP-connected terminal until connectivity with the system is re-established. Enter the Start TCP and End TCP commands from the system console or from a green-screen terminal. 128 Clustering and IASPs for Higher Availability on the iSeries Server 2. Right-click the system name. Select Application Administration from the drop-down list as illustrated in Figure 7-3. Figure 7-3 Access Application Administration in Operations Navigator 3. If a window is displayed, as illustrated in Figure 7-4, click OK to continue. Figure 7-4 Application Administration window Chapter 7. Operations Navigator independent ASP GUI 129 4. Select the Host Applications tab on this window, as shown in Figure 7-5. Figure 7-5 Host Applications tab 5. On the Host Applications page (Figure 7-6), expand the Operating System/400 and Service folders until Disk units is displayed. Select the Default Access and the All Object Access squares next to the Disk units. Click OK. Figure 7-6 Enabling disk unit access Now the Disk Units function can be used from within Operations Navigator. 130 Clustering and IASPs for Higher Availability on the iSeries Server 7.2 The independent auxiliary storage pool GUI IASPs can be standalone or switchable. The steps to create an IASP depend on the type of IASP to be created. The steps are described in this section. 7.2.1 Creating a standalone independent auxiliary storage pool Figure 7-7 illustrates a non-switchable independent ASP called IASP1. It is created on a system named AS24. Figure 7-7 Non-switchable independent ASP with Integrated xSeries Adapters (IXA) attached IASPs are useful to segregate parts of the Integrated File System. They also can be used to store data for two Integrated xSeries Adapters. If one of the Integrated xSeries Adapters fails, the other Integrated xSeries Adapter can be configured to use the data on the IASP. A standalone IASP is created using the Disk Pools function of Operations Navigator. To arrive at the Disk Pools section within Operations Navigator, click My Connection-> System Name-> Configuration and Service-> Hardware-> Disk Units-> Disk Pools. The steps to create a standalone IASP are: 1. Sign on to DST using the Service Tools user ID and password, as illustrated in Figure 7-8. Internal Disk Internal IASP IXA 1 IXA 2 iSeries AS24 IASP1 Chapter 7. Operations Navigator independent ASP GUI 131 Figure 7-8 Signing on to DST 2. Right-click Disk Pools and select New Disk Pool to invoke the New Disk Pools wizard, as illustrated in Figure 7-9. Figure 7-9 New Disk Pool 3. Once the IASP is created, vary it on. This example next copies some PC files to the IASP to illustrate that they are now usable from the IASP. Asm01 Asm15 Asm24 132 Clustering and IASPs for Higher Availability on the iSeries Server The display in Figure 7-10 illustrates the New Disk Pool wizard’s Welcome panel. Figure 7-10 Welcome panel of the New Disk Pool Wizard 4. When the New Disk Pool wizard starts, click Next. A Specify Disk Pool Type panel is presented, as illustrated in Figure 7-11. Chapter 7. Operations Navigator independent ASP GUI 133 5. Use the pull-down menu and select the type of disk pool. Enter a name for the pool. If any disk units are to be included in a device parity set, select the Protect the data in this disk pool check box. Figure 7-11 Specifying the disk pool type In this example, we select Independent for disk pool type, iasp67 as the pool name, and select Protect the data in this disk pool. The pool name is used to distinguish it from other ASPs that are configured on the system. iasp67 134 Clustering and IASPs for Higher Availability on the iSeries Server 6. Select the disk units to be protected, as illustrated in Figure 7-12, or select All disk units. Figure 7-12 Protecting a disk pool If the disk is not added at this time to a parity set, it can be added later using Operations Navigator. a. Click OK to return to the New Disk Pool Welcome panel. b. Click Next to continue. The next display lists the disk units available to add to a pool. This display (as illustrated in Figure 7-13) only appears if there are disks that are eligible to be included in an existing device parity set. If so, an option is offered to start parity on the selected units. Similarly, if the eligible disk units support disk compression, an option is offered to start compression on the selected disk units. Note: Depending on the cluster, some disk units may not be displayed even though they are non-configured. Chapter 7. Operations Navigator independent ASP GUI 135 7. Highlight the disk units to be in the pool. Click Add, as illustrated in Figure 7-13. Figure 7-13 Selecting the disk units 8. When finished, click Next. 9. To have the system automatically balance the new disk pool, select the Yes, balance disk pools option, as illustrated in Figure 7-14. Figure 7-14 Balancing the disk pools Note: If the disk pool is comprised of all new (empty) disk units, select the No option. 136 Clustering and IASPs for Higher Availability on the iSeries Server Click Next. A summary dialog (Figure 7-15) of the disk pools on the system appears. Figure 7-15 Summary of the disk configuration 10.Click Finish to complete the configuration. A moving bar (Figure 7-16) indicates the progress of the operation. Figure 7-16 New Disk Pool Status window When complete, a successful completion message (Figure 7-17) is displayed. Chapter 7. Operations Navigator independent ASP GUI 137 Figure 7-17 Disk pool created The new IASP is now visible to Operations Navigator (see Figure 7-18). Figure 7-18 Disk pool visible to Operations Navigator The disk pool has been created. The status is Unavailable. Note: Operations Navigator uses the term “unavailable” to indicate “varied off”. 138 Clustering and IASPs for Higher Availability on the iSeries Server 11.Before the resources within a new disk pool (IASP) can be used by the system (node), the IASP must be varied on. To make the IASP available (vary it on), right-click the pool and select Make Available (Figure 7-19). Figure 7-19 Varying on the IASP 12.Confirm the choice by clicking the Make Available button for the independent auxiliary storage pool (Figure 7-20). Figure 7-20 Confirming to make the disk pool available Chapter 7. Operations Navigator independent ASP GUI 139 13.A successful vary on completion message is displayed after the vary on operation completes, as illustrated in Figure 7-21. Figure 7-21 Vary on completed 14.Click OK. When an IASP device is created, the system automatically generates a user-defined file system (UDFS) with the same name as the device (IASP) name. Place the files to be used by the application environment into the default UDFS (root/iasp-name/mydir). Directories can be created under the IASP directory. When the IASP is made available (varied on), the default UDFS file system is automatically mounted in the root directory of the system’s Integrated Files System (IFS). The root/dev/iasp-name ASP and UDFS iasp-name are then visible through the Operations Navigator IFS view. 15.Expand the Integrated File System option in Operations Navigator. 67 140 Clustering and IASPs for Higher Availability on the iSeries Server 16.Expand the items under the Root directory. The new IASP is the last item listed, as illustrated in Figure 7-22. Figure 7-22 IASP visible on the Integrated File System 17.Copy some PC files to the new IASP. Figure 7-23 illustrates the results of a copy. Figure 7-23 PC files on the IASP Directories can also be created under the IASP directory. IASP67 IASP67 Chapter 7. Operations Navigator independent ASP GUI 141 18.Use the Work with Object Links (WRKLNK) command to display the Integrated File System on a green screen, as illustrated in Figure 7-24. Figure 7-24 Displaying IFS files with WRKLNK The files copied to the IFS are listed. 7.2.2 Creating a switchable independent auxiliary storage pool In this section, a switchable IASP named IASP2 is created under a cluster named AS1723R. AS1723R is comprised of two nodes: System AS01B and System AS01C. The Switchable Hardware Group (Device CRG) under which this IASP is managed is called Switch2. This relationship is illustrated in Figure 7-25. 142 Clustering and IASPs for Higher Availability on the iSeries Server Figure 7-25 Simple two-node cluster using a switchable IASP Figure 7-25 shows that IASP2 is attached to both system AS01B and system AS01C. It can be switched between both systems. The IASP is typically an expansion tower, or it can be a shared IOP in an LPAR scenario. In the event that one of the systems fails, the switchable IASP automatically fails over to the other system. Any Integrated File System object stored in the IASP is then visible and usable to the other system. In addition, it is possible to perform a manual switch of the IASP from one system to the other by varying it off on one system and varying it on the other. Before a switchable IASP is created, a cluster must be defined. Here are some key points to remember when creating a switchable IASP:  Create the cluster and ensure that it can be started and stopped.  Use the New Group option under the Switchable Hardware section of Operations Navigator to create a switchable IASP. The switchable IASP is created as a part of creating the switchable hardware group. To access the switchable hardware section, select Management Central-> Clusters-> Cluster Name-> Switchable Hardware. Right-click the Switchable Hardware icon and select the New Group option to start the Switchable Hardware Group wizard. Follow the steps to create the switchable hardware group depending on whether the IASP exists: – To specify an existing IASP, enter the IASP device description name when prompted for the disk pool name. A confirmation and warning message is then displayed to indicate that the name specified already exists. Click Yes to use the existing IASP. – To create a new IASP, follow the wizard prompts. This is the simplest method and typically presents the least number of problems. To create a switchable IASP using the wizard, follow these steps: 1. Click the + (plus sign) next to the Cluster name to expand the options. Direct attached switchable disk iSeries AS01B iSeries AS01C IASP2 Cluster AS1723R Device CRG: Switch2 Chapter 7. Operations Navigator independent ASP GUI 143 2. Right-click Switchable Hardware. 3. Select New Group, as illustrated in Figure 7-26. Figure 7-26 Creating a new switchable hardware group A switchable hardware group is another term for a switchable IASP. 4. The Welcome panel (Figure 7-27) of the wizard appears. Click Next. Figure 7-27 The Welcome panel Asm01 Asm15 Asm24 Asm01 Asm15 Asm24 144 Clustering and IASPs for Higher Availability on the iSeries Server 5. The New Group – Specify Primary Node window appears (Figure 7-28).Type the name of the Primary node of the cluster. Figure 7-28 Selecting the primary node 6. Click Next to continue. Chapter 7. Operations Navigator independent ASP GUI 145 7. The New Group – Specify Primary Name window appears (Figure 7-29). Specify a name for the Switchable Hardware Group. Figure 7-29 Specifying a group name Note that Switch2 is not the name of the switchable IASP being created. Switch2 is the name of the switchable hardware group (the Switchable Device CRG) under which the switchable IASP is to be managed. At this point, the independent ASP or disk pool does not yet exist. 146 Clustering and IASPs for Higher Availability on the iSeries Server 8. Specify the name to call the disk pool. Indicate whether to protect the data in the pool, as illustrated in Figure 7-30. – If the disk pool does not exist, the New Group – Create New Disk Pool dialog box appears as shown in Figure 7-30. Figure 7-30 Specifying the disk pool name Chapter 7. Operations Navigator independent ASP GUI 147 – If the disk pool does exist, a dialogue box appears that asks you to specify whether to use the existing disk pool name. If you specify an existing pool name, a dialogue box appears. Click Yes. The wizard ends with the New Group – Summary window (Figure 7-31). Figure 7-31 New Group – Summary 9. Click Finish. 10.Click Next to continue. 148 Clustering and IASPs for Higher Availability on the iSeries Server 11.For a new disk pool, the Add Disk Pool wizard (Figure 7-32) starts. Click Next to continue. Figure 7-32 Add Disk Pool wizard Chapter 7. Operations Navigator independent ASP GUI 149 12.The Add Disk Unit window (Figure 7-33) appears. The disk units that are available to be part of the new disk pool are located on the left side of the box. Select a disk unit to be part of the disk pool. Click the Add button. Do this for each of the disk units to be added. Figure 7-33 Selecting the disk units 150 Clustering and IASPs for Higher Availability on the iSeries Server Use the Remove button to deselect the disk unit if it is selected in error. An example of how the screen appears after the switchable disk pool disk units are selected is shown in Figure 7-34. Figure 7-34 Units selected Chapter 7. Operations Navigator independent ASP GUI 151 13.To balance the disk pool so that an equal amount of data resides on each disk, select Yes, balance disk pools, as illustrated in Figure 7-35. Click Next. Figure 7-35 Balance Disk Pools 152 Clustering and IASPs for Higher Availability on the iSeries Server 14.A summary of the auxiliary storage pools on the system is displayed, as they appear after the new disk pool is created. See Figure 7-36 for an illustration. Figure 7-36 Disk pool summary Nothing is changed on the system up to this point. The disk configuration has not yet been modified. Chapter 7. Operations Navigator independent ASP GUI 153 To proceed with the disk pool creation and commit the changes, click Finish. The disk pool is now created. See Figure 7-37 for an illustration. Figure 7-37 Creating disk pool 154 Clustering and IASPs for Higher Availability on the iSeries Server 15.This step can take from a few minutes to one hour or more, depending on the number of disk units to be initialized and added to the IASP. When the group has been created, a successful creation message is displayed, as illustrated in Figure 7-38. Figure 7-38 Successful creation message Chapter 7. Operations Navigator independent ASP GUI 155 16.The configuration summary of the New Group is displayed. Click Finish to continue, as illustrated in Figure 7-39. Figure 7-39 Group summary 156 Clustering and IASPs for Higher Availability on the iSeries Server 17.Right-click the group name to start the new hardware group. Select Start, as illustrated in Figure 7-40. Figure 7-40 Start New Hardware Group 18.The group is, by default, attached to the primary node of the cluster. A window is displayed that shows the IASP as it appears under the Integrated File System of the primary node. The IASP is seen under the Root directory of the IFS. See Figure 7-41 for an illustration. Figure 7-41 IASP before switch IASP Attached to system AS01C Chapter 7. Operations Navigator independent ASP GUI 157 In this example, you see that some PC files have been placed in the IASP. There is a directory named “ITSO documents”. 19.To perform a manual switch of the IASP between systems, right-click the Switchable Hardware Group name. Select Switch, as illustrated in Figure 7-42. Figure 7-42 Switching the IASP group 20.A dialogue box appears to confirm the switch of resources. Select Yes to confirm this action. The confirmation helps ensure that the IASP is not randomly switched between systems. See Figure 7-43 for an illustration. Figure 7-43 Switch confirmation Asm01 Asm15 Asm24 158 Clustering and IASPs for Higher Availability on the iSeries Server The switching of resources to the backup system is complete. The disks that represent IASP2 have been switched to AS01B. The switching software handles the vary on. A manual vary on is not necessary. Figure 7-44 illustrates how the results of the switch are indicated on the backup system (AS01B). Figure 7-44 Disks attached to the backup system The PC files have been moved and are now available to users on AS01B. Now attached to AS01B IASP2 and its files have been switched Chapter 7. Operations Navigator independent ASP GUI 159 The Work with Disk Status (WRKDSKSTS) command can be used to verify where the IASP disks are attached. Prior to the switch, WRKDSKSTS indicates the disk units are attached to the Primary system (System AS01C). See Figure 7-45 for an illustration. Figure 7-45 WRKDSKSTS shows disks attached to primary node Note that the disk units appear as type 4xxx, which indicates they are switchable. After the switch is performed, the 4xxx disk units are no longer available to the original system. Figure 7-46 illustrates the Primary system (AS01C) after the switch. Figure 7-46 Disks are not visible after the switch 160 Clustering and IASPs for Higher Availability on the iSeries Server The IASP is now part of the backup system. Figure 7-47 illustrates this with the output of the WRKDSKSTS command on System AS01B. Note that the disk units appear as type 4xxx, which indicates they are switchable. Figure 7-47 IASP attached to backup node © Copyright IBM Corp. 2000, 2002 161 Chapter 8. ClusterProven for iSeries applications Disruption of a user’s access to the system is visible to the user through the application interfaces used to process transactions and run applications. True availability is achieved when user applications are consistently, and constantly, available to the user. This application resiliency requirement is recognized and designed into the iSeries cluster architecture. IBM recognizes the importance of continuous availability and supports the need for applications to participate in a high availability solution. IBM ClusterProven branding is recognized across all four ~ platforms to drive the standard for availability higher. ClusterProven branding identifies those applications that take steps to increase application resiliency. The ClusterProven program has unique criteria for each platform. ClusterProven for iSeries is defined to mean that an application can switch over to an alternate cluster node, provide for automated configuration and activation by cluster management, and return the application user to an application menu screen or beyond after a failover, while the user is active. ISV applications that meet the requirements are listed in the IBM Global Solutions Directory as ClusterProven and can display the ClusterProven logo (see Figure 8-1) in an approved manner. This chapter describes the process for applications to achieve the ClusterProven for iSeries designation. 8 Figure 8-1 IBM logo for ClusterProven applications 162 Clustering and IASPs for Higher Availability on the iSeries Server 8.1 ClusterProven components The iSeries operating system provides the basic cluster infrastructure that combines the functions of the Cluster Resource Services, cluster middleware software, and the application software to produce the iSeries cluster solution. This partnership recognizes the need for both data resiliency and application resiliency in the solution. The components of a cluster partnership are presented in Figure 8-2. Figure 8-2 iSeries cluster partnership 8.1.1 OS/400 Cluster Resource Services Cluster Resource Services provide cluster functions and an open set of application programming interfaces (APIs). As part of the iSeries base operating system since V4R4, applications can use these services to create and manage a cluster. Cluster Resource Services establish the architecture from which all high availability business partners and independent software vendors can build solutions to enable high availability. The Cluster Resources are controlled by the iSeries server. 8.1.2 Data resiliency Data resiliency means to maintain one or more copies of application data on one or more backup systems or logical partitions so that the data is always available. Data resiliency can be achieved within the iSeries cluster architecture by replication or switched disk technology. Switched disk technology uses switchable towers, independent ASPs, and other system functions to make the data resilient to the user. A single copy of the data is maintained on disk towers that can be made available to a second server in the event of the loss of the primary server. Replication technology uses journaling and other techniques to keep an up-to-date copy of the data on a backup server. Cluster middleware products from DataMirror, Lakeview Technology, and Vision Solutions offer products that replicate data objects to backup iSeries servers. Their replication functions are controlled by data CRGs, and their products each provide an associated exit program that seamlessly interfaces with Cluster Resource Services. Cluster Middleware Products Cluster Management Data Resiliency via replication or switched disk Application Resiliency Cluster Resource Services APIs ClusterProven Applications Chapter 8. ClusterProven for iSeries applications 163 8.1.3 Cluster management Cluster management provides the interface to the cluster operator for controlling the creation and operation of the cluster. It is the primary interface for handling all data resiliency and application resiliency operations in the cluster. Control of the cluster nodes (adding, removing, starting, and ending) and control of all CRGs (starting, stopping, and switchover) are handled from a single interface located on any cluster node. Cluster management can be provided by Management Central within Operations Navigator for clusters with applications that use device CRGs. Cluster middleware products include sophisticated cluster management utilities for full support of all CRGs (device, data, and application) and clusters with more than two nodes. Refer to Part 3, “Cluster middleware business partners” on page 227, for further information on the cluster management products offered by DataMirror, Lakeview Technology, and Vision Solutions. Refer to Chapter 5., “Implementing and managing clusters with IBM solutions” on page 59, for further information on managing two-node switch disk solutions with the cluster functions within Management Central. 8.1.4 Application resiliency Resilient applications provide for maintaining across a failure, or an automated recovery of, the application user’s state to the primary server and the resulting switchover to a backup cluster node. Within the iSeries cluster architected solution, a resilient application is one that uses data or device CRGs, application CRGs, and an IP takeover address to maintain resiliency. There are levels of participation in the iSeries cluster. An application can be unaware of the cluster and only have the application data controlled by a data CRG. Or it could have a universal application CRG exit program that allows it to have an IP takeover address and start and stop control of the application. Or, the application CRG exit program can include recovery actions. The options for iSeries applications operating in an iSeries cluster range from no involvement at all to designing for the highest level of application resiliency with no loss of the end user display during a failover in a client server environment. Applications that take full advantage of the iSeries cluster functions available to them can qualify to become ClusterProven for iSeries applications. There are two designations of resiliency for iSeries applications: ClusterProven and Advanced ClusterProven. The criteria for each designation is discussed in the following section. 8.2 ClusterProven defined ClusterProven for iSeries designation is available for applications that meet specific availability design criteria based on OS/400 Cluster Resource Services functions and architecture. Simple ClusterProven requires returning to an application menu display. The focus is on application resiliency and the ability to restart the application on the backup server. The key to application restart is in the ability to reproduce the job state on the backup server. The job state includes the current user, internal program variables, partially written spooled files, record pointers, program call stack, and other job-related attributes. Keeping 164 Clustering and IASPs for Higher Availability on the iSeries Server track of all these elements for a traditional, green-screen interactive application can present a difficult challenge because the job state information is stored on the primary system. Client/server applications are more conducive to application restart because the client stores most (and in some cases, all) of the job state information. As designs are made for higher levels of availability, the user state is maintained in the client. Or the application is designed to maintain the user state on the backup server and actions are taken to return the user to the proper state on a subsequent signon of the particular user after a failover. An application designated as ClusterProven for iSeries meets the requirements of the specification to:  Provide information to enable automatic configuration and activation for resilient resources  Supply an exit program to restart the application  Integrate with data resiliency services (frequently provided by a cluster middleware provider) The specifications for ClusterProven, including the Resilient Definition and Status Data Area, Object Specifier File, and the application CRG exit program, are located on the iSeries high availability Web site at: http://www.ibm.com/eserver/iseries/ha A sample exit program is also provided in the QUSRTOOL library (OS/400 Option 7), member name TCSTAPPEXT in the file QATTSYSC. The required effort is application dependent. You can find the layout of an object specifier file in B.4, “Object specifier file layout” on page 288. 8.2.1 The Advanced ClusterProven for iSeries Program The Advanced ClusterProven for iSeries Program offers a branding logo for solution developer applications that demonstrate highly available characteristics. Criteria for iSeries Advanced ClusterProven include application characteristics that:  Meet all of the criteria for ClusterProven for iSeries program listed in 8.2, “ClusterProven defined” on page 163.  Provide enhanced application resilience through more robust handling of cluster events (action codes) by the application CRG exit program.  Provide greater level of application restart support.  For host-centric applications, the user is repositioned to a transaction boundary via commitment control or checkpoint functions.  For client-centric applications, the user experiences a seamless failover with minimal service interruption. 8.3 Obtaining the ClusterProven trademark Obtaining the ClusterProven for iSeries trademark is a two-step process: 1. Validate the application against the criteria listed in Table 8-1 and submit the results to iSeries PartnerWorld (PWD). PartnerWorld is the final arbiter of whether the criteria for registration as ClusterProven for iSeries is met. 2. The software developer agrees to the terms and conditions covering the use of the ClusterProven trademark. Chapter 8. ClusterProven for iSeries applications 165 Regardless of whether an application is verified as meeting the criteria herein, or whether IBM has accepted such verification, no right to use the trademarks is granted until both parties have signed the ClusterProven Trademark Agreement. Criteria to obtain ClusterProven trademark The type of criteria used to identify applications as ClusterProven for the iSeries server is listed in Table 8-1. Table 8-1 ClusterProven for iSeries criteria You can find additional information about ClusterProven applications at: http://www-1.ibm.com/servers/eserver/iseries/ha Function Characteristic Cluster management resilient environment  An auto configuration of application resiliency is performed using the architected data area in the application produce library. The data area identifies the resources to be resilient.  Auto-activation of application resiliency from Cluster Management product.  Changes to the data objects are available to backup nodes due to replication or by storing on a switchable IASP. Application resiliency  Application CRG is generated through auto configuration, representing the application function.  Application CRG exit program handling of action codes, including start, end, restart, switchover, and failover.  IP takeover is utilized for application failover.  Failover is coordinated with associated data or device CRGs.  Application resiliency is configured using the information found in the automated installation data area.  A switchover operation results in the transfer of the primary data server to the first backup data server defined in the data CRG.  The IP address of an application CRG moves from the primary application server to the first backup application server as defined in the application CRG.  For a host-centric application the active session at the point of switchover returns to an application menu screen or beyond following a subsequent log-on at the backup server.  For a client-centric application, the active session at the point of switchover resumes at the same point on the backup server.  The application CRG exit program validates that the required data CRG or CRGs are active on the backup node. Data resiliency  A data or device CRG is generated through auto-configuration, representing the data function.  The application-related data objects listed in the object specifier file associated with a data or device CRG are copied to backup cluster nodes or stored in a switchable IASP.  Following a switchover, the application moves to the current primary data server for subsequent data operations. 166 Clustering and IASPs for Higher Availability on the iSeries Server 8.4 ClusterProven Domino for iSeries Lotus Domino for iSeries Release 5.0.7 is certified by the Rochester laboratory as ClusterProven in April 2001. In a switched disk environment, the same Domino server can be configured on a second iSeries server (cluster node) provided both systems can switch access to that server’s data directory by using an independent auxiliary storage pool. The same Domino server can be restarted on that second sever with minimal interruption in the server user’s environment. This means that the Domino application can have its configuration and files switched over to a second system (cluster node) with minimal or no interruption in the running Domino environment. ClusterProven Domino for iSeries is an OS/400-specific enhancement to Domino that allows V5R1 OS/400 Cluster Management to manage iSeries-based Domino servers. A Domino server's definition is duplicated on multiple iSeries servers (known as nodes) in an OS/400 cluster managed by OS/400 Cluster Management. The same Domino server is automatically defined on all the nodes in the cluster that can access a switchable IASP automatically that stores the servers' data directory. With OS/400 ClusterProven clustering support, the clustering is done on a server's entire data directory and not at a Domino database level. Instead of the databases being replicated, the definition of the Domino server itself is duplicated on other cluster nodes. The cluster supported server's data directory is kept on a switchable disk device. Once configured, the same Domino server can be started on any iSeries logical partition or server that can potentially access the server's data directory on that switchable device. The OS/400 Cluster Management GUI interface can be used to start, stop, and switch between nodes configured for the clustered Domino server. Only one cluster node can access a shared IASP resource at a time. A ClusterProven Domino server is prevented from starting if the cluster node cannot access the IASP, since that server’s data directory is not accessible then. The Domino server is prevented from starting on more than one cluster node since the Domino server is managed as a clustering application Cluster Resource Group (application CRG). Using OS/400 cluster management to support Domino provides automatic failover to backup iSeries servers or LPARs in the case of a system failure. It can also be used to effectively switch a Domino server from one system or LPAR and back. This functionality provides continuous support for the server on a backup system in the case of system downtime for scheduled maintenance or a system IPL. Figure 8-3 illustrates the clustering solution implemented with Domino on the iSeries server. Note: You may come across terms such as “cluster ready” or “cluster aware” as relating to applications. This means that these applications can, to some extent, interact with an OS/400 cluster, but not as painlessly as described above. They are not part of the ClusterProven designation. Chapter 8. ClusterProven for iSeries applications 167 Figure 8-3 ClusterProven Domino for iSeries The requirements for ClusterProven Domino for iSeries server include:  OS/400 5.1  Domino 5.0.7 or later 8.4.1 ClusterProven Domino customer benefits The ClusterProven Domino solution offers customers these unique benefits:  Only one copy of the server's Data Directory and the Domino databases is required With traditional Domino clustering, two copies of the Data Directory and the Domino databases are required. The implementation offered by ClusterProven Domino reduces the requirement for disk space by half.  Reduced or eliminated replication overhead With a ClusterProven Domino solution, there is no or very little replication overhead. The Domino database is not replicated.  You can move the same server between systems or LPARs System maintenance can be scheduled without disrupting users access to Domino functions.  Improved failover operations In case of a failure on the primary system, cluster management failover can start the Domino Server on the secondary system.  Flexible cluster management Domino servers can be managed by Cluster Management tools provided by business partners, or by the IBM Cluster Management GUI of Operations Navigator. Note: As illustrated in Figure 8-3, store the Domino server's data directory on a disk storage device that can be switched between all the systems configured as cluster nodes. CLUSTER #5074Tower Server DomA Data Directory SYS1 SYS2 App. CRG Server DomA App. CRG Server DomA *IASP 168 Clustering and IASPs for Higher Availability on the iSeries Server 8.4.2 Comparing traditional Domino clustering support It is important to note that the new ClusterProven for Domino support is not the same as Domino clustering support. ClusterProven for Domino can be used in conjunction with Domino clustering support. Domino database clustering works on all Domino servers on all platforms that support Domino. It is configured on a database level. Each database can be clustered so that if the primary server does not respond, access to that database is rerouted to a backup server where a copy of that database is automatically maintained by Domino. Domino database clustering is “instantaneous”. Multiple copies of the database are kept. When a server with a database copy fails or is ended, the application or Notes user accessing the database simply gains access to the database copy and starts operating on this copy without much disruption. In that window of time, while accessing the database copy, there is no backup of the data until the original server comes back online and the changes made to the database are replicated to its copy to synchronize things again. The application or Notes user is switched back to the original database copy on the restarted server. In the event that more than one server fails or is ended, to support a database on three (or more) backup nodes, maintain three (or more) copies of the database. Databases that are clustered at the application level have to be replicated to the backup servers. There is some overhead to do this replication. Traditional Domino clustering support requires a duplicate set of disks to support data replication. That is, copies of the database need to be stored on the backup servers. Figure 8-4 illustrates the support that is offered with traditional Domino clustering. Figure 8-4 Domino replication For more information on ClusterProven Domino, refer to the “ClusterProven Domino for AS/400” white paper at: http://www-1.ibm.com/servers/eserver/iseries/domino/domclust.htm Data CRG Device CRG Data CRG Cluster Database Database Replication © Copyright IBM Corp. 2000, 2002 169 Chapter 9. Making applications continuously available For an application to support continuous availability, all critical objects defined to the application must be resilient. This includes the programs that make up the application, the data used by the application, and any permanent objects created or used by the application. Each critical object must exist on, or be accessible from, more than one node of the cluster. Switched disk architecture (IASPs) enables the accessibility of objects and application resiliency. This chapter discusses the treatment of critical objects and actions taken by Cluster Resource Group (CRG) exit programs to support a continuously available environment on iSeries servers. For more information on application considerations and for examples scenarios and coding, watch for the redbook Moving Applications to Switchable Independent ASPs, SG24-6802, which will be available later in the second half of 2002. 9 Note: Example cluster and CRG configuration code is presented in Chapter 10, “Sample cluster environment and applications” on page 183, to support the concepts described within this chapter. 170 Clustering and IASPs for Higher Availability on the iSeries Server 9.1 Defining critical objects All critical objects must be replicated or otherwise accessible to support application resiliency. The first step to make applications resilient is to define which objects are the critical objects. For some applications, this may only require part of the application’s environment, while other applications require a complete copy of the environment. For example, many applications make use of temporary work files, which are recreated each time an application is restarted. It is not necessary to replicate these temporary files to a backup system if this data is not critical in case of an outage. To address the requirements of resiliency, tools are available that help in the process of making applications ClusterProven. These processes are described in this section. Refer to Chapter 8, “ClusterProven for iSeries applications” on page 161, to further understand the iSeries ClusterProven identity. 9.1.1 Non-ClusterProven applications Identifying critical objects can be difficult for non-cluster proven applications. With a detailed knowledge of the application, the objects can be identified and specified individually. Cluster middleware provider products have selection tools to expedite the selection and exclusion process for objects. Generics are supported as a means to specify a complete set of objects, or all objects within a library. Cluster middleware providers have tools available to synchronize and journal the specified objects. If knowledge of the critical objects is limited, or not currently available, then an alternative approach is to select all objects for replication. Selecting all objects is not generally recommended, but it does guarantee that all critical objects are replicated. However, depending on the application and communications bandwidth, a lot of extraneous information can be sent to the backup system, causing a communications back log to occur. If an outage occurs (planned or unplanned) while this backlog exists, information can be lost, or an unexpected delay can occur while the backlog is processed. As more knowledge is gained about the application, eliminate non-critical objects from the replication process to help streamline the operation. 9.1.2 ClusterProven applications If the application is a ClusterProven application, then the critical objects are determined by the ISV. Application critical objects are predefined in the object specifier file. The object specifier file contains a list of all objects that are critical to making the application resilient. When a resilient application environment is established, the object specifier file is used by the Cluster Management GUI to ensure that the application environment is synchronized between the primary system and the other recovery domain nodes. The Cluster Management GUI can also ensure that the objects are ready for the replication process, for example, by verifying that journals exist. This is explained in more detail in the following sections. You can find a layout of the object specifier file in B.4, “Object specifier file layout” on page 288. Chapter 9. Making applications continuously available 171 9.2 Cluster Resource Group exit program Once the critical objects are identified, and the cluster is created, the process of defining the recovery domain can begin. Recovery domain situations can be handled manually by the user or automatically by the exit program. This section discusses how the CRG exit programs can be used to establish and manage the recovery domain. The exit program is responsible for establishing and managing the environment necessary for both data and application resiliency within a cluster. Cluster Services calls the exit program during different phases of a cluster application. As cluster APIs are run, the exit program is called. The functions that the exit program perform depend on the type (action code), status, and role of the node that gains control. The CRG exit program is called when:  A node leaves the cluster unexpectedly  A node leaves the cluster as a result of the End or Remove Cluster Node API  The cluster is deleted  A node is activated  Communication is re-established  A CRG API is run (except the List API) Consider these concepts and rules regarding CRG exit programs:  The exit program name and library name are specified when a CRG is created.  The exit program must exist in the same library on all nodes within the recovery domain.  The exit program runs in a named activation group or the caller’s activation group.  The exit program can be passed up to 256 bytes of data when it is called. This data is specified when the CRG is created and can be modified at other times by the application. 9.2.1 Cluster Resource Group interface All types of CRGs provide interfaces to exit programs. Exit programs are required for data and application CRGs, and are optional for device CRGs. As the name implies, the data CRG controls the resiliency of the data and objects. The application CRG handles the application and takeover IP addresses. And the device CRG controls the switchable devices, such as an independent auxiliary storage pool (IASP). CRG exit programs and the Cluster Management GUI communicate by updating and reading information from architected data areas. The data areas are provided by ISVs and are initialized and updated by applications and cluster middleware products. 9.2.2 Input data area A clustering input data area named QCSTHAAPPI contains information about the application, application resilience information, and information about required data information. Generally, this data area should only be written to by application CRG exit programs, but can be read by all types of CRG exit programs and the Cluster Management GUI. Note: The segments of code documented in this section represent example user exit programs only. The examples show a data and application CRG exit program that supports two nodes: a primary and a backup. 172 Clustering and IASPs for Higher Availability on the iSeries Server The general layout of the QCSTHAAPPI input data area is:  Application information: One portion of the input data area contains information about the application. Such information includes the version of the program, and other information that may be valuable to the application provider and any cluster middleware product.  Application CRG information: One portion of the input data area contains information to create one or more application CRGs.  Resilient data information: One portion of the input data area contains information to identify which objects to make resilient. This information is needed to create the necessary data CRG or device CRG. Refer to Table B-1 on page 284 for a complete layout of the QCSTHAAPPI input data area. 9.2.3 Output data area A clustering output data area named QCSTHAAPPO contains information that reflects the results of setting up the resilient environment for the application. Generally, this data area should only be written to by the Cluster Management GUI or the data CRG exit program, but can be read by all types of CRG exit programs. The general layout of the QCSTHAAPPO output data area is:  Application CRG information: This portion of the output data area contains information about the cluster and the application CRG created.  Data and device CRG information: This portion of the output data area contains information about the CRG created and the replication or switched disk environment established for the application CRG. Refer to Table B-2 on page 285 for a complete layout of the QCSTHAAPPO output data area. 9.2.4 Returning from the exit program Before the exit program ends, the value of the success indicator must be set. If the exit program process is successful, set the success indicator to successful (success indicator = 0). Cluster resources continue with the appropriate function. However, if a non-recoverable error occurs during the exit program, set the indicator to unsuccessful (success indicator = 1 or 2). Depending on the action code, Cluster Services calls all nodes with an action code of 15 (Undo), which reverses the unsuccessful processes. 9.2.5 Using the exit program to establish the environment An exit program can be used to configure and verify that the recovery domain is setup correctly. Important: The data CRG exit program is typically provided by the cluster middleware program that performs data replication. The code snippets provided in this chapter are for example purposes only. An example application CRG exit program is provided with QUSRTOOL at V5R1. Chapter 9. Making applications continuously available 173 Follow these steps when a CRG is established: 1. Create the resilient objects on the recovery domain nodes. 2. Synchronize the resilient objects on the recovery domain nodes. 3. Create the journaling environment on the recovery domain nodes. 4. Journal the critical objects (as required). 5. Start the replication process. 6. Synchronize the data. Table 9-1 and the examples in this section identify how the exit program can be used to handle these environmental issues. The examples provided contain more detail on the specific functions of the exit programs. In each example, the first description shows the data CRG. The second description shows the application CRG. Table 9-1 summarizes the actions taken by the data CRG and application CRG exit programs for a subset of the action codes. Table 9-1 Action code and exit programs Creating a Cluster Resource Group When a CRG is created, the exit programs on each node are called with an action code of 1 (initialize). Figure 9-1 shows an example of the data CRG exit program when a CRG is created. Note: Although some of these steps are clearly for a data CRG, similar steps may be necessary for an application CRG to establish the resilient environment and to handle application state or application control information. Action code data CRG exit program Application CRG exit program 1 = Initialize Prime and put data on all nodes in recovery domain. Prime and put applications on all nodes in recovery domain. 2 = Start Start the remote journal and start the replication. Starts the application. 4 = End Stop the remote journal and stop the replication. End the application. 11 = Add Perform an Initialize (action code 1). If CRG is active, perform Start (action code 2). Perform an Initialize (action code 1). 13 = Change Redirect replication and journaling if necessary. Nothing. 10 = Switch (planned) Stop replication and stop remote journal. Stops application on primary and starts it on the backup. 9 = Switch (failover) Redirect remote journal receivers. Start application on backup. Note: Only a subset of all possible action codes are described here. For a full listing, refer to the iSeries Information Center at: http://www.ibm.com/eserver/iseries/infocenter 174 Clustering and IASPs for Higher Availability on the iSeries Server Figure 9-1 Scenario A: Creating a data CRG exit program example (EXITPGM) The exit program performs these functions:  Sets the QCSTHAAPPO data area to a status of “Data Is Available (A)”. This sets the status field at a known starting point for subsequent operations.  Creates the journal environment. In this example (Scenario A), it creates a remote journal environment. Therefore, it calls a function to return the node information. It then calls the CRTJRNENV function with the appropriate node name.  Journals the appropriate files. Consider these additional functions for the exit program to perform:  Create the resilient objects on all nodes in the recovery domain  Verify the objects are synchronized Figure 9-2 shows an example of the application CRG exit program when a CRG is created. This example exit program (for Scenario A) sets the QCSTHAAPPI data area status flag to “Available (A)”. Scenario A: /* Initialize - called when Cluster Resource Group created.*/ /* Init haappo dataara status to available */ setHaappoStatus(dataAvailable); /* Get Journal details, then create. */ if( 0 == memcmp(g.nodeInfo.node1Name.c, ibmData->This_Nodes_ID, 8) ) CRTJRNENV(g.jrnName.objName.c, g.jrnName.libName.c, g.nodeInfo.node2Name.c); else CRTJRNENV(g.jrnName.objName.c, g.jrnName.libName.c, g.nodeInfo.node1Name.c); /* Start Journaling on the pertinent files */ startJournalingFile(userData); break; Note: The list of files to start journaling on is retrieved from the object specifier file. This process involves these steps: 1. Retrieve the name of the object specifier file from the QCSTHAAPPI data area. 2. Open the object specifier file. 3. Read a record from the object specifier file. 4. If the entry is a generic name, find all objects which match 5. Start journaling on that file. 6. Repeat steps three, four, and five until all records have been processed. Important: The data CRG exit program is typically provided by the cluster middleware program that performs the data replication. The code snippets provided in this chapter are for example purposes only. An example application CRG exit program is provided with QUSRTOOL at V5R1. Chapter 9. Making applications continuously available 175 Figure 9-2 Scenario A: Creating the application CRG exit program example (EXITPGMAPP) Consider these additional functions for the exit program to perform:  Copy the pertinent applications on all nodes in the recovery domain  Prime all nodes in the recovery domain Starting the Cluster Resource Group When a CRG is started, the exit programs on each node in the recovery domain are called with an action code of 2 (Start). Figure 9-3 shows an example (Scenario B) of the data CRG exit program when a CRG is started. The exit program queries the node information to determine if this node is the primary or backup node:  If on the primary node, it starts the remote journal.  If on the backup node, it: a. Sets the QCSTHAAPPO flag to “Switch In Progress (I)”. b. Starts the apply process In most cases, this is a call to the cluster middleware data replication start procedure. Figure 9-3 Scenario B: Starting the CRG Data exit program example (EXITPGM) Scenario A:* Create - called when Cluster Resource Group created. */ /* Init haappo dataara status to available */ setHaappiStatus(applicationAvailable); break; Scenario B /* Start - called when Cluster Resource Group started. */ /* Get the nodeinformation. */ if( (g.nodeInfo.node1Role == primary && 0 == memcmp(g.nodeInfo.node1Name.c, ibmData->This_Nodes_ID, 8)) || (g.nodeInfo.node2Role == primary && 0 == memcmp(g.nodeInfo.node2Name.c, ibmData->This_Nodes_ID, 8)) ) { if( 0 == memcmp(g.nodeInfo.node1Name.c, ibmData->This_Nodes_ID, 8) ) STRRMTJRN(g.jrnName.objName.c, g.jrnName.libName.c, g.nodeInfo.node2Name.c); else STRRMTJRN(g.jrnName.objName.c, g.jrnName.libName.c, g.nodeInfo.node1Name.c); } else { /* Change the backup haappo dataara status to 'Switch In Progress’ */ setHaappoStatus(dataSwitchInprogress); /* Start the apply process. */ SBMAPYJOB(g.jrnName.objName.c, g.jrnName.libName.c, -1); } break; 176 Clustering and IASPs for Higher Availability on the iSeries Server Figure 9-4 shows an example of the application CRG exit program (Scenario B) when a CRG is started. The exit program queries the node information to determine if this node is the primary or backup node:  If it is on the backup node, it returns a successful completion code. No additional function is required.  If it is on the primary node, it: a. Starts the application b. Sets the QCSTHAAPPI data area status flag to “Application In Progress (I)”. c. Loops until the QCSTHAAPPI data area status flag is set to “Available for Switch (A)”. In this example (Scenario B), the program waits for 30 seconds before checking the flag again. Figure 9-4 Scenario B: Starting the CRG application exit program example (EXITPGMAPP) Adding a node When a node is added to a CRG, the exit programs on each node in the recovery domain called with an action code of 11 (Add node). Handling the add node action code is similar to handling the initialize and start action codes. However, these actions are only handled on the node being added. The data CRG exit program should perform these functions:  Query the node role to see if this is the node being added: – If it is not the node being added, an action successful code is returned. No additional function is required. – If it is the node being added, follow these steps: i. Set the QCSTHAAPPO data area to a status of “Data is Available”. Note: Even though a switch is not actually in progress, the status flag must be set to indicate that the data is not available on the backup system. Scenario B: /* Start - called when Cluster Resource Group started. */ /* If on primary, start application, set HAAPPI status. */ if( (g.nodeInfo.node1Role == primary && 0 == memcmp(g.nodeInfo.node1Name.c, ibmData->This_Nodes_ID, 8)) || (g.nodeInfo.node2Role == primary && 0 == memcmp(g.nodeInfo.node2Name.c, ibmData->This_Nodes_ID, 8)) ) { STRORDENT(); setHaappiStatus(applicationInProgress); while( getHaappiStatus() == applicationInProgress ) sleep(30); } break; Important: The application exit program must stay active at this point. When this exit program returns, Clustering Services issues an End CRG (action code 4) request to all nodes in the recovery domain. Chapter 9. Making applications continuously available 177 ii. Create the journal environment. iii. Journal the appropriate files.  Query to see if the nodes status is active. If it’s Inactive, an action successful code is returned. No additional function is required.  Query the node information to determine if this node is the primary or backup node. – If it is on the primary node, start the remote journal. – If it is on the backup node, follow these steps: i. Set the QCSTHAAPPO flag to switch in progress (I). ii. Start the apply process. In most cases, this is a call to the cluster middleware data replication start procedure. Consider these additional functions for the exit program to perform:  Create the resilient objects on all nodes in the recovery domain.  Verify the objects are synchronized. The application CRG exit program should set the QCSTHAAPPI data area status flag to “Available (A)”. Consider these additional functions for the exit program to perform:  Copy the pertinent applications on all nodes in the recovery domain.  Prime all nodes in the recovery domain. Changing the node When a node is changed within a CRG, the exit programs on each node in the recovery domain is called with an action code of 13 (Change node). The exit programs are only called if the recovery domain is changed. 9.2.6 Managing the environment The exit program can be used to manage the recovery domain. Cluster Services calls the exit program as a result of:  Application CRG or API activity, for example to initiate a switchover  Activity not specifically initiated by the end user, for example to initiate a failover Actions that should be handled by the exit program include:  Controlling a planned switch  Controlling a unplanned switch  Ending a Cluster Resource Group  Ending journaling if required  Ending replication if required  Ending the application Important: The status flag must be set to this value even though a switch is not actually in progress. This setting indicates that the data is not available on the backup system. Note: Do not call the application CRG with this action code. 178 Clustering and IASPs for Higher Availability on the iSeries Server Ending a Cluster Resource Group When a CRG is ended, the exit programs on each node in the recovery domain are called with an action code of 4 (End). The data CRG exit program should query the node information to determine if this is the primary or backup node:  If its on the primary node, end remote journaling.  If its on the backup system, end the replication immediately. The application exit program should end the application program. Planned switch When a planned switch occurs via the Initiate Switchover API, the exit program on each node in the recovery domain is called with an action code of 10 (Switchover). When both a data and application CRG are to be switched, the switching process must be synchronized between the two exit programs. The synchronization process is handled by writing to and monitoring the status flags within the architected QCSTHAAPPI and QCSTHAAPPO data areas. See 4.7.5, “Exit programs” on page 47, for a discussion of the data areas. Figure 9-5 shows an example of the data CRG exit program when the CRG switches (Scenario C). The exit program queries the node information to determine if this node is the primary or backup node:  If it’s on the primary node: a. Wait until the application has been shut down. This occurs after the application CRG ends the application. In this case, a two-second wait occurs between checks. b. Send a journal entry to the journal of the old backup system. This journal entry is a user created entry which signifies to the apply process to end. Therefore, all transactions before this entry are applied before the apply process ends on the old backup system. c. End remote journaling. d. Set the QCSTHAAPPO flag to “Switch In Progress (I)”. e. Start the apply process  If it’s on the backup system: a. Wait until the apply process has processed all transactions and has ended. In this example, the apply process sets a flag in a data area indicating that it is done. b. Start remote journaling. Note: The apply process (provided with cluster middleware code) must save its ending point so it knows where to start applying once the process is restarted. Note: When the exit program is called for a switchover, the roles of the nodes have been switched by cluster services. Therefore, the old primary system is now a backup node, and the old backup one node is the primary node. Note: At this point, a switch is no longer in progress. However, this status flag must be set to this value to indicate that the data is not available on the backup system. Chapter 9. Making applications continuously available 179 c. Set the QCSTHAAPPO flag to “Data Available (A)”. Figure 9-5 Scenario C: Switchover CRG data exit program example (EXITPGM) Figure 9-6 shows an example of the application CRG exit program (Scenario C) when the CRG switches. The exit program queries the node information to determine if this node is the primary or backup node:  If it’s on the primary node: a. End the application b. Set the QCSTHAAPPI data area status flag to “Application Available (A)”. Scenario C: /* Switchover (Stop replication on primary) */ /* Get the node information */ if( (g.nodeInfo.node1Role == primary && 0 == memcmp(g.nodeInfo.node1Name.c, ibmData->This_Nodes_ID, 8)) || (g.nodeInfo.node2Role == primary && 0 == memcmp(g.nodeInfo.node2Name.c, ibmData->This_Nodes_ID, 8)) ) { while( getHabpStatus() != acNone ) sleep(2); /* Start remote journaling in the opposite direction. */ if( 0 == memcmp(g.nodeInfo.node1Name.c, ibmData->This_Nodes_ID, 8) ) STRRMTJRN(g.jrnName.objName.c, g.jrnName.libName.c, g.nodeInfo.node2Name.c); else STRRMTJRN(g.jrnName.objName.c, g.jrnName.libName.c, g.nodeInfo.node1Name.c); /* Set the 'new' primary side data status field */ setHaappoStatus(dataAvailable); } else { while( getHaappiStatus() != applicationAvailable ) sleep(2); /* create journal entry (UXI) */ sendUXIEntry(); /* End remote journal */ if( 0 == memcmp(g.nodeInfo.node1Name.c, ibmData->This_Nodes_ID, 8) ) ENDRMTJRN(g.jrnName.objName.c, g.jrnName.libName.c, g.nodeInfo.node2Name.c); else ENDRMTJRN(g.jrnName.objName.c, g.jrnName.libName.c, g.nodeInfo.node1Name.c); /* Set the 'new' apply side data status field */ setHaappoStatus(dataSwitchInprogress); /* Start the apply process. */ SBMAPYJOB(g.jrnName.objName.c, g.jrnName.libName.c, -1); } break; 180 Clustering and IASPs for Higher Availability on the iSeries Server  If it’s on the backup node: a. Wait until the QCSTHAAPPO data area status flag is set to “Data Available (A)”. This indicates that the data is quiesced, and the applications can start up on the old backup system. b. Start the application c. Set the QCSTHAAPPI data area status flag to “Application in Progress (I)”. Figure 9-6 Scenario C: Switchover CRG application exit program example (EXITPGMAPP) Unplanned switch (failover) When a cluster resource detects a node failure or resource failure, the exit programs on each node in the recovery domain are called with an action code of 9 (failover). 9.2.7 Rejoining or restarting the application Restarting an application can be the direct result of an application failure. The application CRG allows for the situation where the application attempts to be restarted (up to three times) on the node currently acting as primary. When a node defined to a CRG comes back online after a node or resource failure, an action code of 8 (Rejoin) is sent to all exit programs within the recovery domain. The data CRG exit program for a rejoin action should query the node information to determine if this node is the primary or backup node:  If it’s on the primary node, return, nothing to do (should never get called).  If it’s on the backup node: a. Resynchronize the data. b. If the node status is active, start the replication process. Scenario C: /* Switchover - planned switch */ /* If on primary, end application, and set haappi status. */ if( (g.nodeInfo.node1Role == primary && 0 == memcmp(g.nodeInfo.node1Name.c, ibmData->This_Nodes_ID, 8)) || (g.nodeInfo.node2Role == primary && 0 == memcmp(g.nodeInfo.node2Name.c, ibmData->This_Nodes_ID, 8)) ) { /* Else must be backup, wait til data is flushed. */ while( getHaappoStatus() != dataAvailable ) sleep(2); /* Restart application. */ STRORDENT(); /* Set the 'new' primary side data status field */ setHaappiStatus(applicationInProgress); } else { ENDORDENT(); setHaappiStatus(applicationAvailable); } break; Chapter 9. Making applications continuously available 181 The application CRG exit program should query the node information to determine if this node is the primary or backup node:  If it’s on the primary node, if the node status is active, start the application.  If it’s on the backup node, return, nothing to do. 182 Clustering and IASPs for Higher Availability on the iSeries Server © Copyright IBM Corp. 2000, 2002 183 Chapter 10. Sample cluster environment and applications This chapter illustrates the use of the cluster commands that are available with the V5R1 QUSRTOOLs library. The setup and administration of a cluster configuration is typically performed through a Cluster Management GUI interface, as provided either by a cluster middleware provider or the IBM Simple Cluster Management GUI (V5R1 Operations Navigator). To illustrate the concepts in this redbook from an application perspective (in particular, Chapter 9, “Making applications continuously available” on page 169), this chapter defines the setup of a three-node cluster that allows applications on two systems to be backed up on a common backup system. Four Cluster Resource Groups are created to handle this configuration. This chapter also discusses changes to a sample order entry application first to support remote journals and then to make the application more highly available. To allow data resilience across the systems, remote journaling is used. 10 Note: The application code to support high availability, as represented in this chapter, is provided to serve as an example only. The code does not represent a real application. you can find additional examples in the redbook Moving Applications to Switchable Independent ASPs, SG24-6802, which is scheduled for publication later in the second half of 2002. 184 Clustering and IASPs for Higher Availability on the iSeries Server 10.1 Example cluster configuration The example cluster shown in Figure 10-1 has three systems, with names of M20, M27, and M22. The plan for availability is to have an application from System M20 backed up on System M22 and to have an application from System M27 backed up on System M22. These three systems comprise a cluster by the name of CLUSTERA. The Cluster Resource Group defining the data recovery domain for Systems M20 and M22 is named CRG1. The Cluster Resource Group defining the application recovery domain for Systems M20 and M22 is named CRG1APP. Similarly, the Cluster Resource Group defining the data recovery domain between System M27 and M22 is named CRG2. And the Cluster Resource Group defining the application recovery domain for Systems M27 and M22 is named CRG2APP. Figure 10-1 Application cluster CLUSTERA Before the clustering environment is setup, a link between the systems is required to propagate the cluster setup commands. In the example illustrated in Figure 10-2, the three systems were set up on a common LAN. TCP/IP is started for the systems. M20 M22 M27 Chapter 10. Sample cluster environment and applications 185 Figure 10-2 Assignment of IP addresses in cluster CLUSTERA The three systems are setup with the following IP addresses for the primary system access and cluster control:  System “M20” on IP address 9.5.92.18  System “M27” on IP address 9.5.92.19  System “M22” on IP address 9.5.92.26 The IP address that users of application 1 are to use is address 9.5.92.44. The IP address that users on application 2 are to use is 9.5.92.46. Address 9.5.92.44 is defined on both the primary system (M20) and the backup system (M22). Address 9.5.92.46 is defined on both the primary system (M27) and the backup system (M22). Each of these addresses is started only on the system serving as the primary for the application. 10.1.1 Creating the sample clustering environment For this example, the CRTCLU, CRTCRG, STRCLUNOD, and STRCRG cluster commands available with V5R1 QUSRTOOL are used to setup and control the cluster environment. These commands call the system APIs listed in Table B-3 on page 286 and Table B-4 on page 287. High availability business partners have a GUI utility to serve this purpose, or they use a different form of calling the cluster APIs. Note: The IP addresses of 9.5.92.44 and 9.5.92.46 must be available addresses on the network. There must be no devices currently using them. If these addresses are in use elsewhere in the network, Cluster Resource Services cannot setup the application Cluster Resource Groups. M20 M22 M27 CRG1 and CRG1APP CRG2 and CRG2APP 9.5.92.26 9.5.92.18 9.5.92.19 9.5.92.44 9.5.92.46 186 Clustering and IASPs for Higher Availability on the iSeries Server Example cluster setup Figure 10-3 through Figure 10-5 show the command and parameters used in the setup of the sample three node cluster described in 10.1, “Example cluster configuration” on page 184, and illustrated in Figure 10-1 on page 184. Figure 10-3 Example cluster setup (Part 1 of 3) The first cluster command listed in Figure 10-1, Create Cluster (CRTCLU), creates the three node cluster for nodes M20, M27, and M22. Since multiple cluster nodes are defined by CRTCST rather than individual use of the Add Cluster Node Entry (ADDCLUNODE) command, the nodes are not automatically started. The start indicator parameter is ignored on the CRTCLU command. Therefore, the STRCLUNOD command must be run for each node. The CRTCLU command gives each node an ID name and interface address (IP address). This IP address is used by Cluster Resource Services to communicate with other nodes within the cluster. It cannot be the IP address used by the application users. A second interface address can be specified for backup use by Cluster Resource Services, but it is not to be used by the application users either. The systems defined as cluster nodes must not be setup with the Allow Add to Cluster (ALWADDCLU) system network attribute set to *None. Use the Change Network Attribute (CHGNETA) command to change this attribute. As with other OS/400 commands, the Monitor Message (MONMSG) command allows for verification of the desired action. In our example, feedback message CPFBB05 indicates that the cluster node could not be started. CPFBB05 occurred several times. This failure to start the remote cluster node can occur because the remote system does not have the INETD server running. The solution is to run the STRTCP SERVER(*INETD) command on the remote system. /* Setup cluster environment for three node network + between M20 and M22 with M20-primary M22-backup + and between M27 and M22 with M27-primary M22-backup */ PGM CHGJOB LOG(4 10 *SECLVL) LOGCLPGM(*YES) /* Create three node cluster */ CRTCLU CLUSTER(CLUSTERA) NODE('9.5.92.18'/M20 + '9.5.92.19'/M27 '9.5.92.26'/M22) /* Start TCP server INETD on all nodes */ /* STRTCPSVR SERVER(*INETD) */ STRCLUNOD CLUSTER(CLUSTERA) NODE(M20) MONMSG MSGID(CPFBB05) EXEC(GOTO CMDLBL(STRCLUERR)) STRCLUNOD CLUSTER(CLUSTERA) NODE(M27) MONMSG MSGID(CPFBB05) EXEC(GOTO CMDLBL(STRCLUERR)) STRCLUNOD CLUSTER(CLUSTERA) NODE(M22) MONMSG MSGID(CPFBB05) EXEC(GOTO CMDLBL(STRCLUERR)) GOTO CMDLBL(NEXT1) StrCluErr: SNDPGMMSG MSG('Error on Start Cluster Node - Check + Joblog for details') TOPGMQ(*EXT) GOTO CMDLBL(ENDPGM) Chapter 10. Sample cluster environment and applications 187 The output of the List Cluster Information (PRTCLUINF) command gives useful information about the definitions and status of the cluster. Use PRTCLUINF to verify the cluster name with the status of the individual nodes within the cluster. Example resource group setup Figure 10-4 shows the commands used to define the recovery domains for the example configuration. Figure 10-4 Example cluster setup (Part 2 of 3) The Create Cluster Resource Group (CRTCRG) command is run once for each of the four Cluster Resource Group objects to be setup. The Cluster Resource Groups define the recovery domain for the applications. The implied recovery domain is defined by the nodes within the Cluster Resource Group. In this example, the two Cluster Resource Groups named CRG1 and CRG1APP define a recovery domain of nodes M20 and M22. The preferred mode of M20 is as primary node. The preferred mode for M22 is as backup node. CRG1 defines a data resource group. CRG1APP defines the application resource group. /* ADD CLUSTER RESOURCE GROUPS */ NEXT1: CRTCRG CLUSTER(CLUSTERA) CRG(CRG1) CRGTYPE(*DATA) + EXITPGM(CLUSTER/CRG1EP) USRPRF(EPGMUSER) + TEXT('Data Cluster Resource group for + Application 1') RCYDMN((M20 *PRIM) (M22 + *BACK1)) CRTCRG CLUSTER(CLUSTERA) CRG(CRG1APP) CRGTYPE(*APP) + EXITPGM(CLUSTER/CRG1APPEP) + USRPRF(EPGMUSER) EXITPGMDTA('Data Goes + Here') TEXT('Prog Cluster Resource group + for Application 1') + TKVINTNETA('9.5.92.46') JOB(CRG1APP) + ALWRESTART(*YES) NBRRESTART(1) + RCYDMN((M20 *PRIM) (M22 *BACK1)) CRTCRG CLUSTER(CLUSTERA) CRG(CRG2) CRGTYPE(*DATA) + EXITPGM(CLUSTER/CRG2EP) USRPRF(EPGMUSER) + TEXT('Data Cluster Resource group for + Application 2') RCYDMN((M27 *PRIM) (M22 + *BACK1)) CRTCRG CLUSTER(CLUSTERA) CRG(CRG2APP) CRGTYPE(*APP) + EXITPGM(CLUSTER/CRG2APPEP) + USRPRF(EPGMUSER) EXITPGMDTA('Data Goes + Here') TEXT('Prog Cluster Resource group + for Application 2') + TKVINTNETA('9.5.92.44') JOB(CRG2APP) + ALWRESTART(*YES) NBRRESTART(1) + RCYDMN((M27 *PRIM) (M22 *BACK1)) ***************** End of data **************************************** 188 Clustering and IASPs for Higher Availability on the iSeries Server When the CRTCRG command is run, it attempts to start the related exit program to pass the initialize action code. If the defaults are used, the API submits a job to the QBATCH job queue to start the exit program. The CRTCRG command then waits for confirmation that the exit program has handled the initialize action code. If both of these jobs are submitted to a job queue with a maximum activity of one, the CRTCRG waits forever. Therefore, it is a good idea to run the CRTCRG either interactively or from a separate job queue. Example startup of recovery domains Figure 10-5 shows the commands to start the data and application recovery domains. Figure 10-5 Example cluster setup (Part 3 of 3) The List Cluster Resource Groups (PRTCLUINF) command provides information about the cluster resource definitions. It provides information on the number, names, and status of the individual resource groups. The List Cluster Resource Group Information (PRTCRGINF) command produces a report to verify the detailed definitions of the resource group. This provides the current information on the individual resource groups as defined in the create and succeeding change commands. 10.1.2 Sample setup of journaling Figure 10-6 through Figure 10-8 display a Command Language (CL) program written to journal files. Pgm: STRCRG CLUSTER(CLUSTERA) CRG(CRG1) STRCRG CLUSTER(CLUSTERA) CRG(CRG1APP) STRCRG CLUSTER(CLUSTERA) CRG(CRG2) STRCRG CLUSTER(CLUSTERA) CRG(CRG2APP) EndPgm: ENDPGM Chapter 10. Sample cluster environment and applications 189 Figure 10-6 Sample journal setup (Part 1 of 3) Figure 10-7 Sample journal setup (Part 2 of 3) /* STRJRNFLS Starts journaling the files needed for the Order Entry Application + If journaling already exists then remove it and start again */ PGM DCL VAR(&APPLIB) TYPE(*CHAR) LEN(10) + VALUE('AVAIL2') DCL VAR(&JRNLIB) TYPE(*CHAR) LEN(10) + VALUE('AVAIL2') DCL VAR(&JRN) TYPE(*CHAR) LEN(10) VALUE('JRN') DCL VAR(&JRNRCV) TYPE(*CHAR) LEN(10) + VALUE('JRNRCV0000') /* Check to see if journal is defined */ CHKOBJ OBJ(&JRNLIB/&JRN) OBJTYPE(*JRN) MONMSG MSGID(CPF9801) EXEC(GOTO CMDLBL(BUILDNEW)) /* If journal exists stop journaling and remove objects */ ENDJRNPF FILE(*ALL) JRN(&JRN) DLTJRN JRN(&JRNLIB/&JRN) DLTJRNRCV JRNRCV(&JRNLIB/&JRNRCV) /* Remove remote journal if it exists */ RUNRMTCMD CMD('DLTJRN JRN(&JRNLIB/JRN)') + RMTLOCNAME(AS22 *IP) RMTUSER(USERAAA) /* Add remote journal to Backup system */ ADDRMTJRN RDB(AS22) SRCJRN(&JRNLIB/JRN) TEXT('Remote + Journal on M22') /* Start Remote journal on Backup system */ CHGRMTJRN RDB(AS22) SRCJRN(&JRNLIB/JRN) JRNSTATE(*ACTIVE) /* Add files to be jounaled to journal */ STRJRNPF FILE(&APPLIB/STOCK) JRN(&JRNLIB/&JRN) + OMTJRNE(*OPNCLO) STRJRNPF FILE(&APPLIB/CSTMR) JRN(&JRNLIB/&JRN) + OMTJRNE(*OPNCLO) STRJRNPF FILE(&APPLIB/DSTRCT) JRN(&JRNLIB/&JRN) + OMTJRNE(*OPNCLO) STRJRNPF FILE(&APPLIB/ORDERS) JRN(&JRNLIB/&JRN) + OMTJRNE(*OPNCLO) STRJRNPF FILE(&APPLIB/ORDLIN) JRN(&JRNLIB/&JRN) + OMTJRNE(*OPNCLO) STRJRNPF FILE(&APPLIB/USERSTATUS) JRN(&JRNLIB/&JRN) + OMTJRNE(*OPNCLO) EndPgm: ENDPGM 190 Clustering and IASPs for Higher Availability on the iSeries Server Figure 10-8 Sample journal setup (Part 3 of 3) 10.1.3 Journal environment to allow reverse remote backup When setting up the journal environment, it is desirable to use the same library and object names on both systems of a cluster. This allows the CRG exit programs and any programs they call to be the same on both the primary and backup systems. With the arrangement described in this section, the roles of the two systems can be reversed. The same files and journal names can appear in the same libraries. The journaling environment shown in Figure 10-9 and Figure 10-10 explains how this works. /* Build a new environment and start journaling the files */ BuildNew: CRTJRNRCV JRNRCV(&JRNLIB/&JRNRCV) MONMSG MSGID(CPF0000) EXEC(DO) SNDPGMMSG MSG('Journal Receiver' *BCAT &JRNLIB *TCAT + '/' *TCAT &JRNRCV *BCAT 'was not built') + TOPGMQ(*EXT) GOTO CMDLBL(ENDPGM) ENDDO CRTJRN JRN(&JRNLIB/&JRN) JRNRCV(&JRNLIB/&JRNRCV) MONMSG MSGID(CPF0000) EXEC(DO) SNDPGMMSG MSG('Journal' *BCAT &JRNLIB *TCAT '/' *TCAT + &JRN *BCAT 'was not built') TOPGMQ(*EXT) GOTO CMDLBL(ENDPGM) ENDDO /* Add remote journal to Backup system */ ADDRMTJRN RDB(AS22) SRCJRN(&JRNLIB/JRN) TEXT('Remote + Journal on M22') Note: The remote journal must be setup as a remote journal type 2 to allow the remote journal to be in a different library than the local journal it duplicates. Chapter 10. Sample cluster environment and applications 191 Figure 10-9 Resilient data from System A to B Figure 10-10 Resilient data from System B to A System A - primary Application Data Remote Journal from System B in its own library Local Journal System B - backup Application Data Remote Journal from System A in its own library Local Journal Apply changes to backup data System A - backup Application Data Remote Journal from System B in its own library Local Journal System B - primary Application Data Remote Journal from System A in its own library Local Journal Apply changes to backup data 192 Clustering and IASPs for Higher Availability on the iSeries Server 10.2 Sample RPG order entry application To illustrate the coding required for an application to support high availability, this section describes a sample order entry program. For this application, high availability is implemented in two stages:  Stage 1: Cluster application to use remote journals describes the changes to allow the application to take advantage of the iSeries cluster features.  Stage 2: Cluster application to support a highly available environment outlines further changes to the application that make it more highly available, the data more reliable and also provide a more finite restart capability. 10.2.1 Original RPG application This sample order entry application is designed to allow multiple users to create orders for customers. It validates the customer number and credit balance, validates the item number and stock balance, assigns a sequential order number, creates an order header record, creates an order detail record for each item sold, updates the customer account, and passes off a trigger to a batch print program to print the pick/pack slip. The application updates the order number at the start of building an order and retains the order detail information in memory until the order is eventually closed. At this time, the order files, stock files, and customer file are updated. Therefore, an interruption of the system can cause the loss of any detail lines entered before the order closes. There is no check for interference from one user to another. This means that if more than one order taker is working with the same inventory item at the same time, the first one to close their order updates inventory from stock. This potentially leaves the second order taker in an out of stock situation, which does not show up until the order is closed. The sample application does not use journaling or commit control and does not provide for system integrity of the data files. In its original design, the trigger from the order program to the print program is a data queue. Prior to V5R1, data queues are not automatically captured in a journal. Therefore, if the journaled data is moved to a second system in a backup apply process, the integrity of the print trigger data queue is not maintained. With V5R1, the data queues can be journaled, and adding journaling to the application for data integrity protects the data queue trigger. However, this example does not use journaling of the data queue, but illustrates an alternate solution. 10.2.2 Stage 1: Cluster application to use remote journals To provide for a more available backup, remote journaling is used to assist the replication of data to the backup system. The data queue used in the original program as the print trigger, is replaced by a logical view of unprinted orders based on a status in the order header file. Therefore, the information passed by the data queue is moved to the order file to allow replication on the remote database. As a first step in keeping the database of the backup system in synchronization with the primary system, the apply journal change program uses the Retrieve Journal Entry (RTVJRNE) command (or equivalent system API) on the remote backup system. Chapter 10. Sample cluster environment and applications 193 Clustering support is used to detect a failover situation and trigger a rollover from the primary to the backup system. The Cluster Resource Group exit programs are written to control the Cluster Resource Groups that are defined. Stage 1 application changes to support remote journals To support remote journaling, these changes are required at the first stage:  Remote journaling is started on the database files.  A user status file is created to allow restart from within the active programs in use by the user. Figure 10-11 shows the DDS specifications used to create this user status log file. Figure 10-11 Definition of the StatusLog file Functions provided in programs that are to handle this design change include:  The application must log into this StatusLog file at each potential point it from which it is required to restart.  At the logical end of the program, the program clears out the log status file for itself.  A service module is written to log the current status of the application program. It is called at various stages of the application to log the development through the order entry for a customer order.  For the order entry program, the status log module is called when an order number is assigned to the customer and an order header record written. The status is updated when the order is complete. A log is generated for the customer maintenance program, at the time of starting to work with customer data, then again when the customer update is complete.  To complement the status log module, a second module is written to check for outstanding entries in the log file and determine if a restart is required for one or more of the application programs.  The log saves the *entry plist parameters that may be passed back to the application program in a restart mode.  An initial program is written for the users that check this status log. If there are entries, the appropriate program is called with the saved parameters.  The application programs are modified to use the passed *Entry parameters as the starting point for the respective user. *************** Beginning of data ***************************************************** * User Status in application UNIQUE R USERSTR USUSER 10A COLHDG('User' 'Name') USWKSID 10A COLHDG('Workstation' 'ID') USLSTDT Z COLHDG('Last' 'Activity') USPROGN 10A COLHDG('Program' 'Name') USPROGL 10A COLHDG('Program' 'Lib') USPLIST 256A COLHDG('Entry' 'PList') K USUSER K USWKSID K USPROGN K USPROGL ****************** End of data ******************************************************** 194 Clustering and IASPs for Higher Availability on the iSeries Server  A program is called by the application exit program to apply the remote journal changes.  The programs are changed to allow them to restart part way through the process. For example, the order entry program accepts entry parameters that bypass the first data entry screens if the order is currently open and incomplete. The program sets up the display and working data to the same point as the last invocation for the open order and customer.  A flag is added to the order header file to indicate the print status. This flag is used by the printer to control printing of the order. The data queue processing is removed. 10.2.3 Stage 2: Cluster application to support a highly available environment To provide for a higher degree of data integrity, commitment control is added to the application. The application implication of this change is that a more discrete commit boundary is implemented. By changing the logical unit of work (LUW), or the commit boundary, to a detail line item on the order, and changing the order entry program to restart part-way through the processing, the user is allowed to continue with the order after the last order line commits to the database. These changes add features to the program that have advantages other than a disaster restart. The application program can now be a called program from other steps within the application, to continue with the order processing for other reasons. By processing a commit at the order detail time, the order taker can ensure that the data is still valid by the time the order is complete. To implement these changes, the application must be further changed from stage 1 to:  Commit after each order detail line  Add a function to allow backing out of previously committed stages, allow a cancel of committed order lines, or cancel of all committed items for the order  Start and continue working with incomplete orders © Copyright IBM Corp. 2000, 2002 195 Chapter 11. Considerations when planning for iSeries clusters and recoverable applications There are strong benefits to implement high availability. But to achieve success can be a long process. A typical high availability installation can take a day to complete. But the planning, configuration, customization, training, and implementation of new operational procedures can take several months. The success of the project depends on the many factors, each based on management support, and planning is critical. Once the impact of downtime is understood, develop a business continuity plan. Gather input from everyone from the CEO to network administrators, application programmers, and end users. Each employee must be aware of the methods to avoid and minimize a disruption to the business. This chapter discusses many of the areas to investigate when planning for an iSeries cluster solution. It presents considerations when developing an implementation plan, for application support of clustering, and planning for the ongoing management of a cluster. The intent of the material that is provided is to provoke thoughts and to initiate actions to represent as tasks in a clustering implementation plan. These actions are not easy to objectively define. As such, the information provided within this chapter is not by itself a project plan, but is rather a checklist of important considerations for a successful clustering implementation. 11 Tip: The tasks necessary to implement a clustering and independent ASP on the iSeries server are unique to the customer, based on where a customer’s high availability solution is positioned. A project plan can be built using the information in this redbook, as well as in:  Roadmap to Availability on the iSeries 400, REDP0501  High Availability on the AS/400 System: A System Manager’s Guide, REDP0111 196 Clustering and IASPs for Higher Availability on the iSeries Server 11.1 Planning for iSeries clustering It is important to carefully plan for the implementation of a clustering solution. Planning helps prepare for the technical installation of the cluster setup and facilitates a smooth installation. The planning tasks depend on the type of cluster to be created. In general, make sure the planning process includes these key activities:  Thoroughly understanding the concepts of the proposed clustering solution  Clearly defining what is to be accomplished by implementing clusters or independent ASPs on the iSeries server  Obtaining a service level agreement. Agree on service hours, planned downtime, and so forth. Clearly set and document the correct level of expectations. In particular, the setup and management of a clustered environment is a nontrivial task. The tasks depend on which type of cluster you want to create. In general, the tasks involved are:  Initial configuration a. Specify systems in a cluster b. Create Cluster Resource Groups (CRGs) for data and application c. Create device domains for resilient devices d. Activate the cluster  Configuration modifications (as required) a. Add or remove a node to or from the cluster b. Create new CRGs or delete existing CRGs c. Change the property of a CRG, for example primary or backup, or a change in the order d. Identify resilient resources e. Start and end a node or CRG  Application requirements a. Modify application to work with clusters b. Enable restart features for interactive, batch, and client-server jobs c. Modify procedures to allow for application maintenance in a clustered environment  Administration and management tasks a. Display cluster topology and cluster resources b. Display CRG contents c. Initiate switchover d. Delete cluster configuration  Systems management a. Obtain service level agreements with service providers b. Implement a capacity and performance plan c. Implement standards for security and user profiles Many of the planning tasks involved for implementing a clustering solution are further described in this section. Tip: The investment in skills is significant and cannot be achieved quickly. Consider developing skills early in the clustering implementation. Chapter 11. Considerations when planning for iSeries clusters and recoverable applications 197 11.1.1 Measuring the impact of an outage to the business To understand the value of a high availability clustering solution, it is helpful to understand the impact of a computer outage to a business. It is important to determine an estimated cost of downtime. What direct and indirect costs are affected by the business when the system (or one of its components) is not available? Investigate what system outages have occurred over the past couple of years. Include both planned and unplanned outages. Obtain an estimate of the cost of these outages. Separate outage costs into two categories:  Tangible losses, which include: – Loss to share holdings and profits – Losses incurred through product or campaign delays – Employee idle time waiting for the system (or application) to become available – Employee overtime to enter transactions not entered during the outage – Cost of facilities and equipment during the idle period – Consequential loss through penalties charged by customers or suppliers for delayed delivery – Goods lost through damage or aging  Intangible losses, which include: – Credibility in the marketplace – Lost revenue when customers buy elsewhere – Market share Once these costs are tallied, other scenarios can be planned. Calculate an estimated cost for the loss of each application. This helps set the priority of applications. 11.1.2 Determining the desired level of availability Once the financial justification of availability of the business is established, decide the level of availability that the business can afford. Do not be deterred by the results of the analysis. If the desired level of availability cannot be achieved at first, consider implementing a tactical solution before moving to the more strategic solution. An example of a tactical solution is to run with an application that has a basic ClusterProven status only. A switchover may not be seamless in this scenario. If there are 5250 devices, the end users need to sign on to the backup system. However, when these users open their application session, they are positioned back to the menu they were last. With this tactic, after an outage, the I/T group needs to establish the integrity of data before the application and users start performing updates. Although a tactical or practical solution is not the ideal, it may yet be a better or more structured solution than what currently exists in the organization. A tactical solution can be implemented relatively quickly, and provide high availability while a strategic solution is developed. A strategic solution can be to implement applications that meet Advanced ClusterProven requirements. An Advanced ClusterProven status demands that commitment control for application rollback, or a similar function is implemented. An Advanced ClusterProven solution takes longer to develop, depending on the recoverability of the existing application. 198 Clustering and IASPs for Higher Availability on the iSeries Server Remember that the more systems that are in the proposed cluster solution, the more complex the implementation is. Nodes can always be added to the cluster. Additional Cluster Resource Groups related to other applications and data sets can always be started after the initial cluster is setup. 11.1.3 Understanding the required configuration of a cluster To determine the configuration required to implement clustering, it is important to understand the roles, location, and size of the systems (nodes) to be in the cluster. If there are a number of iSeries servers in the business, decide how much of the operational environment and application is to be replicated. In the event that the system and one key application is replaced, the business can be supported by a simple cluster solution. Use the benefits by this simple cluster to develop experience and skills to support a more complete cluster. The remaining hardware and application can be moved to the cluster environment at a later time. An understanding of the business’ infrastructure is required when implementing clustering. The key tasks that are involved are to:  Perform an inventory of all installed iSeries server hardware, including: – Processor – Storage – Disk unit, capacity, and utilization – IOPs – IOAs  Determine the operating system release level installed, identify the applications involved, and determine the release level and compatibility of all software products.  Document other related systems that are not to be part of the cluster, yet affect the same sphere of business operation as the cluster. These related systems can be other systems (servers or clients) plus their operating systems, databases and applications; network hardware (LAN, Internet Service Providers, routers, topology); and peripheral devices (tapes, printer, and displays).  Select the applications that are to be clustered.  Decide the most appropriate location (node) to run these applications.  Size the systems at these locations to determine if there is spare capacity to implement the availability features and the resilient application under all conditions. Decide where any additional capacity is needed. With today’s price per performance structure, it is not uncommon to find production systems running 30% utilized. In these cases, the production machine may have plenty of capacity to run additional recovery features.  Ensure the capacity of the backup system is sufficient to handle any application load that may be moved to it in the event of data or application failover or switchover. Tip: Start simple and build the solution. Chapter 11. Considerations when planning for iSeries clusters and recoverable applications 199 11.2 Making applications recoverable Making applications recoverable is key to enable high availability solutions for the iSeries customer. The ability of a program to recover from an outage involves a change of the design or coding of the program, to support recoverability. A discussion of application design and considerations, and user recovery both in interactive and batch jobs, is found in the Redpaper High Availability on the AS/400 System: A System Manager’s Guide, REDP0111. You can also learn more about application considerations in the redbook Moving Applications to Switchable Independent ASPs, SG24-6802, which is scheduled for publication later in the second half of 2002. Whether an application is developed in-house, or offered by an ISV, it is a worthwhile, yet not a difficult task, to cluster-proof applications. ClusterProven applications are recoverable. And there are resources available to assist with cluster-proofing applications. Refer to Chapter 8, “ClusterProven for iSeries applications” on page 161, and Appendix C, “iSeries cluster resources” on page 291, to understand the support and efforts involved. Detailed programming recommendations are beyond the scope of this redbook. This section offers general guidelines for enabling the recovery characteristics of a typical application. 11.2.1 Application object inventory To prepare for ClusterProving an application, first look at the applications that are running throughout the business. Consider both iSeries applications and applications running on other platforms. Determine for which areas of the business you want to require continuous availability. Determine which applications to make recoverable. Changes may be required to applications on the iSeries server and on the systems with which the iSeries server interfaces. Determine what data is to be resilient. Build an inventory of the objects used by the selected applications that need to be on the backup system in the event of an application failover or switchover. Add to this list any other objects that are to be on the backup system. For iSeries applications, there are several objects types that require special handling, for example:  Temporary files  Data spaces  Data queues Cluster middleware providers and ISV programmers are proficient with the special handling procedures to replicate these types of objects. Work with these IBM partners for a replication solution. 11.2.2 Resilient data Resilient data is data that survives a switchover. When planning a clustering installation, establish which objects on which nodes are to be resilient. This can be done by completing the inventory procedure, as described in 11.2.1, “Application object inventory” on page 199. Once these objects are identified, replicate the objects. This replication involves journaling and replication of objects between two or more systems in the cluster. 200 Clustering and IASPs for Higher Availability on the iSeries Server Enter these resilient objects into the object specifier file associated with the QCSTHAPPI data area for the application. In this way, the cluster management tool can automatically create data resilience as represented by a data CRG, and then set up the replication or switched disk environment. The layout of an object specifier file can be found in B.4, “Object specifier file layout” on page 288. Contact a cluster middleware provider, as identified in Part 3, “Cluster middleware business partners” on page 227, for middleware software to replicate objects. 11.2.3 Resilient applications Resilient applications are applications that survive a switchover. When implementing a clustering solution, decide the level of availability for each application. Select an application that is ClusterProven. Decide whether Basic or Advanced ClusterProven is required. For applications developed in-house, create a development plan for any modifications required to meet the ClusterProven criteria for high availability. Review “Criteria to obtain ClusterProven trademark” on page 165 for more information. Plan the recovery domains and the IP-takeover addresses to be related to application CRGs. Decide which nodes the applications are to run on and which nodes are to be the backup nodes. Determine what the characteristics of the device switchover should be. For 5250 devices (displays and printers), include a hardware switch in the configuration if 5250 types of users are to switch or failover to a backup machine. The 5250 devices are switched manually or automatically as a result of a switch or failover occurring. An automatic switch requires third-party software. This software can be available as part of the cluster middleware providers product. For IP devices, such as PCs that browse to the node, a simple refresh of the browser reselects the IP takeover address on the new node. The user can then re-access their application. 11.2.4 Switchover Once an application becomes ClusterProven, and the node to run the application on is known, consider the switchover characteristics of the business itself. The tasks involved with a switchover include:  Move existing users off the application  Prevent new users access to the application  Stop the application  Complete the apply tasks Some applications may have already implemented these functions, especially in the banking and services sector. These organizations tend to have stringent end-of-day (EOD) routines that require all users to be off the system for a short period of time while the EOD tasks run. These applications have methods for removing users from the application. Chapter 11. Considerations when planning for iSeries clusters and recoverable applications 201 11.2.5 Failover A failover is similar to a switchover, but with less control. In theory, if the failover is completely seamless, it can be used as the switchover. For example, a switchover means press the Off button. However, given the option, it is safer to switch. The tasks involved in planning for a failover ensure that the users can be returned to the same position they were at before the failure. 11.2.6 Job restart OS/400 job restart is a complicated task. Careful planning is required to achieve the fastest and safest restart of jobs on the backup node. The restart characteristics of different types of jobs running on an iSeries server are described in this section. Interactive jobs Interactive jobs are run from a twinaxial display or in an emulator session. In a switchover situation, interactive jobs can normally be ended in a controlled fashion. All transactions typically complete without loss of data. In a failure condition, interactive jobs end abnormally. Transactions are incomplete and temporary objects are lost. However, with a good understanding of the application, the losses can be contained and the recovery can be planned. Since these interactive devices use a 5250 data stream, they cannot be controlled by IP takeover. They must be manually switched. This hardware switch process can be linked to the IP takeover. Batch jobs With a long running single thread batch job, establish whether this job can have restart points added or whether it must be completely restarted. Restarting the batch job can be necessary. However, it can be a long running operation that can seriously effect the overall availability of the application or business. Multi-threaded batch jobs are more complex. Restart points may not be available within the job. The job may need to be rolled out and restarted. Client/server jobs Client/server is perhaps the easiest iSeries environment to cluster. The state of the client is not important to the iSeries server. It is important to consider the client under a different part of the cluster or high availability project. Clients are typically IP-connected devices. IP takeover can handle the movement of these devices from primary to the backup. In most cases, the client should see very little impact from a failure or switchover. 11.2.7 Application maintenance Application maintenance is a potentially difficult area to support high availability in a business. If the application only needs changes to the programs running within it, maintenance is minimized. However, if the application requires changes to the underlying database, maintenance is more complicated. 202 Clustering and IASPs for Higher Availability on the iSeries Server The design of an application must support these events to afford resilient functionality: 1. Switchover the primary system to the first backup node. 2. Replication is ended between the primary and first backup system. 3. With the normal primary system offline, application maintenance is carried out. A database mapping program is installed. These three functional steps are illustrated in Figure 11-1. Figure 11-1 through Figure 11-3 illustrate how to retain full protection for the cluster while performing an application maintenance task. Chapter 11. Considerations when planning for iSeries clusters and recoverable applications 203 Figure 11-1 Application maintenance in a cluster (Part 1 of 3) 4. The original primary node is added back into the cluster as a second backup. The database is resynchronized with the primary system. 5. The role is swapped between the first and second backups. System C is taken offline to maintain the application. System B Primary node System C 1st Backup node System A 2nd Backup Updates mapped to new database Old Database New Database Old Database System B Primary node System C 1st Backup node System A not available Replication System B 1st Backup node System C 2nd Backup node System A Primary node Replication Replication Replication is ended between the primary and first backup. Normal primary is taken offline and the application maintenance is carried out. A database mapping program is installed. Backups run production load with roles changed. Original primary is added back into the cluster as a second backup. The database is re-synchronized with the primary. During the apply process, the old database is mapped on to the new database on the second backup. 204 Clustering and IASPs for Higher Availability on the iSeries Server 6. During the apply process, the old database is mapped to the new database on the second backup system. 7. The original primary becomes the first backup. It is now in a position to become the primary system. These four steps are illustrated in Figure 11-2. Figure 11-2 Application maintenance in a cluster (Part 2 of 3) System B not available System C 1st backup node System A Primary node New Database New Database New Database The original primary and second backup now run with a new application and no mapping program. System C is added back into the cluster as the second backup. The original primary becomes the first backup. This is now in a position to become the primary. System B Primary node System C not available System A 1st Backup node New Database New Database Old Database System B Primary node System C 2nd backup node System A 1st backup node New Database New Database Old Database System B has had the application maintenance work carried out, and its database is re-synchronized with Systems A and B. Chapter 11. Considerations when planning for iSeries clusters and recoverable applications 205 8. System C is added back into the cluster as a second backup. The old database is replicated to the first backup and remapped to the new database. The new database is then replicated from the first backup to the second backup. 9. The original primary and second backup now run with the new application and no mapping program. 10.System B has had the application maintenance work carried out. Its database is re-synchronized with Systems A and B. 11.In the final phase, System B is added back into the cluster as the second backup. Then, its role is switched to the first backup. The cluster is returned to its original state. These four step are illustrated in Figure 11-3. Figure 11-3 Application maintenance in a cluster (Part 3 of 3) 11.2.8 Database performance If replication software is currently running, you need to understand whether there is a database performance problem. Database performance is not directly related to creating a clustered solution. A resolution to the performance problem on nodes of a cluster is no different than if the problem occurred on a single system. The use of journaling and commitment control in the application is needed for full deployment of a clustered solution. Journaling does add performance overhead to an application. Note that technology improvements in OS/400 and the iSeries hardware have minimized performance degradation with journaling and commitment control. These areas continue to be enhanced and improved with each release of OS/400. However, the significant recovery options facilitated with journaling and commitment control are not without a compromise in performance. And adding journaling and commitment control to a poorly designed database can make things run even slower. System B 2nd backup node System C 1st backup node System A Primary node New Database New Database New Database 206 Clustering and IASPs for Higher Availability on the iSeries Server 11.3 Systems management System management is critical component of a clustering implementation plan. Cluster management is eased with the support of stable system management policies. Incorporate a discipline for system management before you implement a clustering project. Effective systems management involves plans that define and support a business’ expectations for service, operations, managing problems and change, planning for capacity, optimizing performance, and protecting the system, as discussed in this section. 11.3.1 Service level agreements When considering service level agreements, start with the business executives. They are the key sponsors for developing service level agreements that support the needs of the business. The executives are also the source of the requests to the finance department. Much of the planning for a service strategy is done when developing the financial case for the availability solution. 11.3.2 Operations management In a single system environment, the operations staff typically has a proven management system. Daily run schedules and overnight batches are well understood. Normally there is a simple but long running recovery process. In a cluster environment, a more lights-out operation can be run. That is, many tasks can be performed automatically. Establish a cutover plan from the existing environment to the clustering environment. This can mean changing work-shift patterns and possibly adding staff to cover tasks that could run over weekends. The skills and resources that are required to implement and manage a cluster solution are different from most current I/T departments. Critical skills are database management and networking. Most customer shops have programming skills and some networking skills. As the mission critical application starts, the ability to remedy the problem very quickly is important to meet service level agreements. Having the right skills is essential. Once these steps are complete, update or re-write the operational documentation. 11.3.3 Problem and change management Establishing an effective problem and change management strategy is critical when managing clustered systems. If there are problem and change management processes in place to support a single system, modify them to manage a clustered environment. Account for different service level agreements. In a clustered setup, it is more important to reporting and analyze problems as quickly as possible. Minimize any time spent waiting for a key person to return when a problem occurs. To make fast informed decisions, improve the escalation process of reporting problems. For example, when the operator notes errors reported by disk units of an impending failure, do not wait for the return call of a Customer Engineer. Pump the disk. Prepare for a switchover if the system performance degrades. Chapter 11. Considerations when planning for iSeries clusters and recoverable applications 207 Analyze each system throughout the business for a risk assessment. Prioritize each system’s availability. Document failover plans. Include the decision points in the failover plan, with directions on which step to take next. Consider this example. A processor sends a warning of an overload. One of the applications running on that processor needs to be switched to another processor that has spare capacity. Prioritize the applications on the overloaded system. Implement the predefined plan. Initiate the planned switch for the application. Exit programs cause the CRGs, IP address, and users to be switched to the backup system. This application remains on the backup system until the primary processor is analyzed and the problem rectified. Then switch the application back to the primary system. Many of the normal problems of maintaining a highly available single system are automated or disappear. Now, different problems exist and need to be addressed, such as:  Partition state  Application maintenance  Managing a mix of applications with a different resilience characteristics  Managing batch applications in a cluster 11.3.4 Capacity planning Cluster functions cause minimal overhead to system resources. Nevertheless, size the systems to support the cluster setup. The easiest way to size a cluster is to first plan the capacity as a single system. Then model the load produced by journaling and the apply process. Use BEST/1 to model these functions and to provide a relatively accurate model of the single node. Planning for capacity can be more complex depending on the roles of the nodes, and the applications run in different settings. For example, one system is planned to be the primary node for an application in one recovery domain. With a failure or switchover, this node supports another application. Include this additional application workload in the planning process. Review each node and model for the worst case scenario. Make sure that the capacity of other components related to the node are included, for example, I/O processors, network connections, and backup devices. Once the cluster is up and running, regularly monitor and re-evaluate the capacity of all the nodes. Do not allow the resources on the backup nodes to become overutilized. If a failure or switchover is necessary, the additional load on the backup machine can create an availability problem of its own. 11.3.5 Performance planning Performance considerations for clusters are similar to capacity planning for clusters. Take performance measurements regularly to monitor that service levels are achieved. Register any out-of-line situations. Take corrective action to reduce the risk of losing the integrity of the cluster. When a switchover occurs for the purposes of routine maintenance, take recordings from the backup node to ensure that it still meets the performance expectations and that the backup node is not degraded by the added workload. 208 Clustering and IASPs for Higher Availability on the iSeries Server 11.3.6 Security and password considerations The Allow Add to Cluster (ALWADDCLU) network attribute specifies whether a node allows itself to be added to a cluster. Use the Change Network Attribute (CHGNETA) command on any system that is to be set up as a cluster node. Set a value for the ALWADDCLU network attribute, before you add a node to a cluster. Depending on the option chosen for this attribute, the use of X.509 digital certificates can be required. A digital certificate is a form of personal identification that can be verified electronically. Because there is no central security administration to update nodes, user profiles are not automatically updated across cluster nodes. Be sure to update the security information across all nodes to ensure that any public or private authorities associated with any cluster objects, Cluster Resource Groups, applications, or data have the correct security level. Synchronize the user profiles across systems in a recovery domain so that the user profile name, the UID, and the GID are the same on all systems. One mechanism to update security information and synchronize user profiles is through the Management Central framework. Perform administrator or operator functions across multiple systems and groups of systems. Another option is to use software functions provided by a cluster middleware provider. 11.4 Hardware considerations Hardware is relatively inexpensive when compared to the cost of failure. When investigating the cost of hardware, do not simply look at the hardware related to the computer system. There are many other hardware components of a complete continuously available solution. It is relatively easy to provide a configuration that includes redundant hardware in a continuously available system complex. However, redundant hardware adds complexity to overall system management. When planning the total computing solution, consider a redundant configuration for these components:  Processor complex (includes bus) – Disk redundancy – Adapter redundancy – Remote site redundancy This redundancy can consist of a complete remote location or a remote controller at the main site.  Site – Machine room – Air conditioning – Power supply – Office space – Telephone services  Network hardware From routers to remote controllers, review all network hardware. If there are critical requirements for remote access, provide alternative network paths. This can be as straightforward as a dial-up link, or as complex as a multi-path private network. Chapter 11. Considerations when planning for iSeries clusters and recoverable applications 209  Network connection If planning to extend business services to an intranet or the Internet, consider the impact of a single Internet Service Provider (ISP). The ISP is another single point of failure. For the highest availability, use multiple network providers. 11.4.1 Network planning Network planning includes capacity and accessibility factors. The network must be able to maintain the same level of availability as the nodes of the cluster. Communication providers must provide guarantees that are available and have sufficient capacity for all possible switch scenarios. There must be alternative network paths to enable the cluster services to manage the cluster resources. These redundant paths should prevent a cluster partition occurring. Figure 11-4 illustrates redundant communications paths between the nodes in the cluster. Figure 11-4 Redundant network connections A redundant communications path is when there are two communication lines configured between two nodes in a cluster. If a failure occurs, the second communication path can take over to keep communications running between the nodes. This minimizes the conditions that can put one or more nodes of the cluster into a cluster partition situation. Note that if both communication lines are defined to go into the same adapter on the system, both lines are at risk if the single adapter fails. Redundant adapters are recommended. See 12.3, “Recovering from a cluster partition state” on page 220, for more information on cluster partitions. Memory card Memory card Processor Card Memory card Memory card LAN Adapter Card (redundant) LAN Adapter Card (active) Processor Card System B Processor These cards are shown as LAN cards, but could be WAN or ATM cards Mirrored disks Mirrored disks System A Processor Network LAN Adapter Card (redundant) LAN Adapter Card (active) 210 Clustering and IASPs for Higher Availability on the iSeries Server 11.5 Testing clusters Testing is a well-established and controlled part of most development shops. A second system or separate LPAR partition enables testing of the operating system and application test environments. Unfortunately, this testing is not always extended to all facets of the business. Network, hardware, and external link testing are often overlooked. A classic example of the need for testing is Web page design. A Web page is built and tested on the internal LAN and then placed onto the Web. The site is tested from the LAN out to the Web and back into the Web site. High speed links are typically used. However, remote testing is not done. When the remote site connects with, for example, a 14.4 Kbps modem on the other side of the world, and the application is made available, it takes an extended time to load. Visitors do not stay on a site with slow response time. Determine whether the development environment is a critical resource. If it is, include the development system in the cluster. A totally separate cluster test configuration is needed. Figure 11-5 illustrates how a simple customer setup can be changed to produce a more effective test environment. The test scenario illustrated is a simple high availability environment. It is a two-node cluster or replication environment. A separate system is available for development which has no links to the cluster. Development cannot test changes in a clustered environment. To enable tested changes to be made to the cluster, a fourth system is added. Changes can then be tested on the development systems before moving these changes into production. Figure 11-5 Cluster test scenario Figure 11-5 shows the basic systems. It does not show the routes, LANs, WANs, etc. that need to simulate the real environment. Creating a separate cluster with two small systems meets most testing needs. An issue with this arrangement is the possibility that certain types of hardware and peripherals may not work with smaller systems, and it may be difficult to do any accurate volume testing. System B Production System C Backup System D Development 2 System A Development 1 This is a very simple HA environment. There is a two-node cluster or replication environment. A separate system is available for development that has no links to the cluster. But development cannot test changes in a clustered environment. To enable tested changes to be made to the cluster, a fourth system is added. Changes can then be tested on the development systems, before moving these changes into production. Chapter 11. Considerations when planning for iSeries clusters and recoverable applications 211 Whether a highly available solution is implemented, or building a cluster is the plan, consider a test environment during the implementation. Testing is as critical as any application on the system. The cost of a test system is relatively trivial. Do not try to save money in this area. Establish an ongoing problem and change management test environment. 11.5.1 System management tests System management testing is mainly aimed at performance and operations. These areas are tested:  Application process (normally part of development testing)  Application volume  Hardware and peripheral (tape, DASD, IOPs, remote devices, clients)  Interoperability  Network performance  Network hardware When performing volume-related testing, it is important to have a well-documented script for producing the test. If the capacity is not available on the local test machines, consider an external testing source, for example, one of the IBM Benchmark Centers. Visit this Web site to see more IBM testing sites: http://www.developer.ibm.com 11.5.2 Cluster management tests Some of the scenarios to test before moving the cluster into production are:  Planned switch  Failover  Rejoin  Adding a cluster node Re-test these scenarios after a system upgrade or major change to any of the cluster components. 11.6 Roles and responsibilities when implementing clustering IBM supports the cluster middleware business partner solutions for clustering on the iSeries server. Implementation of a clustering solution for an iSeries customer is a cooperative effort between IBM, the cluster middleware provider selected by the customer, and the application business partner responsible for the application running at the customer site. This section describes the roles fulfilled by IBM, the cluster middleware provider, and the application provider when implementing a full cluster solution. 11.6.1 The role of IBM and OS/400 IBM’s role is to provide the foundation for clustering services. To fulfill that role, OS/400 delivers integrated system services and a set of APIs to create, change, delete, and manage clusters, nodes and CRGs. One critical clustering system service is activation of the exit program whenever an event occurs for a recovery domain. Calling the exit program is much like calling a trigger program when a database event occurs. The programmer determines what happens when the program is called, but OS/400 initiates the program automatically on all the nodes in the 212 Clustering and IASPs for Higher Availability on the iSeries Server affected recovery domain. When any change to the cluster environment occurs, OS/400 calls the exit program with information such as the current role of the node and the action code – addition of a node, for example. Most of the clustering APIs allow developers to specify up to 256 bytes of information to be passed to the exit program. Other clustering system services, while less visible, are still important because some functions are implemented more efficiently at the operating-system level than they can be with any third-party product. For example, an IP address takeover (or IP takeover) makes it possible for multiple nodes in the recovery domain to have the same IP address at different times. (Two nodes can never have the same IP address at the same time.) IP takeover facilitates a transparent switchover in a TCP/IP environment. Perhaps the most critical clustering function, a function that forms the basis of all clustering support from OS/400 V4R4 onward, is heartbeat monitoring. Heartbeat monitoring constantly checks communications between the nodes in a cluster. If communication between two nodes is lost, heartbeat monitoring attempts to reestablish communications. If a node fails, heartbeat monitoring reports the node failure to the rest of the cluster. Although the high availability business partners (HABPs) can implement a form of heartbeat monitoring, IBM's system-level implementation of heartbeat monitoring consumes fewer resources and provides a more accurate view of a node’s status. Heartbeat monitoring, in conjunction with other integrated cluster services, ensures that all nodes have a consistent view of the cluster. To assist the users who prefer to work with clusters themselves, resources are available in the QUSRTOOL library that allow the user to build a set of Cluster Resource Service commands. These commands provide a user friendly interface to the Cluster Resource Service APIs. 11.6.2 The role of a cluster middleware provider Although it is possible for a user to build a clustered environment, this work is often performed in cooperation with, or by, a cluster middleware business partner such as those described in Part 3, “Cluster middleware business partners” on page 227. OS/400 APIs are available to define resilient resources and initiate planned switchovers. Cluster middleware providers use these APIs to deliver interfaces and tools to manage clusters. These tools complement their existing high-availability offerings and insulate application developers from coding directly to the clustering APIs. For managing cluster objects, IBM has defined a standard for cluster management utilities. Some cluster middleware providers provide a graphical tool with its own unique personality that satisfies this standard and integrates OS/400 clustering functions with functions in their high-availability product. 11.6.3 The role of an application developer Application developers handle all application-specific clustering tasks. Some of these tasks work in conjunction with the high-availability solutions. For example, an application developer defines resources such as files and program objects for replication in the automated installation data area. The cluster middleware provider usually handles the task of replicating information. Application developers also provide an exit program to restart applications on a backup system after a switchover. For example, the exit program can be used to ensure that the required CRGs are available before an application is restarted. Chapter 11. Considerations when planning for iSeries clusters and recoverable applications 213 Ideally, an application is transferred from one iSeries server to another and the user is repositioned at precisely the same spot in a transaction as before the switchover occurs. In pursuit of this ideal, application developers can add checkpoint facilities to their applications. An application checkpoint is usually implemented using commitment control. In conjunction with an appropriate exit program, a checkpoint application has the ability to restart at the last complete transaction. 214 Clustering and IASPs for Higher Availability on the iSeries Server © Copyright IBM Corp. 2000, 2002 215 Chapter 12. Problem determination for iSeries clustering To effectively manage an iSeries cluster, the operator must first know where to look for error messages that deal specifically with clustering and understand how to resolve the errors. This chapter identifies problem determination tools and techniques that are useful when encountering a problem during the setup of clusters or when managing an iSeries cluster. 12 216 Clustering and IASPs for Higher Availability on the iSeries Server 12.1 Monitoring for problems As with any component of the iSeries and OS/400, error logs exist to help in problem determination and resolution. There are several system log entries and error messages unique to clustering:  Vertical Licensed Internal Code (VLIC) logs (VLOG) entries with a major code of 4800 indicate a clustering situation.  Many of the messages related to clustering are in the range of CPFBB00 to CPFBBFF. The occurrence of CPF messages can be monitored for. Alertable messages can be found in the QHST history log and in the QSYSOPR message queue. Use the Display Log (DSPLOG) command to display the history log, and use the Display Message (DSPMSG) command to see what is logged in QSYSOPR. If following the suggested resolution in the message text does not resolve the problem, note the message ID and message text before calling IBM for service. For example, message ID CPFBB05 contains the help text: Cluster node xx cannot be started. The recovery action based on the cause code is also found within the message text. See Figure 12-1 for an illustration. Figure 12-1 Recovery action for clustering error message Messages related to cluster configuration are logged to the QCSTCTL job log. Messages related to configuring a Cluster Resource Group (CRG) are logged to the QCSTCRGM job log. Messages related to managing a Cluster Resource Group are logged to the CRGs job log. All of these job logs are found in the QSYSWRK subsystem. Run the Work with Active Job (WRKACTJOB) command to display messages about these Cluster Resource Service jobs. Use the WRKACTJOB command to display messages about the Cluster Resource Group jobs. Look for the name of the Cluster Resource Group job under the QSYSWRK subsystem. For example, if the name of the Cluster Resource Group is CRG1, look for the job named CRG1 in QSYSWRK. To find an application Cluster Resource Group job, follow these steps: 1. Determine the subsystem where the application job is running. Check the Cluster Resource Group object to determine the user profile used when the application Cluster Resource Group job was submitted. Every user profile is associated with a job description and every job description is associated with a subsystem. Cause . . . . . : Cluster node &1 in cluster &2 cannot be started. The reason code is &3. The reason code is defined as follows: 1 -- Could not communicate with cluster node &1. The errno value is &4. 2 -- Loopback interface address (127.0.0.1) for cluster node &1 not active. Recovery . . . : Recovery actions for each reason code are: 1 -- If TCP/IP is not active on this system, start TCP/IP communications using the Start TCP/IP (STRTCP) command. If the INETD server is not active on cluster node &1, have the system operator on that system start it using the Start TCP/IP Server (STRTCPSVR) command. Ignore the errno value if it is 0. 2 -- Start the loopback interface address for cluster node &1 using the Start TCP/IP Interface (STRTCPIFC) command. Chapter 12. Problem determination for iSeries clustering 217 2. Check this subsystem for the application Cluster Resource Group job. 12.2 Problems with the status of a cluster This section addresses commonly asked questions about the status of clustering jobs when working on a system with clusters. You can find more complete information in the Troubleshooting clusters topic in the Information Center at: http://www.ibm.com/eserver/iseries/infocenter To locate the problem determination section, click Systems Management-> Clusters-> Troubleshooting clusters. 12.2.1 Is my cluster up and running? To determine if Cluster Resource Services (CRS) is active on the system, run the WRKACTJOB command from an OS/400 command line. Under the QSYSWRK subsystem, look for two jobs:  QCSTCTL  QCSTCRGM If these jobs exist, Cluster Resource Services is active and the cluster is up and running. QCSTCTL and QCSTCRGM jobs are cluster-critical jobs. Both jobs must be active for Cluster Resource Services to be active. Should one of these jobs end, clustering ends on that system (node). CRG jobs are not cluster-critical jobs. Clustering can remain active when a CRG job ends. 12.2.2 Why won’t my cluster start? When a cluster is not started, check these areas:  Make sure that TCP/IP is active: a. Enter the WRKACTJOB command. b. Locate the QSYSWRK subsystem. c. Look for a job named QTCPIP running in the QSYSWRK subsystem. If this job exists, TCP/IP is running on the system. Or follow these steps: a. Enter the network status command (NETSTAT). b. Select option 1 to see if TCP/IP is active. If TCP/IP is not active, run the Start TCP/IP (STRTCP) command from the OS/400 command line.  Be sure that the *INETD server is started by performing one of the following tasks: – Under the QSYSWRK subsystem, look for a job named QTOGINTD. If this job exists, the *INETD server is started. – Use NETSTAT and select option 3 to see if the *INETD server is started. If *INETD is not started, run the Start TCP Server (STRTCPSVR *INETD) command from the OS/400 command line. 218 Clustering and IASPs for Higher Availability on the iSeries Server  Check the ALWADDCLU network attribute The ALWADDCLU network attribute specifies whether a node allows itself to be added to a cluster. This should be set to either *ANY or *RQSAUT depending on the environment. The default value is *NONE, which does not allow the system to be added to a cluster.  Check that the IP addresses chosen to be used for clustering locally and on the target node show an Active status. The local and any remote nodes must be able to PING using the IP addresses to be used for clustering to ensure network routing is active.  Check that the LOOPBACK address (127.0.0.1) locally and on the target node is also active. 12.2.3 Why is my CRG hung up? The Cluster Resource Group job can appear to be in a hang (wait) state for a number of reasons. For example, a hang state can appear if:  The exit program associated with the CRG is itself in a long wait state (status). The CRG hangs upon a return of control from the exit program.  The CRG exit program job has not ended or returned to the CRG job.  There is an inquiry message on the QSYSOPR message queue while the CRG job logs First Failure Data Capture (FFDC) messages, and the spooled file reaches the maximum number of records allowed.  An exit program is submitted to a job queue in a subsystem that releases one job at a time. In this case, the CRG waits for the exit program to return a completion message. If the exit program does not complete, the CRG appears to be in a hang state. Maximum number of jobs from job queue or in subsystem The default job description submits jobs to the QBATCH job queue. This QBATCH is used for many user jobs. Set the maximum jobs to release from QBATCH to a value that allows the exit program job to run in a timely fashion. In addition to the control offered by the number of jobs allowed to run from the job queue at any time, the subsystem definition has a similar throttle. Be sure that the subsystem the Cluster Resource Group exit program runs in allows more than one job to run at a time. Use the Change Subsystem Description (CHGSBSD) command and specify *NOMAX, or a number greater than 1, for the maximum jobs parameter. If it is not possible to change the maximum job value to *NOMAX, consider creating a separate subsystem for the CRG exit program job or other jobs. 12.2.4 I cannot use the IBM Cluster Management GUI To access the IBM Simple Cluster Management GUI, the High Availability Switchable Resources option of OS/400 must be installed on the system. A valid license key for this option must exist. Tip: Specify a unique job queue name in the job description that identifies the exit program associated with the CRG. Chapter 12. Problem determination for iSeries clustering 219 Use the GO LICPGM CL command and select option 11 (Display Licensed Programs). Look for option 41 HA Switchable Resources and install it if necessary. 12.2.5 I cannot use any new release functions An attempt to use a new release function that is not compatible with the current cluster version errors with a CPFBB70 error message. The text of CPFBB70 indicates that the API request is not compatible with the current cluster version. This happens when the current cluster version does not support the function requested by the API. Note that the new release functions are not available until both of the following points are true:  All cluster nodes have a potential cluster version that supports the new function.  The current cluster version has been set to match this potential cluster version. For example, consider the use of the Change Cluster Resource Services API (QcstChgClusterResourceServices). In a cluster setup consisting of two-nodes, Node A is at OS/400 V4R5 and Node B is at V5R1. An attempt is made on Node B to change the cluster performance tuning level to be more sensitive to communications failures. This function is available with the V5R1 QcstChgClusterResourceServices API. Another example is the Add Device Domain Entry API (QcstAddDeviceDomainEntry). Even though these APIs are supported on one of the nodes of the cluster, Cluster Resource Services (CRS) does not allow the operation on any node of the cluster, because the cluster, as a whole, does not support the V5R1 function. To resolve this conflict, upgrade all cluster nodes to the new release level. Then use the QcstAdjustClusterVersion API to adjust the current cluster version and try the request again. You can learn more about cluster versioning in “Cluster versioning” on page 36. 12.2.6 How do I recover from a Cluster Resource Group job failure? Failure of a Cluster Resource Group job is usually indicative of some other problem. Look in the job log associated with the failed job for messages that describe why it failed. Correct any error situations. To recover from a failure of a Cluster Resource Group job, follow these steps: 1. End clustering on the node where the job failure occurred. 2. Restart clustering on the node. 12.2.7 Why do I have two clusters after fixing my cluster partition? The most common reason for more than one cluster to exist in a partition is when the Start Cluster Node (QcstStartClusterNode) API runs in an inactive node. Run this API on an active node in the cluster to start Cluster Resources Services on the inactive node. Note: If the cluster entry does not appear in Operations Navigator when you expand Management Central, that is likely because “Logical Systems” was not selected when installing Operations Navigator. Logical Systems is not included in the default setup of Operations Navigator. Re-install Operations Navigator on the workstation. Be sure to select Logical Systems on the Component Selection window. This will solve the problem and clusters will appear under Management Central. 220 Clustering and IASPs for Higher Availability on the iSeries Server 12.3 Recovering from a cluster partition state A cluster partition happens when contact is lost between one or more nodes in the cluster and a failure of the lost nodes cannot be confirmed. A CPFBB20 error message is issued to indicate the cluster is in a partitioned cluster situation. To recover, find the CPFBB20 error message in the QHST history log and in the QCSTCTL job log in the QSYSWRK subsystem. Follow the recovery action found in the message text. 12.3.1 Cluster partition error example This section illustrates a cluster partition condition that involves a cluster made up of four nodes, known as A, B, C, and D. The Cluster Resource Groups associated with these nodes are named CRGA, CRGB, CRGC, and CRGD respectively. For this example, a loss of communication occurs between cluster nodes B and C. The cluster then divides into two cluster partitions. Figure 12-2 illustrates the recovery domain of each Cluster Resource Group. Figure 12-2 Cluster partition The types of Cluster Resource Group actions that can be taken within a cluster partition depend on whether the partition is a primary or a secondary cluster partition. The cluster partition that contains the current primary node in the recovery domain of a Cluster Resource Group is considered the primary partition of the Cluster Resource Group. All other partitions are secondary partitions. The primary partitions may not be the same for all Cluster Resource Groups. Table 12-1 and Table 12-2 identify the partition type in which each Cluster Control and Cluster Resource Group API is allowed to run. The action performed by the API takes affect only in the partition in which the API runs. Chapter 12. Problem determination for iSeries clustering 221 Table 12-1 Cluster Control API partition restrictions Table 12-2 Cluster Resource Group API partition restrictions Cluster Resource Group API Partition the API is allowed to run in Add Cluster Node Entry Not allowed in any partition Add Device Domain Entry * Adjust Cluster Version Not allowed in any partition Change Cluster Node Entry Any partition Change Cluster Resource Services Any partition Create Cluster Not allowed in any partition Delete Cluster Any partition End Cluster Node Any partition** List Cluster Information Any partition List Device Domain Information Any partition Remove Cluster Node Entry Any partition Remove Device Domain Entry Any partition*** Retrieve Cluster Information Any partition Retrieve Cluster Resource Services Information Any partition Start Cluster Node Any partition * Allowed only for an existing device domain where all members are in the same partition. ** Allowed only in the same partition as the node being ended. *** All members must be in the same partition. Cluster Resource Group API Partition the API is allowed to run in Add CRG Device Entry Primary* Add Node to Recovery Domain Primary Change CRG Primary Change CRG Device Entry Primary Create CRG Not allowed in any partition Delete CRG Any partition** Distribute Information Any partition** End CRG Primary Initiate Switch Over Primary List CRGs Any List CRG Information Any Remove CRG Device Entry Primary Remove Node from Recovery Domain Primary 222 Clustering and IASPs for Higher Availability on the iSeries Server By following these restrictions, Cluster Resource Groups can be resynchronized when the cluster is no longer partitioned. As nodes rejoin the cluster from a partitioned status, the version of the Cluster Resource Group in the primary partition is copied to nodes from a secondary partition. When a partition is detected, neither the Add Cluster Node Entry or the Create Cluster API can be run in any of the partitions. All of the other Cluster Control APIs may be run in any partition. However, the action performed by the API takes affect only in the partition running the API. Once the partitioned cluster situation is corrected, a CPFBB21 message is issued to indicate the cluster partition is recovered. The CPFBB21 message can be found in the QHST history log and in the QCSTCTL job log of the QCSTCTL job running in the QSYSWRK subsystem. See B.3, “Cluster APIs and related QUSRTOOL commands” on page 286, for a listing and description of each cluster API. 12.3.2 Cluster partition tips The rules for restricting operations within a partition are designed to make merging the partitions feasible. Without these restrictions, reconstructing the cluster can require extensive work. This section offers tips for managing cluster partitions:  If the nodes in the primary partition are destroyed, special processing can be necessary in a secondary partition. The most common scenario that causes this condition is the loss of the site that makes up the primary partition. Refer to Figure 12-2 on page 220 as an illustration. Assume that Partition 1 is destroyed. To locate the primary node for Cluster Resource Groups B, C, and D Partition 2, perform these operations: a. Delete Cluster Resource Groups B, C, and D in Partition 2. b. Remove Nodes A and B from the cluster in Partition 2. Partition 2 is now the primary cluster. c. Create Cluster Resource Groups B, C, and D in Partition 2. Specify Nodes C and D as the recovery domain. d. Establish any replication environments that are needed in the new cluster. Start CRG Primary * All nodes in the CRGs recovery domain must be active in the primary partition. ** Affects only the partition running the API. Cluster Resource Group API Partition the API is allowed to run in Add CRG Device Entry Primary* Add Node to Recovery Domain Primary Change CRG Primary Change CRG Device Entry Primary Create CRG Not allowed in any partition Delete CRG Any partition** Chapter 12. Problem determination for iSeries clustering 223 Since nodes are removed from the cluster definition in Partition 2, an attempt to merge Partition 1 and Partition 2 fails. To correct the mismatch in cluster definitions, run the Delete Cluster API on each node in Partition 1. Then add the nodes from Partition 1 to the cluster, and re-establish all the Cluster Resource Group definitions, recovery domains, and replication activity. This process is difficult and prone to errors. Perform this procedure only in a site loss situation.  A start node operation is processed differently depending on the status of the node being started: – If the node fails or an End Node operation ends the node: • Cluster Resource Services is started on the node that is being started. • A cluster definition is copied from an active node in the cluster to the node that is being started. • Any Cluster Resource Group that has the node being started in the recovery domain is copied from an active node in the cluster to the node being started. No Cluster Resource Groups are copied from the node that is being started to an active node in the cluster. – If the node is in a partitioned state: • The cluster definition of an active node is compared to the cluster definition of the node that is being started. If the definitions are the same, the start continues as a merge operation. If the definitions do not match, the merge stops. The user needs to intervene. • If the merge continues, the node that is being started is set to an active status. • Any Cluster Resource Group that has the node being started in the recovery domain is copied from the primary partition of the Cluster Resource Group to the secondary partition of the Cluster Resource Group. Cluster Resource Groups can be copied from the node that is being started to nodes that are already active in the cluster. 12.3.3 Merging a cluster partition A merge operation is similar to a rejoin operation except that a merge occurs when a cluster has become partitioned. The partition can be a true partition in that Cluster Resource Services is still active on all nodes. However, some nodes cannot communicate with other nodes due to a communication line failure. Or, the problem may be that a node actually fails, but is not detected as such. In the first case, the partitions are automatically merged back together once the communication problem is resolved. This happens when both partitions periodically try to communicate with the partitioned nodes and eventually re-establish contact with each other. In the second case, Cluster Resource Services must be restarted on the failed node. Call the Start Cluster Node API from one of the nodes that is active in the cluster to start the CRS. If the Start Cluster Node API is called on the failed node, it becomes a one-node cluster and does not merge back into the rest of the cluster. As shown in Figure 12-3, a merge operation can occur with one of the configurations that is present. 224 Clustering and IASPs for Higher Availability on the iSeries Server Figure 12-3 Possible merge operations Primary and secondary partitions are unique to Cluster Resource Groups. For a CRG, a primary partition is defined as a partition that has the CRG's primary node active in it. A secondary partition is defined as a partition that does not have the primary node active in it. For example, a cluster has two nodes: Node A and Node B. The cluster has two CRGs: CRG 1 and CRG 2. Node A is the primary node for CRG 1, and Node B is the backup node. Node B is the primary node for CRG 2, and Node A is the backup node. If a partition occurs, Node A is the primary partition for CRG 1 and the secondary partition for CRG 2. Node B is the primary partition for CRG 2 and the secondary partition for CRG 1. This setup is illustrated in Figure 12-4. Figure 12-4 Primary-secondary merge operation During a primary and secondary merge, as illustrated in Figure 12-4, these merges are possible:  CRG 1 with CRG 3  CRG 1 with CRG 4 Merge Secondary Partition Secondary Partition Merge Primary Partition Secondary Partition Merge Primary Partition Secondary Partition Does not have copy of CRG 4 Has copy of CRG 3 Has copy of CRG 1 Does not have copy of CRG 2 Chapter 12. Problem determination for iSeries clustering 225 A merge of CRG 2 and CRG 3 cannot happen since a primary partition has the primary node active and must have a copy of the CRG. Likewise, a merge of CRG 2 and CRG 4 cannot happen since a primary partition has the primary node active and must have a copy of the CRG. Primary and secondary merge In a primary and secondary merge situation, a copy of the CRG object is sent to all nodes in the secondary partition. The results vary. As seen on the nodes of the secondary partition, these results are possible:  No action since the secondary node is not in the CRG's recovery domain.  A secondary node's copy of the CRG is updated with the data from the primary partition.  The CRG object is deleted from a secondary node since the secondary node is no longer in the CRG's recovery domain.  The CRG object is created on the secondary node since the object does not exist. However, the node is in the recovery domain of the CRG copy that is sent from the primary partition. During a secondary-secondary merge as shown in Figure 12-5, these merge situations are possible:  CRG 1 with CRG 3  CRG 1 with CRG 4  CRG 2 with CRG 3  CRG 2 with CRG 4 Figure 12-5 Secondary-secondary merge operation Secondary and secondary merge: Situation 1 In a merge of two secondary partitions, one possible situation is that the node with the most recent change to the CRG is selected to send a copy of the CRG object to all nodes in the other partition. If multiple nodes are selected because they all appear to have the most recent change, the recovery domain order is used to select the node. The resulting actions that can occur on the receiving partition nodes are:  No action since the node is not the CRG's recovery domain.  The CRG is created on the node since the node is in the recovery domain of the copy of the CRG object it receives.  The CRG is deleted from the node since the node is not in the recovery domain of the copy of the CRG object is receives. Merge Secondary Partition Secondary Partition Does not have copy of CRG 4 Has copy of CRG 3 Has copy of CRG 1 Does not have copy of CRG 2 226 Clustering and IASPs for Higher Availability on the iSeries Server Secondary-secondary merge: Situation 2 In a merge of two secondary partitions, one possible situation is that a node from the partition that has a copy of the CRG object is selected to send the object data to all nodes in the other partition. The CRG object can be created on nodes in the receiving partition if the node is in the CRG's recovery domain. Secondary-secondary merge: Situation 3 In a merge of two secondary partitions, one possible situation is that internal data is exchanged to ensure consistency throughout the cluster. A primary partition can subsequently be partitioned into a primary and secondary partition. If the primary node fails, CRS detects it as a node failure. The primary partition becomes a secondary partition. The same result occurs if the primary node that uses the End Cluster Node API is ended. A secondary partition can become a primary partition if the primary node becomes active in the partition through either a rejoin or merge operation. For a merge operation, the exit program is called on all nodes in the CRG's recovery domain, regardless of the partition in which the node is located. The same action code as rejoin is used. No roles are changed as a result of the merge, but the status of the nodes in the CRG's recovery domain is changed from partition to active. Once all partitions merge together, the partition condition is cleared, and all CRG APIs can be used. © Copyright IBM Corp. 2000, 2002 227 Part 3 Cluster middleware business partners Cluster middleware business partners provide high availability solutions using the Cluster Resource Services support enabled in OS/400. Their customized solutions provide full function support for:  Cluster management  Data resiliency Application resiliency can be delivered by exploiting the OS/400 cluster technology and the cluster management services. Part 3 highlights the cluster management utilities provided for iSeries customers by three cluster middleware business partners:  DataMirror  Lakeview Technology  Vision Solutions Part 3 228 Clustering and IASPs for Higher Availability on the iSeries Server © Copyright IBM Corp. 2000, 2002 229 Chapter 13. DataMirror iCluster DataMirror’s iCluster is an easy to implement and high performance solution for ensuring the continuous availability of business-critical applications, such as e-business, ERP and customer-facing applications. Built on IBM’s cluster technology as implemented within OS/400 at V4R4 and later, iCluster provides customers with continuous availability during both planned and unplanned outages. iCluster is for customers who require even greater levels of availability than can normally be attained through a non-clustered iSeries (AS/400) high availability environment. With the involvement of iSeries Solution Developers (SDs), IBM’s ClusterProven program, and DataMirror iCluster software, iSeries shops now have the whole solution to continuous availability. DataMirror iCluster software further enhances the iSeries cluster solution by providing the easy-to-use cluster management and robust data resiliency required in today's 24 x 365 e-business world. 13 230 Clustering and IASPs for Higher Availability on the iSeries Server 13.1 Introduction to iCluster iCluster is built on the underlying engine of DataMirror’s award winning HA Suite product. All of the features and ease of use that customers have come to rely upon are included in iCluster. It includes such features as:  XtremeCache technology that optimizes the flow of data into and out of a high speed software cache to help customers attain near zero latency for clustered iSeries high availability environments.  A single product code base for ease of use, administration, and less complex switching.  Match Merge technology to ensure data and object integrity.  Real-time auto registration to minimize administration.  Real-time Integrated File System replication for critical applications such as Domino, WebSphere and ERPs like J.D. Edwards OneWorld and SAP. iCluster provides three interfaces for iSeries cluster management. All three can be used interchangeably and provide a consistent view of the cluster. The three iCluster interfaces are:  A Java graphical user interface (GUI) client running on a PC or workstation  An OS/400 green-screen menu interface  A full set of OS/400 commands for cluster setup and management In addition to cluster management and data and object replication, iCluster fully supports ClusterProven applications and traditional iSeries applications. In other words, a ClusterProven application is not needed to take advantage of iCluster’s features and Java interface. iCluster also supports type 3 Cluster Resource Groups (CRGs) (or IASPs or switched disk) as provided in OS/400 V5R1. iCluster provides traditional high availability functions such as the ability to:  Check whether objects and data are synchronized across two systems.  Monitor replication processes, both current and historical, with alarms and alerts to allow for notification when user-defined latency thresholds are exceeded.  Stop and start replication apply processes while continuing the replication journal scrape processes to allow for backups to be performed on the remote system.  Define synchronization points in a replication process, with optionally specified user exits to be executed when a synchronization point is reached.  Define user exits to be executed automatically before or after a group switchover or failover (failure of a group’s primary node).  Define message queues where messages are placed by iCluster in the event of a failure of a group’s primary node. The basic steps that are performed to set up and run a cluster using DataMirror iCluster are explained in the following sections. Remember that each step can be performed through either the Java GUI, via green-screen menu options or through commands. 13.2 Getting started with iCluster Once the system administrator installs DataMirror iCluster on the nodes to form the cluster and the iCluster GUI interface (called the iCluster Administrator) is installed on the PC or workstation, a cluster can be setup. Chapter 13. DataMirror iCluster 231 If the iCluster Administrator is used on the PC or workstation, the user logs in with an iSeries user ID and password. The iCluster Administrator main window is presented, as shown in Figure 13-1. Figure 13-1 The DataMirror iCluster Administrator main window 13.3 Creating a cluster After the first node in the cluster is defined, a cluster is created. iCluster automatically activates (starts) each node as it is added to the cluster. Nodes can be de-activated (ended) and re-activated (re-started) at any time through either the Java GUI or the commands, for example: DMSTRNODE NODE(DEMO400A) Once the node is started, its status is shown as *ACTIVE. When a node is ended, its status displays as *INACTIVE. The cluster’s first node must be defined as the iSeries server that is currently used. Other nodes in the cluster must be defined from a system that is already an active node in the cluster. To define a node from a system that is not a node in the cluster, create a new cluster with that system as its first node. The first node defined in the cluster becomes its master node. The master node is responsible for maintaining the information that iCluster needs for data and object replication. This information has to be maintained on all the nodes in the cluster. That way, in the event of a failure or removal of the master node, any other node can automatically assume the role of the master node. For this reason, the master node, or any node that can potentially become the master node, must be directly accessible to all the nodes of the cluster via the TCP/IP interface given when each node is defined. 13.3.1 Adding a node to the cluster A node can be defined using the Add option on the iCluster Work with Nodes display, the DataMirror iCluster Add Node (DMADDNODE) command, or the iCluster Administrator Add Node input dialog, as shown in Figure 13-2. 232 Clustering and IASPs for Higher Availability on the iSeries Server Figure 13-2 The iCluster Administrator Add Node input dialog Expand the node list in the iCluster Administrator main window to view the complete list of nodes in the cluster and their current status (Figure 13-3). Figure 13-3 The iCluster Administrator cluster nodes display View the nodes with the Work with nodes option from the iCluster main menu on the iSeries server. Chapter 13. DataMirror iCluster 233 13.4 Creating and using Cluster Resource Groups DataMirror iCluster allows creation of data CRGs, application CRGs, and device CRGs that have either one node (the primary) or two nodes (a primary and a backup) in their recovery domain. Using two node groups, more complex cluster scenarios can be created. For example, a cluster consisting of a single primary node with two or more backup nodes can be setup. Simply create as many data CRGs as there are backup nodes, all with the same primary node, and select the same object specifiers to all the CRGs. See Figure 13-4. Figure 13-4 Cluster with a single primary node and three backup nodes 13.4.1 Creating data CRGs A data CRG is created in one of two ways:  Use the DataMirror iCluster Add Group (DMADDGRP) command, the Add option from the iCluster Work With Groups screen, or the iCluster Administrator Add Group input dialog. This creates a data CRG in the cluster.  Use the DataMirror iCluster Add Group (DMADDAPP) command, the Add option from the iCluster Work With Resilient Applications screen, or the Add option from the iCluster Administrator Resilient Applications window. This sets up a resilient application that contains one or more data CRGs. Use the first approach when there is specific, known high-availability requirements for data and objects. This approach allows a direct selection of the objects required for high availability. The second approach is primarily intended for setting up a ClusterProven resilient application (or an application that has been converted to be “cluster aware”) on the cluster. Note: ClusterProven applications can be used with any high availability business partner’s cluster software. 234 Clustering and IASPs for Higher Availability on the iSeries Server DataMirror consultants can help convert regular applications into “cluster aware” applications by creating the QCSTHAAPPI data area and the switching user exit required for iCluster. The remainder of this section deals with data CRGs created using the first approach, that is, as individual groups not associated with any resilient application. Figure 13-5 shows the input required to create a data CRG with the iCluster Administrator Add Group input dialog. Figure 13-5 The iCluster Administrator Add Group input dialog Note that an alternate message queue name can be specified to receive failover messages (in this case MWARKENT in QUSRSYS). Select other tabs to specify the recovery domain, user exits to be executed before and after a role swap, user-defined parameters to control replication of spooled files, and default database journals. These options are displayed in the iCluster Administrator Groups window as shown in Figure 13-6. Chapter 13. DataMirror iCluster 235 Figure 13-6 The iCluster Administrator Group window View the groups in the cluster and their current status with either the iCluster Work With Groups screen or the iCluster Administrator Groups window. Note that CRGs are not automatically activated (started) when they are created. A group remains in *INACTIVE status until it is activated. Also data CRGs (group type *REPL) have a second status value – the replication status. The replication status indicates whether replication processes are active for the group. Normally, if a data CRG is in *ACTIVE status, its replication status should also be *ACTIVE. 13.4.2 Selecting objects for a data CRG for high availability After defining a data CRG, select the objects required for high availability with either the DataMirror iCluster:  Select Object (DMSELOBJ) command  Select option on the Work with Object Specifiers by Group screen from the iCluster Work with Groups screen  Administrator Select/Add Object Specifier input dialog The iCluster Administrator Select/Add Object Specifier input dialog is shown in Figure 13-7. 236 Clustering and IASPs for Higher Availability on the iSeries Server Figure 13-7 The iCluster Administrator Select/Add Object Specifier input dialog As illustrated in the dialog under the Path Object Specifier radio button, all byte stream files in the payroll folder are selected. Prior to this selection under the Native Object Specifier radio button, all objects in library PAYROLL of all object types had also been selected. Note that exclusions and generics can be used to limit the objects that should be selected to the PAYROLL group. In this case, we selected all objects but excluded *PGM object types. The objects that match the object specifiers selected to the group are replicated from the group’s primary node to its backup node when the group is activated (started). See which object specifiers are selected to a particular group by using the Show Selected function (F16) on the Work with Object Specifiers By Group screen or through the GUI Administrator. See Figure 13-8. Chapter 13. DataMirror iCluster 237 Figure 13-8 iCluster GUI Administrator Object Specifiers in PAYROLL group Note that the objects to be replicated do not need to exist when the object specifier is selected to the group. iCluster’s real-time auto-registration technology can detect when an object that matches the specifier is created and begins replicating the object as soon as it is created. Remove (de-select) object specifiers from a data CRG with any of these tools:  DMDSELOBJ command  De-select option on the iCluster Work with Object Specifiers by Group screen  iCluster Administrator Deselect Object input dialog 13.4.3 Creating application CRGs Application CRGs are created according to the specification in the QCSTHAAPPI automated installation data area architected for application resiliency by IBM. See 13.4, “Creating and using Cluster Resource Groups” on page 233, for details. 13.4.4 Creating device CRGs A type 3 CRG can be created in iCluster by first enabling each node in the cluster for switchable resources as shown in Figure 13-9. This is done through either the Add option on the iCluster Work with Nodes screen, the DataMirror iCluster Add Node (DMADDNODE) command, or the iCluster Administrator Add Node input dialog by changing the Enable switchable resources parameter to *YES. Note: Object specifiers cannot be directly selected or de-selected from CRGs that are part of a resilient application. See 13.4, “Creating and using Cluster Resource Groups” on page 233, for more information. 238 Clustering and IASPs for Higher Availability on the iSeries Server Figure 13-9 iCluster Add node display Once this is done, create an IASP group. This can be done with either the DataMirror iCluster Add Resource Group (DMADDGRP) command, the Add option from the iCluster Work with Groups screen, or the iCluster Administrator Add Group input dialog. Figure 13-10 shows the Add option from the Work With Groups display. Figure 13-10 DM Add Resource Group display In this example, a new group called Domino of type *IASP is created to connect to a storage device called domdev. 13.4.5 Changing a CRG recovery domain With DataMirror iCluster, a CRG can be initially defined with either one node (the primary) or two nodes (primary and backup) in its recovery domain. If the CRG is defined with a primary node, a backup node can be added later before activating the group. Add and remove backup nodes as necessary when the group is inactive. Select option 5 (Display) on the iCluster Work With Groups screen or select Groups and Display details in the DataMirror iCluster Administrator window to view a group’s current recovery domain. Figure 13-8 shows that the recovery domain for the PAYROLL group consists of DEMO400A and DEMO400B. iCluster Add node (DMADDNODE) Type choices, press Enter. Hold config object source . . . *CLUSTER *CLUSTER, *YES, *NO Staging store size (in MB) . . . 1024 512-1048576 Staging store library . . . . . dmstore Name Enable switchable resources . . *YES *YES, *NO Bottom F3=Exit F4=Prompt F5=Refresh F12=Cancel F13=How to use this display F24=More keys DM Add Resource Group (DMADDGRP) Type choices, press Enter. Group . . . . . . . . . . . . . > DOMINO Name Group type . . . . . . . . . . . > *IASP *REPL, *IASP Recovery domain source . . . . . *LIST Character value, *LIST Primary node . . . . . . . . . . DEMO400A Name Backup nodes . . . . . . . . . . DEMO400B Name + for more values Replicate nodes . . . . . . . . *NONE Name, *NONE + for more values IASP device name . . . . . . . . domdev Character value Online at switchover . . . . . . *YES *YES, *NO Description . . . . . . . . . . Domino IASP group Bottom F3=Exit F4=Prompt F5=Refresh F12=Cancel F13=How to use this display F24=More keys Chapter 13. DataMirror iCluster 239 If a CRG has only one node in its recovery domain (by definition the primary node), add a backup node with the DataMirror iCluster Add backup Node (DMADDBACK) command, the Add Backup option on the Work With Groups screen, or the iCluster Administrator Add Backup input dialog. If the CRG has two nodes in its recovery, the backup node can be changed by removing it and adding another node as the backup. Use either the DMRMVBACK command, the Remove Backup option on the iCluster Work With Groups screen, or the iCluster Administrator’s Remove Backup dialog to remove the existing backup. Note that a CRG’s primary node cannot directly be changed. To change the primary node, perform a switchover on the group so that the current backup node becomes the primary node. (See 13.4.8, “Switching over a data CRG” on page 239.) Or, re-define the group with a different primary node. 13.4.6 Activating or starting a data CRG A data CRG that is not part of a resilient application can be activated (started) with the DataMirror iCluster:  Start Group (DMSTRGRP) command  Start option on the iCluster Work With Groups screen  iCluster Administrator Start Group input dialog Once the CRG is activated, its status changes to *ACTIVE. If the CRG has objects or data selected to it, replication of the objects or data from the primary node to the backup node begins and the group’s replication status changes to *ACTIVE. Replication activation typically takes longer than CRG activation due to the number of jobs that have to be started. 13.4.7 De-activating or ending a data CRG Use either the DataMirror iCluster End Group (DMENDGRP) command, the End option on the iCluster Work With Groups display, or the iCluster Administrator End Group input dialog to de-activate or end a data CRG that is not part of a resilient application. 13.4.8 Switching over a data CRG Switchover is the process of interchanging the primary and backup roles of a CRG’s recovery domain and changing the direction of object and data replication in a data CRG. Switchover an active data CRG that is not part of a resilient application with the DataMirror iCluster Start Switch Over (DMSTRSWO) command, the Start Switch Over option on the iCluster Work With Groups screen, or the iCluster Administrator Switch Over Group input dialog. Switching over a group may not happen instantaneously, particularly if large amounts of objects and data are replicated by the group. Other factors that can increase the time required for switchover to complete are: Note: The application CRGs and data CRGs that are part of a resilient application are activated by activating the resilient application with which they are associated. See 13.5.5, “Activating or starting a resilient application” on page 246. Note: An application CRG and data CRG that are part of a resilient application are de-activated by de-activating the resilient application with which they are associated. See 13.5.6, “De-activating or ending a resilient application” on page 246, for more information 240 Clustering and IASPs for Higher Availability on the iSeries Server  Latency in the apply processes on the backup node  Switchover user exit processing  Starting journaling of database files on the new primary node, particularly if many files need to be journaled  Setting up trigger programs and enabling database file constraints on the new primary node While a group is undergoing the switchover process, the group’s status is displayed as *SWO_PENDING. When switchover is complete and the group starts replicating in the opposite direction, the group’s status reverts to *ACTIVE. 13.4.9 Problem solving iCluster’s GUI administrator includes capabilities to assist in problem solving. Two such tools are:  Eventlogs: A physical file that contains status messages and error conditions.  Status Monitor: Displays latency and journal information. It provides alarms and alerts on critical latency thresholds or error messages. Combine these instruments with additional external message queues, and monitor with third-party packages to further assist in problem solving. One of the nicest features of the iCluster Administrator is the GUI display of the event viewer. From the GUI Administrator, select Window New Event Viewer and optionally filter which messages to display on the PC or workstation. Figure 13-11 shows the Change Filter dialog. Several message filtering options are available. You can choose to display:  Only replication messages  Communications messages  Only clustering messages  All messages Selective filtering by group or node is possible within each of these categories. Messages can be filtered based on severity level or even by time. Note: Switchover application CRGs and data CRGs that are part of a resilient application by switching over the resilient application with which they are associated. See 13.5.7, “Switching over a resilient application” on page 246. Chapter 13. DataMirror iCluster 241 Figure 13-11 iCluster GUI Event Viewer Change Filter display Once filtering is selected, all of the eventlog messages from the iSeries server are brought down in buffers to the PC or Workstation. Double-click the message to see second level help text. See Figure 13-12 for an illustration. 242 Clustering and IASPs for Higher Availability on the iSeries Server Figure 13-12 iCluster GUI Event Viewer Detailed Message display Once the message is displayed, right-click the message to print or export either the selected message, or messages, or all messages. Export the messages as plain text, HTML, or CSV format, or it can be brought into a file, the clipboard, or directly to the printer. See Figure 13-13 for an illustration. Figure 13-13 iCluster GUI Event Viewer Export Log dialogue Chapter 13. DataMirror iCluster 243 13.5 DataMirror ClusterProven applications iCluster provides a simple interface to implement ClusterProven applications in a cluster. Resilient applications can be setup, started, ended, switched over, changed, updated, and removed with DataMirror iCluster. Once the application is setup, a CRG cannot be added or removed from a resilient application. Cluster operations on the groups that comprise the resilient application cannot be performed individually, but can as part of the resilient application. Refer to Chapter 8, “ClusterProven for iSeries applications” on page 161, to further understand the iSeries ClusterProven identify. 13.5.1 Setting up a resilient application A resilient application can be setup with either one node (the primary) or two nodes (a primary and a backup) in its recovery domain with DataMirror iCluster. Considerations to set up a resilient application include:  The takeover IP address of the resilient application.  The name of the ClusterProven application’s installation library on the systems. The library used to install the application must exist on all nodes of the application’s recovery domain and must contain the QCSTHAAPPI data area. This data area defines what CRGs are to be created for the resilient application and what object specifiers are to be selected to the application’s data CRGs. QCSTHAAPPI is provided by the application vendor. DataMirror provides these options to set up a resilient application:  The iCluster Add Application (DMADDAPP) command  The Add option on the iCluster Work With Resilient Applications display  The iCluster Administrator Add Resilient Application input dialog Figure 13-14 shows the iCluster Administrator Add Resilient Application input dialog. 244 Clustering and IASPs for Higher Availability on the iSeries Server Figure 13-14 iCluster GUI Add Resilient Application input dialogue After a resilient application is created, it appears on the iCluster Work With Resilient Applications screen or the iCluster Administrator Resilient Applications window, as illustrated in Figure 13-15. Figure 13-15 The iCluster Resilient Applications window Choose the Work With Groups option on the iCluster Work With Resilient Applications screen to view the list of groups that are associated with an application. Figure 13-15 shows that there are two groups associated with the Payroll resilient application, PAYDTA (a data CRG) and PAYGRP (an application CRG). Chapter 13. DataMirror iCluster 245 The display as shown in Figure 13-15 also displays the status of the groups associated with the resilient application. Note that the replication status field of group PAYGRP is blank. This indicates that PAYGRP is an application CRG (type *APPL), not a data CRG (type *REPL) like the PAYDTA group. 13.5.2 Selecting objects to a resilient application The object specifiers required for a resilient application are listed in a file that is named in the QCSTHAAPPI data area for the application. iCluster reads this file when defining the resilient application and automatically selects the object specifiers to the appropriate data CRGs that are associated with the resilient application. De-selecting object specifiers from a resilient application or a group that is associated with a resilient application is done automatically by iCluster when the application is updated or removed. 13.5.3 Changing or updating a resilient application A resilient application’s takeover IP address and its description directly can be changed with DataMirror’s iCluster:  Change Application (DMCHGAPP) command  Change option on the Work with Resilient Applications screen  Administrator Change Resilient Application input dialog A resilient application’s recovery domain can also be changed. See 13.5.4, “Changing a resilient application’s recovery domain” on page 245. However, no other parts of a resilient application’s definition can be changed directly. To change any other aspect of a resilient application’s definition (for example, the object specifiers selected for replication or the number of groups associated with the application), the application must be updated. The update process removes the groups currently associated with the application and reads the application’s QCSTHAAPPI data area to re-define the groups and re-select the object specifiers required for the application. Use the DataMirror iCluster Update Application (DMUPDAPP) command, the Update option on the iCluster Work With Resilient Applications screen, or the iCluster Administrator Update Resilient Application input dialog to update a resilient application. When the ClusterProven application is upgraded with a new version supplied by the application vendor, the upgrade may also include some changes to the resilient application’s definition. The application vendor provides a new QCSTHAAPPI data area to take account of these changes. In this situation, update the resilient application using the method described in the previous paragraph. 13.5.4 Changing a resilient application’s recovery domain Using iCluster, a resilient application can be defined with either one (the primary) or two nodes (a primary and a backup) in its recovery domain. Backup nodes can be added and removed as necessary when the resilient application is inactive. Add a backup node with either the DMADDBACK command, the Add Backup option on the iCluster Work With Resilient Applications screen, or the iCluster Administrator Add Backup Node input dialog if a resilient application has only a primary node in its recovery domain. 246 Clustering and IASPs for Higher Availability on the iSeries Server Remove the backup node with either the DMRMVBACK command, the Remove Backup option on the iCluster Work With Resilient Applications screen, or the iCluster Administrator Remove Backup Node input dialog, if a resilient application has two nodes in its recovery domain. A resilient application’s primary node cannot be changed. To change the primary node, perform a switchover on the resilient application so that the current backup node becomes the primary node. Or re-define the resilient application with a different primary node. 13.5.5 Activating or starting a resilient application Use the DataMirror iCluster Start Application (DMSTRAPP) command, the Start option on the iCluster Work With Resilient Applications screen, or the iCluster Administrator Start Resilient Application input dialog to activate or start a resilient application. If the resilient application has data CRGs with objects selected to them, replication is also activated for those CRGs. 13.5.6 De-activating or ending a resilient application Use the DataMirror iCluster End Application (DMENDAPP) command, the End option on the iCluster Work With Resilient Applications screen, or the iCluster Administrator End Resilient Application input dialog to de-activate or end a resilient application. 13.5.7 Switching over a resilient application Switchover an active resilient application with either the DataMirror iCluster Switch Over Application (DMSWOAPP) command, the Start Switch over option on the iCluster Work With Resilient Applications screen, or the iCluster Administrator Switchover Resilient Application input dialog. 13.6 Removing the cluster and its components This section describes how to handle some of the on-going cluster management tasks. Once the cluster is up and running, some of its components or even the cluster itself may need to be removed. This is how to carry out these tasks. 13.6.1 Removing a resilient application Remove a resilient application with either the DataMirror iCluster Remove Application (DMRMVAPP) command, the Remove option on the iCluster Work With Resilient Applications screen, or the iCluster Administrator Remove Resilient Application input dialog. When a resilient application is removed, the object specifiers selected to the application are also removed. However, the objects that were replicated by the application’s CRGs are not affected on either the primary or backup node of the application. 13.6.2 Removing a data CRG Remove a data CRG that is not associated with a resilient application with either the DataMirror iCluster Remove Group (DMRMVGRP) command, the Remove option on the iCluster Work With Groups screen, or the iCluster Administrator Remove Group input dialog. Chapter 13. DataMirror iCluster 247 When a data CRG is removed, the object specifiers that were selected to the group are also removed, but the objects that were replicated by the group are not affected on either the primary or backup node of the group. 13.6.3 Removing a node from the cluster A node can be removed from the cluster at any time. Remove a node when it is active to ensure a complete cleanup of cluster data from the node. If any cluster data is left over after the node is removed from the cluster, it can lead to difficulties if the node is added to a new cluster or the same cluster at a later time. Remove a node from the cluster with the DataMirror iCluster Remove Node (DMRMVNODE) command, the Remove option on the iCluster Work With Nodes display, or the iCluster Administrator Remove Node input dialog. 13.6.4 Removing the entire cluster Remove all resilient applications, data CRGs and nodes from the cluster with the DataMirror iCluster Delete Cluster (DMDLTCLSTR) command. This command can be invoked on the command line or as an option in the DataMirror iCluster Commands (DMCMDS) menu, which is accessible from any iCluster menu or screen on the iSeries server. Note that removing the entire cluster only means that the cluster is de-activated, and nodes and other cluster components are removed. The objects that were replicated by the cluster’s data CRGs are not affected. The iCluster product itself is still accessible as it was before the cluster was created. If the cluster is not partitioned and all the nodes in the cluster are active, call the DataMirror iCluster Delete Cluster (DMDLTCLSTR) command on one node to remove the entire cluster. However, if the cluster is partitioned, call the DMDLTCLSTR command once in the primary partition and once on each node in the secondary partitions. Similarly, if any nodes in the cluster are inactive, call this command on each inactive node of the cluster and in the active part of the cluster. The DMDLTCLSTR command can be used to delete any cluster. 13.7 Using iCluster commands to access Cluster Services operations Most iCluster commands correspond directly to an OS/400 Cluster Services operation or API. Use the iCluster commands to access the OS/400 Cluster Services operations, for example, when recovering from a partition or node failure. Chapter 12, “Problem determination for iSeries clustering” on page 215, describes the cluster operations that are allowed in a cluster partition situation and shows how to recover from a node failure with Cluster Services operations. Recovery from a cluster partition or node failure can be performed with the iCluster commands that map to the Cluster Services operations. Table 13-1 lists the mapping between the Cluster Services APIs and the DataMirror iCluster commands. 248 Clustering and IASPs for Higher Availability on the iSeries Server Table 13-1 Mapping Cluster Services operations to iCluster commands Table 13-2 lists the mapping between Cluster Resource Group operations and iCluster commands. Table 13-2 Mapping Cluster Resource Group operations to iCluster commands 13.8 For more information For the latest information on DataMirror and iCluster, visit the DataMirror site on the Web at: http://www.datamirror.com Cluster Services operation iCluster command Add a node to the cluster DMADDNODE Change a cluster node DMCHGNODE Remove a node from the cluster DMRMVNODE Start a cluster node DMSTRNODE End a cluster node DMENDNODE Delete the cluster DMDLTCLSTR Cluster Resource Group operation iCluster commands Create a Cluster Resource Group DMADDGRP, DMADDAPP Change a Cluster Resource Group DMCHGGRP, DMCHGAPP Delete a Cluster Resource Group DMRMVGRP, DMRMVAPP Add node to recovery domain DMADDBACK Remove node from recovery domain DMRMVBACK Start a Cluster Resource Group DMSTRGRP, DMSTRAPP End a Cluster Resource Group DMENDGRP, DMENDAPP Initiate switchover DMSTRSWO, DMSWOAPP © Copyright IBM Corp. 2000, 2002 249 Chapter 14. Lakeview Technology MIMIX Lakeview Technology is an IBM Business Partner specializing in availability management for the IBM ~ iSeries server. Lakeview’s wide array of solution offerings includes the MIMIX® suite of products:  MIMIX Replicator™: For near real-time replication of data and objects  MIMIX Monitor™: For automated system management and switching in non-clustered environments  MIMIX Promoter™: Supports continuous operations during planned downtime events For clustered iSeries environments, Lakeview offers MIMIX Cluster Server™ as an integrated part of MIMIX Replicator™. Implementing MIMIX Cluster Server provides a robust clustering environment for data and application resiliency. Lakeview also offers MIMIX FastPath™, an exclusive Lakeview Technology Solution Services offering designed to enable applications to work in clustered iSeries environments with little or no modification of the application’s original code. This service is especially useful for Independent Software Vendors (ISVs), in-house application development shops, or customers who want to use clustering for their entire high availability (HA) environment. 14.1 MIMIX Cluster Server MIMIX Cluster Server, from Lakeview Technology, offers a new and completely integrated clustering solution for the availability of applications and data; centralized cluster management; and worldwide, single-point-of-contact support 24 hours a day, 7 days a week. MIMIX Cluster Server includes a Java-based GUI Cluster Manager, high performance MIMIX Optimizer, and MIMIX Replicator high availability software. When this software is coupled with MIMIX Fastpath and Lakeview’s Solution Services for clustering end users, the result is a totally integrated environment that delivers a robust high availability solution capable of rapid, coordinated planned switchovers, and unplanned failovers. 14 250 Clustering and IASPs for Higher Availability on the iSeries Server Cluster Server’s industry-leading functionality is designed in direct response to customer requirements and reflects Lakeview’s proven track record of over eleven years in the high availability marketplace. Some examples of the extensive range of functionality found in Cluster Server include:  Automated configuration of MIMIX for ClusterProven or a cluster-enabled application, providing faster deployment of the solution and thereby further improving Return on Investment (ROI).  Automated creation of the resilient objects for ClusterReady or ClusterProven applications. Creating resilient objects from a fully functional, switch-tested MIMIX configuration eliminates any doubt that the application can fully participate in the clustering environment. Not only does this apply to the initial creation of resilient objects for an application, it also allows resilient objects to be quickly re-generated and updated to keep pace with changes to the deployed, in-production clustering solution.  Total integration of the clustering environment including all applications and their associated objects as well as all the other objects, system settings, and values that are necessary to provide a complete HA solution. The clustering architecture addresses a good portion of the total solution, but does not stipulate how these other objects and environmental issues should be managed. Cluster Server addresses the totality of the HA environment.  Complete customizing of the application exit program or programs created by the FastPath Service. In the application world, one size does not fit all and customizing is the norm. Cluster Server recognizes and embraces this reality by allowing end-users the flexibility to “have it their way”. For example, a ClusterProven core application can be surrounded by a number of other off-the-shelf or in-house developed applications. Customizing allows the core application exit program to also coordinate and manage the restart and recovery sequencing of any ancillary applications. In addition to the application exits, the MIMIX Cluster Server’s data exit programs can be fully customized.  Automated distribution of resilient objects for clustering to all nodes in a recovery domain. This simplifies the initial deployment of the clustering solution as well as the management of subsequent solution updates.  Automated search for resilient objects for clustering – no need for the end-user to specify the application libraries where these objects reside.  Flexibility to manage specific components of an application suite or the entire application suite as an entity. It is not an “all-or-nothing” proposition with MIMIX Cluster Server. There are choices and options.  End-user specification of the data relationships between the various nodes within a recovery domain. MIMIX Cluster Server’s data provider configuration option is especially useful in managing the data relationships after a switching event occurs. This capability provides greater flexibility than the clustering architecture behaviors would otherwise dictate.  Request Start from any participating node. Normally, a node can only be started by a request originating from an active node. Cluster Server determines which nodes in the cluster are active and starts the requesting node on the correct system automatically. This means a start request is successful from any node participating in the cluster.  Switchover/Failover intervention allows customers better control over the clustering solution behavior – beyond what is provided by the architecture. This is especially useful when, for example, you simply want to take the primary system down without switching to the backup – perhaps the primary is simply being IPLed and is to be back up quickly. Chapter 14. Lakeview Technology MIMIX 251  MIMIX Optimizer is a generalized automation tool that can be used to programmatically automate virtually any iSeries function or event – independently or in collaboration with clustering. 14.1.1 Implementing clustering with the MIMIX Cluster Server Using MIMIX Cluster Server simplifies the process of establishing and maintaining a total clustering environment. Figure 14-1 presents an overview of how to enable a clustering solution using MIMIX. Once MIMIX Replicator is operational, new and separate system definitions, transfer definitions, journal definitions, or data group definitions are not necessary to enable clustering. Clustering uses the existing definitions that are used with MIMIX Replicator. Some existing definitions may need to be modified to designate the systems and communications to be used by the cluster. OS/400 Cluster Resource Services are used to enable cluster functions and provide programming interfaces that are used to create and manage a cluster. MIMIX uses the Start MIMIX Manager (STRMMXMGR) command to start the OS/400 Cluster Resource Services. Once the systems are identified that are to participate in the cluster, and how they are to communicate with each other, create an application group. An application group defines application and data resiliency for an application to be included in the cluster environment. With existing cluster-enabled applications, use the Load Application Groups (LODAG) command to save time. The LODAG command searches the libraries on the local system for cluster-enabled applications. When the LODAG command encounters these applications, it creates application groups and data CRG entries for each unique cluster-enabled application it finds. The LODAG command also attempts to add a node entry for the *LOCAL system. Next run the Create MIMIX Definitions (CRTMMXDFN) command to populate the MIMIX environment with the data group definitions, journal definitions, and other entries associated with the data groups that are created. These entries are derived from the Object Specifier Files (OSF) associated with the data CRG entry. STRAG Start application groups CRTAGDFN Application CRGs IP takeover address MIMIX Replicator System definitions Journal definitions Transfer definitions Data group definitions Journal definitions Transfer definitions ADDDTACRGE One per data group BLDCLUOBJ QCSTHAAPPI data area QCSTHAAPPO data area Object specifier files Exit programs SNDCLUOBJ Send cluster objects to remote nodes BLDAGENV Create CRGs ADDNODE Add node to application group Figure 14-1 Cluster enable with MIMIX 252 Clustering and IASPs for Higher Availability on the iSeries Server If there are no cluster-enabled applications, create a data CRG for each MIMIX Replicator data group to define the data to be made resilient. MIMIX assumes that the first part of the name of the data group represents one set of data regardless of how many data groups are defined. For example, with a data group named ACCOUNTING SYS1 SYS2 and another named ACCOUNTING SYS2 SYS3, MIMIX assumes that these data groups contain the same set of data and represents that data with only one data CRG. Once the applications and data to be included in the cluster are identified, designate which nodes (systems) are to be used by the application group. MIMIX uses the Add Node Entry (ADDNODE) command to enable assignment of a system to the cluster and to an application group, and to designate what role (primary, backup, or replicate) the system is to play in the application group. MIMIX uses the Build Cluster Objects (BLDCLUOBJ) command to cluster-enable a MIMIX configured clustering application. This command creates the resilient objects for clustering that are required for cluster enabling an application, based on the MIMIX configuration. Once a cluster-enabled application is created, distribute it to the other systems in the cluster. MIMIX uses the Send Cluster Objects (SNDCLUOBJ) command for this purpose. The SNDCLUOBJ command uses the functionality in the MIMIX Replicator Send Network Object (SNDNETOBJ) command to distribute the cluster objects to the other systems in the cluster. When the cluster is operational, these actions are possible:  Add additional nodes to the cluster  Change the role of the nodes associated with an application group  End an application group  Perform other cluster management tasks When the application group definition is complete, use the Build Application Environment (BLDAGENV) command to create the application CRG and data CRGs based on the application group specified. This command builds all the child application groups defined for a parent application group. Note that this command does not create the cluster. Run the Create Mimix Cluster (CRTMMXCLU) command if the cluster does not exist. 14.1.2 Technical support In a multi-vendor clustered environment, it can be difficult to isolate the cause of a problem so that the appropriate vendor can be called for assistance. With MIMIX Cluster Server, Lakeview Technology and its worldwide network of partners provide “Follow the Sun” Support for the entire cluster through a worldwide single point-of-contact. For more information about Lakeview Technology, MIMIX, or iSeries Clustering services, visit the Lakeview Technology Web site at: http://www.lakeviewtech.com 14.2 MIMIX FastPath MIMIX FastPath services prepare applications to take advantage of clustering, a process referred to as “cluster enabling”, with little or no modification to the application’s original code. Applications enabled through MIMIX FastPath are prepared for continuous availability solutions. For ISVs, MIMIX FastPath is the service that prepares applications to achieve IBM ClusterProven branding. Chapter 14. Lakeview Technology MIMIX 253 14.2.1 Resilient objects for clustering To take advantage of iSeries clustering, three elements must be in place:  OS/400 V4R4 (or higher)  High availability replication software, such as MIMIX Replicator  Cluster enabled applications To support clustering, applications undergo a detailed evaluation and analysis to determine which of their many program components are critical for re-establishing operations on a backup node after a switch. Lakeview’s customized object specifier file is used to allow the iCluster middleware product and OS/400 to work in concert with the application to provide the ultimate in continuous availability. When considering the effort to cluster enable applications, the critical issues for developers are the development time, the resource investment, and the high availability expertise required when modifying applications to take advantage of the Cluster Resource Services, as well as the ongoing support of those modifications. Many ISVs and in-house developers find these challenges too great to readily adopt any clustering technology. MIMIX FastPath provides an optimal solution by providing services that cluster enable applications with a minimal amount of effort and investment. 14.2.2 MIMIX FastPath services MIMIX FastPath for iSeries is an exclusive Lakeview Solution Services offering. This offering consists of tools, services, support, Managed Availability Services, and clustering expertise designed to fully enable applications to work in an iSeries clustering environment with little or no modification of the application code. Lakeview Technology Solution Services consultants begin the MIMIX FastPath process by determining the level of availability required, assessing the application, and creating the ROCs necessary to cluster-enable the application and achieve ClusterReady status. The process is completed with professional skills training, extensive testing in a fully operational clustered iSeries environment, and ClusterReady certification. It also includes a report that details any additional work that may be required to achieve IBM ClusterProven or Advanced ClusterProven branding for the application. 14.2.3 MIMIX FastPath support Maintaining the clustering modifications throughout the life of the application is a significant challenge. MIMIX FastPath provides a single point of worldwide support for ongoing modifications, updates, and upgrades to the MIMIX FastPath work through the life of an agreement. This assures compliance with new releases and fixes of the operating system, application version changes, and other required updates, while freeing critical ISV resources to focus on the development of core product functionality. 14.2.4 MIMIX FastPath Professional Services As part of its ongoing support as application developers and Cluster Server implementations, Lakeview Technology offers additional professional services. Note: The IBM ClusterProven process is described in Chapter 8, “ClusterProven for iSeries applications” on page 161. 254 Clustering and IASPs for Higher Availability on the iSeries Server Advanced ClusterProven Service The Advanced ClusterProven Service is designed to assist the ISV or in-house developer in bringing applications to a higher level of integration with iSeries clustering. Through professional consultation and collaboration, the developer’s in-depth application knowledge and the Lakeview Technology consultant’s iSeries clustering expertise are leveraged to develop upgraded application design models and processes that meet the more demanding requirements of IBM’s Advanced Cluster Proven branding. See 8.2.1, “The Advanced ClusterProven for iSeries Program” on page 164, for a discussion of the IBM Advanced ClusterProven program. Application Clustering Audit Over time, cluster-enabled applications can change. During an Application Clustering Audit, Lakeview Technology consultants work with the developers to ensure that, after redevelopment or upgrade to a new point release, applications remain fully compliant with current IBM clustering requirements. Cluster Server Integration Based on the market-proven MIMIX FourPack service, Cluster Server Integration covers all aspects of implementing the MIMIX suite of products in a clustered iSeries environment. This integration includes cluster and non-cluster enabled iSeries applications. The full functionality of an HA environment is only partially addressed by the clustering architecture. Other non-application objects, environmental settings, and values must also be replicated or managed appropriately to achieve a complete, totally integrated, and optimized HA solution. Clustering education Different modes of education are available depending on the required level of clustering knowledge. Lakeview clustering courses range from a half-day overview seminar that reviews the IBM clustering initiatives, to a full five-day course that gives iSeries technical professionals an in-depth understanding of the details of clustering technology. Note: IBM’s education and service offerings are listed in Appendix C, “iSeries cluster resources” on page 291. © Copyright IBM Corp. 2000, 2002 255 Chapter 15. Vision Solutions Vision Suite With OMS/400 Cluster Manager, recovery from unplanned failovers or planned switchovers can now be both seamless and rapid. Building upon the Vision Suite of middleware high availability software products, OMS/400 Cluster Manager extends the ability to create highly available and resilient data, application, and user environments. 15 Note: Section 15.5, “Enhancements for OS/400 V5R1 functionality” on page 271, summarizes the latest enhancements to Vision Solutions (OMS 8.0), which includes support for the journaling and clustering features available in OS/400 V5R1. For the latest enhancements, and complete documentation on Vision Suite 8.0 and its clustering support, refer to the Vision Solutions Web Site at: http://www.visionsolutions.com Follow the links to Vision Clustering Support. 256 Clustering and IASPs for Higher Availability on the iSeries Server 15.1 Vision Solutions OMS/400 Cluster Manager In addition to non-clustering related product features, such as mirroring database files, data areas, and data queues in real-time using IBM journaling abilities, OMS/400 Cluster Manager provides object mirroring support for data Cluster Resource Groups (CRGs) and ClusterProven applications. OMS/400 Cluster Manager provides these capabilities through new menus and screens presented to the user in two ways:  The traditional OS/400 green-screen interface  A client-server Java application with a graphical user interface running on a PC or workstation Both of these interfaces are fully integrated with OMS/400. They allow the user to define sets of objects and, using bi-directional communication paths, to create and maintain additional sets of synchronized data. 15.1.1 Implementation goals In addition to supporting clustered environments, the Vision Solutions objectives in implementing OMS/400 Cluster Manager include to:  Build upon the OMS/400 high level of data integrity to increase data resiliency on all clustered systems  Work with ISVs to build highly resilient application environments  Assist ISVs in the process of obtaining IBM ClusterProven status 15.2 Getting started with OMS/400 Cluster Manager Before you install the client, set up the iSeries servers for clustering. Ensure that all managed systems are on the same operating system level and enabled for TCP/IP and clustering. OMS/400 R6.3 (or higher) must be installed. 15.2.1 Installing the client In a Windows implementation of Vision Solutions OMS/400 Cluster Manager, there are five installation panels. The first panel is shown in Figure 15-1. Chapter 15. Vision Solutions Vision Suite 257 Figure 15-1 OMS Welcome page 15.2.2 Starting the product Upon first use of the GUI, OMS/400 Cluster Manager asks for the hostname of the cluster node to which to initially connect. Either the node’s hostname or TCP/IP address of at least one cluster-enabled node is required to login and begin managing clusters. 15.2.3 Defining host systems To determine which iSeries servers in a network are currently cluster-enabled, use the Client Server Configuration Wizard. Built into OMS/400 Cluster Manager, the Wizard automatically detects and reports on the cluster-enabled status and operating system level of all nodes reachable from the client computer. When at least one cluster-enabled node is configured to OMS/400 Cluster Manager, management of the clustered environment can begin. To work with pre-defined clusters (for example, clusters built with the green-screen version of OMS/400), send a request for cluster information to any node in an existing cluster. Even if that request finds that the node is inactive, OMS/400 Cluster Manager attempts to forward that request to other nodes. To configure new clusters using the GUI interface, log on to any iSeries server. Use OMS/400 Cluster Manager’s built-in wizards to define clusters, CRGs, and recovery domains. 15.2.4 Auto-detecting clustered nodes As requests are sent to various systems, those iSeries servers are automatically added to the list of configured host machines. OMS/400 Cluster Manager can then forward requests directly to the additional cluster nodes. To illustrate this concept, refer to Figure 15-2. The client has only Node 1 currently defined in its list of host systems. When cluster information is requested from “Node 1”, the response tells the client that there are actually three nodes in the cluster and stores in memory the additional nodes’ host configuration information. When the client application is closed, that information is stored on the client computer for retrieval next time the application is started. 258 Clustering and IASPs for Higher Availability on the iSeries Server Figure 15-2 Auto-detecting nodes Similarly, if new nodes have been added to an existing cluster since last using OMS/400 Cluster Manager, the client recognizes those hosts as “new” and adds them to the list of currently defined host systems. This ability to auto-forward requests to any iSeries server reachable via TCP/IP allows organizations to rapidly configure and implement clustering environments. 15.2.5 IP interface selection An additional feature allows the selection of an IP interface. When adding and configuring systems for clusters, you can view all IP interfaces that can interconnect to the nodes in a clustered environment. This feature allows organizations to define specific routing paths for cluster-enabled networks and reduce IP traffic on other, non-clustered networks. 15.2.6 Working with ClusterProven applications As part of Vision Solutions’ continuing support for application integrity, OMS/400 Cluster Manager works with mixed data and application CRG environments for seamless switchovers. To prevent the loss of in-flight data transactions, OMS/400 Cluster Manager, working with ClusterProven applications, waits until the application completes its activities before notifying the data CRG that switchover or failover can commence. Client computer and AS/400 auto-detect nodes 2 and 3 Node 1 Node 2 Node 3 Cluster grows Cluster Chapter 15. Vision Solutions Vision Suite 259 The interaction between the application CRG and the data CRG varies, depending on the specific resiliency requirements of the application. For example, OMS/400 ensures the data associated with a ClusterProven application is in-sync. The term “in-sync” in this example means the recovery domain and switchover or failover information is the same (such as the current roles of the primary node and first and second backups are the same for both application and data CRGs). If a commitment control scheme is used to increase application resilience, OMS/400 Cluster Manager only begins a data switchover when the following conditions are met:  All users are removed and disconnected from the application, ensuring no more transactions are created.  Transactions that are not committed are rolled back.  No more transactions are coming into the journals. Only then does the application CRG notify the data CRG that a data switchover can begin. Similarly, when the switchover or failover is completed (assuming the former primary node is now a backup node, and the node that was the first backup is now the primary node), the application can restart. This allows users to log back into the application on the new primary system and begin working again. The data CRG then notifies OMS/400 to begin picking up new transactions and send them to the new backup system. 15.3 OMS/400 Cluster Manager sample displays The following figures illustrate how to perform various clustering tasks using the GUI version of OMS/400 Cluster Manager. 15.3.1 Working with clusters and CRGs Figure 15-3 shows the OMS Cluster Manager window and contains selection buttons to create a cluster and gather cluster information. From the File pull-down menu, a range of other cluster-related activities is available. Figure 15-3 OMS Cluster Manager Cluster Information Exit (exit program from this window; exit from window on any subsequent windows.) Window control buttons: minimize, maximize, close Window pull-down menu: Jump from one window to another. File pull-down menu: Access Create Cluster, Cluster Information, Message Queues, Activity Console, and Host Configuration windows. Create New Cluster Wizard pull-down menu: Configure client-server connections, clusters, CRGs, and ISV data areas. 260 Clustering and IASPs for Higher Availability on the iSeries Server 15.3.2 Creating new clusters When creating a new cluster, a window appears as shown in Figure 15-4. Figure 15-4 Creating a cluster window 15.3.3 Viewing cluster information Once the cluster is created, cluster information and resources can be viewed from the cluster information window. Two additional panels are available: View Resources and Edit Resources. See Figure 15-5 for an illustration. New Save Exit Chapter 15. Vision Solutions Vision Suite 261 Figure 15-5 Cluster information windows 15.3.4 Adding a node to the cluster Add a node to the cluster by selecting the node from a OMS Cluster Manager standard window list. See Figure 15-6 for an illustration. Figure 15-6 Adding a node Delete Resources Start Cluster Nodes Stop Cluster Nodes Open Cluster Resource Groups Print Clusters and their current status are listed here Create New Cluster Save Changes to Resources Two additional panes: View Resources and Edit Resources Reports on the current cluster status “as reported by” a given node Exit 262 Clustering and IASPs for Higher Availability on the iSeries Server 15.3.5 Activating and de-activating nodes in the cluster Once the initial setup tasks are completed, the cluster can be activated. When it is running, it can be de-activated. The nodes displayed can be selected and processed by clicking the End or Start buttons. Select a node and then click the End or Start Cluster Node icon (circled in Figure 15-7) to deactivate or activate the node. Figure 15-7 Cluster activation 15.3.6 Creating and using Cluster Resource Groups To create resilient objects in the Cluster Resource Groups window, select the Edit CRG Configuration tab (Figure 15-8). This panel allows the creation of both data and application CRGs. Depending on the type of CRG, not all input boxes are required. Figure 15-8 Creating CRGs with iCluster Chapter 15. Vision Solutions Vision Suite 263 15.3.7 Changing a CRG recovery domain Changing the recovery domain and altering the role of a node is one of the tasks performed by the operations group when managing the cluster. Toggle between the current and preferred recovery domain roles. See Figure 15-9 for an illustration. Figure 15-9 Changing a recovery domain 15.3.8 Activating or starting a data or application CRG Once an application or data CRGs is created, it can be selected for activation. Select an inactive CRG, and click the Start Resource Group Services button (circled in Figure 15-10). Figure 15-10 Activating CRG 264 Clustering and IASPs for Higher Availability on the iSeries Server 15.3.9 De-activating or ending a data or application CRG To end a data or application CRG, first highlight the active CRG. Then click the Stop Resource Group Services button (circled in Figure 15-11). Figure 15-11 Stopping Resource Group Services The Cluster Resource Groups Listing view can be used to perform a data switchover or application CRG. Select an active CRG, and click the Initiate Switchover icon (circled in Figure 15-12). Figure 15-12 Switching over CRG 15.3.10 Creating an application CRG recovery domain When creating an application CRG recovery domain, you must specify a takeover IP address See Figure 15-13 for an illustration. Chapter 15. Vision Solutions Vision Suite 265 Figure 15-13 Creating an application CRG The takeover IP address must not be active on any of the nodes. See Figure 15-14. Figure 15-14 Takeover IP address 15.3.11 Removing a data or application CRG Removing a data or application CRG is a standard management function. Select an inactive CRG and click the Delete Cluster Resource Group icon. Figure 15-15 shows an example of this function. Figure 15-15 Removing CRGs 266 Clustering and IASPs for Higher Availability on the iSeries Server 15.3.12 Removing a node from the cluster Back at the Cluster information window, select the Edit Resources tab (Figure 15-16). The panel that appears enables a node to be selected and removed from the cluster. Figure 15-16 Removing a node from a cluster 15.3.13 Removing the entire cluster In certain cases, the entire cluster must be removed. At the Cluster Information window, select the Listing tab. In the view, select the cluster and then click the Delete cluster button (see Figure 15-17). Figure 15-17 Removing the cluster Chapter 15. Vision Solutions Vision Suite 267 15.4 Working with applications If the application is to be cluster aware, edit the ISV data area QCSTHAPPI. QCSTHAPPI will be changed if the application is developed by an ISV. If the application is developed in-house, change this data area to make the application cluster aware. 15.4.1 ISV data area contents The QCSTHAPPI data area can be modified from the ISV Data Area Management window. To access from the Cluster Resource Group window, select the ISV Data Area Management icon (Figure 15-18). Figure 15-18 QCSTHAPPI contents 15.4.2 Creating ISV data areas for application CRGs When creating ISV data areas for application CRGs, select the View/Edit tab (Figure 15-19) for the data area input fields. To access from the Cluster Resource Group window, click the ISV Data Area Management icon. 268 Clustering and IASPs for Higher Availability on the iSeries Server Figure 15-19 Creating QCSTHAPPI 15.4.3 Changing or updating data areas To change or update a data area, select the View/Edit tab from the ISV Data Area Management window. Then, select the CRG to be changed in the List of Data CRGs panel (Figure 15-20). Figure 15-20 Changing QCSTHAPPI 15.4.4 Changing a resilient application’s data area contents The data area contents are displayed and available for update in the Add/Edit panel (Figure 15-21). Chapter 15. Vision Solutions Vision Suite 269 Figure 15-21 Updating QCSTHAPPI contents 15.4.5 Working with object specifiers Object specifiers are the files that contain the resilient information associated with a particular application CRG. The Object Specifier Management window, shown in Figure 15-22, allows the management of these object specifier files. Figure 15-22 Object specifier list To work with object specifiers, select the Add/Edit tab. The object specifier details are then displayed (Figure 15-23). 270 Clustering and IASPs for Higher Availability on the iSeries Server Figure 15-23 Working with object specifiers 15.4.6 Object selection results The Object Selection Results panel (Figure 15-24) displays objects that are found within the library or directory that is selected. Figure 15-24 Object selection 15.4.7 Creating a list of objects for high availability The wizard for ISV Data Management enables easy selection of objects for resiliency. From the Wizard for ISV Data Area Management, select a data area, and then click the View/Edit tab. Click the Generate OMS/400 Object List icon (circled in Figure 15-25). Chapter 15. Vision Solutions Vision Suite 271 Figure 15-25 Creating a resilient object list 15.4.8 Viewing OMS/400 links and statistics From the Cluster Resource Groups main window, select the OMS/400 Link Information tab. On this panel (Figure 15-26), the resilient resources status is displayed. Figure 15-26 Viewing OMS/400 links and statistics 15.5 Enhancements for OS/400 V5R1 functionality Vision Suite supports the clustering functions available with OS/400 V5R1. This section provides an overview of the enhanced OMS/400 features: 272 Clustering and IASPs for Higher Availability on the iSeries Server  Clustering technology Level 2 cluster services provided for in OS/400 V5R1 are supported and managed through OMS/400. This includes the device CRG, which adds resilient hardware to the clustering environment.  Switched disk configuration OMS/400 supports the creation of an independent ASP, defined as a device CRG to allow switching of Integrated File System objects. Switchable towers (for switchable standalone hardware) and switchable DASD IOP (for switching between LPAR partitions) are supported.  Vision Command Center Management A Java-based Command Center (VCC) is offered. VCC represents a new fully Java-based architecture that extends the graphical central point management capabilities offered in earlier Vision solutions.  Cluster Tuning Clustering Version 2 (V5R1 and higher) includes a performance tuning feature to monitor and change the cluster services heartbeat and messaging characteristics to better match a network and response time requirements.  Data area and data queue journaling Clustering Version 2 supports the journaling enhancements available in V5R1 for data areas and data queues. OMS/400 now supports sending data queues and restoring the queue contents.  Large Object (LOB) OMS/400 fully supports the configuration and mirroring of large object fields in database files.  Minimized journal entry data OMS/400 fully supports a mirroring of the V5R1 minimized entry specific journal data feature.  Byte stream file journaling OMS/400 includes new features to support the replication of changes, creations, and deletions of files stored in the Integrated File System (IFS) on V5R1 systems. While IFS byte stream file replication is enabled in ODS/400, a change to an IFS object requires that the entire object be replicated to the target system. With the V5R1 support of byte stream journaling, only the changed bytes are replicated rather than the entire object.  Held Object Analysis Held Object Analysis (HOA) is a utility application that can help troubleshoot the cause of an object on hold status.  Support for APYJRNCHGX OMS/400 supports elements of the extended journaling features of this option. For full information on the latest clustering support from Vision Solutions, refer to the Vision Solutions Web site at: http://www.visionsolutions.com Note: The screens in this chapter document the Vision Clustering and Java-based Cluster Management Support available prior to OS/400 V5R1. © Copyright IBM Corp. 2000, 2002 273 Part 4 Appendices Part 4 includes the appendices that complement the material presented in this redbook. The appendices contain information on the iSeries software and hardware functions that are not unique to cluster support, but vital for a highly available solution. Part 4 274 Clustering and IASPs for Higher Availability on the iSeries Server © Copyright IBM Corp. 2000, 2002 275 Appendix A. Advanced clusters explained For the more advanced (or more curious) reader, the technologies and architectural features available to support clustering from OS/400 V4R4 onward are described in the following sections. This appendix provides more detailed information than Chapter 4, “iSeries clusters explained” on page 31. A 276 Clustering and IASPs for Higher Availability on the iSeries Server A.1 Underlying technologies This section describes the design and recovery of iSeries clusters. A.2 Peer cluster node design Many cluster implementations follow the paradigm of having a leader for various clustering protocols. A leader may be established as a result of configuration (for example, the primary node is the leader), or it may be determined through an internal algorithm (for example, based on an IP address). iSeries cluster architecture is leaderless architecture. It involves a peer relationship among the cluster nodes. Each active node has all of the information needed to understand the total configuration and operational characteristics of the cluster. As such, a request for a cluster action can be initiated from any active node in the cluster. Furthermore, any node (not necessarily the requesting node) can assume the role as the coordinator for a particular protocol. The iSeries peer design helps to ensure that a single outage, or even an outage of several cluster nodes, seldom constitutes a cluster failure. A.2.1 Heartbeat and cluster communication Heartbeat monitoring determines whether each cluster node is active. When the heartbeat processing for a cluster node fails, the condition is reported, and the resilient resources can automatically fail over to a backup node. A heartbeat failure is more complex than just one missed signal. A heartbeat message is sent every three seconds from every node in the cluster to its upstream neighbor. In return, each node expects an acknowledgment of the heartbeat signal. In effect, this presents a two-way liveness mechanism. If a node fails or a break occurs in the network, or when a heartbeat or its acknowledgment is not received, a failure is not immediately reported. Heartbeating continues every three seconds to try to re-establish communications. If a node misses four consecutive heartbeats, a heartbeat failure is signaled. After this failure is confirmed, the failover process causes access to the cluster resources to be switched over to the designated first backup node. Using a low-level message function, the heartbeat service within cluster topology services ensures low system overhead during normal operations. Heartbeating on remote subnets may be four times the overhead of local heartbeating. Other components of Cluster Resource Services (CRS) rely on cluster topology services to determine when a node is unreachable. In some circumstances, heartbeat failure does not translate into a node failure, in which case a failover may not occur. If the cluster consists of multiple physical networks, the heartbeat process is more complex. Routers and relay nodes are used to tie the physical networks together as though it were one logical network. A router can be another iSeries server or a router box that directs communication to another router. Every local network is assigned a relay node. The relay node is determined to be the cluster node with the lowest node ID in the network. Appendix A. Advanced clusters explained 277 For example, if two networks are involved, a logical network containing the two relay nodes is created. The relay nodes can then send heartbeats to each other. By using routers and relay nodes, the cluster nodes in these two networks can monitor each other and signal any node failures. See Figure A-1 for an illustration. Figure A-1 Relay nodes in heartbeat protocols iSeries Cluster Resource Services makes no assumption about throughput, latency, topology, or stability of the network. The heartbeat algorithms are expected to work over any supported network configurations. A.2.2 Distributed activities Most cluster actions are distributed activities resulting from a user request or system detected event. The synchronization of actions across the nodes of a cluster, or across a subset of the nodes, is accomplished through a distributed activity. All of the cluster nodes affected by the action need to be involved to ensure that the results are consistently reflected across the cluster. The cluster engine and cluster communications provide the underlying services for building what is referred to as distributed activity groups. The Cluster Engine’s Group membership services are used by cluster control and the Cluster Resource Group manager to defined distributed activity groups. For cluster control, a distributed activity group is used for the distributed activities associated with the definition and administration of the cluster. Each node in the cluster is a member in this distributed activity group. There are multiple distributed activity groups associated with the Cluster Resource Group manager. One set, called the Cluster Resource Group manager distributed activity group, is a distributed activity group. It is defined across the entire cluster and is used to handle the creation of new CRGs on each cluster node in the recovery domain and other similar global activities. A distributed activity group is defined for each CRG to handle processing specific to that CRG. A B C F D E Physical networks Nodes A and D are relay nodes 278 Clustering and IASPs for Higher Availability on the iSeries Server Using distributed activities, cluster control and Cluster Resource Group manager can synchronize their services across all affected nodes within the cluster. Any change to internal information or external cluster objects on one cluster node is simultaneously reflected on all nodes in the cluster. Complex protocol flows may be needed to accomplish this processing or to back out changes in the event that an error condition is detected. There are no assumptions made regarding the guaranteed low latency for the services of the underlying network. The reliance is solely on asynchronous distributed agreement solutions. A.2.3 Job structure for Cluster Resource Services The use of the cluster engine’s group services is apparent by looking at the Cluster Resource Services (CRS) job structure. When a cluster is started on a cluster node, a set of system services is started. Each of these services is designed to be highly available (resilient to errors). These services are represented by multi-threaded jobs running in the QSYSWRK subsystem. Anytime a cluster node is active, the following jobs are active in that subsystem:  A cluster control job called QCSTCTL  A Cluster Resource Group manager job called QCSTCRGM  Additional jobs are started for handling the Cluster Resource Groups. One job exists for each CRG defined in the cluster. The job name is the same as the CRG name. Figure A-2 shows an example job structure with just one CRG defined (CRG a). The figure also shows the related jobs, including:  User jobs to initiate the cluster request (normally in the subsystem for the cluster management processing)  Exit program job that is called to handle CRG specific processing  Application subsystem for a highly available application Figure A-2 Example job structure Cluster management subsystem (originator of API request) CRG exit program job Application subsystem QCSTCTL QCSTCRGM CRG A QSYSWRK subsystem Appendix A. Advanced clusters explained 279 In addition to the system jobs, consider the user job that originates the request for a cluster service. The request normally consists of a call to a clustering API. After the API is validated, the request passes to the appropriate cluster job in the QSYSWRK subsystem. The cluster job then handles the distributed processing of the request. Through a distributed activity group technology, the request is distributed to other members of the group on the other nodes of the cluster. The request is appropriately processed, and the results are returned to the node that initiated the request. Once responses are received from all participating members of the activity, the results are returned to the results information queue. Finally, Cluster Resource Services initiates the exit program associated with the CRG on all active nodes in the recovery domain. These exit program jobs run in a user-specified subsystem, which can be the same as the application subsystem. Typically, the exit program jobs are transitory and exist only for the duration of the API request. An exception is the CRG exit program that starts the resilient application, which runs only on the primary system. This job remains active and serves as a daemon job between the application and Cluster Resource Services. A.2.4 Cluster engine services Cluster Engine Group Membership Services provide the ability to define and modify distributed activity group membership definitions. Each live group member is notified of any change made to the definition or to the state of a member. Notification is via a special message called a membership change message. The cluster engine ensures that cluster membership changes are handled consistently across affected groups for both administrative changes and changes as a result of a failure. Therefore, a consistent view of the membership is guaranteed across members of the same distributed activity group, as well as across related groups. The messaging services provided to group members by the cluster engine include a variety of reliability and ordering guarantees over group messaging. These include:  Non-reliable, FIFO ordered messaging FIFO messaging means that group messages sent by the same node are received in the same order by all the group members.  Reliable, FIFO ordered messaging Reliable messaging is a variation of virtually synchronous messages. Members that appear in two consecutive membership change notifications receive the same set of messages between these notifications.  Reliable, totally ordered messaging Totally ordered messaging implies that group members who receive the same set of messages receive them in the same order. These guarantees are defined per group. A cluster engine provides the ability to send non-reliable messages to the group or to a subset of the group. A.2.5 Cluster partition state A cluster is in a partition state when the cluster cannot communicate with one or more nodes and no certain failure is identified. Do not confuse a cluster partition with a logical partition. A cluster partition is not good. 280 Clustering and IASPs for Higher Availability on the iSeries Server The typical cause of a cluster partition occurs when there is a communications link failure and a redundant path for the clusters is not established. Neither node has failed. But neither node knows the status of its counterpart. See Figure A-3 for an illustration. Figure A-3 Cluster partitions What has failed is the communication between the SNOW and COLD nodes. When communication between nodes in the cluster is lost, and the status of the “missing” nodes is unknown, this is a cluster partition. When a cluster partition occurs, failover should not be done because one node is still active. For example, in Figure A-3, the node named SNOW is still active. The IP address is still started on SNOW. Users can still access the application and the data on SNOW. The nodes operate as independent until communication is restored. When communication between the nodes is restored, OS/400 cluster support merges the partitions to their original state. When the cluster is partitioned, CRS takes overt action to ensure that:  As many operations as possible can continue normally  Operations that would cause inconsistencies between partitions are not allowed The recovery goal is to ensure that the partitions can be joined back together (merged). If configuration and operational changes are allowed to be made independently in two or more partitions, there can be no guarantee that the merging of the partitions would be successful. iSeries design of cluster partition recovery The first problem to solve in a partitioned cluster scenario is to determine which cluster node is to assume the role of primary node for each of the CRGs. WINTER Cluster   1.3.22.406 1.3.22.407 1.3.22.322 1.3.22.323 Node SNOW Node COLD 1.3.22.114 (Inactive 1 ) .3.22.114 (Active) Appendix A. Advanced clusters explained 281 There are numerous methods in the industry to determine where the primary role should be, including quorum protocols and complex voting algorithms. The design of the iSeries cluster architecture allows for the initial set of CRG types to cause the least amount of disruption to current operations. Therefore, the primary location for a group of resources is not moved when a partition occurs. The partition that includes the node with the primary role is called the primary partition for that CRG. Any other partition is known as a secondary partition. A node in the secondary partition cannot assume the role of primary. The second problem to solve is to ensure that the partitions do not make inconsistent changes. An inconsistent change is one that would adversely affect the ability to bring the partitions back together (a merge of partitions). Operations on the cluster configuration and individual CRG that would prevent partition merging (for example, adding a node to the cluster in one partition) are not allowed. Table A-1 summarizes the CRG operations allowed when clusters are in a partition state. Table A-1 CRG operations allowed in LPAR partition See 12.2, “Problems with the status of a cluster” on page 217, for a further discussion of cluster partitions. A.2.6 Cluster versions Cluster versions (or cluster versioning) are supported on the iSeries servers to enable a cluster node to recognize and interoperate with other cluster nodes that are at different release levels. Multiple releases of OS/400 can coexist in a single cluster. Therefore, an individual node can be upgraded to the next release of OS/400 without taking the cluster offline (and thereby minimizing the amount of planned unavailability for system maintenance). To support this nondisruptive clustering environment, Cluster Resource Services implements levels of versioning beyond what is supported by existing iSeries server capabilities. One level of versioning is in the objects used by CRS. Any internal change to an object causes the version information to change. When information is exchanged between nodes, the system services accounts for different object versions. Cluster action Primary partition Secondary partition Add node to recovery domain Y N Change CRG Y N Create CRG N N Delete CRG Y1 Y1 End CRG Y N Initiate switchover Y N List CRGs Y N List CRG information Y2 Y2 Remove node from recovery domain Y N Start CRG Y N 1) After a merge, the CRG is also deleted from the secondary partition 2) The CRG must exist in the partition 282 Clustering and IASPs for Higher Availability on the iSeries Server The second level of versioning is in the messages passed between nodes and between cluster components. Enhanced messaging, and therefore additional services, can be introduced without hindering the ability to communicate with nodes at the previous release level. © Copyright IBM Corp. 2000, 2002 283 Appendix B. Referenced lists This appendix contains lists and tables referred to from other locations in this redbook. They have been moved to this appendix to improve the readability of the main content of each chapter. B 284 Clustering and IASPs for Higher Availability on the iSeries Server B.1 Clustering data area layout The layout of the QCSTHAAPPI input data area is shown in Table B-1. Table B-1 QCSTHAAPPI data area Note: This section is referenced from 9.2.2, “Input data area” on page 171, and 9.2.3, “Output data area” on page 172. Offset Type Field 0 CHAR(10) Data area level information 10 CHAR(10) Application name 20 CHAR(6) Application Release level 26 CHAR(50) Application identification information 76 CHAR(34) Reserved 110 CHAR(10) Application CRG name (or *NONE or *LIST) 120 CHAR(20) Qualified exit program name formatted as:  CHAR(10) -- exit program name  CHAR(10) -- library name 140 CHAR(10) User profile name 150 CHAR(256) Exit program data 406 CHAR(10) Job name 416 BIN(4) Application restart indicator 420 BIN(4) Number of restarts 424 CHAR(1) Application status 425 CHAR(35) Reserved 460 BIN(4) List type 464 BIN(4) Number of entries (max of 20) * ARRAY(*) of CHAR(76) List of entries array These fields repeated for each entry in the list CHAR(30) Qualified name of file or data area formatted as:  CHAR(10) -- File or Data Area name  CHAR(10) -- Library name  CHAR(10) -- Member name BIN(4) Number of object specifiers CHAR(20) Qualified default journal name or IASP name CHAR(1) Criticality of data indicator CHAR(10) Preferred CRG name CHAR(1) Data Resilience Mechanism CHAR(10: Reserved Appendix B. Referenced lists 285 The layout of the QCSTHAAPPO output data area is represented in Table B-2. Table B-2 QCSTHAAPPO data area B.2 Unpacking and creating QUSRTOOL APIs and commands Follow these steps to use the commands provided in the QUSRTOOL library: 1. Programs are available to change save files to source physical files and to change source physical files to save files (UNPACKAGE and PACKAGE respectively). Before any tools can be compiled and run, unpackage the appropriate save files. The write up of each tool identifies the members that make up the tool and the file in which they reside. To create the install program (TCSTCRT), enter: CRTCLPGM PGM(userlib/TCSTCRT) SRCFILE(QUSRTOOL/QATTCL) Here userlib is the name of the existing user library in which the install program and Cluster Resource Service commands is to reside. Offset Type Description 0 CHAR(10) Data area level information 10 BIN(4) Success indicator 14 CHAR(10) Cluster name 24 CHAR(10) Application CRT name or *LIST 34 CHAR(16) Takeover IP Address 50 CHAR(1) Data resilience status 51 CHAR(19) Reserved 70 IBIN(4) Number of entries (max of 20) * ARRAY(*) of CHAR(40) Name list array These fields repeated for each name in the list CHAR(10) Object name (CRG or Data Area) CHAR(20) Qualified journal name or IASP name CHAR(1) CRG data status CHAR(1) CRG Type CHAR(8) Reserved Note: This section is referenced from Chapter 5, “Implementing and managing clusters with IBM solutions” on page 59. Tip: To unpackage all save files in the QUSRTOOL library, run the following command: CALL QUSRTOOL/UNPACKAGE (‘*ALL ‘ 1) 286 Clustering and IASPs for Higher Availability on the iSeries Server 2. Run the install program (TCSTCRT) to generate the cluster command objects. Enter the command: CALL userlib/TCSTCRT userlib Here userlib is the same as the userlib specified in step 1 on page 285. This creates all the objects necessary to use the cluster commands. The objects are created into library userlib. B.3 Cluster APIs and related QUSRTOOL commands B.3.1 Cluster Control APIs and QUSRTOOL commands Table B-3 lists the V5R1 Cluster Control APIs, with a brief description of what the API is used for, and the equivalent command available in the QUSRTOOL library. Table B-3 Cluster Control API and QUSRTOOL command descriptions Note: This section is referenced from:  Chapter 5, “Implementing and managing clusters with IBM solutions” on page 59  Section 5.3, “Using QUSRTOOL CL commands and OS/400 APIs to implement an iSeries cluster” on page 87  Sample 10.1.1, “Creating the sample clustering environment” on page 185  Section 12.3, “Recovering from a cluster partition state” on page 220 Cluster Control API name Description QUSRTOOL command name Add Cluster Node Entry (QcstAddClusterNodeEntry) Adds a node to the membership list of an existing cluster. Also assigns the IP interface addresses to be used by cluster communications. ADDCLUNODE Add Device Domain Entry (QcstAddDeviceDomainEntry) Adds a node to a device domain membership list so that it can participate in recovery actions for resilient devices. The addition of the first node to a device domain has the effect of creating that device domain. ADDDEVDMNE Adjust Cluster Version (QcstAdjustClusterVersion) Adjusts the current cluster version to the next level, for example, so that new function can be used within the cluster. CHGCLUVER Change Cluster Node Entry (QcstChangeClusterNodeEntry) Changes the fields in the cluster node entry. For example, the IP interface addresses used for cluster communications can be changed. CHGCLUNODE Change Cluster Resource Services (QcstChgClusterResourceServices) Adjusts cluster performance and configuration tuning parameters to match the communications environment of the network used for cluster communications. CHGCRS Create Cluster (QcstCreateCluster) Creates a new cluster of one or more nodes. CRTCLU Delete Cluster (QcstDeleteCluster) Deletes an existing cluster. Cluster resource services is ended on all active cluster nodes and they are removed from the cluster. DLTCLU Appendix B. Referenced lists 287 You can find a description of how to create QUSRTOOL commands in B.2, “Unpacking and creating QUSRTOOL APIs and commands” on page 285. B.3.2 Cluster Resource Group APIs and QUSRTOOL commands Table B-4 lists the V5R1 Cluster Resource Group APIs, with a brief description of what the API is used for, and the equivalent command available in the QUSRTOOL library. Table B-4 CRG Group API and command descriptions End Cluster Node (QcstEndClusterNode) Ends Cluster Resource Services on one or all nodes in the membership list of an existing cluster. The node becomes unavailable to the cluster until it is restarted using the Start Cluster Node API. ENDCLUNOD List Cluster Information (QcstListClusterInfo) Retrieves information about a cluster. For example, the complete cluster membership list can be returned. PRTCLUINF List Device Domain Information (QcstListDeviceDomainInfo) Lists device domain information of a cluster. For example, the list of currently defined device domains can be returned. PRTDEVDMNI Remove Cluster Node Entry (QcstRemoveClusterNodeEntry) Removes a node from the membership list of a cluster. The node is removed from any recovery domains, cluster operations are ended on the node, and all Cluster Resource Services objects are deleted from the node. RMVCLUNODE Remove Device Domain Entry (QcstRemoveDeviceDomainEntry) Removes a node from a device domain membership list. If this is the last node in the device domain, this also has the effect of deleting the device domain from the cluster. RMVDEVDMNE Retrieve Cluster Information (QcstRetrieveClusterInfo) Retrieves information about a cluster. For example, the cluster name and current cluster version are returned. PRTCLUNAM Retrieve Cluster Resource Services Information (QcstRetrieveCRSInfo) Retrieves information about the Cluster Resource Services performance tuning and configuration parameters. PRTCRSINF Start Cluster Node (QcstStartClusterNode) Starts Cluster Resource Services on a node that is part of a cluster but is currently not active. This API must be called on a node that is currently active in the cluster. STRCLUNOD Cluster Resource Group API name Description QUSRTOOL command name Add CRG Device Entry (QcstAddClusterResourceGroupDev) Adds a new device entry to a CRG. The device becomes a member of the group of switchable devices. ADDCRGDEVE Add Node to Recovery Domain (QcstAddNodeToRcvyDomain) Adds a new node to the recovery domain of an existing CRG. A node can be added as a primary node (if the CRG is inactive), as a backup node, or as a replicate node. ADDCRGNOD Change CRG (QcstChangeClusterResourceGroup) Changes attributes of a CRG. For example, the takeover IP address for an application CRG can be modified. CHGCRG Change CRG Device Entry (QcstChgClusterResourceGroupDev) Changes a device entry in a CRG. For example, the option to vary the configuration object online at switchover or failover can be modified. CHGCRGDEVE 288 Clustering and IASPs for Higher Availability on the iSeries Server You can find a description of how to create QUSRTOOL commands in B.2, “Unpacking and creating QUSRTOOL APIs and commands” on page 285. B.4 Object specifier file layout The Data Description Specification (DDS) for an object specifier file is shown in Table B-5. The DDS describes the record format used to identify objects for a replication solution. Table B-5 Record format of object specifier file Create CRG (QcstCreateClusterResourceGroup) Creates a CRG object. The CRG object identifies a recovery domain, which is a set of nodes in the cluster that will play a role in recovery. CRTCRG Delete CRG (QcstDeleteClusterResourceGroup) Deletes a CRG from the cluster. The CRG object will be deleted from all active systems in the recovery domain. DLTCRGACT Distribute Information (QcstDistributeInformation) Delivers information from a node in the recovery domain of a CRG to other nodes in that CRG's recovery domain. SNDCRGMSG End CRG (QcstEndClusterResourceGroup) Disables resiliency of the specified CRG. Upon successful completion of this API, the CRG status is set to inactive. ENDCRG Initiate Switchover (QcstInitiateSwitchover) Causes an administrative switchover to be performed for the CRG. The recovery domain is changed so that the current primary node becomes the last backup and the current first backup node becomes the new primary. CHGCRGPRI List CRGs (QcstListClusterResourceGroups) Generates a list of CRGs and some information about the CRG in the cluster. PRTCRG List CRG Information (QcstListClusterResourceGroupInf) Returns the contents of a CRG object. For example, the recovery domain with the current node roles can be returned. PRTCRGINF Remove CRG Device Entry (QcstRemoveClusterResourceGroupDev) Removes a device entry from a CRG. The device will no longer be a switchable resource. RMVCRGDEVE Remove Node From Recovery Domain (QcstRemoveNodeFromRcvyDomain) Removes a node from the recovery domain of an existing CRG. The node will no longer participate in recovery action for that group of resources. RMVCRGNOD Start CRG (QcstStartClusterResourceGroup) Enables resiliency for the specified CRG. The CRG becomes active within the cluster. STRCRG Note: This section is referenced from 8.2, “ClusterProven defined” on page 163, 9.1.2, “ClusterProven applications” on page 170, and 11.2.2, “Resilient data” on page 199. Field name Field type Field definition QCSTETYP Bin(4) Entry type (0 for library, 1 for directory) QCSTOTYP Char(10) Object type or *ALL QCSTEOAT Char(10) Extended object attributes (e.g. physical file) Appendix B. Referenced lists 289 QCSTINEX Bin(4) Include or exclude indicator QCSTRSRV Char(14) Reserved QCSTCSID Bin(4) CCSID QCSTCTID Char(2) Country (or region) ID QCSTLGID Char(3) Language ID QCSTNLSR Char(3) NLS reserved field QCSTFLAG Bin(4) Flag byte QCSTPTHL Bin(4) Number of bytes in path name field QCSTPTHD Char(4) Path name delimiter QCSTRSV2 CHAR(10) Reserved QCSTPTHN Char(5000) VARLEN(100) Path name (Variable length field) Field name Field type Field definition 290 Clustering and IASPs for Higher Availability on the iSeries Server © Copyright IBM Corp. 2000, 2002 291 Appendix C. iSeries cluster resources For customers, independent software vendors (ISVs) and IBM Business Partners who want to investigate iSeries highly available solutions and clusters, refer to the following resources and contacts:  iSeries Clustering with Switched Disks - 2.5 day IBM classroom education, S6224  iSeries Technology Center: Send e-mail to rchclst@us.ibm.com  PartnerWorld for Developers: http://www.developer.ibm.com/  Information Center Web site: http://www.ibm.com/eserver/iseries/infocenter  iSeries Information Center CD-ROM (English version), SK3T-4091  iSeries home page: http://www.iseries.ibm.com  IBM ~ iSeries cluster home page: http://www.ibm.com/servers/clusters  IBM Direct: Call 1 800-426-2255 C 292 Clustering and IASPs for Higher Availability on the iSeries Server © Copyright IBM Corp. 2000, 2002 293 Related publications The publications listed in this section are considered particularly suitable for a more detailed discussion of the topics covered in this redbook. IBM Redbooks For information on ordering these publications, see “How to get IBM Redbooks” on page 294.  The System Administrator's Companion to AS/400 Availability and Recovery, SG24-2161  AS/400 Remote Journal Function for High Availability and Data Replication, SG24-5189  AS/400e to IBM ~ iSeries Migration: A Guide to System Upgrades at V4R5 and V5R1, SG24-6055  Moving Applications to Switchable Independent ASPs, SG24-6802 This redbook is currently not available, but is scheduled for publication in the second half of 2002.  Roadmap to Availability on the iSeries 400, REDP0501  High Availability on the AS/400 System: A System Manager’s Guide, REDP0111 Other resources These publications are also relevant as further information sources:  iSeries Information Center CD-ROM (English version), SK3T-4091  iSeries Backup and Recovery, SC41-5304  System API Reference, SC41-5801  Toigo, Jon. Disaster Recovery Planning: Managing Risks and Catastrophe in Information Systems. Yourdon Press, 1989. ISBN 0132149419 Referenced Web sites These Web sites are also relevant as further information sources:  iSeries home page: http://www.iseries.ibm.com  IBM ~ iSeries cluster home page: http://www.ibm.com/servers/clusters  PartnerWorld for Developers: http://www.developer.ibm.com/  Clusterproven applications and high availability: http://www-1.ibm.com/servers/eserver/iseries/ha  Domino for iSeries clustering capabilities: http://www.ibm.com/eserver/iseries/domino  Information Center: http://www.ibm.com/eserver/iseries/infocenter  IBM Benchmark Center: http://www.developer.ibm.com  DataMirror: http://www.datamirror.com 294 Clustering and IASPs for Higher Availability on the iSeries Server  Lakeview Technology: http://www.lakeviewtech.com  Vision Solutions: http://www.visionsolutions.com How to get IBM Redbooks You can order hardcopy Redbooks, as well as view, download, or search for Redbooks at the following Web site: ibm.com/redbooks You can also download additional materials (code samples or diskette/CD-ROM images) from that site. IBM Redbooks collections Redbooks are also available on CD-ROMs. Click the CD-ROMs button on the Redbooks Web site for information about all the CD-ROMs offered, as well as updates and formats. © Copyright IBM Corp. 2000, 2002 295 Glossary This glossary provides definitions for terms used within this redbook. The terms are listed in alphabetical order. application resilient (type-2) Enables an application (program) to be restarted on either the same node or a different node in the cluster. backup node Has the ability to take over the functions of the primary node in the event of an outage (planned or unplanned) on the primary node. If there is more than one backup node, the recovery domain defines the order in which control is transferred to the backup nodes. cluster A group of one or more servers that work together as a single system. A cluster is identified by a ten-character name. cluster node Each iSeries that is a member of a cluster is a cluster node. Each cluster node is identified by an eight-character cluster node identifier (usually the system name). There are three types of cluster nodes: primary, backup, and replicate. cluster policies Failover and switchover. ClusterProven for iSeries An IBM designation that defines certain high-availability requirements that are applied to a software product either by itself or in combination with other software products. A solution that satisfies the technical criteria of these requirements can be validated with IBM and licensed to be marketed with the IBM ClusterProven trademark. cluster resource Any part of the system that is available across multiple cluster nodes. The three types of system resources that can be resilient are:  Objects that are kept up to date by using replication  A resilient application and its associated IP address, which can be switched  A resilient device that can be switched (IASPs) Cluster Resource Group (CRG) A Cluster Resource Group is an OS/400 system object that is a set or group of cluster resources. The group describes a recovery domain and supplies the name of the Cluster Resource Group exit program that manages cluster-related events for that group. One such event would be moving an access point from one node to another node. Cluster Resource Group objects are either defined as data resilient (type-1), application resilient (type-2), or device resilient (type-3). Cluster Resource Group exit program This program is called during different phases of the cluster environment and is responsible for establishing and managing the environment necessary for data and application resiliency within a cluster. Cluster Resource Group manager (CRGM) Provides object management functions for the CRG's objects, such as creation, deletion, and modification. The CRGM also calls the CRG exit program whenever the status of the CRG changes. cluster version (cluster versioning) The support to enable nodes in a cluster to communicate with other nodes in the cluster that have a different release level of OS/400. data resilient (type-1) Enables multiple copies of data that is maintained on more than one node in a cluster. device resilient (type-3) Is used with IASPs. Every Cluster Resource Group has a Cluster Resource Group exit program associated with it. failover The system automatically switches over to one or more backup systems in the event of a system failure. 296 Clustering and IASPs for Higher Availability on the iSeries Server full clustering A full, automated high availability environment that uses clustering technology and takes advantage of V5R1 support. Full clustering includes these elements:  Highly available hardware  Highly reliable operating system  Concurrent operations/maintenance  Data resiliency  Application resiliency  Transaction monitoring  Co-operation between OS/400 functions and business partner solutions join To become a new member of some entity such as a cluster. partitioned (cluster partition) When communication with a node is lost, but node failure cannot be guaranteed, a cluster then becomes partitioned. recovery domain A subset of nodes in the cluster that are grouped together in a Cluster Resource Group for a common purpose such as performing a recovery action. A domain represents those nodes of the cluster from which cluster resources can be accessed. The subset of cluster nodes that is assigned to a particular Cluster Resource Group either supports the primary point of access, secondary (backup) point of access, or replicates. rejoin To become an active member of a cluster after having been a nonparticipating member. For example, when clustering is restarted on a node after the node has been inactive, the cluster node rejoins the cluster. replicate node Contains copies of information from the primary node. They do not have the ability to take over the functions of a primary or backup node. Typically, replicate nodes are used to store information for disaster recovery or for functions such as data warehousing. replication The ability to synchronize a copy of data and objects from one system to another. resilient resource Any system resource (data, a process, an application, or a device) that is available on more than one node in a cluster and that can be recovered if a node in a cluster fails. switchover Happens if you manually switch access from one system to another. You would usually do this if you wanted to perform system maintenance such as applying program temporary fixes (PTFs), installing a new release, or upgrading your system. switchover and failover order The relationship (or order) that you define among the primary node and backup nodes in a recovery domain. In a recovery domain, there can be multiple backup nodes. You specify one node as first backup, another as second backup, and so on. If a primary node fails, the access point for the resilient resources switches to the first backup node. © Copyright IBM Corp. 2000, 2002 297 Index Symbols *AUTL 120 *IOSYSCFG 86 *IOSYSCFG authority 62 Numerics 24x365 21 5250 datastream 201 A activating and de-activating nodes in the cluster 262 activating or starting a data or application CRG 263 active backup iSeries server 34 adapter redundancy 208 ADD Cluster Node Entry (ADDCLUNODE) command 81 Add Device Domain Entry (ADDDEVDMNE) command 81 Add Service Table Entry (ADDSRVTBE) command 126 ADDCLUNODE (ADD Cluster Node Entry) command 81 ADDDEVDMNE (Add Device Domain Entry) command 81 adding a node 176 adding a node to a cluster 211, 261 adding disk units to a pool 115 ADDSRVTBE (Add Service Table Entry) command 126 Advanced ClusterProven 163 Advanced ClusterProven for iSeries Program 164 advantages of IASP 106 All Disk Units 117 Allow Add to Cluster (ALWADDCLU) network attribute 62, 76, 86 ALWADDCLU (Allow Add to Cluster) network attribute 63, 218 API 87, 93, 162 QcstAddClusterNodeEntry 81 QcstAddDeviceDomainEntry 81 QcstCreateCluster 81 QcstDistributeInformation 36 QcstStartClusterNode 81, 219 APIs and commands to implement, manage iSeries clusters 60 application architecture 11 application CRG 48 exit program, example 37 ISV data areas 267 recovery domain 264 application maintenance 201, 207 application object inventory 199 application resiliency 51, 55, 163, 165, 170, 199 managing 53 application resiliency and IP address takeover, example 53 application resilient 45 application resilient (type-2) CRG 45 application servers 21 ASP (auxiliary storage pool) 19 authorization list 119 auto-detection of clustered nodes 257 automated storage management 20 auxiliary storage pool (ASP) 19, 100, 103 availability 5, 16 factors 5 ratings 6, 15 B backup node 43 Backup Recovery Media Services (BRMS) 19 backup server 34 backup system 34, 207 basic cluster 21 Basic ClusterProven 164 basic disk pool 103 batch applications in a cluster 207 batch job 201 benefits of clustering 32 benefits of iSeries clusters 34 BEST/1 207 BRMS (Backup Recovery Media Services) 19 business impact costs 197 C capacity 207 Change Subsystem Description (CHGSBSD) command 218 changing a CRG’s recovery domain 263 changing a node 177 changing or updating data areas 268 CHGSBSD (Change Subsystem Description) command 218 client/server job 201 client-centric 164 cluster 32 advanced technologies, architecture 275 configuration tasks 63 creation 231 definitions 94 error messages, system log entries 216 for high availability 21 hardware requirements 22 implementation examples 48 partition state 279 performance tuning 36 replication technology 22 service job 40 software requirements 22 status questions 217 testing 210 298 Clustering and IASPs for Higher Availability on the iSeries Server traditional Domino 168 cluster architecture 56 cluster communication 41, 276 cluster configuration, example 184 cluster control 41 cluster elements 42 Cluster Engine 41 Cluster Engine Group Membership Services 279 cluster engine services 33, 279 cluster information object 41 cluster management 55 Cluster Management GUI 27 cluster management related tests 211 cluster management tool 22 cluster membership list 43, 94 cluster middleware 162–163 cluster node 43, 94, 220 cluster partition 37, 42, 219–220, 280 error, example 220 merging 223 recovering 220 recovery 280 tips 222 versus logical partition 279 Cluster Resource Group exit program 171 Cluster Resource Group (CRG) 44, 59, 94, 198, 262 creating 173 ending 178 hang (wait) state 218 manager distributed activity group 277 starting 175 Cluster Resource Group Manager 41 Cluster Resource Services (CRS) 21–22, 33, 38, 55, 59, 162 job structure 278 structure 40 Cluster Resource Services API 64 cluster resources 45 cluster setup, example 186 cluster topology services 42 cluster version 36, 281 Cluster version parameter 88 cluster versioning 281 clustering framework 38 technology 4 using Operations Navigator GUI to implement, manage 60 ClusterProven 55, 75, 163, 170, 200, 243, 256, 258 trademark 164 working with applications 258 ClusterProven Domino for iSeries 166 commands and APIs to implement, manage iSeries clusters 60 commitment control 12, 19, 22–23 common problems with Operations Navigator GUI 86 communications environment 62 Concurrent Maintenance 17 concurrent maintenance 17 configuration of a cluster 198 configuration source 105 configuring and managing IASP 113 continuous availability 5, 10, 21, 50, 169 continuous availability requirements 33 continuous operations 5 continuously available 183 cost to the business 10 CPFBB05 message ID 216 CPFBB20 error message 220 CPFBB21 message 222 Create Cluster (CRTCLU) command 81, 88 Create Device ASP (CRTDEVASP) command 108 creating a cluster 231 creating a disk pool 114 creating an application CRG recovery domain 264 creating and using Cluster Resource Groups 262 creating ISV data areas for application CRGs 267 creating new clusters 260 CRG 45, 207, 258 CRG exit program 41 criteria to obtain ClusterProven trademark 165 critical objects 169 critical resource 21 CRS (Cluster Resource Services) 22 CRTCLU (Create Cluster) command 81, 88 CRTDEVASP (Create Device ASP) command 108 D data and objects replication 25 data area input 171 QCSTHAAPPI 171 data area, QCSTHAAPPO 172 data CRG 48, 259 data integrity 10 data queue 199 data replication 56 data resiliency 29, 51, 55, 162–163, 165 in a simple two-node cluster example 51 data resilient 45 data resilient (type-1) CRG 45 data space 199 database performance 205 database server 21 DataMirror 162, 229 DataMirror ClusterProven 243 DataMirror iCluster 229 de-activating or ending a data or application CRG 264 definitions of clustering terms 94 device CRG 109 device CRG object 109 device domain 36, 46, 109 object 108 device parity protection 16 device resiliency 45 device resilient (type-3) CRG 45 disadvantages of IASP 106 disaster recovery 10, 34 Index 299 disk pool 103, 114 disk redundancy 208 disk unit adding to a pool 115 Display Log (DSPLOG) command 216 Display Message (DSPMSG) command 216 distribute information 36 Distribute Information (QcstDistributeInformation) API 36 distributed activities 277 distributed activity groups 277 Domino and independent ASP 112 Domino cluster 168 downtime 7–8, 11 business impact of 8 elements that impact 6 DSPLOG (Display Log) command 216 DSPMSG (Display Message) command 216 Dynamic Hardware Resource Reallocation 17 E education 291 elements impacting downtime 6 emulator session 201 enhanced OMS/400 features 271 environment management 177 environment plan 62 estimated hourly downtime costs 9 example of business impact 9 exit program 45, 47, 171 F factors impacting availability 5 failover 21, 180, 201, 207, 211 four-node mutual takeover cluster example 49 G GUI to implement, manage iSeries clusters 60 GUI, IASP 130 H HA Switchable Resources 64 HABP 23 positioning solutions with IASPs 122 products 170 hardware 208 hardware and software prerequisites 67 heartbeat and cluster communication 276 heartbeat monitoring 39, 212, 276 Hierarchical Storage Management (HSM) 19 high availability 5, 21, 104 high availability middleware 26 High Speed Link OptiConnect 104 higher availability 15 horizontal growth 4 horizontal scalability 4 Host Servers 86 host-centric 164 Hot Pluggable PCI Cards 17 I IASP 109 advantages of using 106 application example 112 authorization list 119 configuration example 110 configuration object 107 configuration source 105 configuring and managing 113 disadvantages of using 106 GUI 130 objects that define the configuration 107 overflow 121 positioning HABP with 122 prerequisite steps to create 126 reclaim storage 121 security 117 support and terminology 102 system operations 121 types 125 unit numbering 116 use considerations 105 user profile 117 uses of 100 IBM Benchmark Center 211 IBM Cluster Middleware Business Partners 59 IBM S/390 Parallel Sysplex 25 IBM Simple Cluster Management GUI considerations 64 iCluster 229–230 iCluster Administrator 230 idle backup iSeries server 34 idle standby 34 idle standby system 34 impact of an outage 15 independent ASP (IASP) 46, 99–100, 102 Domino 112 Integrated xSeries Server 113 input data area 171 input/output processor 16 Integrated xSeries Server independent ASP 113 interactive job 201 Internet Daemon 62 IOP 16 IP address 42, 207 IP interface selection 258 IP network connectivity 42 IP takeover 40, 53, 201 iSeries cluster 29 planning 196 prerequisites 37 technology 276 iSeries IASP with other platform solutions 123 iSeries server hardware 16 iSeries server software 18 ISV 256 ISV data area 267 ISV data areas for application CRGs 267 300 Clustering and IASPs for Higher Availability on the iSeries Server J job consideration 64 job queue jobs 218 job restart 201 job structure 278 journal management 16–17 journaling 18, 22–23, 205 sample setup 188 L Lakeview Technology 249 LAN (local area network) 198 Level 1 recovery 9 Level 2 recovery 10 Level 3 recovery 10 level of availability 197 levels of recovery implementation 9 load balancing 4 logical partition 25 LOOPBACK address 218 Lotus Domino for iSeries 75, 166 LPAR 25, 105, 210 M maintenance 201 Management Central 62, 127 Management Central server 62, 64 managing application resiliency 53 managing the environment 177 maximum number of jobs 218 membership change message 279 merging a cluster partition 223 merging partitions 280–281 message function 39 messages 216 Microsoft Cluster Services 23 middleware 59 MIMIX 249 MIMIX ClusterServer 249 MIMIX FastPath 249 mirrored protection 17 monitoring for problems 216 N network attribute, ALWADDCLU 62–63, 76, 86, 218 network connection redundancy 209 network hardware redundancy 208 network planning 209 New Cluster Wizard 66 new clustering support 4 node 21–22, 198, 207 numbering new pools 114 O object specifier 269 OLTP 24 OMS/400 Cluster Manager 256 OMS/400 enhanced features 271 Online disk balancing 20 Operating System/400 Option 41 104 operations management 206 Operations Navigator 62, 103, 125 common problems with the GUI 86 GUI 60 GUI to implement, manage iSeries clusters 60 Simple Cluster Management GUI 64 OptiConnect 32, 63, 104 Option 41 64, 104 OS/400 API 87 OS/400 Option 41 64 OS/400 software options 104 OS/400 V4R4 15, 26 clustering 32 OS/400 V5R1 clustering 33 enhancements 35 outage 5 outage impact to business 197 output data area 172 P parallel save and restore 20 partition 42, 105 cluster 280 merge 280–281 state 207, 279 PartnerWorld for Developers 291 peer cluster node design 276 performance database 205 planning 207 tuning, cluster 36 peripheral devices 198 planned downtime 8 planned switch 211 planned switchover 178 planning for iSeries clustering 196 pool numbering 114 positioning HABP solutions with IASPs 122 prerequisites 67 hardware 37 software 37 primary and secondary partition merge 225 primary node 43 primary system 22 problem and change management 206 problem monitoring 216 problems with cluster status 217 Q QBATCH job queue 64 QcstAddClusterNodeEntry API 81 QcstAddDeviceDomainEntry API 81 QcstCreateCluster API 81 QCSTCRGM 278 QCSTCTL 216, 278 job log 216 Index 301 QcstDistributeInformation 36 QCSTHAAPP data area layout 172 QCSTHAAPPI 171 QcstStartClusterNode API 81 QDFTJOBD job description 40 QHST history log 216 QSYSOPR message queue 216 QSYSWRK subsystem 217, 278 QUSRTOOL 37, 59, 87 R RAID-5 16 reclaim storage 121 recovering from a clustered partition 220 recovery domain 45, 220 recovery level 2 10 Redbooks Web site 294 Contact us xix rejoin 211 remote backup 190 remote journal 192 remote site redundancy 208 removing a data or application CRG 265 removing a node from the cluster 266 removing the entire cluster 266 replicate node 44 replication 22, 94 technology 22 resilience 207 resiliency 50, 53 resilient application 198, 256 data area contents 268 resilient applications 200 resilient cluster device 36 resilient data 22, 199, 255 resilient device 63 CRG 108 requirement 63 switch 36 resilient resource 94 resource group setup, example 187 restarting the application 180 routers 198 RPG order entry application, example 192 S save and restore 20 save changed objects 20 save-while-active 20 scheduled downtime 8, 15 scheduled outage 5, 15 secondary and secondary merge 225 security 21, 63, 117, 208 security requirement 63 separate server 33 separate server cluster 25 service level agreements 206 Service Tools adapter 126 shared disk 24–25 shared disk setup 24 Simple Cluster Management GUI 36, 60, 64 Simple Cluster Management GUI considerations 64 simple two-node cluster example 48 single system availability 15, 25 single system environment 206 site loss 21 site redundancy 208 SMP (symmetric multi-processing) 25 standalone IASP 100, 108 Start Cluster Node (QcstStartClusterNode) API 219 Start Cluster Node (STRCLUNOD) command 81 startup of recovery domains, example 188 storage 118 storage management 19 strategic solution 197 STRCLUNOD (Start Cluster Node) command 81 subsystem jobs 218 suitability rank 115 switchable independent auxiliary storage pool 36, 141 Switchable Software 75, 82 switched disk 23 considerations 105 switching IASPs *AUTL 120 between nodes 121 switching over a data or application CRG 264 switchover 22, 34, 199–201 planned 178 symmetric multi-processing (SMP) 25 system ASP 102 system maintenance 35 system management related tests 211 system operations 121 system outage 8, 21, 33 System Software Maintenance 21 systems management 206 T tactical solution 197 TCP/IP 21 TCP/IP requirement 63 technology in iSeries clusters 276 temporary files 199 test environment 210 testing clusters 210 total cluster solution 55 traditional Domino clustering 168 transaction level recovery 13 twinax display 201 Type 1 cluster (V4R4 and V4R5) 88 U underlying technology 276 unit numbering 116 unplanned downtime 8 unplanned outages 34 unplanned switch 180 unscheduled downtime 8 302 Clustering and IASPs for Higher Availability on the iSeries Server user ASP 102 user profile 62, 86 user profiles 117 uses for IASP 100 V versioning clusters 281 Vertical Licensed Internal Code (VLIC) logs (VLOG) 216 Virtual OptiConnect 63 Vision Solutions 255 Vision Suite 255 W Work with Active Job (WRKACTJOB) command 216 working with clusters and CRGs 259 WRKACTJOB (Work with Active Job) command 216 (0.5” spine) 0.475”<->0.873” 250 <-> 459 pages Clustering and IASPs for Higher Availability on the IBM ~ iSeries Server ® SG24-5194-01 ISBN 0738422355 INTERNATIONAL TECHNICAL SUPPORT ORGANIZATION BUILDING TECHNICAL INFORMATION BASED ON PRACTICAL EXPERIENCE IBM Redbooks are developed by the IBM International Technical Support Organization. Experts from IBM, Customers and Partners from around the world create timely technical information based on realistic scenarios. Specific recommendations are provided to help you implement IT solutions more effectively in your environment. For more information: ibm.com/redbooks Clustering and IASPs for Higher Availability on the IBM iSeries Server Moving the iSeries server beyond 99.9% availability Independent ASPs and other V5R1 high availabiity solutions Solutions for application and data resiliency With OS/400 V5R1, IBM iSeries servers support two methods of clustering. Replication technology is one method. The other method is switchable disk technology, which is referred to as independent auxiliary storage pools (IASPs) on the iSeries server. This IBM Redbook presents an overview of cluster and switched disk technology available at OS/400 Version 5 Release 1. It explains the concepts and architecture surrounding iSeries clusters. It introduces you to the brand initiative – ClusterProven for iSeries – and explains how it applies to iSeries customers and independent software vendors. Application resiliency can be delivered by exploiting OS/400 cluster technology and cluster management services such as those provided by IBM High Availability Business Partners. It is available through IBM cluster middleware providers. Considerations for this application design are also introduced in this redbook. This redbook is written for IBM customers, technical representatives, and Business Partners who plan business solutions and systems that are continuously available. You should use this book to gain a broad understanding of the cluster architecture available with OS/400 Version 5, Release 1, where clustering is viable. You should also use it to learn how to plan and implement clustering and independent ASPs. Back cover