LOBPDF
LOBPDF
LOBPDF
Paolo Bruni Patric Becker Tim Bohlsen Burkhard Diekmann Dima Etkin Davy Goethals
ibm.com/redbooks
International Technical Support Organization LOBs with DB2 for z/OS: Stronger and Faster November 2006
SG24-7270-00
Note: Before using this information and the product it supports, read the information in Notices on page xv.
First Edition (November 2006) This edition applies to IBM DB2 for z/OS Version 8 (program number 5625-DB2) and IBM DB2 Version 9.1 for z/OS (program number 5635-DB2). Note: This book is based on a pre-GA version of DB2 Version 9.1 for z/OS and may not apply when the product becomes generally available. We recommend that you consult the product documentation or follow-on versions of this IBM Redbooks publication for more current information.
Copyright International Business Machines Corporation 2006. All rights reserved. Note to U.S. Government Users Restricted Rights -- Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
Contents
Figures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . vii Tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ix Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xi Notices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xv Trademarks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xvi Summary of changes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xvii November 2006, First Edition. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xvii November 2007, First Update . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xvii Preface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xix The team that wrote this IBM Redbooks publication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xix Become a published author . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxii Comments welcome. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxii Chapter 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.1 Object-relational in DB2 for z/OS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.2 Changes with DB2 9 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.3 DB2 for z/OS and large objects. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.4 The IBM Redbooks publication contents. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.5 Pointers to LOB functions after DB2 Version 6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 2 3 4 4 4
Chapter 2. Large objects with DB2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 2.1 Introduction to LOB data types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 2.2 The LOB table spaces. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 2.2.1 Single LOB column table space . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 2.2.2 Multiple LOB column table space . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 2.2.3 Partitioned LOB table space . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 2.2.4 The full LOB implementation structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 2.3 LOB locators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 2.3.1 Purpose of LOB locators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 2.3.2 Different types of LOB locators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 2.4 LOB file reference variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 2.4.1 DB2-generated file reference variable constructs . . . . . . . . . . . . . . . . . . . . . . . . . 19 2.4.2 Language support for LOB file reference variables. . . . . . . . . . . . . . . . . . . . . . . . 19 2.4.3 File local/client support . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 Chapter 3. Creating LOBs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.1 Alternatives in defining LOBs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.1.1 Example of automatic creation of objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.1.2 Using CURRENT RULES STD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.1.3 Manual creation of objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.1.4 Adding a LOB column to an existing table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.2 Defining ROWIDs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.2.1 Creating the ROWID column. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.3 LOBs and LOG activity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.3.1 LOGGED and NOT LOGGED attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Copyright IBM Corp. 2006. All rights reserved.
23 24 24 30 32 38 39 40 45 45 iii
3.3.2 Logging for all LOB sizes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.4 Additional considerations for creating LOB objects. . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.4.1 Data conversion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.4.2 Buffer pools and LOB table spaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.4.3 Locking with LOBs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.4.4 Buffer pool and page size considerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.4.5 DSSIZE for LOB table spaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.4.6 GBPCACHE parameter. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.4.7 Impact on cursors fetching LOB values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.5 LOBs are different DB2 objects. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.6 Physical layout of LOBs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
51 53 53 57 57 58 59 60 61 61 63
Chapter 4. Using LOBs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 4.1 Language considerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68 4.1.1 LOB host variables, locators, and file reference variables . . . . . . . . . . . . . . . . . . 68 4.1.2 Use of a double or triple SQLDA in dynamic SQL . . . . . . . . . . . . . . . . . . . . . . . . 69 4.1.3 Working with LOBs in JDBC and SQLJ applications . . . . . . . . . . . . . . . . . . . . . . 70 4.1.4 Specific SQL support for LOBs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71 4.1.5 Functions such as XML2CLOB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 4.1.6 Stored procedures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75 4.2 LOB locators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75 4.2.1 Getting to know LOB locators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76 4.2.2 Examples of using locators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80 4.3 DRDA LOB flow optimization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81 4.3.1 DB2 Universal Java Driver . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83 4.4 Feeding a LOB column . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85 4.4.1 Loading a LOB column using LOAD or the cross loader . . . . . . . . . . . . . . . . . . . 85 4.4.2 Inserting LOBs using the host application. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87 4.4.3 DB2 for Linux, UNIX and Windows import . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95 4.5 Locking . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96 4.5.1 Locking for LOBs with DB2 V8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97 4.5.2 Locking for LOBs with DB2 9 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103 4.6 Unloading LOBs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109 4.6.1 Unloading a LOB using an application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109 4.6.2 Using FETCH CONTINUE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115 4.6.3 Finding the nth occurrence of a string. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121 4.7 Updating LOBs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122 4.7.1 Deleting a specific part of a LOB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122 4.7.2 Updating a specific part of a LOB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123 4.7.3 Updating the entire LOB value . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124 4.8 General best practices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124 Chapter 5. SAP usage of LOBs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.1 Overview of SAP usage of LOBs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.1.1 Some history of SAP LOB usage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.1.2 Basic architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.1.3 Connectivity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.1.4 Why use LOBs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.1.5 SAP usage of LOBs in terms of number and size. . . . . . . . . . . . . . . . . . . . . . . . 5.2 ABAP and Dynpro source and Load . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.3 Programming techniques for the ABAP stack . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.3.1 Basic locator access . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.3.2 CLI Streaming Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127 128 128 128 129 129 130 131 135 135 136
iv
5.4 Optimization techniques and query rewrite . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.4.1 Local LOB buffer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.4.2 Retrieve length and maximal data with locator . . . . . . . . . . . . . . . . . . . . . . . . . . 5.4.3 Optimizing the free locator statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.4.4 Comparison of different techniques using SGEN . . . . . . . . . . . . . . . . . . . . . . . . 5.4.5 Chaining . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.5 Programming techniques with JDBC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.6 Data Dictionary considerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.6.1 ABAP stack . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.6.2 Java stack . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.6.3 DSNZPARMs for DB2 V8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.6.4 ROWID . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.7 Unicode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.8 Some points of SAP LOB usage with CCMS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.9 Portability aspects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.10 Monitoring and tracing. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.11 Database interface layer profile parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.12 Performance measurements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.12.1 Locks and SELECT. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.12.2 Locks and INSERT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.12.3 UPDATE improvement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Chapter 6. Utilities with LOBs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.1 UNLOAD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.2 DSNTIAUL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.3 LOAD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.3.1 Loading LOB data as normal data columns . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.3.2 Loading LOB data using file reference variables . . . . . . . . . . . . . . . . . . . . . . . . 6.3.3 Using the cross loader . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.3.4 Impact of logging. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.4 COPY . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.5 COPYTOCOPY . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.6 QUIESCE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.7 REPORT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.8 RUNSTATS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.9 REORG . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.10 RECOVER and REBUILD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.11 CHECK DATA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.12 CHECK LOB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.13 CHECK INDEX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.14 REPAIR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.15 DSN1COPY and DSN1PRNT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Chapter 7. Data administration with LOBs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7.1 LOBs in the DB2 catalog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7.1.1 Catalog definitions for LOBs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7.1.2 LOBs defined in DB2 catalog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7.1.3 Real Time Statistics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7.2 Recovery strategies and considerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7.2.1 LOGGED base table space with LOGGED LOB table space . . . . . . . . . . . . . . . 7.2.2 LOGGED base table space with NOT LOGGED LOB table space. . . . . . . . . . . 7.2.3 NOT LOGGED base table space with NOT LOGGED LOB table space . . . . . . 7.2.4 LOBs and SYSTEM RECOVERY . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
138 138 139 139 140 140 142 145 145 146 146 146 149 150 151 152 156 157 157 159 159 161 162 171 173 173 174 174 175 179 182 183 184 185 187 198 201 206 209 210 212 213 214 214 219 220 221 221 232 234 235
Contents
7.2.5 Conclusions on recovery of LOB data. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 236 7.3 Altering tables containing LOB columns . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237 Chapter 8. Performance with LOBs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8.1 LOB materialization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8.1.1 The different cases of materialization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8.1.2 Materialization avoidance techniques . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8.2 Virtual storage management for LOBs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8.2.1 DB2 subsystem parameters for LOBs. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8.3 Buffer pools and group buffer pools . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8.3.1 Virtual buffer pools . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8.3.2 Considerations for a data sharing environment . . . . . . . . . . . . . . . . . . . . . . . . . 8.4 Logging with LOBs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8.5 Accessing LOBs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8.5.1 Reading LOBs. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8.5.2 Writing LOBs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8.6 Comparing SQL accounting profiles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8.7 Important I/O aspects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8.8 IFCID enhancements for LOBs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8.9 DRDA LOB flow optimization performance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8.10 LOB recommendations for performance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Appendix A. Additional material . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Locating the Web material . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Using the Web material . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . System requirements for downloading the Web material . . . . . . . . . . . . . . . . . . . . . . . How to use the Web material . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Related publications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . IBM Redbooks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Other publications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Online resources . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . How to get IBM Redbooks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Help from IBM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239 240 241 243 244 245 246 246 248 250 250 250 250 251 252 253 257 258 261 261 261 263 263 265 265 265 266 267 267
vi
Figures
2-1 Association between base table and auxiliary table . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 2-2 Base table with two LOB columns and the two associated LOB table spaces . . . . . . . 13 2-3 Partitioned base table containing two LOB columns. . . . . . . . . . . . . . . . . . . . . . . . . . . 14 2-4 Association between base table, ROWID, auxiliary table, and LOB table space . . . . . 15 2-5 Assigning a LOB locator for a LOB value . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 2-6 DSNTIPE installation panel. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 3-1 Setting up a default buiffer pool for implicitly defined LOBs . . . . . . . . . . . . . . . . . . . . . 26 3-2 Catalog description for table BOOK_BASE_TABLE . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 3-3 SYSIBM.SYSCOLUMNS contents for TBNAME= BOOK_AUX_TABLE . . . . . . . . . . . 37 3-4 Index keys for an auxiliary index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 3-5 LOB structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40 3-6 Applying changes to a LOB table space created with NOT LOGGED . . . . . . . . . . . . . 50 3-7 Mixed client/server environment with different data types . . . . . . . . . . . . . . . . . . . . . . 54 3-8 Differences between code pages 37 and 500. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 3-9 LOB value spanned over pages using chunks and non-chunks . . . . . . . . . . . . . . . . . . 63 3-10 LOB data pages chunked together using a space map and LOB map pages . . . . . . 64 4-1 Concurrent LOB access using LOB locators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77 4-2 Primary chain of locators containing secondary chains . . . . . . . . . . . . . . . . . . . . . . . . 79 4-3 Progressive reference return of LOB data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83 4-4 An example of LOAD with file reference variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86 4-5 Secondary chain of locators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93 4-6 Primary chain of locators containing secondary chains . . . . . . . . . . . . . . . . . . . . . . . . 93 4-7 Lock escalation on LOBs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97 4-8 SELECT lock sequence . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98 4-9 SELECT lock sequence using uncommitted read. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99 4-10 Insert lock sequence . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100 4-11 Delete lock sequence . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100 4-12 Locks acquired by mass delete. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101 4-13 Lock sequence when updating a LOB column . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102 4-14 Lock escalation for UR readers. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104 4-15 Accessing a LOB without a locator reference using ISOLATION (CS) . . . . . . . . . . . 113 4-16 Processing a LOB using a locator reference . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114 5-1 Overview of SAP Web AS 6.40 on DB2 for z/OS (c) SAP AG; 2006 . . . . . . . . . . . . . 129 5-2 Total space usage for SAP MCOD system (c) SAP AG; 2006 . . . . . . . . . . . . . . . . . . 131 5-3 REPOLOAD structure (c) SAP AG; 2006 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132 5-4 REPOSRC structure (c) SAP AG; 2006 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133 5-5 Transaction SGEN (c) SAP AG; 2006 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134 5-6 SQL Trace for simple select using locators (c) SAP AG; 2006 . . . . . . . . . . . . . . . . . . 135 5-7 SQL Trace for update using locator (c) SAP AG; 2006 . . . . . . . . . . . . . . . . . . . . . . . 136 5-8 SELECT statement with LOB locators (c) SAP AG; 2006. . . . . . . . . . . . . . . . . . . . . . 136 5-9 Modified statement (extended DA) on REPOLOAD (c) SAP AG; 2006 . . . . . . . . . . . 139 5-10 Starting the dbsl trace (c) SAP AG; 2006 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153 5-11 SAP Performance Optimizer Tool (c) SAP AG; 2006 . . . . . . . . . . . . . . . . . . . . . . . . 155 5-12 SAP Performance Optimizer Tool DB Trace (c) SAP AG; 2006 . . . . . . . . . . . . . . . . 155 5-13 SAP R3load test case elapsed time (c) SAP AG; 2006 . . . . . . . . . . . . . . . . . . . . . . 158 5-14 R3load test case reduced locks (c) SAP AG; 2006 . . . . . . . . . . . . . . . . . . . . . . . . . 158 5-15 R3load test case reduced network round-trips (c) SAP AG; 2006 . . . . . . . . . . . . . . 159 5-16 Time to update a row when increasing the numbers of updated rows (c) SAP AG; 2006
vii
160 6-1 Heavily updated LOB table space. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-2 LOB Table space REORG with DB2 V8 and prior . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-3 LOB Table space REORG with DB2 9 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-4 Fragmented LOB table space . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-5 Non-fragmented LOB table space . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-1 DB2 materialization overview illustration. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-2 LOB Materialization In user address space in case of data retrieval . . . . . . . . . . . . . 8-3 LOB materialization with INSERT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-4 DSNTIPD installation panel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-5 Buffer pool strategies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-6 Separation of LOB buffer pools. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-7 LOB group buffer pool. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-8 Accounting trace report for LOB and VARCHAR applications . . . . . . . . . . . . . . . . . . 8-9 Striped versus non-striped LOB table spaces. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-10 Performance of LOB Progressive Streaming . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
189 190 190 194 195 241 242 243 245 247 248 249 252 253 257
viii
Tables
1-1 The LOBs functions that have been introduced after Version 6 . . . . . . . . . . . . . . . . . . . 5 2-1 Typical average size for large objects. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 2-2 Maximum number of LOB columns by partitions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 2-3 DB2-generated construct . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 2-4 File option constants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 3-1 Attributes for implicit database creation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 3-2 Default values for implicitly created table spaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 3-3 Base table space created using automatic object creation . . . . . . . . . . . . . . . . . . . . . . 28 3-4 LOB table space created using automatic object creation . . . . . . . . . . . . . . . . . . . . . . 29 3-5 Auxiliary index created using automatic object creation . . . . . . . . . . . . . . . . . . . . . . . . 30 3-6 LOB table space created using CURRENT RULES STD . . . . . . . . . . . . . . . . . . . . . . . 30 3-7 Auxiliary index created using CURRENT RULES STD. . . . . . . . . . . . . . . . . . . . . . . . . 31 3-8 LOG column values scenarios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48 3-9 SYSIBM.SYSCOPY values for LOGGED attribute changes. . . . . . . . . . . . . . . . . . . . . 49 3-10 DB2 Unicode support - Additional useful resources . . . . . . . . . . . . . . . . . . . . . . . . . . 56 3-11 Choosing a LOB page size that minimizes getpages . . . . . . . . . . . . . . . . . . . . . . . . . 58 3-12 Choosing a LOB page size for LOBs that are all the same size . . . . . . . . . . . . . . . . . 59 3-13 Primary and secondary quantity with LOBs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59 3-14 Summary of data set, partition, and partitioned table space sizes . . . . . . . . . . . . . . . 60 4-1 SQLTYPE and SQLLEN of LOB columns or LOB host variables in the SQLDA . . . . . 70 4-2 Casting large objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 4-3 Where large objects come from and how . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85 5-1 LOB objects in one SAP system (c) SAP AG; 2006 . . . . . . . . . . . . . . . . . . . . . . . . . . 130 5-2 Total size of all LOB columns (c) SAP AG; 2006 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131 5-3 Details of Repo tables LOB content (c) SAP AG; 2006 . . . . . . . . . . . . . . . . . . . . . . . 134 5-4 SGEN runs on different optimization levels (c) SAP AG; 2006 . . . . . . . . . . . . . . . . . . 140 5-5 DSNZPARMs for V8 (c) SAP AG; 2006 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146 5-6 Comparison of different databases for aspects of LOBs (c) SAP AG; 2006 . . . . . . . . 152 5-7 dbsl_lib profile parameters for LOB handling (c) SAP AG; 2006 . . . . . . . . . . . . . . . . 157 6-1 Impact of logging if base table space is LOGGED . . . . . . . . . . . . . . . . . . . . . . . . . . . 175 6-2 Impact of logging if base table space is LOGGED . . . . . . . . . . . . . . . . . . . . . . . . . . . 193 6-3 Resetting pending states using REPAIR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211 8-1 LOB linked subsystem parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245 8-2 Current IFCIDs providing information regarding LOBs . . . . . . . . . . . . . . . . . . . . . . . . 254
ix
Examples
2-1 Host variable definitions for LOB locators in COBOL . . . . . . . . . . . . . . . . . . . . . . . . . . 17 2-2 What the DB2 precompiler makes of LOB locators. . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 2-3 Host variable definition for BLOB file reference variable in COBOL . . . . . . . . . . . . . . . 20 2-4 What the DB2 precompiler makes of BLOB file reference variable . . . . . . . . . . . . . . . 20 3-1 DDL for a base table resulting in automatic object creation . . . . . . . . . . . . . . . . . . . . . 25 3-2 Resulting objects for automatic object creation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 3-3 DDL for a base table for manual object creation. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 3-4 Catalog description for a hidden ROWID for LOBs. . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 3-5 Retrieving a generated ROWID value at INSERT time. . . . . . . . . . . . . . . . . . . . . . . . . 33 3-6 Content of LOB indicator columns . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 3-7 DDL for a LOB table space . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 3-8 DDL for an auxiliary table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36 3-9 DDL for an auxiliary table containing data of one base table partition . . . . . . . . . . . . . 36 3-10 DDL for an auxiliary Index. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 3-11 Displaying a database for LOBs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 3-12 Adding a ROWID column . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 3-13 Adding a LOB column . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 3-14 DDL for a table containing a ROWID column . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42 3-15 Inserting a row in CUSTOMER table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42 3-16 ROWID value of a table created with ROWID column . . . . . . . . . . . . . . . . . . . . . . . . 42 3-17 DB2 9 DSN1PRNT of ROWID in hex value . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42 3-18 DB2 V8 DSN1PRNT of ROWID in hex value . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42 3-19 ALTER TABLE adding a ROWID column . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 3-20 ROWID value of a table where a ROWID column was added . . . . . . . . . . . . . . . . . . 43 3-21 DB2 9 DSN1PRNT of ROWID in hex value after adding and updating a row. . . . . . . 43 3-22 DB2 V8 DSN1PRNT of ROWID in hex value after adding and updating a row . . . . . 43 3-23 ROWID values of updated and inserted columns . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44 3-24 DB2 9 DSN1PRNT of updated and inserted ROWIDs in hex value . . . . . . . . . . . . . . 44 3-25 DB2 V8 DSN1PRNT of updated and inserted ROWIDs in hex value . . . . . . . . . . . . . 44 3-26 DISPLAY DATABASE sample output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48 3-27 DSN1LOGP output for logged LOB insert . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 3-28 DSN1LOGP output for not logged LOB insert . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 4-1 Usage example of XML2CLOB function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 4-2 Example output from XML2CLOB function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75 4-3 Syntax for FREE locator and HOLD locator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78 4-4 Loading LOB data using File Reference Variable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87 4-5 Rows tied together in one variable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89 4-6 Host variable declaration for a LOB column . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89 4-7 What the DB2 precompiler makes of your host variable declaration . . . . . . . . . . . . . . 89 4-8 Inserting a single LOB value using one host variable . . . . . . . . . . . . . . . . . . . . . . . . . . 89 4-9 Pseudo code inserting LOBs with one locator chain. . . . . . . . . . . . . . . . . . . . . . . . . . . 90 4-10 Pseudo code inserting LOBs with multiple locator chains. . . . . . . . . . . . . . . . . . . . . . 94 4-11 IMPORT command . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95 4-12 EXPORT command . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96 4-13 Comparison of RLSN and LSN to reclaim space . . . . . . . . . . . . . . . . . . . . . . . . . . . 106 4-14 Unloading LOB data using a file reference variable . . . . . . . . . . . . . . . . . . . . . . . . . 109 4-15 What the DB2 precompiler generates for LOB files . . . . . . . . . . . . . . . . . . . . . . . . . 110 4-16 Unloading LOB data using one host variable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
xi
4-17 Unloading a LOB using locators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-18 FETCH CONTINUE with dynamic SQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-19 FETCH CONTINUE with static SQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-20 Finding a specific occurrence of a string. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-21 Delete Chapter 8 of book CLOB using locators . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-22 Updating a part of a CLOB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-23 Inserting new text at a particular position . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-1 CLI trace for REPOLOAD Select using SQLGetSubString() (c) SAP AG; 2006 . . . . . 5-2 Pseudo code for chaining (c) SAP AG; 2006 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-3 Chaining on insert (c) SAP AG; 2006 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-4 R3load log files for dbs_db2_chaining=20 (c) SAP AG; 2006 . . . . . . . . . . . . . . . . . . 5-5 R3load log files for dbs_db2_chaining=0 (c) SAP AG; 2006 . . . . . . . . . . . . . . . . . . . 5-6 LOB access with JDBC driver (c) SAP AG; 2006 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-7 Insert using progressive reference (c) SAP AG; 2006 . . . . . . . . . . . . . . . . . . . . . . . . 5-8 Table definition for test table TSTLOBDDL in XML format (c) SAP AG; 2006 . . . . . . 5-9 DDL for LOB table DB2 V8 (c) SAP AG; 2006 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-10 DDL for LOB table DB2 9 (c) SAP AG; 2006 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-11 Bind command for UNIX system (c) SAP AG; 2006 . . . . . . . . . . . . . . . . . . . . . . . . . 5-12 DBSL trace displaying all LOB data (c) SAP AG; 2006 . . . . . . . . . . . . . . . . . . . . . . 5-13 Locks taken by simple SELECT on LOB table V8 (c) SAP AG; 2006. . . . . . . . . . . . 5-14 Locks taken by simple SELECT on LOB table with DB2 9 (c) SAP AG; 2006 . . . . . 6-1 DDL for table ##T.NORMEN00. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-2 Unload LOB data as normal data columns with UNLOAD TABLESPACE . . . . . . . . . 6-3 UNLOAD exceeding a 32 KB row size . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-4 Unload LOB data as normal data columns with UNLOAD TABLE . . . . . . . . . . . . . . . 6-5 Unload LOB data as normal data columns in DELIMITED format . . . . . . . . . . . . . . . 6-6 Unload LOB data as normal data columns in DELIMITED format . . . . . . . . . . . . . . . 6-7 Unload LOB data as normal data columns in truncated format . . . . . . . . . . . . . . . . . 6-8 Unload LOB data as normal data columns in truncated format . . . . . . . . . . . . . . . . . 6-9 Unload LOB data to a PDS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-10 Unload LOB data to a PDS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-11 Contents of the SYSREC file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-12 Unload LOB data to a PDSE. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-13 Contents of the SYSREC file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-14 Unload LOB data to a HFS directory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-15 Contents of the HFS directory /u/DB9B . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-16 Contents of the SYSREC file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-17 DSNTIAUL with SQL parameter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-18 DSNTIAUL output with SQL parameter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-19 DSNTIAUL with LOBFILE parameter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-20 DSNTIAUL output with LOBFILE parameter. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-21 LOAD LOB data with input from DSNTIAUL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-22 LOAD LOB data with input from DSNTIAUL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-23 Entries in SYSIBM.SYSTABLESPACE. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-24 LOAD with LOG YES on NOT LOGGED table spaces . . . . . . . . . . . . . . . . . . . . . . . 6-25 LOAD LOB input file not found . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-26 LOAD LOB data with cross loader . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-27 COPY LOB data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-28 Common START_RBA in SYSIBM.SYSCOPY. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-29 CONCURRENT COPY of LOB data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-30 CONCURRENT COPY entries in SYSIBM.SYSCOPY. . . . . . . . . . . . . . . . . . . . . . . 6-31 CONCURRENT COPY of LOB data to one dump data set . . . . . . . . . . . . . . . . . . . 6-32 CONCURRENT COPY entries in SYSIBM.SYSCOPY with FILTERDDN . . . . . . . . xii
LOBs with DB2 for z/OS: Stronger and Faster
112 117 120 121 122 123 124 137 140 141 141 141 142 144 147 148 148 149 153 156 156 162 163 164 164 164 165 165 165 167 167 168 168 169 169 169 170 171 171 172 173 176 176 177 177 178 178 181 181 182 182 182 182
6-33 COPYTOCOPY . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-34 Primary and COPYTOCOPY entries in SYSIBM.SYSCOPY . . . . . . . . . . . . . . . . . . 6-35 QUIESCE a base table space and all LOB table spaces . . . . . . . . . . . . . . . . . . . . . 6-36 QUIESCE entries in SYSIBM.SYSCOPY . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-37 QUIESCE a table space set . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-38 REPORT TABLESPACESET on automatic created objects. . . . . . . . . . . . . . . . . . . 6-39 REPORT TABLESPACESET report . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-40 REPORT RECOVERY . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-41 RUNSTATS on LOB data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-42 REORG SHRLEVEL NONE of one LOB table space . . . . . . . . . . . . . . . . . . . . . . . . 6-43 REORG SHRLEVEL NONE of all LOB objects. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-44 REORG SHRLEVEL REFERENCE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-45 REORG SHRLEVEL REFERENCE output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-46 REORG SHRLEVEL REFERENCE with LISTDEF. . . . . . . . . . . . . . . . . . . . . . . . . . 6-47 REORG INDEX auxiliary index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-48 RTS DSNACCOX query for REORG TABLESPACE . . . . . . . . . . . . . . . . . . . . . . . . 6-49 RTS DSNACCOX query for REORG INDEX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-50 Recover table spaces an indexes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-51 Recover table spaces and rebuild indexes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-52 REBUILD SHRLEVEL CHANGE of the indexes . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-53 Using RECOVER to reallocate a single VSAM cluster of a LOB table space. . . . . . 6-54 Examples of CHECK DATA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-55 Examples of CHECK LOB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-56 Example of CHECK INDEX using a LISTDEF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-57 DUMP or DELETE an entire LOB value . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-1 DDL for table ##T.NORMEN00. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-2 Select from SYSIBM.SYSAUXRELS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-3 Select from SYSIBM.SYSCOLUMNS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-4 Select from SYSIBM.SYSLOBSTATS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-5 Select from SYSIBM.SYSTABLEPART . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-6 Select from SYSIBM.SYSTABLES . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-7 Select from SYSIBM.SYSTABLESPACE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-8 DB2 9, automatic creation of objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-9 Select from SYSIBM.SYSTABLESPACE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-10 DB2 catalog query . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-11 Creating a common recoverable point of consistency using COPY . . . . . . . . . . . . . 7-12 Common START_RBA in SYSIBM.SYSCOPY. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-13 SPUFI delete. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-14 Delete VSAM clusters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-15 RECOVER to current point in time . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-16 RECOVER to current point in time . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-17 Display database command . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-18 Creating a common recoverable point of consistency using QUIESCE . . . . . . . . . . 7-19 SPUFI delete. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-20 Point in time recovery to a common recoverable point of consistency . . . . . . . . . . . 7-21 Point in time recovery to a recoverable quiesce point . . . . . . . . . . . . . . . . . . . . . . . 7-22 Point in time recovery with consistency in DB2 9 . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-23 SPUFI delete. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-24 Point in time recovery of base table only . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-25 Base table space in ACHKP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-26 CHECK DATA SHRLEVEL REFERENCE AUXERROR REPORT. . . . . . . . . . . . . . 7-27 Result of CHECK DATA AUXERROR REPORT . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-28 CHECK DATA SHRLEVEL CHANGE AUXERROR REPORT . . . . . . . . . . . . . . . . .
Examples
183 183 184 184 184 185 185 185 186 188 188 191 191 192 192 196 196 200 200 201 201 205 208 210 211 214 215 216 217 217 217 219 219 219 219 221 221 222 222 222 222 223 224 224 224 224 226 227 227 227 228 228 228 xiii
7-29 CHECK DATA AUXERROR INVALIDATE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-30 Point in time recovery of the LOB table space . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-31 State of the table spaces afterwards. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-32 State of the table spaces after CHECK DATA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-33 SPUFI delete. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-34 Point in time recovery of LOB table space only . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-35 CHECK DATA AUXERROR INVALIDATE SHRLEVEL REFERENCE. . . . . . . . . . . 7-36 Identification and Invalidation of orphan LOBs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-37 Use of REPAIR to delete orphan LOBs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-38 SPUFI Insert . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-39 LOB table space in AUXW . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-40 CHECK LOB output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-41 SPUFI update invalid LOB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-42 RECOVER of NOT LOGGED objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-1 Omegamon XE for DB2 Performance Expert output . . . . . . . . . . . . . . . . . . . . . . . . . 8-2 LOB buffer pool allocation size . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
229 229 229 230 230 231 231 231 232 232 233 233 234 234 244 248
xiv
Notices
This information was developed for products and services offered in the U.S.A. IBM may not offer the products, services, or features discussed in this document in other countries. Consult your local IBM representative for information on the products and services currently available in your area. Any reference to an IBM product, program, or service is not intended to state or imply that only that IBM product, program, or service may be used. Any functionally equivalent product, program, or service that does not infringe any IBM intellectual property right may be used instead. However, it is the user's responsibility to evaluate and verify the operation of any non-IBM product, program, or service. IBM may have patents or pending patent applications covering subject matter described 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: IBM Director of Licensing, IBM Corporation, North Castle Drive, Armonk, NY 10504-1785 U.S.A. The following paragraph does not apply to the United Kingdom or any other country where such provisions are inconsistent with local law: INTERNATIONAL BUSINESS MACHINES CORPORATION PROVIDES THIS PUBLICATION "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Some states do not allow disclaimer of express or implied warranties in certain transactions, therefore, this statement may not apply to you. This information could include technical inaccuracies or typographical errors. Changes are periodically made to the information herein; these changes will be incorporated in new editions of the publication. IBM may make improvements and/or changes in the product(s) and/or the program(s) described in this publication at any time without notice. Any references in this information to non-IBM Web sites are provided for convenience only and do not in any manner serve as an endorsement of those Web sites. The materials at those Web sites are not part of the materials for this IBM product and use of those Web sites is at your own risk. IBM may use or distribute any of the information you supply in any way it believes appropriate without incurring any obligation to you. Information concerning non-IBM products was obtained from the suppliers of those products, their published announcements or other publicly available sources. IBM has not tested those products and cannot confirm the accuracy of performance, compatibility or any other claims related to non-IBM products. Questions on the capabilities of non-IBM products should be addressed to the suppliers of those products. This information contains examples of data and reports used in daily business operations. To illustrate them as completely as possible, the examples include the names of individuals, companies, brands, and products. All of these names are fictitious and any similarity to the names and addresses used by an actual business enterprise is entirely coincidental. COPYRIGHT LICENSE: This information contains sample application programs in source language, which illustrate programming techniques on various operating platforms. You may copy, modify, and distribute these sample programs in any form without payment to IBM, for the purposes of developing, using, marketing or distributing application programs conforming to the application programming interface for the operating platform for which the sample programs are written. These examples have not been thoroughly tested under all conditions. IBM, therefore, cannot guarantee or imply reliability, serviceability, or function of these programs.
xv
Trademarks
The following terms are trademarks of the International Business Machines Corporation in the United States, other countries, or both:
Redbooks (logo) ibm.com iSeries z/OS zSeries z9 AIX CICS Database 2 DB2 Connect DB2 Extenders DB2 Universal Database DB2 DFSMSdss DFSMShsm DRDA Enterprise Storage Server ESCON FlashCopy FICON Geographically Dispersed Parallel Sysplex GDPS IBM IBM WebSphere MQ IMS Language Environment MVS OS/390 Parallel Sysplex PR/SM QMF Redbooks RACF System/390 Tivoli WebSphere
The following terms are trademarks of other companies: SAP, R/3, mySAP, mySAP.com, xApps, xApp, SAP NetWeaver, and other SAP products and services mentioned herein as well as their respective logos are trademarks or registered trademarks of SAP AG in Germany and in several other countries all over the world. EJB, Java, Java Naming and Directory Interface, JDBC, JVM, J2EE, and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both. Visual Studio, Windows, and the Windows logo are trademarks of Microsoft Corporation in the United States, other countries, or both. Intel, Intel logo, Intel Inside logo, and Intel Centrino logo are trademarks or registered trademarks of Intel Corporation or its subsidiaries in the United States, other countries, or both. UNIX is a registered trademark of The Open Group in the United States and other countries. Linux is a trademark of Linus Torvalds in the United States, other countries, or both. Other company, product, or service names may be trademarks or service marks of others. Data contained in this document serves informational purposes only. National product specifications may vary
xvi
Summary of changes
This section describes the technical changes made in this edition of the book and in previous editions. This edition may also include minor corrections and editorial changes that are not identified. Summary of Changes for SG24-7270-00 for LOBs with DB2 for z/OS: Stronger and Faster as created or updated on November 13, 2007.
Changed information
Deleted a sentence on COPYP setting at page 188. Corrected information about from ORGRATIO>10 to ORGRATIO < 10 on page 195. Updated the DSNACCOX formulae listed in Example 6-48 and Example 6-49 on page 196.
New information
Added Figure 3-1 on page 26 and text on TBSBPLOB, the DSNZPARM which allows the user to specify the default buffer pool to use for LOB table spaces. Added PQ96460 and PTF numbers for PK29750 at page 195. Added APAR PK44133 for DSNACCOX at Monitoring Real Time Statistics on page 196.
xvii
xviii
Preface
The requirements for a database management system (DBMS) have included support for very large and complex data objects. DB2 UDB for OS/390 Version 6 introduced the support for large objects (LOBs): they can contain text documents, images, or movies, and can be stored directly in the DBMS with sizes up to 2 gigabytes per object and 65,536 TB for a single LOB column in a 4,096 partition table. The introduction of these new data types has implied some changes in the administration processes and programming techniques. The book Large Objects with DB2 for z/OS and OS/390, SG24-6571, introduced and described the usage of LOBs with DB2 for z/OS at Version 7 level. Major enhancements for LOB manipulation have been introduced with DB2 UDB for z/OS Version 8 and DB2 Version 9.1 for z/OS (DB2 9 in this book). These enhancements include performance functions such as the avoidance of LOB locks and DRDA LOB flow optimization, usability functions such as file reference variables, FETCH CONTINUE, and the automatic creation of objects. DB2 utilities provide integrated support with LOAD and UNLOAD, cross-loader, REORG, CHECK DATA, and CHECK LOB. In this IBM Redbooks publication, we provide a totally revised description of the DB2 functions for LOB support as well as useful information about how to design and implement them. We also offer examples of their use, programming considerations, and the enhanced processes used for their administration and maintenance. We also detail how SAP solutions use LOBs. This book replaces the previous book Large Objects with DB2 for z/OS and OS/390, SG24-6571, for DB2 Version 8 and Version 9.1.
xix
experience with SAP and 19 years experience in the IT industry. Prior to working with SAP R/3, Tim was an MVS System Programmer in Australia for five years, specializing in large system performance and automation. He holds an Honors degree in Computer Engineering from Newcastle University. Tim is also co-author of the book DB2 UDB for z/OS V8: Through the Looking Glass and What SAP Found There, SG24-7088. Burkhard Diekmann is a Senior Developer in the SAP NetWeaver Database Platform organization at SAP's Headquarters in Walldorf. He joined SAP in 1996 and has ten years of experience in DB2 interfacing SAP applications. His areas of expertise include SAP database interface, SAP middleware, and technology development. Dima Etkin is a DB2 System Administrator and a senior DB2 Consultant in Israel. He has ten years of experience in the DB2 System Administration field, as well as instructing for BLUE Education Center (Israel) and IBM Learning Services (Israel). His areas of expertise include DB2 administration and system tuning. Davy Goethals is a Belgian systems engineer. He works for Arcelor Technologies, a subsidiary of Arcelor, a steel producing company. He has experience as a DB2 system administrator since DB2 Version 1 in 1985. He participated in multiple DB2 ESP and QPP programs from DB2 V2.1 up to DB2 V7. Davy is also co-author of the book DB2 for z/OS and OS/390 Version 7 Using the Utilities Suite, SG24-6289. Currently, he is DB2 team leader within the Arcelor Technologies z/OS department, located in Dunkerque, France, responsible for supporting more than 45 DB2 systems for steel plants all over Europe. A photo of the team is in Figure 1. Patric Becker is missing from the group picture.
Figure 1 Left to right: Davy, Dima, Burkhard, Tim and Paolo in SVL
xx
Rich Conway Bob Haimowitz Emma Jacobs Leslie Parham Deanna Polm Sangam Racherla International Technical Support Organization Terry Allen Jeff Berger Ben Budiman Larry Cowdery Bill Franklin Koshy John Jeff Josten Brandon Lee Li-Mey Lee Chao-Lin Liu Bruce McAlister Patrick Malone Roger Miller Esther Mote Haakon Roberts Akira Shibamiya Bryan Smith Bart Steegmans James Teng Frances Villafuerte Maryela Weihrauch Allen Yang Jay Yothers Maureen Zoric IBM DB2 for z/OS Development, Silicon Valley Lab, USA Muni Bandlamoori Roger Lo Manfred Olschanowsky Helmut Roesner Yeong Soong IBM/SAP Integration Center, IBM Silicon Valley Lab, USA Brenda Beane Seewah Chan System Performance Evaluation Test, Poughkeepsie, USA Namik Hrle Johannes Schuetzner IBM Systems and Technology Group, Germany Bernhard Heininger Jennifer Johnson Bernd Kohler Peter Mohrholz SAP AG, Walldorf, Germany
Preface
xxi
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 IBM Redbooks publication form found at: ibm.com/redbooks Send your comments in an E-mail to: [email protected] Mail your comments to: IBM Corporation, International Technical Support Organization Dept. HYTD Mail Station P099 2455 South Road Poughkeepsie, NY 12601-5400
xxii
Chapter 1.
Introduction
The implementation of object-relational in DB2 for z/OS allows you to define custom data types and functions based on the previously existent ones. Some of the data objects you want to model might well be very large and complex. DB2 for z/OS Version 6 has introduced the foundation of object-relational extension, with, on one hand, support for large objects (LOBs), and, on the other one, support for user-defined functions (UDFs), user-defined distinct types (UDTs), and triggers. In this chapter, we outline the implemented functions for object-relational, including extenders, we mention the main changes in DB2 9 for z/OS, and we introduce the LOB-related topics described in this book. This chapter contains: Object-relational in DB2 for z/OS Changes with DB2 9 DB2 for z/OS and large objects The IBM Redbooks publication contents Pointers to LOB functions after DB2 Version 6
IAV Extenders - Image, Audio, and Video extenders Text Extender XML Extender Text Extender adds full-text retrieval to SQL queries by making use of features available in DB2 that let you store unstructured text documents of up to 2 GB in databases. You can use the DB2 Extenders feature of DB2 to store and manipulate image, audio, video, and text objects. The extenders automatically capture and maintain object information and provide a rich body of APIs. These extenders define new data types and functions using DB2's built-in support for user-defined types and user-defined functions. You can couple any combination of these data types, that is, image, audio, and video, with a text search query. The extenders exploit DB2s support for large objects of up to 2 GB, and for triggers that provide integrity checking across database tables ensuring the referential integrity of the multimedia data.
Chapter 1. Introduction
Table 1-1 The LOBs functions that have been introduced after Version 6 Function JDBC functions and DB2 catalog changes for Java support requiring LOBs in DB2 catalog Where described See Chapter 3 of DB2 UDB Server for OS/390 and z/OS Version 7 Presentation Guide, SG24-6121. See Chapter 4 of DB2 UDB Server for OS/390 and z/OS Version 7 Presentation Guide, SG24-6121. See Chapter 5 of DB2 UDB Server for OS/390 and z/OS Version 7 Presentation Guide, SG24-6121. See 6.3, LOAD on page 173 and 6.1, UNLOAD on page 162. See 6.3.3, Using the cross loader on page 174. See 5.12, Performance measurements on page 157. See 4.25 of DB2 UDB for z/OS Version 8: Everything You Ever Wanted thing to Know, ... and More, SG24-6079. See 2.28 of DB2 UDB for z/OS Version 8: Everything You Ever Wanted thing to Know, ... and More, SG24-6079, and 8.2.1, DB2 subsystem parameters for LOBs on page 245. See 5.4 of DB2 UDB for z/OS Version 8: Everything You Ever Wanted thing to Know, ... and More, SG24-6079, and 4.1.5, Functions such as XML2CLOB on page 74. Version 7 Y Version 8 Y Version 9.1 Y
LISTDEF to allow LOAD and UNLOAD to support LOBs < 32 KB and account for them with a 4 byte length field
File reference variables in LOAD and UNLOAD LOB support in the cross-loader
Y (integrated)
ROWID transparency
XML2CLOB
Chapter 1. Introduction
Where described See 8.3.7 of DB2 UDB for z/OS Version 8: Everything You Ever Wanted thing to Know, ... and More, SG24-6079, and DB2 for z/OS Stored Procedures: Through the CALL and Beyond, SG24-7083. See 5.1.13 of DB2 UDB for z/OS Version 8: Everything You Ever Wanted thing to Know, ... and More, SG24-6079 and DB2 for z/OS Stored Procedures: Through the CALL and Beyond, SG24-7083. See 2.37 of DB2 UDB for z/OS Version 8: Everything You Ever Wanted thing to Know, ... and More, SG24-6079. See 9.14.2 of DB2 UDB for z/OS Version 8: Everything You Ever Wanted thing to Know, ... and More, SG24-6079. See the DB2 Installation Guide for each DB2 Version and Appendix A, Additional material on page 261. See 4.5.2, Locking for LOBs with DB2 9 on page 103. See 5.3.2, CLI Streaming Interface on page 136. See 4.6.2, Using FETCH CONTINUE on page 115. See 3.1.1, Example of automatic creation of objects on page 24. See 3.3.1, LOGGED and NOT LOGGED attributes on page 45. See 6.9, REORG on page 187. See 6.12, CHECK LOB on page 206.
Version 7
Version 8 Y
Version 9.1 Y
Long SQL statements as CLOBs. Using dynamic SQL, SQL statements up to 2 MB are passed to DB2 as a CLOB or DBCLOB, because a normal character string can only be up to 32 KB CHECK LOB sort enhancement: SYSUT1 and SORTOUT DD statement for sort input and output are no longer needed
Y Y Y
Removed requirement that 1 GB or greater LOBs be in a NOT LOGGED LOB table space REORG SHRLEVEL REFERENCE for a LOB table space Online CHECK LOB
Y Y
Function Online CHECK DATA DSNTEJ7 now creates the sample LOB database using LOAD utility and file reference variables DSNTIAUL to extract LOB data into files and generate a LOAD statement
Where described See 6.11, CHECK DATA on page 201. See the DB2 9 for z/OS Installation Guide. See 6.2, DSNTIAUL on page 171.
Version 7
Version 8
Version 9.1 Y Y
Chapter 1. Introduction
Chapter 2.
The data types provided by DB2, such as VARCHAR or VARBINARY (V9), are not large enough to hold this amount of data, because of their limit of 32 KB. LOB support is based on the set of data types which were introduced with DB2 V6. With large object support, DB2 stores and manipulates data objects that are much larger. DB2 provides data types to store large data objects (LOBs), which support strings of up to 2 GB in size, well beyond the 32 KB supported by a varchar column. Techniques for storing and retrieving these huge amounts of data have also been created within DB2. The LOB data types allow you to store directly in DB2 tables objects in size of up to 2 GB, and 65,536 Terabytes (TB) per LOB column. Their characteristics depend on the way they are stored in your DB2 subsystem:
Character Large Objects (CLOBs) Binary Large Objects (BLOBs) Double-byte Character Large Objects (DBCLOBs)
For internal structure support, DB2 also uses the data type:
ROWIDs
DB2 also provides host variables and data types that are used for manipulating LOBs:
10
Locators and file reference variables are described later at 2.3, LOB locators on page 16 and 2.4, LOB file reference variables on page 18. We now briefly introduce the data types available in DB2 for LOB support.
CLOBs
A character large object (CLOB) is a varying-length string with a maximum length of 2,147,483,647 bytes (2 gigabytes minus 1 byte). A CLOB is designed to store large SBCS data or mixed data, such as lengthy documents. For example, you can store information such as an employee resume, the script of a play, or the text of a novel in a CLOB. Alternatively, you can store such information in UTF-8 in a mixed CLOB. A CLOB is a varying-length character string, which can be thought of as a varchar field of (almost) unlimited length. Most text documents stored on other platforms cannot be converted to a CLOB value easily because most known editing applications save data using their own format. This format usually contains an interspersed amount of control information used for font types, font sizes, and layout purposes. If you want to store this data as a CLOB value and access it via DB2 functions such as SUBSTR or POSSTR, you might have to convert the data from its format on your client platform to a plain or tagged text file before inserting into a CLOB column. You can consider using a CLOB column for storing large text documents. If you plan to store your PC documents in DB2 for z/OS without converting them, because you want to access them from your client applications for further processing, you need to store them as BLOBs to avoid loss of font and layout control information.
BLOBs
A binary large object (BLOB) is a varying-length string that has a maximum length of 2,147,483,647 bytes (2 gigabytes minus 1 byte). A BLOB contains a binary string representing binary data, which is a sequence of bytes and typically unreadable. A BLOB is designed to store various data such as pictures, voice, and mixed media. BLOBs can also store structured data for use by distinct types and user-defined functions. Although BLOB strings and FOR BIT DATA character strings might be used for similar purposes, the two data types are incompatible. The BLOB function or CAST function can be used to change a FOR BIT DATA character string into a BLOB string. Normal character strings defined with the FOR BIT DATA option cannot be assigned a CCSID, and the same rule applies to BLOB strings.
DBCLOBs
A double-byte character large object (DBCLOB) is a varying length string of double-byte characters that can be up to 2 GB long. Using a DBCLOB column, you can store up to 1,073,741,823 double-byte characters in a single DBCLOB value. A DBCLOB is used to store large double-byte character set (DBCS) character-based data such as documents written with a double-byte CCSID. A DBCLOB is considered to be a graphic string. You can find double-byte CCSIDs for languages such as Japanese (extended Katakana or Katakana-Kanji), Korean, or Chinese (simplified or traditional).
ROWIDs
The ROWID data type (and column) definition was introduced with DB2 V6 to uniquely and permanently identify a row in a table. To understand the role of the ROWID, and why DB2 creates a value for a ROWID column whenever a row is inserted in a table containing this new data type, you must first understand the overall picture of the DB2 objects involved in supporting LOBs, as described first at 2.2, The LOB table spaces on page 12, and then in more detail at 3.2, Defining ROWIDs on page 39.
11
Auxiliary Table
Picture 2
12
Movie 1
Auxiliary Table
Movie 2
Auxiliary Table
Picture 2
Figure 2-2 Base table with two LOB columns and the two associated LOB table spaces
13
Base Table
Col 1 Vala Valc Col 1 Valb Vald LOB Col 1 LOB Col 2
Auxiliary Table
Movie 2
Auxiliary Table
Picture 2
Base Table
Col 1 Vale Valg Col 2 Valf Valh LOB Col 1 LOB Col 2
Auxiliary Table
Movie 4
Auxiliary Table
Picture 4
14
... ...
ABCDEFG...
Picture 1
1234567...
Picture 2
Row ID
Auxiliary Table
Auxiliary Index
Figure 2-4 Association between base table, ROWID, auxiliary table, and LOB table space
An important reason for the separation of LOB columns is performance. The decision was made during the design phase of large object support, based on experiences using middleware systems and LOBs. Assuming table space scans on the base table, LOB values do not have to be processed during these scans. Probably most of the scanning time would be spent in scanning LOB columns if the LOB columns resided in the same table as the non-LOB columns. Based on the nature of LOBs, they can be larger than the biggest available page size, which is still 32 KB in DB2 9 and is also valid for LOB table spaces. Therefore, a single LOB value can span pages. Because each data set of a LOB table space can grow up to 64 GB, and there can be up to 254 data sets per table space, the maximum size of a non-partitioned LOB table space is 16,256 GB (16 TB) in total. Because the number of partitions can grow up to 4,096 in the base table, there are 4,096 single LOB table spaces, each holding up to 16 TB of data as a maximum size. This gives a grand total of 4,096 x 16 TB = 65,536 TB available for a single column of LOB data. A single database can hold a maximum of 65,535 objects, or to be more specific, XFFFF object identifiers (OBDs). Regardless of the number of partitions, you use one OBD for each auxiliary relationship per LOB column. Furthermore, DB2 uses 5 OBDs per LOB column per partition. Therefore, this gives us a maximum of 3 LOB columns for a 4,096 partition table, not exceeding 65,535 OBDs. According to these values: 3 + n + 5np <= 65535
Chapter 2. Large objects with DB2
15
with n as the number of LOB columns in your base table and p as the number of partitions. The formula gives you the number of partitions and LOB columns that can reside inside one database. The values are summarized in Table 2-2.
Table 2-2 Maximum number of LOB columns by partitions Partitions 250 1,000 4,096 Data sets 12,250 13,000 16,384 Maximum number of LOB columns 48 12 3
16
Application
DB2
1 GB BOOK_TEXT SELECT INTO FROM WHERE BOOK_TEXT :BOOK_TEXT_LOCATOR BOOK_BASE_TABLE BOOK_NO = :HV_BOOK_NO
:BOOK_TEXT_LOCATOR
Internal pointer
123454321 123454321
A LOB locator is an association between a host variable and its corresponding LOB value in DB2 at a point in time. The application only accesses the locator while the entire LOB value resides in DB2 and is not propagated to the application program. Using this technique, an application does not need to acquire a buffer large enough to contain the entire LOB value. Instead, the application deals only with LOB locators, therefore largely reducing the amount of resources to be allocated. The definition and usage are not mandatory; however, considerations on performance soon lead you to the conclusion that it might be a better idea for the applications to use them, because locators dramatically reduce the movement of data between the different address spaces involved in LOB data management as well as greatly reducing connectivity issues.
The DB2 precompiler converts the locator structure into the COBOL structure as reported in Example 2-2 on page 18.
17
Example 2-2 What the DB2 precompiler makes of LOB locators 01 BLOB-LOCATOR 01 CLOB-LOCATOR 01 DBCLOB-LOCATOR PIC S9(9) COMP. PIC S9(9) COMP. PIC S9(9) COMP.
The locator 4-byte value is then stored in a host variable; the program, as already shown in Figure 2-5 on page 17, can use it to refer to a LOB value. Even if every LOB locator shows up identically for all definitions of host variables, DB2 knows the associated LOB type and does not let you use a locator with a different type of LOB. If you define a CLOB locator and try to use it for a BLOB, SQLCODE -171 is issued. You can only use LOB locators inside an application program; you cannot deal with them interactively. This means that you cannot use them, for instance, with SPUFI or QMF. For more information about LOB locators, refer to 4.2, LOB locators on page 75 and 8.1.2, Materialization avoidance techniques on page 243.
18
File reference host variables can be used in applications to insert a LOB from a file into a DB2 table or to select a LOB from a DB2 table into a file. They can be used to update a LOB from a file as well. When you use a file reference variable, you can select or insert an entire LOB value without contiguous application storage to contain the entire LOB. In other words, LOB file reference variables move LOB values from the database server to an application or from an application to the database server without going through the applications memory. Furthermore, LOB file reference variables bypass the host language limitation on the maximum size allowed for dynamic storage to contain a LOB value.
Data length
19
01 MY-BLOB-FILE
The DB2 precompiler converts the declaration into the COBOL structure as reported in Example 2-4.
Example 2-4 What the DB2 precompiler makes of BLOB file reference variable
01 MY-BLOB-FILE. 49 MY-BLOB-FILE-NAME-LENGTH PIC S9(9) COMP-5. 49 MY-BLOB-FILE-DATA-LENGTH PIC S9(9) COMP-5. 49 MY-BLOB-FILE-FILE-OPTION PIC S9(9) COMP-5. 49 MY-BLOB-FILE-NAME PIC X(255). Table 2-4 shows the precompiler generated file option constant declarations. You can use these constants to set the file option variable when you use file reference host variables.
Table 2-4 File option constants Constant name SQL-FILE-READ SQL-FILE-CREATE SQL-FILE-OVERWRITE SQL-FILE-APPEND Constant value 2 8 16 32
20
The new APIs are: SQLBindFileToCol SQLBindFileToCol is used to bind a LOB column in a result set to a file reference allowing the column data to be transferred into a file when the row is fetched. SQLBindFileToParam SQLBindFileToParam is used to bind a parameter marker to a file reference allowing the data from the file to be transferred into a LOB column. An ODBC application can use either the statement attributes or the keyword CURRENTAPPENSCHEM to override the default CCSID setting. If both are specified, the statement attributes override the setting of CURRENTAPPENSCHEM in the INI file. ODBC converts the input file name to the applications encoding scheme before passing it to DB2 for processing.
DSNZPARMs affected
DB2 9 introduces the new parameter MAXOFILR (MAX OPEN FILE REFS) to control the maximum number of data sets that can be open concurrently for processing of LOB file reference. The value setting for the parameter appears on the installation panel DSNTIPE as shown on Figure 2-6 on page 22. Though the default value is 100, the highest number in the range is also effectively limited to the setting of the CTHREAD (MAX USERS) parameter. This limitation exists because a thread can hold at most one file open using file references. With z/OS 1.7, DSMAX can be 64K and even get up to 100K, as you note below.
21
DSNTIPE INSTALL DB2 - THREAD MANAGEMENT ===> Check numbers and reenter to change: 1 DATABASES ===> 100 Concurrently in use 2 MAX USERS ===> 200 Concurrently running in DB2 3 MAX REMOTE ACTIVE ===> 200 Maximum number of active database access threads 4 MAX REMOTE CONNECTED ===> 10000 Maximum number of remote DDF connections that are supported 5 MAX TSO CONNECT ===> 50 Users on QMF or in DSN command 6 MAX BATCH CONNECT ===> 50 Users in DSN command or utilities 7 SEQUENTIAL CACHE ===> BYPASS 3990 storage for sequential IO. Values are SEQ or BYPASS. 8 MAX KEPT DYN STMTS ===> 5000 Maximum number of prepared dynamic statements saved past commit points 9 CONTRACT THREAD STG ===> NO Periodically free unused thread stg 10 MANAGE THREAD STORAGE ===> NO Manage thread stg to minimize size 11 LONG-RUNNING READER ===> 0 Minutes before read claim warning 12 PAD INDEXES BY DEFAULT===> NO Pad new indexes by default 13 MAX OPEN FILE REFS ===> 100 Maximum concurrent open data sets PRESS: ENTER to continue RETURN to exit HELP for more information
Note: APARs PK13287 and PK29281 and z/OS 1.7 GRS SPE allow support of up to 100,000 open data sets. Because some storage needs to be allocated for file processing, the parameter also has some effect on the consumption of storage below the 2 GB bar.
22
Chapter 3.
Creating LOBs
In this chapter, we provide information about how to define and load LOBs. We discuss the following topics: Alternatives in defining LOBs Defining ROWIDs LOBs and LOG activity Additional considerations for creating LOB objects LOBs are different DB2 objects Physical layout of LOBs
23
24
Auxiliary table Auxiliary index If no LOB column is specified, DB2 does not create any auxiliary objects. Note: Automatic creation of objects does not apply to explicitly partitioned tables. An implicitly created table space always defaults to a partitioned-by-growth table space. Note: If the ROWID column is omitted during the CREATE TABLE statement for the base table, DB2 generates a hidden ROWID column for you. See A few more details about the base table on page 32 for a detailed description. See Example 3-1 for a DDL to invoke automatic object creation. This creates a table named BOOK_BASE_TABLE with four columns: two fixed length character (CHAR) columns and two LOB columns. The IN database-name.table-space-name clause defined the table space. The absence of the IN clause now triggers the automatic creation mechanism.
Example 3-1 DDL for a base table resulting in automatic object creation CREATE TABLE BOOK_BASE_TABLE ( BOOK_NO CHAR(10) , DESCRIPTION CHAR(32) , BOOK_TEXT CLOB(500M) , BOOK_COVER BLOB(1M) NOT NOT NOT NOT NULL WITH DEFAULT NULL WITH DEFAULT NULL NULL );
If you use the DDL shown in Example 3-1, DB2 creates the objects listed in Example 3-2.
Example 3-2 Resulting objects for automatic object creation
DSNT360I DSNT361I
-DB9B *********************************** -DB9B * DISPLAY DATABASE SUMMARY * GLOBAL DSNT360I -DB9B *********************************** DSNT362I -DB9B DATABASE = DSN00050 STATUS = RW DBD LENGTH = 4028 DSNT397I -DB9B NAME TYPE PART STATUS PHYERRLO PHYERRHI CATALOG PIECE -------- ---- ----- ----------------- -------- -------- -------- ----BOOKRBAS TS 0001 RW L99TVXZL LS RW L99TW33X LS RW IBOO1ITW IX RW IBOOKRBO IX RW ******* DISPLAY OF DATABASE DSN00050 ENDED ********************** DSN9022I -DB9B DSNTDDIS 'DISPLAY DATABASE' NORMAL COMPLETION DB2 implicitly creates two LOB table spaces named L99TVXZL and L99TW33X, and the auxiliary indexes named IB001ITW and IBOOKRBO. Because we have not specified a base table space, a partitioned-by-growth table space named BOOKRBAS is implicitly created as well. All objects are placed in database DSN00050. Tip: Use REPORT utility to find out about the names DB2 has chosen after you have retrieved the table space name for the base table using SYSIBM.SYSTABLES. For details, see 6.7, REPORT on page 184.
25
Note that even if you create more than one table inside one unit of work using automatic creation of objects, all tables are placed in different databases; therefore, they are also placed in different table spaces. Parts of the names are chosen randomly, so that issuing the DDL in your system most likely results in different names of the affected objects. Note: You cannot create your own table in an implicitly created table space nor can you create your own table space in an implicitly created database. At install time you can use the DSNTIP1 panel, see Figure 3-1, to associate LOBs to a buffer pool (and page size) different from the BP0 default.
DSNTIP1 ===>
1 DEFAULT 4-KB BUFFER POOL FOR USER DATA ===> 2 DEFAULT 8-KB BUFFER POOL FOR USER DATA ===> 3 DEFAULT 16-KB BUFFER POOL FOR USER DATA ===> 4 DEFAULT 32-KB BUFFER POOL FOR USER DATA ===> 5 DEFAULT BUFFER POOL FOR USER LOB DATA ===> 6 DEFAULT BUFFER POOL FOR USER XML DATA ===> 7 DEFAULT BUFFER POOL FOR USER INDEXES ===> Enter buffer pool sizes in number of pages. 8 BP0 ==> 20000 18 BP10 ==> 0 9 BP1 ==> 0 19 BP11 ==> 0 10 BP2 ==> 0 20 BP12 ==> 0 11 BP3 ==> 0 21 BP13 ==> 0 12 BP4 ==> 0 22 BP14 ==> 0 13 BP5 ==> 0 23 BP15 ==> 0 14 BP6 ==> 0 24 BP16 ==> 0 15 BP7 ==> 0 25 BP17 ==> 0 16 BP8 ==> 0 26 BP18 ==> 0 17 BP9 ==> 0 27 BP19 ==> 0 PRESS: ENTER to continue RETURN to exit
BP0 BP8K0 BP16K0 BP32K BP0 BP16K0 BP0 28 29 30 31 32 33 34 35 36 37 BP20 BP21 BP22 BP23 BP24 BP25 BP26 BP27 BP28 BP29
BP0 BP8K0 BP16K0 BP32K BP0 BP16K0 BP0 ==> ==> ==> ==> ==> ==> ==> ==> ==> ==> 0 0 0 0 0 0 0 0 0 0
Figure 3-1 Setting up a default buiffer pool for implicitly defined LOBs
Option 5 defines parameter TBSBPLOB. This DSNZPARM allows the user to specify the default buffer pool to use for LOB table spaces that are created implicitly and for LOB table space that are created explicitly without the BUFFERPOOL clause. USE privilege is required on the specified buffer pool in order to use it by default. The default for this parameter is BP0.
26
Table spaces for the base table and the auxiliary table If a table has a LOB column defined and the base table or the base table space is dropped, the LOB table space is implicitly dropped. If the base table space is explicitly created and the LOB table space is implicitly created, DROP is allowed. Note: If the base table is dropped, all dependent objects created implicitly, including the base table space, are dropped, too. If the last object inside the automatically created database is dropped, the database still remains in your DB2 subsystem and can be explicitly dropped by using a DROP DATABASE statement if you prefer.
Implicit databases
If you do not specify a database name, DB2 implicitly creates a database and generates a name for it. If the number of existing implicitly created databases reaches 60 000, DB2 wraps around and uses an existing database that has been implicitly created by DB2 instead of implicitly creating a new one. Each database that is created implicitly by DB2 can contain multiple table spaces. Trying to create your own objects in automatically created databases or table spaces is not allowed and results in SQLCODE -2035, because this involves one or more implicitly created objects. Restriction: Only an implicitly created table space is allowed to be created in an implicitly created database. If you issue a CREATE TABLE statement without specifying a database name, DB2 does not roll back a successful implicitly created database if any failure occurs during the table or table space creation in this database. Note: On an implicit database creation, DB2 uses SYSIBM as the database creator. Table 3-1 on page 27 shows the attributes used for automatic database creation.
Table 3-1 Attributes for implicit database creation NAME DSNnnnnn (nnnnn = 00001 60000) STOGROUP SYSDEFLT SBCS_CCSID Default: DECP setting BUFFERPOOL Default: TBSBPLOB setting IMPLICIT Y DBCS_SSID Default: DECP setting INDEXBP Default: IDXBPOOL setting ENCODING_SCHEME Default: DECP setting MIXED_CCSID Default: DECP setting
The names of implicitly created databases start with DSN followed by exactly five digits, providing a name range from DSN00001 to DSN60000. If your number of implicitly created databases exceeds 60 000, DB2 looks for an existing DSN00001 and creates all the necessary objects in it. If DSN00001 does not exist, DB2 creates a DSN00001 database and creates the objects in it. DB2 then continues with DSN00002 the next time DB2 objects are created implicitly, and DB2 resumes the incrementing of the last digits, either creating a database or adding another set of objects to the existing database.
27
A buffer pool is associated with the created table space according to the record size. The next larger page size can be chosen if the maximum record size reaches approximately 90% of the capacity of the smaller page size when the default buffer pool is not large enough to support future extensions. The implicitly created table space CCSID is the same as the table CCSID if it is specified in the CREATE TABLE statement. Otherwise, the CCSID associated with the table space is set as the DECP default CCSID value. See Table 3-3 for the default values used by DB2 for the automatic creation of our base table space. You can influence using automatic object creation by the buffer pool specified in DSNZPARM TBSBPOOL, which specifies the default buffer pool for user data and TBSBPLOB which specifies the default buffer pool for LOBs (both set to the default BP0 in our system). The other attributes used for implicitly created objects cannot be changed and can only be altered after the object is created.
Table 3-3 Base table space created using automatic object creation TSNAME BOOKRBAS DSSIZE 4194304 MAXROWS 255 BUFFERPOOL (TBSBPOOL) BP0 PQTY/SQTY 3 / -1 MAXPARTITIONS 256 LOCKSIZE ROW FREEPAGE 0 SEGSIZE 4 LOG YES PCTFREE 5 CLOSE YES GBPCACHE
28
The SQTY of -1 indicates that DB2 uses a sliding scale algorithm to allocate an appropriate amount of space as a secondary extent. See Disk storage access with DB2 for z/OS, REDP-4187, for details about the sliding algorithm used for extent allocation.
Again, the only controlling parameters are the buffer pool specified in panel DSNTIP1 (see Figure 3-1 on page 26). All other parameters can only be altered after the object is created. The name of the LOB table space is an 8-character string every time DB2 creates it for you. For the name of the table space, the first character is an L, followed by seven random characters. If you let the implicitly created base table spaces and LOB table spaces use the same buffer pool ( BP0 in our case), both table spaces use the same page size. Altering a table space buffer pool to a different page size is not supported and requires a DROP TABLESPACE and CREATE TABLESPACE statement. Note that dropping the base table space also drops the auxiliary table and the auxiliary index. A page size 4 KB is generally acceptable for the base table but could be considered small for the LOB table.If you have small LOBs, for instance, a 4,000 byte LOB maximum size, because only one LOB can be stored in one page, larger pages waste disk storage. So, in this case the default is good. If you have large LOBs with recent zSeries hardware and software, the I/O performance difference between a 4 KB page and a 32 KB page is disappearing with MIDAW, so the default is still acceptable. However, if you have large LOBs and no MIDAW, it might be worthwhile assigning them to large pages and large CI sizes and considering striping for best performance. See also 3.4.2, Buffer pools and LOB table spaces on page 57 and 3.4.4, Buffer pool and page size considerations on page 58. Note: Automatic creation of objects only supports partition-by-growth table spaces.
29
Table 3-5 Auxiliary index created using automatic object creation IXNAME IBOOK_BOOK_99TWUYZ PIECESIZE 4194304 IXSPACE IBOOKRBO PQTY/SQTY -1 / -1 BUFFERPOOL (IDXBPOOL) BP0 FREEPAGE 0 CLOSE YES PCTFREE 10
One more time, the only parameter you can influence is the index buffer pool specified in DSNZPARM IDXBPOOL. All other attributes used for implicitly created objects cannot be changed. The name of the auxiliary index is also 18 characters long. The first character of the name is an I. The next ten characters are the first ten characters of the name of the auxiliary table. The last seven characters are generated randomly. The most important reason for DB2 coming up with cryptic names for implicitly created objects is to avoid naming collisions with already existing objects. You should be aware of these conventions so that you can plan for any consequences caused by your existing naming conventions, such as SMS ACS routine refinement and so forth.
30
L9WY757H DSSIZE 4 GB
BP32K PQTY/SQTY 3 / -1
ANY FREEPAGE 0
YES PCTFREE 0
YES GBPCACHE
The name of the LOB table space is an 8-character string every time DB2 creates it for you. The first character is an L, followed by seven random characters. The auxiliary table is created as PAOLO.CLOB_DOCUM1LXA0LID. The table name of the auxiliary table is an 18-character string. The first five characters of the name are the first five characters of the name of the base table. The second five characters are the first five characters of the name of the LOB column. The last eight characters are randomly generated. If a base table name or a LOB column name is fewer than five characters, DB2 adds underscore characters to the name to pad it to a length of five characters. The buffer pool for the auxiliary table space is the default buffer pool for user data defined in your system for 32 KB data pages.
Table 3-7 Auxiliary index created using CURRENT RULES STD IXNAME ICLOB_DOCUM9WBL NG3 PIECESIZE 4194304 IXSPACE ICLOBRDO PQTY/SQTY -1 / -1 BUFFERPOOL BP0 FREEPAGE 0 CLOSE YES PCTFREE 10
The name of the auxiliary index is also 18 characters long. The first character of the name is an I. The next ten characters are the first ten characters of the name of the auxiliary table. The last seven characters are generated randomly. The index has the COPY NO attribute, therefore, full image copies and recover utilities are not allowed. You can also modify an existing table for holding a LOB column using the ADD column option in the ALTER TABLE statement. First, you ADD the ROWID column to your designated base table, then, at the time you ADD the appropriate LOB column with the ADD LOB column statement, DB2 also creates all the needed auxiliary objects, if CURRENT RULES STD is chosen. If CURRENT RULES DB2 is not chosen, you have to create the objects on your own.
31
Note that a ROWID column is omitted and created as a hidden column by DB2.
---------+---------+---------+---------+---------+---------+---------+---------+ NAME COLTYPE HIDDEN LENGTH UPDATES DEFAULT ---------+---------+---------+---------+---------+---------+---------+---------+ DOCUMENT_NR CHAR N 10 Y Y DESCRIPTION CHAR N 32 Y Y DOCUMENT BLOB N 4 Y N DB2_GENERATED_ROWID_FOR_LOBS ROWID P 17 N A
DB2 creates the column with a name of DB2_GENERATED_ROWID_FOR_LOBSnn. DB2 appends nn only if the column name already exists in the table, replacing nn with 00 and incrementing by 1 until the name is unique within the row. The implicitly added column is appended to the end of the row after all of the other explicitly defined columns. For the DB2-generated column containing the ROWID, the value of P for the attribute HIDDEN indicates that the ROWID column is not visible in SQL statements except for explicit reference by column name. Updates for that specific column are not allowed, and it is also created with the GENERATED ALWAYS clause.
32
Note: The ROWID transparency enhancement includes the capability of hiding the ROWID column from DML and DDL. This way, applications running on other platforms that do not have a ROWID data type can avoid the special code to handle ROWID and use the same code path for all platforms. A new message warns about possible conflicting specifications in the definition: DSNT408I SQLCODE = -857, ERROR: SPECIFIED CONFLICTING OPTIONS HIDDEN ROWID HAVE BEEN
The data type ROWID is stored as a VARCHAR (17) column in the base table. It is implicitly one part of the unique index for each auxiliary table containing the LOB columns in the LOB table spaces, where the LOB columns are stored. Even if a base table contains more than one LOB column, only one ROWID column is needed. So, all LOB columns in one row are associated with the same ROWID value. Regarding this procedure, the ROWID column is a unique and permanent identifier for each row in the base table. A ROWID is not the same as a record identifier (RID), which is internally used by DB2 to reflect the position of a row in a table. But you can find the RID as a part of the externalized ROWID when you select the ROWID column. There are three ways of assigning a ROWID to a base table, and these are described in more detail in 3.2, Defining ROWIDs on page 39. In case a ROWID is generated by DB2 at the time when you insert your data, you might need to immediately determine the value that has been generated and inserted into the table for you. The INSERT with SELECT statement provides this capability, enhancing the usability and power of SQL. The associated benefits include reduced network costs and simplified procedural logic in stored procedures, because you are decreasing the number of SQL calls from within your application. See Example 3-5 on page 33 for an example of how to retrieve a generated ROWID value during INSERT processing. Note that the example is based on the DDL provided in Example 3-3 on page 32.
Example 3-5 Retrieving a generated ROWID value at INSERT time
SELECT DB2_GENERATED_ROWID_FOR_LOBS FROM FINAL TABLE (INSERT INTO BOOK_BASE_TABLE (BOOK_NO, DESCRIPTION) VALUES ('SG24-7270-00', 'LOBs - Stronger and Faster')); If there is a requirement in your application to retrieve the rows in the same sequence that they are inserted, the application can use the INPUT SEQUENCE keywords with the ORDER BY clause of the SELECT statement. For more detailed information about this topic, refer to DB2 UDB for z/OS Version 8: Everything You Ever Wanted to Know, ... and More, SG24-6079. In the table definitions of the new data types CLOB (500 MB) and BLOB (1 MB) in Example 3-3 on page 32, DB2 implicitly puts two LOB indicators into the base table definition. Only indicator columns are stored in the base table in place of the actual LOB columns. Note that the only supported default value for a LOB column is NULL.
33
For CLOBs, you can also specify the parameters FOR SCBS, MIXED, or BIT DATA. A CCSID EBCDIC or ASCII can also be specified for CLOBs. For BLOBs and DBCLOBs, this is not supported, because BLOBs contain binary data and DBCLOBs have a graphic CCSID associated with them. A LOB indicator for a LOB column consists of six bytes, and it provides useful information about the stored LOB to DB2 when it accesses the column. The LOB indicators are stored like VARCHAR (4) columns, resulting in a total of 6 bytes, including the length field. Figure 3-2 illustrates the catalog information for the created table.
Catalog description
DB2_GENERATED_ ROWID_FOR_LOBS ROWID (17)
The LOB indicator bytes are made up of a 2-byte length field, a 2-byte flag, and a 2-byte string containing the number of the currently stored version of the LOB. The flag bytes contain a NULL flag, which has the information about a NULL, or even a NOT NULL value assigned to a specific LOB value. Further information retrieved from the flag bytes is the zero length flag, which indicates that a LOB column does not contain any data. Invalid LOB values are also marked invalid using the flag bytes. By referring to this information, DB2 does not have to read the auxiliary table when any of these conditions are true. The remaining two bytes contain the current version of the LOB value. This is stored to detect mismatch situations between the base table and the auxiliary table. For further information about possible mismatches, see 6.12, CHECK LOB on page 206. See Example 3-6 for a brief description of the content of a LOB indicator column.
Example 3-6 Content of LOB indicator columns
Length (Hex) 00 04
Version (Hex) 00 02
At this stage, we have only created the base table using manual object creation. Trying to access the base table now, by using SELECT, UPDATE, INSERT, or DELETE, results in DB2 issuing SQLCODE -747. Access to the base table is not allowed, because the base table is marked as incomplete if at least one dependent object is not defined. The information when a table definition is incomplete is stored in column TABLESTATUS in SYSIBM.SYSTABLES. A value of L indicates a missing auxiliary index or auxiliary table for a LOB column. When the content of the value is R, you have used the GENERATED BY DEFAULT clause for your ROWID column and have not yet created the required single column unique index on that particular column in your base table. A value of blank states a complete table definition.
34
Note: You cannot access the base table using SQL until all dependent objects (LOB table space, auxiliary table, and the auxiliary index) are defined.
NOT LOGGED
LOCKSIZE BUFFERPOOL DSSIZE GBPCACHE
Note: The table space containing the base table has to be in the same database as every associated LOB table space. If the base table space has the NOT LOGGED attribute, the same is mandatory for the associated auxiliary table space. It is overridden by DB2 to NOT LOGGED if specified otherwise. The syntax for creating the auxiliary table space in DB2 9 has changed from LOG YES to LOGGED and from LOG NO to NOT LOGGED. For compatibility reasons, the syntax used in former versions before DB2 9 is still supported. The keyword LOB tells DB2 to create the table space with the new format. You cannot store LOB values in any other than LOB table spaces (for instance, the generic LARGE table space). Specifying the free space parameter (FREESPACE and PCTFREE) has no influence with LOBs. The second LOB table space holding the CLOB column is created in a similar way. Every LOB column needs its own LOB table space. Partitioning of LOB table spaces is not allowed, but they are divided in pagesets in accordance with the partitioned base table definition. Compression is not supported for LOB table spaces. For a more detailed description of how the data is stored in a LOB table space, see 3.6, Physical layout of LOBs on page 63. Note: You cannot create a LOB table space inside a work file database.
35
Example 3-8 DDL for an auxiliary table CREATE AUXILIARY IN STORES COLUMN TABLE BLOB_AUX_TABLE_1 LOBDB.BLOBATS1 BOOK_BASE_TABLE BOOK_COVER;
This statement creates the auxiliary table BLOB_AUX_TABLE_1 in the LOB table space created in Creating the LOB table space on page 35. The other auxiliary table storing the CLOB column is created in a similar way. There is no need to specify column names or column types for auxiliary tables. Using the STORES clause tells DB2 what column of which base table you want to store in the created auxiliary table. The associated table consists of only one column, the LOB column. Note: A LOB table space and its associated base table space must be stored in the same database. Otherwise, SQLCODE -764 is issued. If the referenced base table is partitioned, there must be a LOB table space and an auxiliary table for each LOB column in each partition of the base table. In this case, Example 3-9 shows sample DDL for creating the auxiliary table.
Example 3-9 DDL for an auxiliary table containing data of one base table partition CREATE AUXILIARY IN STORES COLUMN PART TABLE BLOB_AUX_TABLE_1 LOBDB.BLOBATS1 BOOK_BASE_TABLE BOOK_COVER n;
The PART clause indicates which partitions BOOK_COVER column you want to store in this auxiliary table, where n is the number of the partition. FIELDPROCs, EDITPROCs, VALIDPROCs, and check constraints cannot be defined on LOB columns.
36
Catalog description
AUXID VARCHAR (17) AUXVER SMALLINT (2) AUXVALUE BLOB (4)
LENGTH2 = 1,048,576
No index columns are defined within this index, because DB2 automatically creates the key definition. The index definition consists of a two key value: The 17-byte system generated ROWID stored as VARCHAR, and a 2-byte version of the LOB stored as SMALLINT, for 21 bytes in total (including the 2-byte length field for VARCHAR columns). No index keys can be defined. If you even try to specify a key column, DB2 issues SQLCODE -767, missing or invalid column specification for an index. Figure 3-4 on page 37 shows the key columns of an auxiliary index.
Auxiliary Index
Figure 3-4 Index keys for an auxiliary index
37
Note: You cannot define an index on a LOB column. DB2 V7 uses the index on the auxiliary table to locate a LOB value for a particular row containing a LOB within the base table. An index defined on an auxiliary table is automatically defined as a unique index, fed by a ROWID from the base table. The buffer pool that you might want to assign to this index does not need any special considerations, because the index only contains two relatively small columns.
A table can only have one ROWID column, and you cannot add a ROWID column to a created temporary table. Important: If you add a LOB column prior to a ROWID column, DB2 generates a hidden ROWID column.
38
As described in 3.2, Defining ROWIDs on page 39, we recommend that you always generate ROWIDs by using DB2s mechanism. Specifying GENERATED BY DEFAULT generates a ROWID only if no value for the ROWID column is provided while inserting into the table. If a value for a ROWID column is provided, DB2 takes it and inserts the value into the base table. By providing a value for a ROWID column, for instance, when moving data across two DB2 subsystems, it is unlikely, but it might happen, that DB2 generates a ROWID that is already stored in the table. Because the GENERATED BY DEFAULT clause always requires a unique index on that column, an insert with a DB2-generated ROWID value can result in SQLCODE -803. In this case, it is your responsibility to resolve the duplication. Once a column of data type ROWID is added, you can proceed with creating the LOB columns using the alter table statement shown in Example 3-13.
Example 3-13 Adding a LOB column ALTER TABLE NEW_LOB_TABLE ADD PICTURE BLOB(1M) NOT NULL WITH DEFAULT;
Adding a LOB column is not allowed for created temporary tables. The same is true when adding ROWID columns. Instead of specifying BLOB (1M), such as in this example, you can use the ALTER to define any other possible LOB column type to DB2. After you have added the designated LOB columns to the base table, you should continue with the same actions shown earlier starting with Creating the auxiliary table on page 35. Remember that only one ROWID column is needed, even if you want to add more than one LOB column to the base table. Note: When you add one or more LOB columns to the base table, the table is marked incomplete until all dependent objects are created. We recommend setting up your LOB environment using manual creation of all necessary objects if you want to influence the parameters that are involved. For most other needs, use automatic object creation to reduce the overhead of creating all the necessary objects by yourself since it fits most needs.
39
Rows represent LOBs LOBs stored outside base table in auxiliary table Base table space may be partitioned
If so, separate LOB table space for each part
A base table can be associated with many LOB or auxiliary columns of different types and lengths. Each auxiliary column is stored in its own auxiliary LOB table in its own LOB table space. An auxiliary index must be created on every auxiliary table before it can be used. To create a base table that contains a LOB column, you must define a ROWID column. The ROWID acts as, but it is not, a bidirectional pointer to the LOB data associated with the particular row: the LOB column values are associated with the proper base table row in both directions using the base table rows ROWID value. The auxiliary index, whose key is based on the ROWID, is used to navigate to LOB data associated with the row. If a base table that contains LOB data is partitioned, you create a separate LOB table space and auxiliary table for each LOB column in each partition. A LOB table space can have a page size of 4, 8, 16, or 32 KB. Because the length of a LOB can exceed 32 KB, it is clear that a LOB can span physical pages, and because there is only one row per page, with LOBs, rows can span pages. LOB pages only contain one LOB value, or row. Starting from DB2 V8, users have the choice of defining a ROWID explicitly or leaving it to be defined implicitly by DB2 during creation of the table. This functionality is frequently referred to as ROWID transparency feature.
40
If you omit an explicit ROWID definition while a LOB column is present in your CREATE TABLE statement, DB2 creates a ROWID column using GENERATED ALWAYS method for you. Using the GENERATED ALWAYS keyword, DB2 always generates a ROWID when inserting a row. Applications and users are not allowed to insert a ROWID. If you use GENERATED BY DEFAULT, users and applications can supply a value for a ROWID column as long as the value was previously generated by DB2 and a unique, single column index that exists on the ROWID column. DB2 checks that the value you are going to insert is a valid ROWID. It is not sufficient to provide unique numbers yourself. You should only use this parameter when inserting data from another table for the purpose of moving data. The recommended usage is GENERATED ALWAYS, either explicitly specified or implicitly by omitting ROWID from the CREATE TABLE statement. As mentioned, you have to create a unique index on the ROWID column when you specify GENERATED BY DEFAULT. Make sure that it is not possible to use the GENERATED ALWAYS clause before implementing GENERATED BY DEFAULT, because the additional index on a table can increase your response time for inserting and deleting transactions on the base table. The index is not affected by an UPDATE statement, because the ROWID is not updateable. If you try to update a ROWID column, DB2 issues SQLCODE -151, because the catalog description indicates that this column cannot be updated. Important: When you specify GENERATED BY DEFAULT for a ROWID column, make sure that a single column unique index exists on your ROWID column. ROWID values can never contain null values, so the ROWID column has to be defined as NOT NULL. Be aware that a ROWID column implies some restrictions, preventing the values in the column from being manipulated: Users are not allowed to update a ROWID column. Null values cannot be assigned to ROWID columns. EDITPROCs, FIELDPROCs, and CHECK CONSTRAINTs are not allowed for ROWIDs. It is not allowed to load a single partition or a range of partitions if a column of data type ROWID is part of the partitioning key. A value for ROWID is stored in the base table data page even if all LOB columns are NULL. The ROWID column is stored as a VARCHAR (17) column. The length of a ROWID column as described in the LENGTH column of catalog table SYSCOLUMNS is the internal length, which is 17 bytes. The length as described in the LENGTH2 column of catalog table SYSCOLUMNS is the external length, which is 44 bytes. A value for a ROWID is never subject to character conversion, because it is considered to contain BIT data. To give you a better understanding of the different occurrences of a ROWID, consider the following scenarios:
41
Example 3-14 DDL for a table containing a ROWID column CREATE TABLE CUSTOMER ( CUSTNO CHAR(10) , CUSTNAME CHAR(32) , ROW_ID ROWID NOT NULL WITH DEFAULT NOT NULL WITH DEFAULT NOT NULL GENERATED ALWAYS );
Now you insert a row into the CUSTOMER table, as shown in Example 3-15, without providing the ROWID column, because it is generated by DB2 at insert time.
Example 3-15 Inserting a row in CUSTOMER table INSERT INTO CUSTOMER (CUSTNO, CUSTNAME) VALUES (0000001406, REGINA RICHARDSON);
After a new table is created, all CUSTNOs being inserted are associated with a unique ROWID value. After you insert a row (at this point in time, a ROWID is associated with the inserted row), a SELECT CUSTNO,CUSTNAME,ROW_ID returns the result set shown in Example 3-16.
Example 3-16 ROWID value of a table created with ROWID column ---------+---------+---------+---------+---------+---------+---------+---------+ CUSTNO CUSTNAME ROW_ID ---------+---------+---------+---------+---------+---------+---------+---------+ 0000001406 REGINA RICHARDSON D6DE97EE118FD4252104015C56300100000000004201
The generated ROWID is externalized as a 44 byte value (40 bytes of data plus length fields), but stored as VARCHAR (17). Example 3-17 shows the output of the DSN1PRNT utility of the HEX values for the ROWID with DB2 9 for z/OS.
Example 3-17 DB2 9 DSN1PRNT of ROWID in hex value 002C D6DE97EE 118FD425 2104015C 5630
Note that the value 0100000000004201 is generated at SELECT time. In DB2 9 for z/OS, the value of 002C in our example gives you the offset within the row of the variable length column containing the ROWID. It varies, depending on the other columns defined in your table, since DB2 9 introduces Reordered Row Format (RRF), a performance improvement for access to data in tables that contain columns of varying length. The format in which the row is stored in the table is changed from V8 to optimize column location for data retrieval and for predicate evaluation. In DB2 V8, the output of DSN1PRNT is similar to the output in Example 3-18.
Example 3-18 DB2 V8 DSN1PRNT of ROWID in hex value 000E D6DE97EE 118FD425 2104015C 5630
In DB2 V8, the value 000E declares the length of the ROWID column, which is 000E in HEX and 14 in decimal. Comparing the information stored in the DB2 catalog for DB2 V8 and DB2 9, ROWIDs are stored as VARCHAR (17) columns: in both versions of DB2, there are three bytes left for future extensions of ROWIDs.
42
Note: A ROWID column must be defined using NOT NULL. When you add a ROWID column, the NOT NULL attribute contradicts the normal usage of ALTER. In fact when ALTERing non-ROWID columns, you must specify NOT NULL WITH DEFAULT. The ALTER TABLE statement does not affect any columns stored in the table, so no ROWID is stored up to now. If you do a SELECT on CUSTNO,CUSTNAME,ROW_ID...FETCH FIRST 1 ROW, you receive the result set of Example 3-20.
Example 3-20 ROWID value of a table where a ROWID column was added ---------+---------+---------+---------+---------+---------+---------+---------+ CUSTNO CUSTNAME ROW_ID ---------+---------+---------+---------+---------+---------+---------+---------+ 0000001406 REGINA RICHARDSON 4200000080000106000D020100000000004201
The ROWID now only consists of 38 bytes, compared to the previously mentioned ROWID of 44 bytes. If you use DSN1PRNT again to look into your table space, you do not find any value for the ROWID column inside your table space. When you select the ROWID value, it is only generated at SELECT time, and stored inside your host variable. You can select the ROWID for a specific row several times, and the value in the ROWID column never changes. The first time you update the row, the ROWID is physically stored in the table, with the same value delivered to you by DB2 when you selected the row before. This behavior is the same for DB2 V8 and DB2 9. When you use DSN1PRNT again after you have performed an UPDATE on the row, in DB2 9 you see the results of Example 3-21 on page 43.
Example 3-21 DB2 9 DSN1PRNT of ROWID in hex value after adding and updating a row 002C 42000000 80000106 000D02
Again, the value 002C declares the offset of the ROWID column. If other VARCHAR columns are stored in your table after the ROWID, other offsets follow the 002C before the ROWID value begins. You can find the output of DSN1PRNT in DB2 V8 for the same scenario in Example 3-22.
Example 3-22 DB2 V8 DSN1PRNT of ROWID in hex value after adding and updating a row 000B 42000000 80000106 000D02
43
In case you use DB2 V8, the value of 000B declares the length of the ROWID column, which means 11 in a decimal value. Adding the two byte length field, as usual, we now have a ROWID column made of 13 bytes. So, if an already existing row is updated and no ROWID value is stored for the updated row up to now, the new ROWID is at least 11 bytes plus the two byte length field. Let us now have a close look at the new rows, which are inserted after the ROWID column was added to the table. All rows that are inserted after the ROWID column was added to the table have a ROWID of length of 14 bytes plus two additional bytes for the length field. The first row shown in Example 3-23 represents the ROWID value for an old row being updated after ROWID was added to the table. It is important to know that this row already had been in the table before the ROWID column was added. The second row shows the ROWID value for a new row inserted after the ROWID column was added.
Example 3-23 ROWID values of updated and inserted columns ---------+---------+---------+---------+---------+---------+---------+---------+ CUSTNO CUSTNAME ROW_ID ---------+---------+---------+---------+---------+---------+---------+---------+ 0000001406 MRS. RICHARDSON 4200000080000106000D020100000000004201 0000001423 MR. KLINGEN 647667FA918FDE192104015C56300100000000004202
If a number of n rows have been in the table before a ROWID column is added, there is a number of n different ROWIDs after ALTER. Each updated row existing before the ALTER has its own unique value. In Example 3-24, you can find the DSN1PRNT output for both ROWID values:
Example 3-24 DB2 9 DSN1PRNT of updated and inserted ROWIDs in hex value 002C 42000000 80000106 000D02 002C 647667FA 918FDE19 2104015C 5630
In conclusion, it is possible that no ROWID value is stored in the table space even if a ROWID column exists in the table, and you can find two different lengths of ROWIDs even if they are stored in the table, depending on when the ROWID column was added to the table and whether or not the row existed at that time. Be careful when altering a table to have a ROWID column, because pre-ALTER rows might never have a value that can be used by code that relies on ROWID value to go directly to the row. ROWID should then be selected and stored somewhere and used for future access when contained in a host variable. After CREATE TABLE, INSERT n ROWS, ALTER ADD ROWID, you SELECT ROWIDs and store them, then the application selects data using the ROWIDs retrieved by the previous SELECT. The output in DB2 V8 is in Example 3-22 on page 43, again preceded by the current length fields 000B and 000E.
Example 3-25 DB2 V8 DSN1PRNT of updated and inserted ROWIDs in hex value 000B 42000000 80000106 000D02 000E 647667FA 918FDE19 2104015C 5630
44
ROWID is a data type that can be used outside LOBs. ROWID gives you guaranteed unique values. This can be useful for applications and table designs where artificial keys have to be generated by the application to ensure uniqueness of a particular row. Using a ROWID column, DB2 is able to handle this special requirement for you. The ROWID behavior, that the first bytes in general appear to be pseudo-random, has made a ROWID column a solution for a partitioning key, which spreads your data randomly across partitions. However, with the separation of attributes for indexes in DB2 V8 and the introduction of new partition definitions in DB2 9, there are other means to obtain similar results. Using a ROWID as a partitioning key is not a good idea when you have to process your data in the order of another key value.
45
space. The force at commit protocol ensures that LOB values persist after a unit of work is committed, because NOT LOGGED LOB values are written at COMMIT. LOB data associated with a LOB table space defined with LOGGED option is written to disk, like for other data, when buffer pool thresholds are reached. LOGGED is the default value when you create your LOB table space. For information about the logging impact when running the Load utility, see 6.3, LOAD on page 173.
46
point, the table spaces are no longer linked. When a LOB table space logging attribute is linked to its base table space logging attribute, the link can also be broken by explicitly altering the LOB table space attribute to NOT LOGGED, even though it already has been implicitly given the NOT LOGGED attribute when its base table space attribute was altered to NOT LOGGED. While it might seem redundant to alter a NOT LOGGED LOB table space to NOT LOGGED, this is provided to allow you to break the link between the logging attributes of a LOB table space and its base table space. If the LOG column of the SYSIBM.SYSTABLESPACE catalog table record for a LOB table space has the value of X, it means that the logging attributes of the LOB table space and its base table space are linked, and that the logging attribute of both table spaces is NOT LOGGED. To break the link, alter the base table space attribute back to LOGGED, which results in both table spaces logging attribute being changed back to LOGGED. Table 3-8 shows the progression of the DB2 catalog SYSIBM.SYSTABLESPACE LOG column values through a set of ALTER TABLESPACE statements that alter the logging attribute of a base table space and two LOB table spaces associated with a table in the base table space. The values are: Y - Logged N - Not Logged X - Not Logged, linked to base In our scenario, we assume that initially all table spaces have been created using the LOGGED attribute.
47
Table 3-8 LOG column values scenarios LOGGED attribute ALTER Initially all LOGGED LOB 2 NOT LOGGED Base to NOT LOGGED LOB 2 to LOGGED Base to LOGGED LOB 2 to LOGGED Base to NOT LOGGED Base to logged Base to NOT LOGGED LOB 2 to NOT LOGGED Base to LOGGED Base table space Y Y N N Y Y N Y N N Y LOB table space 1 Y Y X X Y Y X Y X X Y LOB table space 2 Y N N N N Y X Y X N N LOB 1 and LOB 2 linked to base LOB 1 and LOB 2 link dissolved LOB 1 and LOB 2 linked to base LOB 2 link dissolved LOB 1 link dissolved LOB 1 linked to base Rejected, SQLCODE -763 LOB 1 link dissolved Notes
If the table space is opened for update while it has the NOT LOGGED attribute, the table space is placed in the Informational Copy Pending state. The DISPLAY DATABASE ADVISORY command is enhanced to display the Informational Copy Pending state for table spaces in the database as shown in Example 3-26.
Example 3-26 DISPLAY DATABASE sample output
DSNT360I DSNT361I DSNT360I DSNT362I DSNT397I NAME -------TPIQUQ01 TPIQUQ01 TPIQUQ01 TPIQUQ01
-DB9B *********************************** -DB9B * DISPLAY DATABASE SUMMARY * ADVISORY -DB9B *********************************** -DB9B DATABASE = DSN8D91L STATUS = RW DBD LENGTH = 8066 -DB9B TYPE PART STATUS PHYERRLO PHYERRHI CATALOG PIECE ---- ----- ----------------- -------- -------- -------- ----TS 001 RW,AUXW TS 002 RW,AUXW TS 003 RW,AUXW TS 004 RW,ICOPY
48
The LRSN in these SYSIBM.SYSCOPY records reflects the point in the log at which the logging attribute was altered. When updates on a NOT LOGGED object are rolled back or the thread is canceled prior to commit, the space state of base tables and auxiliary indexes is changed to RECP (Recovery Pending) and the affected pages are added to the LPL list. To remove these objects from the LPL and reset recover pending (RECP), use any of the following: The RECOVER utility, to recover either to most recent recoverable point or to a prior image copy. LOAD REPLACE or LOAD REPLACE PART, either with an input data set to repopulate the table, or without one so that INSERT can repopulate the table. Drop and recreate the table space and repopulate the table. Use Delete without a WHERE clause or new TRUNCATE statement (restrictions apply). For more information about the recovery issues, see 7.2, Recovery strategies and considerations on page 221. See 7.1, LOBs in the DB2 catalog on page 214 for more information about the recognition of LOBs in the DB2 catalog.
49
t
Delete LOB 2 Recover to currency
Log
Log
Log
Log
Insert LOB 1
Update LOB 3
t
Full Image Copy Delete LOB 2 Recover to currency
Log
Figure 3-6 Applying changes to a LOB table space created with NOT LOGGED
This can be a DB2 V8 scenario where you have chosen not to log the LOB table space, while the base table is logged anyway. A full Image Copy is taken of a base table space and the associated LOB table spaces. After completion of the full Image Copies, one LOB is inserted, another one is deleted, and a third one is updated. Assume now that you have to recover the base table space and the LOB table space after all updates are done because of a system failure. For the base table, DB2 can apply all necessary changes from the log. Recovering the LOB table space for DB2 is more difficult with a specified NOT LOGGED option.
50
Inserted LOB
After using the full image copy, DB2 notices that a new LOB was inserted without writing any logs about its value. So the new LOB is marked invalid in the auxiliary table.
Deleted LOB
DB2 knows from the logged system pages what has happened and marks the pages formerly used by LOB number 2 as available. So recovery is possible for deleted LOBs.
Updated LOB
Since UPDATE consists of DELETE and INSERT, the pages are deallocated in the LOB table space. Not having log records to apply for the new LOB value, it is also marked as invalid in the LOB table space. In our case, the LOB table space is set in a new AUX WARNING (AUXW) state for the inserted and updated LOB values. Trying to access an invalid LOB value results in SQLCODE -904. For more information about recovery scenarios, see 7.2, Recovery strategies and considerations on page 221. If you decide to use the NOT LOGGED option on the base table, make sure that image copies of the base table space and all its auxiliary table spaces you take are in sync. Recommendation: COPY base table space, COPY YES indexes, and COPY LOB table spaces (and XML table spaces) in the same COPY invocation with SHRLEVEL REFERENCE to ensure that they all share the same recoverable point. COPY does not allow SHRLEVEL(CHANGE) on NOT LOGGED table spaces.
0000893EABE2
URID(0000893EABE2) LRSN(BF3BF2C96624) TYPE(UR CONTROL) SUBTYPE(BEGIN UR) URID(0000893EABE2) LRSN(BF3BF2C966C8) DBID(014A) OBID(0007) PAGE(00000007) TYPE( UNDO REDO ) SUBTYPE(ALLOC/DEALLOC OF SPACE IN LOB SPACE MAP PAGE) CLR(NO) PROCNAME(DSNODEAL)
0000893EB068
51
0000893EB1B4
URID(0000893EABE2) LRSN(BF3BF2C966CB) DBID(014A) OBID(000B) PAGE(00000003) TYPE( REDO ) SUBTYPE(TYPE 2 INDEX UPDATE) CLR(NO) PROCNAME(DSNKPDGB) URID(0000893EABE2) LRSN(BF3BF2C966CB) OBID(000B) PAGE(00000003) TYPE( UNDO SUBTYPE(TYPE 2 INDEX UPDATE) CLR(NO) PROCNAME(DSNKDLE ) DBID(014A) REDO )
0000893EB2A6
0000893EB321
URID(0000893EABE2) LRSN(BF3BF2C966CE) DBID(014A) OBID(0007) PAGE(00000005) TYPE( UNDO REDO ) SUBTYPE(ALLOC/DEALLOC OF SPACE IN LOB SPACE MAP PAGE) CLR(NO) PROCNAME(DSNOALLO) URID(0000893EABE2) LRSN(BF3BF2C966CF) DBID(014A) OBID(0007) PAGE(00000006) TYPE( UNDO REDO ) SUBTYPE(ALLOC/DEALLOC OF SPACE IN LOB SPACE MAP PAGE) CLR(NO) PROCNAME(DSNOALLO) URID(0000893EABE2) LRSN(BF3BF2C966D0) DBID(014A) OBID(0007) PAGE(00000085) TYPE( REDO ) SUBTYPE(LOB MAP CHANGE) CLR(NO) PROCNAME(DSNOFLMP) URID(0000893EABE2) LRSN(BF3BF2C966D1) DBID(014A) OBID(0007) PAGE(00000085) TYPE( REDO ) SUBTYPE(LOB DATA PAGE CHANGE) CLR(NO) PROCNAME(DSNOLINS) . . . URID(0000893EABE2) LRSN(BF3BF2C9674B) DBID(014A) OBID(0007) PAGE(000000EB) TYPE( REDO ) SUBTYPE(LOB DATA PAGE CHANGE) CLR(NO) PROCNAME(DSNOLINS) URID(0000893EABE2) LRSN(BF3BF2C96FE9) TYPE(UR CONTROL) SUBTYPE(BEGIN COMMIT1) URID(0000893EABE2) LRSN(BF3BF2C96FED) TYPE(UR CONTROL) SUBTYPE(PHASE 1 TO 2) URID(0000893EABE2) LRSN(BF3BF2C97061) TYPE(UR CONTROL) SUBTYPE(END COMMIT2)
0000893EB3AF
0000893EB41F
0000893EB4E8
000089452DC8
0000894601CB
000089460235
000089460269
On the other hand, the NOT LOGGED table space update looks as shown in Example 3-28. You can also see the pageset indicated as Information Copy pending.
Example 3-28 DSN1LOGP output for not logged LOB insert
0000894FAD8D
URID(0000894FAD8D) LRSN(BF3BF3D57D02) TYPE(UR CONTROL) SUBTYPE(BEGIN UR) URID(0000894FAD8D) LRSN(BF3BF3D5900E) OBID(0007) TYPE( REDO ) DBID(014A)
0000894FB1BA
52
SUBTYPE(DBE TABLE WITH EXCEPTION DATA) REDO: DSN8D91L.DSN8S91L ICOPY 0000894FB239 URID(0000894FAD8D) LRSN(BF3BF3D59010) DBID(014A) OBID(0007) PAGE(00000005) TYPE( UNDO REDO ) SUBTYPE(ALLOC/DEALLOC OF SPACE IN LOB SPACE MAP PAGE) CLR(NO) PROCNAME(DSNODEAL) URID(0000894FAD8D) LRSN(BF3BF3D59034) DBID(014A) OBID(0007) PAGE(00000001) TYPE( UNDO REDO ) SUBTYPE(LOB HIGH LEVEL SPACE MAP PAGE UPDATE) CLR(NO) PROCNAME(DSNODEAL) URID(0000894FAD8D) LRSN(BF3BF3D5905A) DBID(014A) OBID(0007) PAGE(00000006) TYPE( UNDO REDO ) SUBTYPE(ALLOC/DEALLOC OF SPACE IN LOB SPACE MAP PAGE) CLR(NO) PROCNAME(DSNODEAL) URID(0000894FAD8D) LRSN(BF3BF3D59061) DBID(014A) OBID(0007) PAGE(00000005) TYPE( UNDO REDO ) SUBTYPE(ALLOC/DEALLOC OF SPACE IN LOB SPACE MAP PAGE) CLR(NO) PROCNAME(DSNOALLO) URID(0000894FAD8D) LRSN(BF3BF3D59061) DBID(014A) OBID(0007) PAGE(00000001) TYPE( UNDO REDO ) SUBTYPE(LOB HIGH LEVEL SPACE MAP PAGE UPDATE) CLR(NO) PROCNAME(DSNOALLO) URID(0000894FAD8D) LRSN(BF3BF3D59064) DBID(014A) OBID(0007) PAGE(00000015) TYPE( REDO ) SUBTYPE(LOB MAP CHANGE) CLR(NO) PROCNAME(DSNOFLMP) URID(0000894FAD8D) LRSN(BF3BF3D5BCD9) TYPE(UR CONTROL) SUBTYPE(BEGIN COMMIT1) URID(0000894FAD8D) LRSN(BF3BF3D5BE6C) TYPE(UR CONTROL) SUBTYPE(PHASE 1 TO 2) URID(0000894FAD8D) LRSN(BF3BF3D5BEEC) TYPE(UR CONTROL) SUBTYPE(END COMMIT2)
0000894FB2C7
0000894FB307
0000894FB421
0000894FB4C3
0000894FB503
0000894FCAB2
0000894FD155
0000894FD189
53
depending on the type of data you plan to store in your large objects. See Figure 3-7 on page 54. One area where this sort of environment exists is in data centers of multinational companies and even more in e-business environments. In both of these examples, a geographically diverse group of users interact with a central server, storing and retrieving data. Today, there are hundreds of different encoding systems. No single encoding could contain enough characters: for example, the European Union alone requires several different encoding schemes to cover all of its languages. Even for a single language such as English, no single encoding was adequate for all the letters, punctuation, and technical symbols in common use.
CCSID 850
CCSID 500
These encoding systems also conflict with one another. That is, two encoding schemes can use the same codes for two different characters, or use different codes for the same character. Figure 3-8 gives you a good example of the described case.
54
It is likely that LOBs are being moved to the mainframe from other platforms and even other geographies, because more businesses are spread geographically all over the world. In these cases, a verification of the needed data conversion is absolutely necessary, unless you decide to use the Unicode support as introduced with DB2 Version 8. Different LOBs are suitable for different tasks. BLOBs are designed to contain binary data. As such, they have no CCSID associated with them. CLOBs and DBCLOBs are designed to contain text data. CLOBs have the normal single byte and mixed CCSIDs associated with them, while DBCLOBs have the graphic CCSID associated with them. The old mechanism of code page translations is still valid in most of the cases. For encoding and decoding, DB2 first accesses the SYSIBM.SYSSTRINGS table. If the conversion cannot be resolved, DB2 turns to z/OS Unicode Conversion Services. This mechanism is constantly updated and improved to make the conversion more efficient. See DB2 UDB for z/OS Version 8 Performance Topics, SG24-6465, for more information. Unicode provides a unique number for almost every character, on any platform, in any language, and by any program. The Unicode character encoding standard is a character-encoding scheme that includes characters from almost all living languages. It is an implementation of the ISO-10646 standard. There are several popular implementations of the Unicode standard such as: UCS-2 - Universal Character Set coded in 2 octets. UCS-4 - Universal Character Set coded in 4 octets. This becomes UTF-32. UTF-8 - Unicode Transformation Format for 8 bit (ASCII safe Unicode). Characters are encoded in 1 to 6 bytes. UTF-16 - Unicode Transformation Format for 16 bits. The format is a superset of UCS-2 and contains an encoding form that allows more than 64 KB characters to be represented.
55
DB2 V7 support for Unicode provides the most popular implementations of Unicode: UTF-8 and UTF-16. CHAR, VARCHAR, LONG VARCHAR, and CLOB data for SBCS data is stored as ASCII (7 bit) CODE CCSID 367. CHAR, VARCHAR, LONG VARCHAR, and CLOB data for mixed data is stored as UTF-8 (Unicode CCSID 1208). GRAPHIC, VARGRAPHIC, LONG VARGRAPHIC, and DBCLOB data is stored as UTF-16 (Unicode CCSID 1200). If you are working with character string data in UTF-8, you should be aware that ASCII characters are encoded into one byte lengths. However, non-ASCII characters, for example, Japanese characters, are encoded into two or three byte lengths in a multiple-byte character code set (MBCS). Therefore, if you define an 'n' bytes length character column, you can store strings anywhere from 'n/3' to 'n' characters depending on the ratio of ASCII to non-ASCII character code elements. DB2 cannot use the table SYSIBM.SYSSTRINGS for conversion to and from Unicode CCSIDs. Instead, DB2 uses z/OS Conversion Services to manage all of the conversions to and from Unicode CCSIDs. Use the links in Table 3-10 on page 56 for additional information about Unicode with DB2:
Table 3-10 DB2 Unicode support - Additional useful resources Title Unicode site The Unicode character code charts DB2 Version 9.1 for z/OS SQL Reference, SC18-9854, Section on Character Conversion DB2 Version 9.1 for z/OS Installation Guide, GC18-9846, Appendix A. Character conversion DB2 9 for z/OS Internationalization Guide z/OS support for Unicode: Unicode Services, SA22-7649 DB2 V7 and V8 Unicode support Unicode performance in DB2 for z/OS All for One and One for All - Part 1 All for One and One for All - Part 2 Link http://www.unicode.org http://www.unicode.org/charts http://www.ibm.com/software/data/db2/zos/v9books.html
http://www.ibm.com/software/data/db2/zos/v9books.html
Note: Character conversion with LOBs causes LOB materialization. Avoid it. For more information and materialization avoidance tips, refer to 8.1, LOB materialization on page 240.
56
57
Note: Starting with DB2 9, LOBs up to 2 GB in size are eligible for logging, so all LOBs are able to be logged. Previously, the limit was 1 GB.
Using this technique, a LOB value of 22 KB means 10 KB of unused space, but only one getpage request for DB2. Therefore, you have to analyze your data to determine what is best for you and your LOBs. Normally, you have 32 KB data pages assigned to your LOB table space, because you should use LOBs only for real large objects. By using Modified Indirect Addressing Words (MIDAW), the impact of performance for getpages using different page sizes can be minimized. IBM z/OS 1.7 support for IBM z9 systems includes a new function that supports MIDAW. The z9 implements a new function for channel programming called modified indirect addressing words. MIDAWs can be used to move data over FICON and ESCON channels. For FICON channels, this support can provide substantially better response time while increasing overall channel bandwidth. MIDAWs exploitation by z/OS is expected to improve performance for some DB2 table scan, DB2 sequential prefetch, BSAM, and extended-format data set operations by reducing system overhead for I/O requests, with no application changes. Therefore, the page size for the LOB table space can become less important from a performance point of view. For more information, see How does the MIDAW facility improve the performance of FICON channels using DB2 and other workloads?, REDP-4201. If your LOB data is all the same size, it might be easier to choose a page size that makes more efficient use of data pages without impacting performance. For LOBs that are all the same size, consider Table 3-12, which maximizes space savings without sacrificing performance.
58
Table 3-12 Choosing a LOB page size for LOBs that are all the same size LOB size (LS) LS < 4 KB 4 KB < LS < 8 KB 8 KB < LS < 12 KB 12 KB < LS < 16 KB 16 KB < LS < 24 KB 24 KB < LS < 32 KB 32 KB < LS < 48 KB 48 KB < LS Recommended page size for LOB table space 4 KB 8 KB 4 KB 16 KB 8 KB 32 KB 16 KB 32 KB
Also, see buffer pool considerations and buffer pool thresholds (DWQT and VDWQT) in 8.3, Buffer pools and group buffer pools on page 246, for more information about this topic. If you have decided on the page size you want to use, DB2 allocates at least n KB of space even if you tell DB2 to allocate less than the minimum amount of space for that page size. Table 3-13 provides information about the minimum space requirements for primary (PRIQTY) and secondary (SECQTY) quantity, and how they might change from your specification. This reflects the DB2 expectation that LOB objects are going to be used as they are intended, that is, for LARGE objects, and prepares the environment accordingly.
Table 3-13 Primary and secondary quantity with LOBs PRIQTY and SECQTY Specification in KB < 200 < 400 < 800 < 1 600 > 4,194,304 Page size 4 KB 8 KB 16 KB 32 KB Any Resulting allocation in KB 200 400 800 1,600 4,194,304
59
Table 3-14 Summary of data set, partition, and partitioned table space sizes DB2 version V8 and 9 Number of partitions 4,096 Maximum size each 64 GB Total maximum size 65,536 TB
Note: DSSIZE specifies the maximum size for each partition, or for LOB table spaces, for each data set. If you specify DSSIZE, you must also specify NUMPARTS, MAXPARTITIONS, or LOB clause. DSSIZE and SMS-managed table spaces are required.
Since each LOB table space can consist of 254 data sets, you can reach the maximum amount of 16,256 GB (approximately 16 TB) for a single LOB column in one LOB table space. Considering a partitioned base table with 4,096 partitions, these 16,256 GB can occur up to 4,096 times (one LOB table space for each partition of the base table), so you can have 66,584,576 GB or 65,536 TB for one single LOB column. For LOB table spaces, if DSSIZE is not specified, the default for the maximum size of each data set is 4 GB. The maximum number of data sets is 254. This means a maximum value of 1,016 GB (approximately 1 TB) for a non-partitioned base table and 258,064 GB (approximately 258 TB) for a partitioned base table consisting of 254 partitions. The maximum amount of space for PRIQTY and SECQTY that you can specify is at least 4,194,304 KB. So, make sure that you have specified PRIQTY, and n times SECQTY, if allocated, is about 64 GB. The value of n depends on the version of DFSMS running in your system. Extended addressability for VSAM data sets, leading to a maximum file size of 64 GB, was introduced in DFSMS Version 1 Release 5. To benefit from the maximum size provided for LOBs, DFSMS Version 1 Release 5 is required. Note: If DSSIZE is greater than 4 GB, make sure that this data set belongs to a DFSMS class that is defined with the extended addressability attribute, and also, that the automatic class selection routine associates this data set with this data class. Otherwise, DB2 is not able to allocate the requested space, and it issues SQLCODE -904.
60
system page is a space map page or any other page that does not contain actual data values. SYSTEM is the default for a LOB table space. In DB2 V8, in a data sharing environment, GBPCACHE SYSTEM is recommended for large objects. In DB2 9, in a data sharing environment, because of the changes in LOB locks management (see 3.4.3, Locking with LOBs on page 57), you might want to consider specifying CHANGED. Note that when you change an option by specifying ALTER TABLESPACE GBPCACHE in a data sharing environment, the table space or partition must be in the stopped state when the statement is executed. See 8.3, Buffer pools and group buffer pools on page 246, for more information.
61
Lock sizes
With LOBs, DB2 uses a different approach to store huge amounts of data that can span over many pages. Common locking techniques acquire locks on table spaces, partitions, tables, pages, or rows. Considering a LOB table space, there is only one table space, containing one table, which possibly holds several LOB values. DB2 does not acquire a lock on many LOB data pages, nor on the entire table space. Therefore, DB2 uses two additional lock sizes to efficiently handle locking for large objects before DB2 9: Shared LOB lock (S-LOB lock) Exclusive LOB lock (X-LOB lock) These types of locks are also acquired by the Internal Resource Lock Manager (IRLM). LOB locks are not related to any pages at all. DB2 takes both lock types explicitly by a combination of the LOB table space, the associated ROWID, and the LOB version number. In general, DB2 9 no longer uses LOB locks to ensure data integrity but locks on the base table space and information about the oldest reader accessing your LOB data. For a more detailed description about locking for large objects and lock sequences in DB2 V8 and DB2 9, see 4.5, Locking on page 96.
Compression
DB2 does not allow you to specify COMPRESS YES for LOB table spaces. Most objects stored in a BLOB column could already be compressed anyway, such as JPEG pictures or ZIP folders. Regardless of compression for a LOB table space, you can specify COMPRESS YES for the table space containing the base table.
Check constraints
A check constraint cannot reference a LOB column. Those values are not designed to be eligible to work with constraints, because they are too large to check when changing a rows content in a table.
62
4 3 2 1
. . .
16 24 23
. . .
28
11 01 10 11 00
11 01 10 11 00
11 01 10 11 00
22 21
. . . . . .
64
11 01 10 11 00
11 01 10 11 00
11 01 10 11 00
. . .
52 51 50 49
86 85
11 01 10 11 00
11 01 10 11 00
11 01 10 11 00
84 83
. . .
11 01 10 11 00
11 01 10 11 00
11 01 10 11 00
Figure 3-9 LOB value spanned over pages using chunks and non-chunks Chapter 3. Creating LOBs
63
LOBs can be stored in chunks of 16 pages and also can be stored using page allocations of fewer than 16 pages (21 - 28 and 83 - 86 in our example). After inserting, deleting, and updating LOB values, the pages can be nearly everywhere.
#P 16 16 9 8 3
LOB MAP Pages
. . .
Figure 3-10 LOB data pages chunked together using a space map and LOB map pages
64
16
. . .
You can think of two different allocation units that a LOB map page points to. First, it can point to a chunk of data pages, which is nothing more than 16 pages of contiguous space (indicated by #P = 16 in Figure 3-10). As soon as DB2 uses partial chunks to store parts of the LOB value, it contains the page number where the allocation starts and the number of contiguous pages used. For a detailed description of LOB system pages, refer to the licensed documentation DB2 Version 9.1 for z/OS Diagnosis Guide and Reference, LY37-3218. Note: When using DSN1PRNT, you might also see pages referring to LOB values that have been already deleted and whose space was not reused up to now.
65
66
Chapter 4.
Using LOBs
This chapter discusses basic considerations when starting to use LOBs in applications. This chapter contains the following: Language considerations LOB locators DRDA LOB flow optimization Feeding a LOB column Locking Unloading LOBs Updating LOBs General best practices
67
68
In a host application, starting with DB2 9, you can use a file reference variable of type BLOB_FILE, CLOB_FILE, or DBCLOB_FILE to insert a LOB from a file into a DB2 table or to select a LOB from a DB2 table into a file. When you use a file reference variable, you can select or insert an entire LOB value without contiguous application storage to contain the entire LOB. In other words, LOB file reference variables move LOB values from the database server to an application or from an application to the database server without going through the applications memory. Furthermore, LOB file reference variables bypass the host language limitation on the maximum size allowed for dynamic storage to contain a LOB value. You can declare a LOB file reference variable or a LOB file reference array for applications that are written in C, COBOL, PL/I, and Assembler. The LOB file reference variables do not contain LOB data; they represent a file that contains LOB data. Database queries, updates, and inserts can use file reference variables to store or retrieve column values. As with other host variables, a LOB file reference variable can have an associated indicator variable.
69
Table 4-1 SQLTYPE and SQLLEN of LOB columns or LOB host variables in the SQLDA SQLTYPE 404/405 408/409 412/413 916/917 920/921 924/925 Data type BLOB CLOB DBCLOB BLOB_FILE CLOB_FILE DBCLOB_FILE SQLLEN 0 0 0 267 267 267
For LOBs, the extended SQLVAR contains following variables: SQLLONGLEN: The length attribute of the LOB column SQLDATALEN: Not used The application program should set the following fields in the base SQLVAR during OPEN, EXECUTE, FETCH, and CALL: SQLTYPE: The data type of the host variable and whether an indicator variable is provided SQLLEN: The length attribute of the host variable. Always 0 for LOBs SQLDATA: The address of the host variable SQLIND: The address of the indicator variable if SQLTYPE is odd SQLNAME: The CCSID of the host variable For LOBs, the extended SQLVAR should be set as follows: SQLLONGLEN: The length attribute of the host variable. SQLDATALEN: If the value of this field is null, the actual length of the LOB is stored in the 4 bytes immediately before the start of the data, and SQLDATA in the base SQLVAR points to the first byte of the field length. The actual length indicates the number of bytes for a BLOB or CLOB, and the number of characters for a DBCLOB. If the value of this field is not null, the field contains a pointer to a 4-byte long buffer that contains the actual length in bytes (even for DBCLOBs) of the data in the buffer pointed to from the SQLDATA field in the matching base SQLVAR.
70
As in any other language, a LOB locator in a Java application is associated with only one DB2 subsystem. You cannot use a single LOB locator to move data between two different DB2 subsystems. To move LOB data between two DB2 subsystems, you need to materialize the LOB data when you retrieve it from a table in the first DB2 subsystem and then insert that data into the table in the second DB2 subsystem. In addition to the methods in the JDBC specification, the IBM DB2 Driver for JDBC and SQLJ includes LOB support in the following methods: You can specify a BLOB column as an argument of the following ResultSet methods to retrieve data from a BLOB column: getBinaryStream and getBytes You can specify a CLOB column as an argument of the following ResultSet methods to retrieve data from a CLOB column: getAsciiStream, getCharacterStream, getString, and You can use the following PreparedStatement methods to set the values for parameters that correspond to BLOB columns: setBytes and setBinaryStream You can use the following PreparedStatement methods to set the values for parameters that correspond to CLOB columns: setString, setAsciiStream, setUnicodeStream, and
getUnicodeStream
setCharacterStream
You can retrieve the value of a JDBC CLOB parameter using the following CallableStatement method: getString You can use the following ResultSet methods to retrieve data from a ROWID column:
71
WHEN clause of a CASE expression Subselect of a UNION without the ALL keyword Most of the restrictions on LOB values are due to the fact that LOB values cannot be compared, except with the LIKE predicate.
LOB functions
One way of manipulating large objects without retrieving the entire object is to use functions. Many of the string functions also work with LOBs. The built-in functions allow you to concatenate strings, get a substring, find the LOB length, find the position in the LOB of a search string, and cast the LOB to another type. UDFs can be used as well. The list of available LOB functions includes: CONCAT SUBSTR LENGTH POSSTR IFNULL VALUE / COALESCE Casts UDFs LIKE within predicates In the following sections, we discuss the most important of the functions listed above.
72
73
Table 4-2 Casting large objects BLOB CHAR VARCHAR CLOB GRAPHIC VARGRAPHIC DBCLOB BLOB CLOB CHAR VARCHAR CLOB GRAPHIC (*) VARGRAPHIC (*) DBCLOB (*) DBCLOB CHAR (**) VARCHAR (**) CLOB (**) GRAPHIC VARGRAPHIC DBCLOB
(*) CAST is only supported if the data is Unicode. (**) CAST is only supported if the data is Unicode. The result length for these casts is 3 * LENGTH (graphic string)
The reason for the length growing up to three times with DBCLOB conversions into a CHAR, VARCHAR, or CLOB column is to allow for expansion when the data is converted from UTF-16 to UTF-8. A character that takes two bytes to represent in UTF-16, can take three bytes in UTF-8.
SELECT c.id,XML2CLOB( XMLELEMENT ( NAME "ID Number", c.cname || ' ' || c.status ) ) AS "Company" FROM companies c; The query can result in the following output shown in Example 4-2 on page 75.
74
id 0002344 0012311
DB2 9 introduces the XMLSERIALIZE function to produce the XML data in string format, and this replaces the XML2CLOB functionality. The XML2CLOB function however remains for compatibility.
75
Once a locator is set to a particular LOB value, there is no action you can take within the database to change that value from the applications point of view until the locator is freed. You can free a locator by issuing a FREE LOCATOR statement or by completing the current unit of work. But how does this work? Locators do not force extra copies of the data in order to provide this function, but maintain a relationship to the underlying data pages. The data remains consistent despite other activity in the system, with the underlying mechanism varying according to the DB2 version. DB2 V8 uses an S-LOB lock when you assign a locator to a specific LOB value (see 4.5.1, Locking for LOBs with DB2 V8 on page 97 for a description of LOB locks); the LOB value is released only at COMMIT time or when you explicitly free the locator using the FREE LOCATOR statement. Therefore, the data pages containing the LOB value cannot be overwritten with different content as long as they are referenced. When you issue the HOLD LOCATOR statement, an assigned locator survives the current unit of work and is valid until the thread terminates or a FREE LOCATOR statement is passed to DB2. Either one of these events releases the S-LOB lock taken on the LOB value in the auxiliary table. DB2 9 does not allow space reuse for LOB data pages before the oldest reader in the system has completed its workload using RLSN comparison techniques; therefore, your application can access the referenced LOB value to finish its work. You can find more details in 4.5.2, Locking for LOBs with DB2 9 on page 103. Note: In DB2 V8, the space in a LOB data page can be reused if the S-LOB lock is released using, for example, a FREE LOCATOR statement. In DB2 9, DB2 relies on the oldest reader in the system to decide if LOB data pages can be reused, because there is no more S-LOB lock in the auxiliary table space for SELECT operations, except for the unconditional lock for UR readers.
76
TRANSACTION 1
01 movie-loc ... IS SQL TYPE IS BLOB-LOCATOR SELECT MOVLENGTH, LOBMOVIE INTO :length, :movie-loc FROM LITERATURE WHERE TITLE = 'The Maltese Falcon';
TRANSACTION 2
UPDATE LITERATURE SET LOBMOVIE=:edited-version WHERE TITLE = 'The Maltese Falcon';
In this example, transaction 1 selects a non-LOB column into a host variable and also a LOB column into a locator variable. After the SELECT is completed in transaction 1, transaction 2 updates the LOB column, which is already referenced by a locator in transaction 1. After the LOB is updated by transaction 2, a new value is inserted into the VIDEOLIB table in transaction 1, using the previously assigned locator for the LOB value by DB2. But the value referenced by the locator is still the same as before the updating transaction has updated the LOB value. How is this possible? Operations on the original LOB value have definitely no effect on the value referenced by a locator. Let us first have a look at LOB delete. A DELETE statement only deallocates pages in the auxiliary table where the LOB data is stored. But the data still remains in the pages; it is not deleted. Now let us have a close look at how a LOB is updated. Updating a LOB consists of DELETE and INSERT, so the pages are deallocated and the data still remains in the auxiliary table. The INSERT statement cannot reuse the previously deallocated pages because of the different mechanisms DB2 uses to prevent space reuse for currently accessed data regarding locators. The conclusion is that these data pages to which a locator is pointing cannot be allocated again, even if they are going to be deallocated by a DELETE statement, as long as an S-LOB lock persists on the referenced LOB value in DB2 V8 or a reader possibly accesses the value in DB2 9.
77
Hold beyond COMMIT: EXEC SQL HOLD LOCATOR :HV-LOCATOR-1, :HV-LOCATOR-2 END-EXEC Free the locator if it is not needed any more: EXEC SQL FREE LOCATOR :HV-LOCATOR-1, :HV-LOCATOR-2 END-EXEC A locator is freed when one of the following conditions occur: An SQL FREE LOCATOR statement occurs An SQL ROLLBACK statement occurs The associated thread terminates If a locator has the hold property, it survives the SQL COMMIT statement. Without the hold property, it does not survive the SQL COMMIT statement. A locator obtains the hold property by the SQL HOLD LOCATOR statement. If you receive SQLCODE -423 (INVALID LOCATOR VALUE) after you have specified more than one host variable for a FREE LOCATOR statement, only those locators up to the invalid locator are freed. According to this result, when you receive SQLCODE -423 after issuing a HOLD LOCATOR statement, all locators listed in the statement after the first invalid locator are not held.
78
LOCATOR-2 Version 1
LOCATOR-1 Version 3
LOCATOR-1 Version 2
LOCATOR-1 Version 1
host variable #3
host variable #2
host variable #1
LOCATOR-2 Version 2
LOCATOR-1 Version 6
LOCATOR-1 Version 5
LOCATOR-1 Version 4
LOCATOR-2 Version 1
host variable #6
host variable #5
host variable #4
79
above the bar or in the users allied address space, depending on the way a LOB is accessed. For more information about materialization, see 8.1, LOB materialization on page 240.
80
EXEC SQL SET :LOCATOR-3 = CONCAT (:LOCATOR-1, :LOCATOR-2) END-EXEC The new value of both strings, now a total 20 MB, is assigned to the new locator LOCATOR-3, to which you can now refer. To store the new value in a table, you can insert a LOB using the locator as a reference in an insert statement or perform other operations such as SUBSTR.
81
applications effectively use locators to retrieve LOB data regardless of the size of the data being retrieved. This mechanism incurs a separate network flow to get the length of the data to be returned, so that the requester can determine the proper offset and length for SUBSTR operations on the data to avoid any unnecessary blank padding of the value. For small LOB data, returning the LOB value directly instead of using a locator would be more efficient, that is, the overhead of the underlying LOB mechanisms can tend to overshadow the resources required to achieve the data retrieval. For these reasons, LOB (and XML) data retrieval in DB2 9 has been enhanced so that it is more effective for small and medium size objects, and still efficient in its use of locators to retrieve large amounts of data. For small LOBs, the performance should approximate that of retrieving a varchar column of comparable size. This functionality is known as progressive streaming. Within the overall dynamic data format of progressive streaming, progressive reference is the mechanism that supports the category of large LOB data retrieval. With the JCC Type 4 driver, a LOB value is associated to one of three categories depending on its size: Small LOBs - DRDA (server) default is 32 KB, the driver can override it by setting smaller values. Medium LOBs - Greater than 32 KB and up to 1 MB size. Large LOBs - Greater than 1 MB and up to 2 GB size. The large threshold is set as DRDA parameter MEDDTASZ, whose default is 1 MB. This threshold should be set to the maximum storage size the application region can handle, but not less than 32 KB. There is no means to override the small threshold (currently set for performance reasons at 12 KB) set by the Type 4 driver. Based on the size, the decision is made how to transfer the data. The structure of the data query block varies according to LOB size. When small-sized LOBs are used, they are treated exactly as VARCHAR type and transferred as part of the row, thus gaining performance close to that of retrieving a varchar. When medium-sized LOBs are used, the non-LOB data is placed in the query data block and the LOBs are placed in overflow blocks. These blocks are called externalized data blocks. This way, all LOBs are retrieved at once and cached on a client for subsequent processing. For large LOBs, it was found that locators are still the most efficient flow method. Thus, the locators are transmitted in a data query block with the rest of the data, avoiding a need to materialize the entire LOB at once. This explanation is depicted in Figure 4-3 on page 83.
82
Data Part
Note: Data streaming is architected in DRDA but is not implemented in a peer to peer DB2 connection where it requires the Java Universal Driver on the client side. Inserting data LOBs are streamed to DB2 by the client and completely materialized on the server side. The object is assembled in the DDF address space and then moved on to the DBM1 address space for further processing. This mechanism provides a very adaptable flow mechanism to seamlessly change the logic used to retrieve data between that suitable for real LOBs, where the data length is indeed large, and data stored within LOB columns that does not really satisfy the description of large. This is particularly useful for data stores where the length of data is subject to wide variations, with DB2 adapting on the fly to minimize the effort to serve the workload it receives.
progressiveStreaming property
This property introduces the ability for the server to dynamically determine the most efficient mode in which to return LOB or XML data as introduced in 4.3, DRDA LOB flow optimization on page 81. When this dynamic data format is enabled, the locator's life span is the scope of the cursor (cursor-based reference) as opposed to the scope of the transaction. The server frees the reference accordingly at the close (implicit or explicit) of the cursor, or it might free the reference earlier after the rows associated with the reference are returned. A new mechanism is also provided for the requester to retrieve sequential chunks of the LOB data, with the progression of the reference (position in the data) maintained at the server. Even though random access is not supported on the underlying DRDA progressive reference, the driver still supports random access (by using reset and skip) in JDBC API. However, using random access API on an underlying progressive reference has performance implications.
83
DB2BaseDataSource.progressiveStreaming can be set to DB2BaseDataSource.NOT_SET (default), DB2BaseDataSource.YES, or DB2BaseDataSource.NO. If the property setting is NOT_SET (the default), progressive references are enabled whenever the server supports progressive references; otherwise, progressive references are not enabled by the driver. If the server does not support progressive references, then DB2BaseDataSource.progressiveStreaming is ignored. If progressive references are enabled, then JDBC executeQuery() requests the dynamic data format for LOB and XML data with OUTOVROPT = OUTOVRNON and DYNDTAFMT (Dynamic Data Format) is set to 0xF1 (True). Subsequent CNTQRY (Continue Query) requests can then set FREPRVREF (Free Previous References) to enable automatic closure of the locator when there is cursor movement (that is, freeing locators previously returned in complete rows and row sets). If progressive streaming is disabled, the LOB data is either fully materialized data or locators are used as they were prior to this feature. Externally, progressive references are closed on cursor movement or cursor closure, but not on stream exhaustion. To summarize, if progressive streaming is disabled, then LOB data is returned as it was prior to this feature, including locators with a transaction life span and support for random access. If progressive streaming is enabled, then LOB and XML data is implicitly closed by the driver upon cursor movement or cursor closure.
streamBufferSize
DB2BaseDataSource.streamBufferSize determines the size of the driver's staging areas for chunking LOB or XML streams, regardless of whether progressive or SQL locators are used. When progressive streaming is requested, data is "inlined" if the stream buffer can accommodate the data size. This setting corresponds to DRDA MEDDTASZ. There is no user external for SMLDTASZ which takes the driver default (currently set at 12 KB). From an externals perspective, the stream chunking size is orthogonal to whether or not data is transported in QRYDTA or EXTDTA.
fullyMaterializeLobData
DB2BaseDataSource.fullyMaterializeLobData in JCC V3 is ignored by the driver whenever progressive references are enabled. When progressive streaming is used, materialization is controlled by the DB2BaseDataSource.streamBufferSize property and the DB2BaseDataSource.fullyMaterializeLobData setting is ignored. Notice that progressive reference becomes the default in JCC V3 (against servers that support it), so applications that rely on DB2BaseDataSource.fullyMaterializeLobData have to explicitly change the property setting for DB2BaseDataSource.progressiveStreaming to DB2BaseDataSource.NO. Some indication of the performance advantages can be seen from test cases where the LOB length is varied around the streamBufferSize threshold, which effectively compares the old non-progressive mechanism with the new progressive streaming, using varying size LOB workloads. Figure 8-10 on page 257 shows the effect of varying LOB data sizes with differing flow mechanisms. For small LOB sizes, the longest run time comes from using LOB locators. It is somewhat more efficient in terms of elapsed time to materialize the LOB instead of using a locator, because a degree of overhead is removed from DB2, and a reduction occurs in the number of data flows. Using progressive streaming further improves the performance by further eliminating overheads involved with invoking LOB specific flow mechanisms.
84
85
KB. See Figure 4-4 for a simple example of LOAD with file reference variables. More examples are provided in 6.3, LOAD on page 173.
new syntax
The LOB input files can be any of these types: A sequential file A member of a PDS or PDSE A HFS file on a HFS directory A z/FS file The LOB input file contains the entire LOB value, and the name of this file is stored in the normal load input file as a CHAR or VARCHAR field. So instead of containing the whole LOB value, the normal input file now only contains a file name which in most cases does not cause the sequential file to hit the 32 KB limit. Additional keywords have been added to the CHAR and VARCHAR field-specifications of the LOAD utility to support a file name as the input for the actual LOB value: BLOBF: The input field contains the name of a file with a BLOB value. CLOBF: The input field contains the name of a file with a CLOB value. DBCLOBF: The input field contains the name of a file with a DBCLOB value. In case of CLOBF and DBCLOBF, CCSID conversions are done when the CCSID of the input data is different than the CCSID of the table space. (EBCDIC, ASCII, Unicode, or CCSID keywords might have been specified for the input data. The default is EBCDIC input data). In case of BLOBF, no conversions are done. When the input field of a BLOBF,CLOBF, or DBCLOBF is NULL, the resulting LOB value is NULL (null indicator field for the CHAR or VARCHAR field specified in the NULLIF keyword is hex FF). The provided input files can be the result of: UNLOAD utility (PDS members, PDSE members, or HFS files) DSNTIAUL utility (sequential files) File generated by another application
86
87
.... 014200 014300 014400 014500 014900 015000 015100 015200 015500 015600 015700 015710 015720 015730 .... .... 021500 021600 021700 021800 021900 022000 022100 022200 022300 022400 022500 022600 022700 022800 022900 023000 023100 023200
**************************************************************** * * INITIALIZATION OF USED VARIABLES * INITIALIZE INTERNAL-VARIABLES BASE-TABLE-AREA LOBDATA MOVE MOVE MOVE MOVE MOVE '0000000001' 'FIRST LARGE OBJECT' 'PAOLOR1.DB2V8.PDF' 17 SQL-FILE-READ TO TO TO TO TO LO-DOCUMENT-NR LO-DESCRIPTION LOBDATA-NAME LOBDATA-NAME-LENGTH LOBDATA-FILE-OPTION
EXEC SQL INSERT INTO PAOLO.BLOB_BASE_TABLE (DOCUMENT_NR ,DESCRIPTION ,DOCUMENT) VALUES (:LO-DOCUMENT-NR ,:LO-DESCRIPTION ,:LOBDATA) END-EXEC
Note: Make sure that your DSNZPARMs LOBVALA and LOBVALS are set appropriately by using file reference variables to handle large files.
Important: Using a file reference variable requires that the source file has a record format of VB. Using a file with record format FB results in SQLCODE -452 with reason 12.
88
Example 4-5 Rows tied together in one variable MOVE 0 PERFORM UNTIL EOF-INPUT READ FILE INTO INPUTRECORD IF NOT EOF-INPUT MOVE LENGTH OF INPUTRECORD MOVE INPUTRECORD ADD LENGTH END-IF END-PERFORM TO HV-LOB-LENGTH
The definition of a host variable, large enough to contain an entire LOB value, is reported in Example 4-6. You need to include it in your WORKING-STORAGE SECTION of your application program if you try to insert a 1 MB CLOB, as in our example.
Example 4-6 Host variable declaration for a LOB column 01 HV-LOB USAGE IS SQL TYPE IS CLOB (1M).
Using this syntax, DB2 generates the definition reported in Example 4-7 for your application program.
Example 4-7 What the DB2 precompiler makes of your host variable declaration 01 HV-LOB. 02 HV-LOB-LENGTH PIC S9(9) COMP. 02 HV-LOB-DATA. 49 FILLER PIC X(32767). [repeated 32 times] 49 FILLER PIC X(32).
The last filler is used to match exactly the requested host variable size of 1 MB as declared for the CLOB. Be aware that your application only defines host variables in a size that you are allowed to acquire, regarding your JCL and your system. You must acquire buffers large enough to store your LOBs. This can be difficult for very large LOBs. For example, Enterprise COBOL for z/OS has significantly raised the limits to support DB2 applications, for example, the maximum data-item size has been raised to 128 MB, which is also the compiler limit for WORKING STORAGE SECTION. The maximum PICTURE clause and the maximum OCCURS integer have been raised to 134,217,727. Because of this limitation, for LOBs bigger than 128 MB, you have to use another method for feeding your LOBs. See Inserting LOBs using locators on page 90 for details. The application has to ensure the delivery of a correct value in the length field of your LOB host variable. Once the host variable contains the entire LOB, you can simply issue an SQL INSERT on the base table to pass your LOB to DB2. You do not need to worry about storing LOBs in the auxiliary table, because this is DB2s job. From the application programmers point of view, there is only one table containing all of the columns that are being used for LOB processing. The statement shown in Example 4-8 is a possible way for you to insert your LOB data.
Example 4-8 Inserting a single LOB value using one host variable EXEC SQL INSERT INTO BASE_TABLE (COL1, COL2, LOB) VALUES (:HV-COL1 ,:HV-COL2 ,:HV-LOB)
89
END-EXEC
We recommend that an application commits after completing the unit of work while inserting a LOB, because COMMIT releases locks taken during insert and frees allocated storage in use by the LOB. A sample program showing how to insert a LOB using one host variable is included for BLOBs and CLOBs in the additional material described in Appendix A, Additional material on page 261. The only restriction is that inserting LOBs bigger than the maximum supported variable size of your programming language is not possible using this method. If you want to insert a LOB larger than the maximum supported variable size of your application language, refer to the section Inserting LOBs using locators on page 90. Note: Make sure that you use the largest host variable you can afford to keep the length of a locator chain as small as possible before you reach your maximum LOB size, because the intended use of locator chains is not dealing with a large number of interrogations. For example, it is definitely better to use 100 times a 1 MB host variable in a locator chain than using 10,000 times a 10 KB host variable to achieve the same result.
TO LENGTH
90
MOVE INPUTRECORD ADD LENGTH IF HV-LOB-LENGTH > 10000000 THEN PERFORM APPEND-LOCATOR MOVE 0 MOVE SPACE END-IF
TO HV-LOB-LENGTH TO HV-LOB-DATA
:APPEND-LOCATOR EXEC SQL SET :LOB-LOCATOR-2 = CONCAT (:LOB-LOCATOR-1, :HV-LOB) END-EXEC EXEC SQL FREE LOCATOR :LOB-LOCATOR-1 END-EXEC MOVE LOB-LOCATOR-2 :FINAL-INSERT IF HV-LOB-LENGTH > 0 THEN PERFORM APPEND-LOCATOR END-IF EXEC SQL INSERT INTO BASE_TABLE (KEYCOL1, COL2, LOB) VALUES (:HV-KEYCOL1, :HV-COL2, :LOB-LOCATOR-1) END-EXEC EXEC SQL FREE LOCATOR :LOB-LOCATOR-1 END-EXEC TO LOB-LOCATOR-1
At the top of Example 4-9 on page 90, you can find the declaration of a CLOB host variable. In this case, the size is 10 MB, because we assume 10 MB as the maximum usable host variable size in our environment. The associated locators are also defined at the beginning of the pseudo-code. The first initialization of LOB-LOCATOR-1 is done by its first reference in the CONCAT statement. Then the application reads the input file in a loop and it builds a host variable using the rows from the input file until an end-of-file condition occurs. After reading one input record, it is appended to our 10 MB CLOB host variable. After the host variable is nearly filled up (CURRENT-SIZE > 10000000, the correct value depends on the possible length of your input records), the host variable is appended to LOB-LOCATOR-1 using the CONCAT function of DB2 to the already existing LOB value, where LOB-LOCATOR-1 is referring to and set to LOB-LOCATOR-2. The locator is not assigned to a specific table yet, only the reference to a value inside of DB2 is created. Using this technique, LOB materialization takes place outside of the application in DBM1 for building the entire LOB. If the host variable is filled with some data even after an end-of-file condition is detected, the content of the host variable is applied one last time to the locator. After all records are appended to your LOB locator (ensure that the correct record length is passed to DB2), the application finally inserts the LOB, using the locator to provide the needed host variable for the LOB value.
91
Attention should be paid to the FREE LOCATOR statement. If you do not FREE the used locators, DB2 tends to keep them around in buffers allocated in the DBM1 address space where the locators reside, and this can cause problems in already constrained virtual storage environments. The intent of the FREE LOCATOR statement is to release the allocated virtual storage space used by the locator itself as well as the virtual storage buffers in DBM1 containing the data referenced by the locator. Unless the LOCATOR has been defined with HOLD, an SQLCOMMIT also frees the locator. If you do not free the locators after using them, the storage remains allocated until COMMIT. Make sure to issue the FREE LOCATOR statement for each append within the concatenation loop as well; this decreases an counter used by DB2 to control the structure built to reference the first locator. This minimizes the risk of causing virtual storage problems when inserting many LOBs without issuing a COMMIT between your LOB insert statements. We recommend that you COMMIT after each single LOB is inserted by your application. The MOVE simply moves the value of our second locator to the first locator, which makes the first locator available again, but with the value of the second locator, which we use temporarily for the concatenation. We have used a final insert statement at the end of the sample program, because we want to avoid long lock durations on the base table. Another technique is to insert the first input record into the table, assign a locator to the LOB value, and start building the locator for a final update on the LOB column using the locator. When you plan to use the updating method, be aware that you hold a lock on the base table and on the auxiliary table in DB2 V8. In DB2 9, inserting partial LOB data can result in data corruption for UR readers accessing the incomplete LOB data. The exclusive lock on the base table can prevent access by other users to the base table depending on the lock size you use. Error-handling routines and possible data movement to non-file-variables are not mentioned in the example above. A sample program showing how to insert a LOB using a 10 MB host variable and a single locator chain is included in the sample files in Appendix A, Additional material on page 261.
92
LOCATOR-1 Version 3
LOCATOR-1 Version 2
LOCATOR-1 Version 1
host variable #3
host variable #2
host variable #1
After assigning the first version of a locator to a host variable, the locator only contains the first host variable (Version 1). After issuing the first concatenation of :LOCATOR-1 = CONCAT (:LOCATOR-1, :HV-LOB), the second version of the same locator is created. Version 2 of the locator contains the new host variable and points to Version 1 of the same locator. So DB2 builds a chain of locators. Appending data to a locator becomes more expensive when the chain grows, because of the recursive interrogation technique we mentioned above. You can especially run into a long chain when you build a large object of comparatively small input records only using locators. This is not the recommended way to feed LOBs, so use a reasonably sized host variable to minimize the length of the locator chain. To improve performance, we can build a primary chain containing the previously built secondary chain to reduce the number of recursions when appending a new host variable to LOCATOR-1. So DB2 only has to go through the long chain containing all host variables when we append a secondary chain to a primary chain. See Figure 4-6 for a visualization of primary and secondary chains.
LOCATOR-2 Version 1
LOCATOR-1 Version 3
LOCATOR-1 Version 2
LOCATOR-1 Version 1
host variable #3
host variable #2
host variable #1
LOCATOR-2 Version 2
LOCATOR-1 Version 6
LOCATOR-1 Version 5
LOCATOR-1 Version 4
LOCATOR-2 Version 1
host variable #6
host variable #5
host variable #4
As soon as a secondary chain becomes very large, we can source it out to a primary chain to reduce the level of recursion we have to go through when we append another host variable to our secondary chain. You can use this method when appending big host variables to a single
93
locator does not satisfy your performance requirements after a large number of concatenations for a secondary chain. The pseudo code reported in Example 4-10 shows you how to perform the same insert as above including a technique dealing with primary and secondary chains.
Example 4-10 Pseudo code inserting LOBs with multiple locator chains Definitions: HV-LOB LOB-LOCATOR-1 LOB-LOCATOR-2 USAGE IS SQL TYPE IS CLOB (100K) USAGE IS SQL TYPE IS CLOB-LOCATOR USAGE IS SQL TYPE IS CLOB-LOCATOR
Additional instruction before reading the 1st INPUTRECORD: EXEC SQL SET :LOCATOR-2 = END-EXEC Pseudo-Code: :APPEND-LOCATOR ADD 1
TO APPEND-LOCATOR-COUNTER
EXEC SQL SET :LOB-LOCATOR-1 = CONCAT (:LOB-LOCATOR-1, :HV-LOB) END-EXEC IF APPEND-LOCATOR-COUNTER = 1000 THEN EXEC SQL SET :LOB-LOCATOR-2 = CONCAT (:LOB-LOCATOR-2, :LOB-LOCATOR-1) END-EXEC EXEC SQL SET :LOB-LOCATOR-1 = END-EXEC MOVE 0 END-IF TO APPEND-LOCATOR-COUNTER
:FINAL-INSERT IF HV-LOB-LENGTH > 0 THEN PERFORM APPEND-LOCATOR END-IF IF APPEND-LOCATOR-COUNTER > 0 THEN EXEC SQL SET :LOB-LOCATOR-2 = CONCAT (:LOB-LOCATOR-2, :LOB-LOCATOR-1) END-EXEC END-IF EXEC SQL INSERT INTO BASE_TABLE (KEYCOL1, COL2, LOB) VALUES (:HV-KEYCOL1, :HV-COL2, :HV-LOB-LOCATOR-1) END-EXEC EXEC SQL FREE LOCATOR :LOB-LOCATOR-1,:LOB-LOCATOR-2
94
END-EXEC
The difference between these two examples is the locator management in the APPEND-LOCATOR subroutine. After 1,000 times of appending a host variable (which means nearly 100 MB of data in our example), we create a primary chain by issuing SET :LOCATOR-2 = CONCAT (:LOCATOR-2, :LOCATOR-1). After LOCATOR-1 was outsourced successfully, we can reset it to point to an empty string to start building a new secondary chain. It is a good programming practice to free both locators after the final insert statement in order to release the virtual storage allocated out of the DBM1 address space, and make it available for further usage in the application. Otherwise, the storage remains allocated until the implicit or explicit COMMIT releases the entire allocated storage. Before you start coding your application, consider that every invocation of SQL takes a certain amount of time. So try to keep SQL calls to a minimum number and exploit as much storage as you can get for your host variable. This results in a reduction of SQL calls and leads you to a better performing application. But, also be aware of storage allocation issues if you do not free your locators. Important: Do not make extensive use of LOB locators by concatenating small pieces of storage. Instead, concatenate the largest host variable you can afford to acquire to benefit from performance and reduce the risk of virtual storage constraints. A sample program showing how to insert a LOB using a 10 MB host variable and two locator chains is included in the sample files described in Appendix A, Additional material on page 261.
import from filename of ixf lobs from lobpath insert into X.MYTABLE
95
Explanations of Example 4-11 on page 95 are: filename: Contains the name of the IXF input file that contains the data to be loaded (data of the base table columns and the names of the LOB files). If the path is omitted, the current working directory is used. IXF: File format of the input file supported by DB2 on the host (IXF is integrated exchange format, in which most of the table attributes are saved). lobpath: Specifies the path where the LOB files are stored. The names of the LOB data files are stored in the main input file in the column that is loaded into the LOB column. into: Specifies the host table or host view to be loaded. The best way to create a working base for the IMPORT command is to first EXPORT a similar table from the host to the workstation using an EXPORT command as shown in Example 4-12. Similarly, you first have to CONNECT to the host DB2 system.
Example 4-12 EXPORT command
export to filename of ixf lobs to lobpath lobfile lobfile modified by lobsinsepfiles select * from X.MYTABLE The explanations for Example 4-12 are: filename: Contains the name of the IXF file to which data is to be exported. If the complete path to the file is not specified, the export utility uses the current directory and the default drive as the destination. lobpath: Specifies a path to a directory in which the LOB files are to be stored. lobfile: Contains the base file name for the LOB files. When creating LOB files during an export operation, file names are constructed by appending the current base name from this list to the current path from lobpath and then appending a 3-digit sequence number. For example, if the current LOB path is the directory c:\u\davy\lobpath, the LOB files created are c:\u\davy\lobpath\lobfile.001.lob, c:\u\davy\lobpath\lobfile.002.lob, and so forth. lobsinsepfiles: Required parameter to specify that the LOBs are stored in separate files on the lobpath. From: Specifies a host table or host view containing the columns to unload from the host. Afterwards, you can create a similar IXF file on the workstation and edit it with the names of the LOB files you want to upload. See the DB2 for Linux, UNIX and Windows manuals for complete information about the IMPORT and EXPORT commands. Tip: Be sure that the input file does not contain values for the ROWID column. These are rejected by DB2 on the host when the ROWID column was defined there as GENERATED BY DEFAULT.
4.5 Locking
Locking for LOBs has significantly changed in DB2 9; therefore, the information about LOBs locking techniques with DB2 V8 and DB2 9 are mentioned in two separate sections. For LOB locking with DB2 V8, see 4.5.1, Locking for LOBs with DB2 V8 on page 97. Locking for LOBs beginning with DB2 9 is described at 4.5.2, Locking for LOBs with DB2 9 on page 103. Note that the different locking mechanisms introduced in DB2 9 were not retrofitted to DB2 V8.
96
escalation
Auxiliary
Table
LOB
lock
97
Page: S (3)
LOB: S (5)
Note: This differs from the general DB2 lock mechanism, where no parts of a row can be updated while it is delivered to your application. Using lock avoidance or uncommitted read delivers the row as it was at the point in time when your SQL statement was issued.
98
LOB: S (3)
99
Page: X (4)
LOB: X (5)
The IX LOB locks are held until the application commits or the thread terminates.
Page: X (3)
LOB: S (5)
After establishing the usual IX locks on the base table space and the base table (if segmented), only a intent-share (IS) lock is requested for the LOB table space. The page containing the associated data in the base table is also provided with an X-lock. There is no IX lock request for the LOB table space, because deleting a LOB value is implemented by deallocating the allocated pages used by the LOB, and not directly updating the data pages. For this reason, the requested lock on the LOB is only a shared LOB (S-LOB) lock. If an 100
LOBs with DB2 for z/OS: Stronger and Faster
S-LOB lock exists for a LOB value, the deallocation is done at DELETE time, but the space can only be reused if all S-LOB locks held by readers (see Locks with SELECT on page 98 for locks requested by LOB readers) are released. So deleting applications acquire S-LOB locks to reserve space in case of a rollback. Even if the deleting application commits the unit of work or its thread ends, the COMMIT is done and the LOB is only accessible for the thread currently reading the LOB value.
BASE Table Space: IX (1) BASE Table: IX (2) X (3) X mass delete (4)
101
Old
New
Page: X (3)
LOB: S (5)
LOB: X (7)
102
103
R-Scan
S
Figure 4-14 Lock escalation for UR readers
A thread accesses the base table using isolation level UR on a relational scan to avoid any locking conflicts. To ensure data integrity of LOB data while reading them, even an isolation UR reader has to acquire an S-LOB lock to ensure data consistency between a base table row and its corresponding LOB value (see Using ISOLATION (UR) for LOBs on page 99 for more information). Assuming the UR reader reads more than one LOB without committing frequently, which is typically the case for UR readers, the number of LOB locks can frequently exceed the maximum limitation for the affected table space and DB2 has to escalate the lock scope to the LOB table space level. Another problem facing UR readers relies on the fact that DB2 performs a base row update and its corresponding LOB update in two separate stages, which implies UR readers might retrieve the new data from the base table row but are unable to fetch its corresponding LOB data, which can even be partial LOB data in a data sharing environment. The reason for retrieving partial LOB data in data sharing is related to physical LOB storage spanning multiple pages. Because the LOB pages and the LOBs index pages can be written to the global buffer pool (GBP) in any order, it is possible for an UR reader on a different member to see partial LOB data.
104
DB2 9 now allows you to serialize the access of a LOB table space by only maintaining the locks on a base table row or a base table space data page. This base table lock basically blocks readers with isolation levels CS, RS, and RR except readers using UR who are using a lock avoidance scheme. For a LOB table space, DB2 now rarely takes locks to ensure data integrity. There are two new lock duration modes introduced in DB2 9: Manual duration mode For INSERT and UPDATE operations, DB2 must continue to hold an X-LOB lock on the LOB data. The locks on the LOB table space pages are released immediately after completing the INSERT or UPDATE statement of the corresponding LOB table space pages and its auxiliary index. This is called manual duration mode. Access to LOB data by non-UR readers is furthermore prohibited due to an exclusive lock on the base table space row or data page. In a data sharing environment, prior to unlocking, DB2 flushes out the changed data of LOB data pages and its index pages to the global buffer pool. These operations ensure that any UR reader in other DB2 subsystems can access a complete copy of your LOB data. Changing to manual duration mode can significantly shorten the time that a LOB lock is held and improve the overall lock contention. Autorel mode For SELECT operations, DB2 relies on the lock taken on the base table to ensure the access of a correct copy of LOB data. As soon as your application uses isolation UR, if LOB columns are to be selected, the UR reader must acquire a S-LOB lock to serialize with concurrent INSERT and UPDATE operations. The lock is immediately released after it was acquired because the purpose was just to check that no other lock had been established. This is called autorel mode. We refer to a third lock mode called commit duration, which releases the locks at COMMIT time. This lock mode is used by DB2 V8 for INSERTs.
105
system. This means that before space reuse can be invoked, all readers of LOB values of the affected LOB data pages have to have completed their access. For space reuse in a LOB table space, DB2 9 removes the use of LOB locks previously required to determine which deallocated LOB storage can be reused for new allocations. DB2 now depends on a comparison of the read LRSN and delete LRSN to determine the availability of already deallocated storage. When a unit of recovery (UR) starts accessing a LOB table space, it first needs to acquire a read claim, this is the read LRSN. DB2 keeps tracks of this read LRSN for each UR and knows the read LRSN of the oldest one. By knowing the delete LRSN of the page considered for reuse, DB2 can use the comparison between the delete LRSN and the oldest read LRSN to determine if the UR is committed or not. When DB2 deletes a LOB, it marks all the pages for that LOB to be deallocated on the status bit and stores the deleted LRSN for each page on the space map page. Before V9, the delete LRSN is one value on the low level space map page and it indicates the latest deletion of any page belonging to this low level space map page. One or more low-level space map pages refer to all data pages of one single LOB column. This LRSN comparison does not give enough information to reuse a page which was already committed. A LOB LOCK must be used. In V9, DB2 stores the delete LRSN on each page. This allows DB2 to use the LRSN comparison method to determine if the page can be reused. See Example 4-13 for a brief description.
Example 4-13 Comparison of RLSN and LSN to reclaim space
RLSN of oldest read claim : XFEDCBA098765 LSN in LOB page : X1234567890AB RLSN > LSN of page considered for reuse Yes: Page can be reused, reader started after the deallocated page was committed
RLSN of oldest read claim : X1234567890AB LSN in LOB page : XFEDCBA098765 RLSN > LSN of page considered for reuse No: Page cannot be reused because of possible active reference In the first case, the RLSN of the oldest reader in the system is greater than the LSN contained in the LOB page. This means that the pages considered for reuse were deallocated and committed before the reader has started accessing LOB data; therefore, it is safe to reuse the data pages for a new LOB value. In the second case, the RLSN of the oldest reader in the system is less than the LSN contained in the LOB page. This implies that the page considered for reuse was deallocated after the oldest reader has started accessing that particular LOB data. As a consequence, the affected LOB data page cannot be reused since reusing the data page can result in corrupting data for the application currently accessing its value.
106
107
data page that you reference. Using this common technique, data consistency can be guaranteed for the data residing in the base table. If the data is consistent in the base table, the LOB data is also consistent and can be accessed. Once your application accesses the LOB data for a specific row through the base table, data can be retrieved even if the LOB data pages are deallocated by another transaction during retrieval time. Only the next reference to the LOB itself through the base table fails if a concurrently running DELETE statement deletes the corresponding row from the base table.
Recommendation for DB2 9: In data sharing, consider specifying GBPCACHE CHANGE to avoid flushing changed pages to disk.
108
109
MOVE 'PAOLO.SG247270.PDF' MOVE 18 MOVE SQL-FILE-CREATE EXEC SQL SELECT INTO FROM WHERE END-EXEC
By providing a variable with SQL TYPE IS BLOB-FILE, the precompiler generates the structure as reported in Example 4-15.
Example 4-15 What the DB2 precompiler generates for LOB files
01 49 49 49 49
LOBDATA. LOBDATA-NAME-LENGTH PIC S9(9) COMP-5 SYNC. LOBDATA-DATA-LENGTH PIC S9(9) COMP-5. LOBDATA-FILE-OPTION PIC S9(9) COMP-5. LOBDATA-NAME PIC X(255).
[...] 77 77 77 77 SQL-FILE-READ SQL-FILE-CREATE SQL-FILE-OVERWRITE SQL-FILE-APPEND PIC PIC PIC PIC S9(9) S9(9) S9(9) S9(9) COMP-4 COMP-4 COMP-4 COMP-4 VALUE VALUE VALUE VALUE +2. +8. +16. +32.
The LOBDATA-NAME contains the name of the file where the LOB is going to be unloaded and it can be provided at run time. LOBDATA-NAME-LENGTH contains the length of the LOBDATA-NAME itself. DB2 always creates a variable length file with LRECL 27,994. The LOBDATA-DATA-LENGTH is set to the length of the new data written to the file and is ignored as input. The values of fields SQL-FILE-READ, SQL-FILE-CREATE, SQL-FILE-OVERWRITE, and SQL-FILE-APPEND can be used as input for LOBDATA-FILE-OPTION to tell DB2 how to deal with the specified output file: SQL-FILE-READ for a regular file that can be opened, read, and closed. SQL-FILE-CREATE creates a new file. If the file already exists, an error is returned. SQL-FILE-OVERWRITE for existing files with the specified name. If the file exists, it is overwritten; otherwise, DB2 creates the file. SQL-FILE-APPEND for existing files with the specified name. If the file exists, new data is appended; otherwise, DB2 creates the file. You can still use these variables to move them to the FILE-OPTION field since DB2 generates them at precompile time. For more information about file reference variables, refer to 2.4, LOB file reference variables on page 18. Note: DB2 always uses variable length data sets with LRECL 27,994 for CLOBs, BLOBs, and DBCLOBs when you unload your LOB values using a file reference variable.
110
A sample program showing how to unload a LOB using a file reference variable for BLOBs and CLOBs is included in the files described in Appendix A, Additional material on page 261.
PERFORM WRITE-DATA :WRITE-DATA MOVE 1 PERFORM UNTIL BYTE-COUNTER > HV-LOB-LENGTH MOVE HV-LOB-DATA (BYTE-COUNTER:OUTPUT-FILE-LENGTH) WRITE OUTPUT-RECORD ADD OUTPUT-FILE-LENGTH END-PERFORM
TO BYTE-COUNTER
TO OUTPUT-RECORD TO BYTE-COUNTER
This solution works fine as long as the maximum LOB value is not bigger than the largest size of a host variable that you are allowed to acquire. If you are not able to acquire a host variable as big as the size of your maximum LOB value, you can use locators for unloading your data as we discuss in Case 3. A sample program showing how to unload a LOB using a host variable for BLOBs and CLOBs is included in the files described in Appendix A, Additional material on page 261.
111
Example 4-17 Unloading a LOB using locators Definitions: HV-LOB LOB-LOCATOR-1 Pseudo-Code: EXEC SQL SELECT INTO FROM WHERE END-EXEC USAGE IS SQL TYPE IS CLOB (1M) USAGE IS SQL TYPE IS CLOB-LOCATOR
COMPUTE AMOUNT-FULL-SUBSTR = CURRENT-LENGTH / MAX-VAR-SIZE COMPUTE AMOUNT-REMAIN-SUBSTR = CURRENT-LENGTH - (AMOUNT-FULL-SUBSTR * MAX-VAR-SIZE) PERFORM VARYING SUBSTR-COUNTER FROM 1 BY 1 UNTIL SUBSTR-COUNTER > AMOUNT-FULL-SUBSTR EXEC SQL SET :HV-LOB = SUBSTR(:LOB-LOCATOR-1, 1, MAX-VAR-SIZE) END-EXEC PERFORM WRITE-DATA END-PERFORM IF AMOUNT-REMAIN-SUBST > 0 THEN EXEC SQL SET :HV-LOB = SUBSTR(:LOB-LOCATOR-1,1,:AMOUNT-REMAIN-SUBSTR) END-EXEC PERFORM WRITE-DATA END-IF EXEC SQL FREE LOCATOR :LOB-LOCATOR-1 END-EXEC
Before we start retrieving parts of the LOB, the application sets a locator to a LOB value in order not to allow changes to the LOB value during the unit of work. Otherwise, in DB2 V8, the content of the LOB can change while the application processes the LOB data. In this case, we acquire a locator to refer to a frozen LOB value for our unit of work. The idea behind retrieving values using a locator is the same idea we use when we insert LOB value, try using large host variables to reduce the number of your SQL calls. A sample program showing how to unload a LOB using a host variable of 1 MB and locators for BLOBs and CLOBs is included in the files described in Appendix A, Additional material on page 261. The variable AMOUNT-FULL-SUBSTR tells your program how often it has to perform the SUBSTR to retrieve a part of the LOB value that is the size of your largest host variable. For the remaining bytes of the LOB, we calculate AMOUNT-REMAIN-SUBSTR to retrieve those bytes, which are not covered by the previously issued statements. After retrieving the results of each SUBSTR function, the data is written to a file using the WRITE-DATA subroutine as mentioned in Case 1. This example for retrieving your LOB data avoids materialization of the LOB, because DB2 knows where the parts you want to retrieve using the SUBSTR function are stored. Therefore, 112
LOBs with DB2 for z/OS: Stronger and Faster
DB2 uses the LOB pageset structure to locate the data pages you want to retrieve. For a detailed description of the LOB pageset structure, see 3.6, Physical layout of LOBs on page 63. Figure 4-15 shows you how a delete from another transaction can affect your unit of work when you do not use a locator technique to freeze a LOB value from your applications view, or when you do not use isolation levels that can protect you from this situation. In our specific example, we assume cursor stability (CS) as the isolation level with CURRENTDATA(NO) for lock avoidance and RELEASE(COMMIT).
Tran 1
SELECT SUBSTR (LOBCOL, 1, 1024) Lock WHERE KEYCOL = Vala S-LOB
Tran 2
S-LOB
S-LOB Lock
SQLCODE
Figure 4-15 Accessing a LOB without a locator reference using ISOLATION (CS)
Note: Note that in DB2 9, no S-LOB locks are acquired for SELECT statements. Refer to 4.5.2, Locking for LOBs with DB2 9 on page 103 for more details. Every SELECT SUBSTR acquires an S-LOB lock for the time that it takes to retrieve the requested value. As soon as DB2 has delivered the value (depending on your current settings for DB2 locking), it releases the S-LOB lock. The LOB lock is taken again by DB2 as soon as the next SELECT SUBSTR statement is issued. When you use this method, a second transaction is able to delete the LOB which is currently processed by another transaction. To avoid this kind of situation, use a locator to freeze the object that you currently access. When your application assigns a locator to a particular LOB value, in DB2 V8 the lock is held by DB2 until you explicitly free the locator or issue DB2 COMMIT as shown in Figure 4-16 on page 114.
113
S-LOB Lock
Tran 1
Tran 2
SELECT SUBSTR (:LOB-LOCATOR, 1, 1024) S-LOB Lock SELECT SUBSTR (:LOB-LOCATOR, 1025, 1024) DELETE LOBCOL WHERE KEYCOL = Vala COMMIT end of UOW / thread SELECT SUBSTR (:LOB-LOCATOR, 2049, 1024) . . . end of UOW / thread
Transaction two acquires an S-LOB lock which is compatible with the S-LOB lock already held by transaction one. After transaction two issues a COMMIT and its thread terminates, the LOB is only visible for transaction one. The pages are finally deallocated when transaction one releases its S-LOB lock for the accessed value. Note: In DB2 9, there is no S-LOB lock taken for LOB locators, but once referenced by a LOB locator, the LOB data pages can still be referenced even if the pages are deallocated by another DELETE statement. DB2 does not reuse the LOBs data pages before the locator is finally freed.
114
Solution
The FETCH CONTINUE standard FETCH SQL statement extension allows an application to do a FETCH against a table that contains LOB or XML columns, using a buffer that might not be large enough to hold the entire LOB or XML value. If any of the fetched LOB or XML columns do not fit, DB2 returns information about which columns were truncated and what the actual length is. To enable this behavior on the FETCH, the application must add the WITH CONTINUE clause. The application is then able to use that actual length information to allocate a larger target buffer, and to then execute a FETCH statement with the CONTINUE clause to retrieve the remaining data for those columns. Alternatively, the application can be coded to handle large LOBs or XML values by "streaming" the data. That is, the application can use a fixed-size buffer, and following the initial FETCH, perform repeated FETCH CONTINUE operations to retrieve the large LOB or XML value, one piece at a time. Note that
Chapter 4. Using LOBs
115
the application is not required to consume all LOB or XML objects in their entirety. It can FETCH the next row at any time, even if truncated columns remain in the current row. This technique is primarily useful for applications that retrieve an entire LOB or XML column and process it before fetching another row for the cursor or closing the cursor. (Note, however, that it is not required to fetch the entire column before moving to the next row.) Note: For applications that need to perform "random access" to parts of a LOB, using functions, such as LENGTH, SUBSTR, and POSSTR the use of LOB locators, is still recommended.
Restrictions
The following restrictions might appear: FETCH CONTINUE is not supported with multi-row fetch (SQLCODE -225, SQLSTATE 42872, or this might be caught by the precompiler with DSNH104I). No intervening operations on this cursor are allowed between FETCH and FETCH CURRENT CONTINUE. FETCH CONTINUE only preserves truncated data for result set columns of type BLOB, CLOB, DBCLOB, or XML, and only when the output host variable data type is the appropriate data type. 116
LOBs with DB2 for z/OS: Stronger and Faster
Note: The following is allowed with FETCH CONTINUE: Scrollable Cursors The FETCH CURRENT CONTINUE functionality can be used with scrollable cursors as well. The FETCH operation can specify WITH CONTINUE even for backward, relative, and absolute fetches. Following such FETCH operations, the FETCH CURRENT CONTINUE statement can retrieve any truncated data. Allocated Cursors A FETCH CURRENT CONTINUE statement can reference an allocated cursor associated with a stored procedure result set. Likewise, the FETCH against an allocated cursor can use the WITH CONTINUE clause. Cursors declared WITH HOLD For a cursor that is held across a commit operation, a FETCH CURRENT CONTINUE following the commit can retrieve LOB data that was truncated on a FETCH that occurred before the commit operation.
Assumptions: Table exists created as following: CREATE TABLE T1 (C1 INT, C2 CLOB(100M), C3 CLOB(32K)); There is a row in the table T1 where: C1 - valid integer C2 - 10MB object
117
C3 - 32KB object Program Flow: [1] EXEC SQL DECLARE CURSOR1 CURSOR FOR DYNSQLSTMT1; EXEC SQL PREPARE DYNSQLSTMT1 FROM 'SELECT * FROM T1'; [2] EXEC SQL DESCRIBE DYNSQLSTMT1 INTO DESCRIPTOR :SQLDA; [3] EXEC SQL OPEN CURSOR1; [4] Prepare for FETCH: Allocate data buffers (32K for each CLOB) Set data pointers and lengths in SQLDA. [5] EXEC SQL FETCH WITH CONTINUE CURSOR1 INTO DESCRIPTOR :SQLDA; [6] if truncation occurred on any LOB column loop through each column if column is LOB and was truncated allocate larger buffer area for any truncated columns, move first piece into larger area reset data pointers, length fields in SQLDA endif endloop [7] EXEC SQL FETCH CURRENT CONTINUE CURSOR1 INTO DESCRIPTOR :SQLDA; endif Work with returned data... [8] EXEC SQL FETCH WITH CONTINUE CURSOR1 INTO DESCRIPTOR :SQLDA; [9] EXEC SQL CLOSE CURSOR1; Description: 1. The application declares a cursor for a dynamic SQL statement, then prepares a SELECT statement which retrieves LOB columns of different sizes. 2. The application DESCRIBEs the statement. This populates the SQLDA with the initial data type and length information. 3. The application opens the cursor. 4. The application prepares for the FETCH by allocating storage to receive each of the output columns. For the LOB and XML columns, it allocates 32,767 bytes. This is an arbitrary size. A larger, or smaller size could be used. This example assumes that the programming language being used allows for dynamic storage allocation. The application then completes the SQLDA setup in preparation for the FETCH. It sets the SQLDATA pointers to point at each allocated buffer area and sets the SQLLONGLEN field to 32,767. It can optionally set each SQLDATALEN field to point at a 4-byte length field to hold the LOB output length. 5. The application issues the FETCH request using the new WITH CONTINUE clause to tell DB2 to manage LOB and XML truncation on output differently, as described below. After the FETCH, the buffers contain the complete data for C1 (the integer) and C3 (it fits in the 32 KB buffer). Because the data of C2 is greater than 32 KB, truncation occurs for this column. The FETCH returns a truncation warning - SQLWARN1 is set to 'W', and SQLCODE +20141 might be returned. Because the FETCH CONTINUE flag is on for truncated column C2, DB2 performs the following actions: The amount of data written to the data buffer equals the length specified by the SQLLONGLEN field in the secondary SQLVAR minus possibly 4 bytes depending on whether SQLDATALEN is NULL or not.
118
The remaining data remains materialized (cached) at the server, and it can be retrieved by the application using FETCH CURRENT CONTINUE immediately following the current FETCH. If the data contains multi-byte characters, a partial character might result at the truncation point because the data is truncated on a byte boundary. The required buffer length is reported in one of two places. If the SQLDATALEN field in the secondary SQLVAR is not NULL, it contains a pointer to a 4-byte long buffer that contains the required buffer length in bytes (even for DBCLOB). If the SQLDATALEN field is NULL, the required buffer length (in bytes for CLOB and BLOB, in characters for DBCLOB) is stored in the first 4 bytes of the buffer pointed at by the SQLDATA field in the base SQLVAR. A required buffer length is the length of buffer space required to hold the entire data value; therefore, it includes the amount of data already written to the data buffer. For this example, assume that the SQLDATALEN pointer is not null. 6. The application checks the result of the FETCH and processes the returned data. If any data has been truncated, then the SQLWARN1 field in the SQLCA is set to 'W'. SQLCODE +20141 is returned when a LOB value is truncated and the length of the value that was truncated is too large to be returned in the indicator variable. The indicator variable contains a value of 32K. However, checking SQLWARN1 is the best way to check for truncation. In this example, we know that truncation has occurred. So, the application loops through each output column to find the truncated columns. For the LOB columns, it does this by comparing the value pointed at by SQLDATALEN with the value in SQLLONGLEN in the corresponding secondary SQLVAR. If the SQLDATALEN value is greater, truncation has occurred. The application then uses the value pointed at by SQLDATALEN to allocate a new buffer. It then copies the first piece of data into the new buffer and resets the SQLDATA pointer to point just past that new data piece. SQLLONGLEN is then set to the new buffer length minus the length of the first chunk (32,767 in this case). Alternatively, the application could have set the SQLDATALEN pointer to zero. In that case, the processing would be similar, except that DB2 would place the actual length into the first four bytes of that data output area pointed at by SQLDATA. 7. The application issues a FETCH CURRENT CONTINUE. DB2 then processes the SQLDA, ignores SQLVARs for columns that are neither LOB nor XML, and finds that there is data cached for C2. DB2 then writes the data to the provided host variables in the same way that it would for a normal FETCH operation, but begins at the truncation point. The application then processes the returned data in the data buffers. In this example, the application allocated the buffer sizes for the FETCH CURRENT CONTINUE to be successful. However, if the one of the data buffers was still too small, DB2 would again set the truncation warnings and lengths as described on the FETCH WITH CONTINUE step. 8. This FETCH operation just fetches the next row of data in the result set. In this example, the application consumed all of the LOB data and did not leave any truncated data. But if it had, this FETCH would make that data unavailable. The application is not required, when using this continue capability, to consume all of the truncated data. When the cursor is moved to the next row, or closed, that data is then unavailable. Steps 4 through 8 can be repeated until the application does not request any more rows, the application closes the cursor, or in the case of non-scrolling cursors, there are no more rows of the result set available. 9. The application closes the cursor. Similarly, if there had been any truncated LOB columns that had not been fully fetched, DB2 would discard the remaining data.
119
operation. For example, it is written to a file, or piped to another tool. See Example 4-19 below for a more detailed description of the processing.
Example 4-19 FETCH CONTINUE with static SQL
Assumptions: Table exists created as following: CREATE TABLE T1 (C1 INT, C2 CLOB(100M), C3 CLOB(32K)); There is C1 C2 C3 a row in the table T1 where: valid integer 10MB object 32KB object
Program Flow: [1] EXEC SQL BEGIN DECLARE SECTION DECLARE CLOBHV SQL TYPE IS CLOB(32767); EXEC SQL END DECLARE SECTION; [2] [3] [4] [5] EXEC SQL DECLARE CURSOR1 CURSOR FOR SELECT C2 FROM T1; EXEC SQL OPEN CURSOR1; EXEC SQL FETCH WITH CONTINUE CURSOR1 INTO :CLOBHV; if (sqlcode >= 0) + sqlcode <> 100 loop until LOB is completely fetched (no truncation occurred - compare returned length to provided buffer length or examine the contents of SQLWARN1) write current piece of data to output file [6] EXEC SQL FETCH CURRENT CONTINUE CURSOR1 INTO :CLOBHV; endloop endif [7] EXEC SQL CLOSE CURSOR1; Description: 1. The application declares a CLOB host variable that it uses to fetch the CLOB into. 2. The application declares a cursor for a static SQL SELECT statement that retrieves one CLOB column from the table. 3. The application opens the cursor. 4. The application issues the FETCH request. It uses the WITH CONTINUE clause on the FETCH to enable subsequent FETCH CURRENT CONTINUE operations. The precompiler generates the code that sets up the appropriate indicators in the RDI parameter block. DB2 sees that FETCH WITH CONTINUE was specified and processes column C2 accordingly: The amount of data written to the data buffer equals the length specified by the SQLLONGLEN field in the secondary SQLVAR minus 4 bytes. The remaining data remains materialized (cached) at the server, and can be retrieved by the application using FETCH CURRENT CONTINUE immediately following the current FETCH. If the data contains multi-byte characters, a partial character might result at the truncation point because the data is truncated on a byte boundary. 120
LOBs with DB2 for z/OS: Stronger and Faster
The precompiler-generated code does not use the SQLDATALEN field, so the required buffer length is reported (in bytes for CLOB and BLOB, in characters for DBCLOB) in the first 4 bytes of the buffer pointed at by the SQLDATA field in the base SQLVAR. The required buffer length is the length of buffer space required to hold the entire data value, therefore, it includes the amount of data already written to the data buffer. 5. The application checks for a successful fetch and then enters a loop in which it writes the buffer contents out to an external file, then checks if truncation occurred. To check for truncation, the application first checks the SQLWARN1 field to see if it is set to 'W'. If so, that means that at least one column was truncated. To check each column, the application must compare the length returned in the first 4 bytes of the output data with the length of the buffer that it provided (this is still set in SQLLONGLEN). If there was truncation, it executes the FETCH CURRENT CONTINUE statement to get the next piece of data. This is repeated until the LOB column is completely fetched. The check for truncation involves comparing the integer value in the first 4 bytes of the data buffer with the length of the input host variable. 6. When doing the FETCH CURRENT CONTINUE, the application uses a direct host variable reference in the INTO clause. If there had been other host variables in the original SELECT list, those would have had to have been specified in the INTO clause as well. To process the FETCH CURRENT CONTINUE statement, DB2 writes data to the output host variables in the same way that FETCH does, but beginning at the truncation point. DB2 only writes out data for LOB or XML columns that were previously truncated. Other columns are ignored. The application processes the returned data in the data buffers. In this case, the application allocated the required sizes for the FETCH CURRENT CONTINUE to be successful. However, if the LOB data buffer is still too small, DB2 would again set the truncation warnings and lengths as described on the FETCH step. One difference is that the length returned in the first 4 bytes on the FETCH CURRENT CONTINUE statement is equal to the length of the data from the truncation point to the end. 7. After the loop, the application closes the cursor. If there had been truncated columns with unfetched data remaining, the unfetched data would have been discarded.
TO FINAL-POS START-POS
121
COMPUTE POS-START = FINAL-POS + STRING-LENGTH EXEC SQL SET :POS = POSSTR (SUBSTR (:LOB-LOCATOR, :POS-START), :SEARCH-STRING) END-EXEC [determine if correct position is returned] END-PERFORM END-IF
The first POSSTR statement returns as usual the first search string position in the LOB value hiding behind a LOB locator. Beginning with DB2 9, you can also use POSSTR function to search your host variable instead searching a value inside of DB2. Note that you add the additional overhead of invoking SQL for using POSSTR instead of using the appropriate functions of your host programming language.
122
EXEC SQL SET :START-POSITION = POSSTR (:LOB-LOCATOR-1, Chapter 8) END-EXEC EXEC SQL SET :END-POSITION = POSSTR (:LOB-LOCATOR-1, Chapter 9) END-EXEC EXEC SQL SET :LOB-LOCATOR-2 = SUBSTR (:LOB-LOCATOR-1, 1, :START-POSITION - 1) CONCAT SUBSTR (:LOB-LOCATOR-1, :END-POSITION) END-EXEC EXEC SQL UPDATE BASE_TABLE SET LOB = :LOB-LOCATOR-2 WHERE KEYCOL1 = :HV-KEYCOL1 END-EXEC EXEC SQL FREE LOCATOR :LOB-LOCATOR-1, :LOB-LOCATOR-2 END-EXEC
A sample program showing how to delete a specific part of a LOB using locators is included in BLOB and CLOB sample files described in Appendix A, Additional material on page 261.
123
So LOCATOR-2 is made of the former text referenced by LOCATOR-1 up to the start position minus one byte, the NEW-TEXT variable which can consist either of a host variable or a LOB locator, and the remaining text referenced by LOCATOR-1 from your end position up to the end of the LOB value. Using the technique mentioned above, you are also able to insert certain new text at a particular position in your CLOB. The only thing you have to figure out is the position where you want to insert the text in your CLOB. A sample program showing how to update a specific part of a LOB using locators is included in the BLOB and CLOB sample files described in Appendix A, Additional material on page 261. Let us now assume that you want to insert more text at the end of Chapter 8. For this reason, you only have to find a position in the LOB where you want to place the new text value. After you have determined the correct position by using POSSTR, you can assign a new locator to the complete new value of the LOB. Example 4-23 shows you how you can perform an insert of new text to a known position in a LOB.
Example 4-23 Inserting new text at a particular position EXEC SQL SET :LOB-LOCATOR-2 = SUBSTR (:LOB-LOCATOR-1, 1, :START-POSITION - 1) CONCAT :NEW-TEXT CONCAT SUBSTR (:LOB-LOCATOR-1, :START-POSITION) END-EXEC
In this example, the NEW-TEXT variable can also be a host variable or another LOB locator.
124
If only a small number of your LOB values can fit into the dedicated buffer pool, use a relatively small buffer pool for your LOB table space to avoid inefficient usage of your system resources. Just make sure the buffer pool is large enough to avoid disabling list prefetch because of a buffer shortage condition. Always use LOG YES or the LOGGED keyword to avoid recovery complications unless you are really looking for a challenge. In data sharing, use GBPCACHE SYSTEM: GBPCACHE SYSTEM parameter was added for LOBs to prevent LOB data from flooding your group buffer pool. Specifying GBPCACHE SYSTEM caches only the LOB control (system) information in the group buffer pool. In a data sharing environment, GBPCACHE SYSTEM is recommended for large objects. See 8.3, Buffer pools and group buffer pools on page 246 for more information. If you use IBM WebSphere MQ to store large messages into LOB table spaces in a shared-queue environment, use GBPCACHE CHANGED because it is recommended for volatile LOB data and in DB2 9. Use the LOAD utility with file reference variables to insert your LOB data into the target table space outside of your applications. Use the UNLOAD utility with file reference variables to unload your LOB data into data sets outside of your applications. See Table 1-1 on page 5 for the required maintenance for supporting LOAD and UNLOAD of LOB data greater than 32 KB. In general, you should check APAR II13767 to verify the recommended maintenance when using LOBs.
125
126
Chapter 5.
127
128
Figure 5-1 Overview of SAP Web AS 6.40 on DB2 for z/OS (c) SAP AG; 2006
The SAP Web AS consists of two stacks, the ABAP stack and the Java stack. The ABAP stack is based on a kernel written in C or C++. This kernel interacts with the database by means of a database interface library, which is referred to as lib_dbsl. The Java stack uses a JDBC driver as connectivity.
5.1.3 Connectivity
SAP has used different connectivity middleware in the past. In this section, we give a short overview and explain why we only discuss distributed connections in this chapter. With SAP NetWeaver 2004s, the Integrated Call Level Interface (ICLI) connectivity was phased out and DB2 Connect was introduced. ICLI is a protocol that was delivered with z/OS; it was used by SAP in prior releases and essentially provided a subset of DRDA-like connectivity. SAP NetWeaver 2004s is also the last release to support the application server running natively on z/OS. Starting with release SAP NetWeaver 2004s, connectivity is only supported using Distributed Data Facility (DDF) on the server side and DB2 Connect on the client side. This client-side software can be either the CLI interface of DB2 Connect or the DB2 JDBC Universal Driver (JCC) for the Java stack. Therefore, we only discuss distributed connections in this chapter.
129
Also, SAP expects a performance improvement in the long run because less code is executed on the Application Server and potentially fewer SQL statements are executed on the database. Prior to the arrival of LOBs, logical SAP objects with a large amount of data attached to them had to be blocked into 32 KB chunks. Thus, for one logical object several corresponding rows would exist on the database. Assurance of consistency for write and read (under a heavy load) is then a much more difficult task. If one piece of data is changed, several rows on the database have to be locked. Currently, not all interfaces have been changed to use LOBs. For example, the SAP Cluster interface is still using blocked objects today. The reason is that the current implementation performs very well and is very critical. Also, migrating to a new data format makes an unload and load necessary. As the data volume can be huge, this is currently not feasible because this would induce long down times during the upgrade. In 5.2, ABAP and Dynpro source and Load on page 131, we discuss the REPOLOAD and REPOSRC tables as examples for SAP LOB tables. The interface to these tables is less critical than the Cluster interface, because the REPOLOAD table is buffered on the Application Server. In a production environment that has gone through the initial startup phase, the REPOLOAD and REPOSRC tables are not accessed in an extensive manner. However, this is not true for a development system.
In this section, we give an example of the total sizes of LOB columns in a Multiple Components in One Database (MCOD). See Table 5-2 on page 131. An MCOD system contains more than one SAP system. More details can be found in SAP on DB2 Universal Database for OS/390 and z/OS: Multiple Components in One Database (MCOD), SG24-6914. Each SAP system stores its data in a different schema in the same DB2 subsystem. In the example, there are three SAP Enterprise systems within one database.
130
Table 5-2
Total size of all LOB columns (c) SAP AG; 2006 Total size of all columns in KB 21,302,815 5,042 32,236
These numbers can be compared to the total size of the system as shown Figure 5-2.
Figure 5-2 Total space usage for SAP MCOD system (c) SAP AG; 2006
131
Because most of the SAP system and all of the application logic are coded into ABAP reports and Dynpros, these tables are the heart of an SAP system. Every time a report is modified, created, transported, compiled, or executed while it is not yet in the local (SAP) buffer, LOBs are read from or written to the database. Concepts such as local SAP buffering and transporting programs are SAP specific topics beyond the scope of this book. As a result, the requirements for stability, robustness, and performance for LOB objects are the same or higher as for every other data type. In Figure 5-3, we display the structure of the REPOLOAD table using SAPs Data Dictionary Tools. The columns that map to a LOB column in this case are LDATA and QDATA, with an SAP data type of RAWSTRING.
In Figure 5-4 on page 133, we display part of the structure of the REPOSRC table. The table has 34 columns in total. The column that maps to a LOB column in this case is DATA, with an SAP data type of RAWSTRING.
132
Prior to SAP Web Application Server Version 6.10, the data was stored in VARCHAR FOR BIT DATA columns. The reason why the data was shifted to LOB fields is a good example of the advantages of LOBs. For example, the table REPOSRC stores the ABAP source code in a compressed form, while the REPOLOAD table stores the compiled sources, the so-called ABAP Load. The length of a report can easily exceed the 32 KB boundary. Prior to the arrival of LOBs, the interface to these tables had to block in this case the objects accordingly into several rows. To assure consistency for write and read (under a heavy load) is then not trivial, because one logical object (an ABAP report) corresponds to a number of rows. With the use of LOBs, one row of the table corresponds exactly to one object. Because all SAP tables use row locking, this considerably simplified the interface responsible for the persistency of the ABAP reports. REPOLOAD and REPOSRC are also good examples that in SAP usage LOBs are not necessarily large objects but rather objects without length. There are many small LOBs in REPOSRC and also large ones.
133
Table 5-3 Details of Repo tables LOB content (c) SAP AG; 2006 REPOLOAD LDATA SUM AVG length Total number of rows Total < 32 KB Total (32 KB - 64 KB) Total (64 KB - 1 MB) Total >= 1 M Total > 100 M 3,390,540,497 24,865.54 136,355 114,032 10,208 12,114 1 0 REPOLOAD QDATA 1,607,356,266 11,788.03 136,355 126,566 3,709 6,080 0 0 REPOSRC DATA 2,362,162,619 1,561.80 1,512,436 1,505,927 5,134 1,375 0 0
A good test case to check LOB performance is to run transaction SGEN (see Figure 5-5). This transaction can be used to generate some or all ABAP reports. It is mainly called after an upgrade or an install, because these operations either invalidate the load or just provide the sources. The program reads data from REPOSRC (and others) where the majority of data is in a LOB column, and updates data in the LOB columns of REPOLOAD (and others). As such it is a very effective test case of LOB performance, and is also able to produce repeatable loads with the same underlying data manipulation.
134
Another good test case is to load the REPOLOAD table via R3load SAP loading tool. This tool uses mass insert without any application logic as the SAP transport tools and R3trans do.
Figure 5-6 SQL Trace for simple select using locators (c) SAP AG; 2006
135
Now, we give you an example of how LOBs are updated with locators. For the UPDATE, first a locator is retrieved. The INSERT statements work the same way. Next the data is attached to the locator. Finally, the locator is used in the statement as shown in Figure 5-7 on page 136. The locator statements in this example use table #LOBU because it is a Unicode system.
Figure 5-7 SQL Trace for update using locator (c) SAP AG; 2006
Figure 5-8 SELECT statement with LOB locators (c) SAP AG; 2006
If it is a non-Unicode system, table #LOB is used. The first host variable, the question mark character (?), is the locator on input (that is, the locator for the data already transferred to DB2. The second host variable (?) is BLOB data. The select returns a new locator pointing to the new data. Up to release SAP NetWeaver 2004s, the lib_dbsl basically uses these direct calls to locators as explained above. However, several optimizations are built on top of this. These are explained in 5.4, Optimization techniques and query rewrite on page 138. In 5.3.2, CLI Streaming Interface on page 136, we discuss an alternative using the CLI streaming APIs.
136
SQLGetSubString() is used to retrieve a portion of a large object value, referenced by a large object locator that has been returned from the server (returned by a fetch or a previous SQLGetSubString() call) during the current transaction. SQLParamData() is used in conjunction with SQLPutData() to send long data in pieces. It can also be used to send fixed-length data at execution time. SQLPutData() is called following an SQLParamData() call returning SQL_NEED_DATA to supply parameter data values. This function can be used to send large parameter values in pieces. We give you an example of a typical sequence of calls from the DB2 Connect CLI trace in Example 5-1. Note that some unimportant calls have been omitted to keep the trace reasonably small and improve readability. First, the Select from REPOLOAD is prepared, then the input and output variables are bound (omitted), the cursor is opened (omitted), the fetch is executed, and the locator is retrieved and then used to SQLGetLength() to get the length of the LOB and in SQLGetSubString() to retrieve the data.
Example 5-1 CLI trace for REPOLOAD Select using SQLGetSubString() (c) SAP AG; 2006 SQLExtendedPrepare( hStmt=1:19 ) ---> Time elapsed - +2.000000E-005 seconds ( pszSqlStr="SELECT "LDATA" FROM "REPOLOAD" WHERE "PROGNAME" = ? AND "R3STATE" = ? AND "MACH" = ? FOR FETCH ONLY WITH CS ", cbSqlStr=109, cPars=3, sStmtType=SQL_CLI_STMT_SELECT, cStmtAttrs=1( Attribute=1, piStmtAttr=SQL_CURSOR_HOLD, pvParams=0 ) SQLExtendedPrepare( ) **** SQLFetch( hStmt=1:19 ) ---> Time elapsed - +1.900000E-005 seconds sqlccsend( Handle - 0000004609406048 ) sqlccsend( ulBytes - 143 ) sqlccsend( ) rc - 0, time elasped - +4.000000E-006 sqlccrecv( ) sqlccrecv( ulBytes - 95 ) - rc - 0, time elapsed - +1.934000E-003 ( iRow=1, iCol=1, fCType=SQL_C_BLOB_LOCATOR, rgbValue=BD09179B, pcbValue=4, piIndicator=4 ) SQLFetch( ) <--- SQL_SUCCESS Time elapsed - +2.011000E-003 seconds ***** SQLGetLength( hStmt=1:20, fCType=SQL_C_BLOB_LOCATOR, iLocator=-1123477605, pcbLocator=&0000000112b006e4, piIndicatorValue=<NULL pointer> ) ---> Time elapsed - +8.000000E-006 seconds ( Row=1, iPar=1, fCType=SQL_C_BLOB_LOCATOR, rgbValue=BD09179B ) sqlccsend( Handle - 0000004609406048 ) sqlccsend( ulBytes - 132 ) sqlccsend( ) rc - 0, time elasped - +5.000000E-006 sqlccrecv( ) sqlccrecv( ulBytes - 92 ) - rc - 0, time elapsed - +1.084000E-003 ( Row=1, iPar=2, fCType=SQL_C_LONG, rgbValue=79057 ) SQLGetLength( pcbLocator=79057 ) <--- SQL_SUCCESS Time elapsed - +1.230000E-003 seconds **** SQLGetSubString( hStmt=1:20, fCType=SQL_C_BLOB_LOCATOR, iLocator=-1123477605, iFrom=1, iLength=9, fCTypeTarget=SQL_C_BINARY, rgbValue=&0000000113063ff0, cbValueMax=9, pcbValue=&0fffffffffffbe9c, piIndicatorValue=&0fffffffffffbd64 ) ---> Time elapsed - +8.000000E-006 seconds ( Row=1, iPar=1, fCType=SQL_C_BLOB_LOCATOR, rgbValue=BD09179B ) sqlccsend( Handle - 0000004609406048 ) sqlccsend( ulBytes - 132 ) (c) SAP AG; 2006 sqlccsend( ) rc - 0, time elasped - +4.000000E-006 Chapter 5. SAP usage of LOBs
137
sqlccrecv( ) sqlccrecv( ulBytes - 92 ) - rc - 0, time elapsed - +2.895000E-003 ( Row=1, iPar=2, fCType=SQL_C_LONG, rgbValue=79057 ) ( Row=1, iPar=1, fCType=SQL_C_BLOB_LOCATOR, rgbValue=BD09179B ) ( Row=1, iPar=2, fCType=SQL_C_LONG, rgbValue=1 ) ( Row=1, iPar=3, fCType=SQL_C_LONG, rgbValue=9 ) sqlccsend( Handle - 0000004609406048 ) sqlccsend( ulBytes - 148 ) sqlccsend( ) rc - 0, time elasped - +8.000000E-006 sqlccrecv( ) sqlccrecv( ulBytes - 111 ) - rc - 0, time elapsed - +1.802000E-003 ( Row=1, iPar=4, fCType=SQL_C_BINARY, rgbValue=x'FFA42B0400121F9D02', pcbValue=9, piIndicatorPtr=9 )
These APIs can only be used with the new MERGE statement available with DB2 9 for z/OS. In DB2 V8, the MERGE statement has to be emulated by a series of Update and Insert statements. The SQLPutData is not suited for this, because the data has to be sent prior to the insert and update.
When writing, the pieces are not directly written to the database but into the buffer. The buffer is flushed to the database once it is filled or the last piece is written.
Figure 5-9 Modified statement (extended DA) on REPOLOAD (c) SAP AG; 2006
In this case, we retrieve the length, the data, and the locator. The data and locator appear both as LDATA. The data type specifies the difference. Obviously this technique requires a manipulation of the statement itself. Because the database layer under normal circumstances does not parse the statement, this technique is restricted to special interfaces, the so-called trusted interfaces, and several well known statements on SAP report and Dynpro source and Load tables. The parameter dbs/db2/use_eda of the dbsl_lib profile controls this extended description area feature. It is called extended because it includes the length and the data. If use_eda is set to 0, the extended da feature is turned off.
139
The amount of storage connected to the locators is tracked. If this storage exceeds a given threshold (normally 1 GB), then the locators are freed. The threshold can be adjusted by profile parameter dbs/db2/max_lob_free_length (in MB). Note that the same number of host variables are always used for the FREE LOCATOR statement, so that only one slot in the statement cache is used. To fill up the missing host variables, the last locator is repeated. DB2 issues an SQLCODE -423 (Invalid locator value). This code is ignored by the database interface. At every Commit or Rollback, the buffer is reset. With DB2 9, the new concept of the progressive reference is introduced. These references are implicitly freed when the cursor is closed. Therefore, the free locator buffer becomes obsolete with DB2 9.
5.4.5 Chaining
It is possible to have a reduction of network flows with CLI array input chaining. CLI array input chaining is a feature that, when enabled, causes requests for the execution of prepared insert, update, and delete statements to be held and queued at the client until the chain is ended. Once the chain has been ended, all of the chained SQLExecute() requests at the client are then sent to the server in a single network flow. Chaining avoids LOBs or sparsely filled long variable length columns filling up the internal SAP buffer for array operations. The effect is that data gets buffered within the CLI layer, reducing the network flow and the number of SQL statements executed. The following sequence of events (presented as pseudo code) is an example of how CLI array input chaining can reduce the number of network flows to the server. The statement attribute SQL_ATTR_CHAINING_BEGIN is set in order to turn chaining on. To turn chaining off, the SQL_ATTR_CHAINING_END attribute is set. See Example 5-2.
Example 5-2 Pseudo code for chaining (c) SAP AG; 2006 db2rc db2rc db2rc .... db2rc = SQLSetStmtAttr(*stmth_p, SQL_ATTR_CHAINING_BEGIN,(SQLPOINTER) 1, SQL_IS_UINTEGER ); = SQLEXECUTE ( stmth ) ; = SQLEXECUTE ( stmth ) ; = SQLSetStmtAttr(*stmth_p, SQL_ATTR_CHAINING_END,(SQLPOINTER) 1, SQL_IS_UINTEGER );
Example 5-3 Chaining on insert (c) SAP AG; 2006 5.125 CO2MAP REEXEC 13 0 DELETE WHERE "ID" = 1105 11 CO2MAP EXECSTA 0 0 START CHAIN (cursor=70, statement=INSERT INTO "CO2MAP" VALUES( ? , ? , ? , ? , ? , ? ) ) 20 CO2MAP REEXEC 0 0 INSERT VALUES( 1105 , 18 , 2 , 1105 , 0 , 0 ) 13 CO2MAP REEXEC 0 0 INSERT VALUES( 1105 , 19 , 3 , 1105 , 0 , 0 ) 13 CO2MAP REEXEC 0 0 INSERT VALUES( 1105 , 21 , 4 , 1105 , 0 , 0 ) 13 CO2MAP REEXEC 0 0 INSERT VALUES( 1105 , 22 , 5 , 1105 , 0 , 0 ) 13 CO2MAP REEXEC 0 0 INSERT VALUES( 1105 , 24 , 9 , 1105 , 0 , 0 ) 13 CO2MAP REEXEC 0 0 INSERT VALUES( 1105 , 27 , 11 , 1105 , 0 , 0 ) 13 CO2MAP REEXEC 0 0 INSERT VALUES( 1105 , 30 , 14 , 1105 , 0 , 0 ) 13 CO2MAP REEXEC 0 0 INSERT VALUES( 1105 , 32 , 14 , 1105 , 0 , 0 ) 12 CO2MAP REEXEC 0 0 INSERT VALUES( 1105 , 34 , 14 , 1105 , 0 , 0 ) 12 CO2MAP REEXEC 0 0 INSERT VALUES( 1105 , 36 , 16 , 1105 , 0 , 0 ) 13 CO2MAP REEXEC 0 0 INSERT VALUES( 1105 , 38 , 16 , 1105 , 0 , 0 ) 13 CO2MAP REEXEC 0 0 INSERT VALUES( 1105 , 40 , 26 , 1105 , 0 , 0 ) 32 CO2MAP REEXEC 0 0 INSERT VALUES( 1105 , 43 , 36 , 1105 , 0 , 0 ) 2.863 CO2MAP EXECSTA 13 0 STOP CHAIN (cursor=70, statement=INSERT INTO "CO2MAP" VALUES( ? , ? , ? , ? , ? , ? ) )
The first number to the right gives the execution time in microseconds. You can see that the inserts are very fast, because they are just client-side operations. The chain buffer is then flushed to the database at chain end time. One restriction to CLI chaining is that it can only be applied to one statement at a time; if several statements are open at the same time, then the chain buffer must be flushed before a new statement can execute. Chaining helps with mass insert, for example, when loading the REPOLOAD table. It does not help with single LOB operations such as those used by transaction SGEN. Chaining is always used for LOBs. In the other cases, the chaining behavior is governed by the dbsl profile parameter dbs_db2_chaining. If the number of rows fitting into the internal buffer is less than or equal to the value set in dbs_db2_chaining, chaining is used. The internal buffer usually has a size of 32 KB. The default for dbs_db2_chaining is 20. To turn chaining completely off, it must be set to 0. The effect on LOB insert is shown in Example 5-4 where a copy of the REPOLOAD table is loaded with all LOBs chained.
Example 5-4 R3load log files for dbs_db2_chaining=20 (c) SAP AG; 2006
(DDL) Info: Deleting data from ZZNPSOURCE Time : 20060124 104145 (DB) INFO: ZZNPSOURCE deleted/truncated (IMP) INFO: import of ZZNPSOURCE completed (34834 rows) #20060124 104238 (DB) INFO: disconnected from DB R3load: job completed R3load: END OF LOG: 20060124 104238 The total time for the import is 53 seconds. The case where no LOBs are chained is shown in Example 5-5.
Example 5-5 R3load log files for dbs_db2_chaining=0 (c) SAP AG; 2006
141
(DB) INFO: ZZNPSOURCE deleted/truncated (IMP) INFO: import of ZZNPSOURCE completed (34834 rows) #20060124 122542 (DB) INFO: disconnected from DB R3load: job completed R3load: END OF LOG: 20060124 122542
The total time for the import is 79 seconds. This yields an improvement of about 33%.
.... String insertStmt = "insert into "+ TEST_TABLE + " (FCHAR4, FINT, FCLOB, FBLOB) " + "values (?, ?, ?, ?)"; try { PreparedStatement ps = getConnection().prepareStatement(insertStmt); ps.setString(1, "A"); ps.setInt(2, 1); char[] cArray = { ' ', 'B', 'C' }; Reader r = new CharArrayReader(cArray); ps.setCharacterStream(3, r, cArray.length); byte[] bArray = { 'D', 'E', 'F' }; ByteArrayInputStream bais = new ByteArrayInputStream(bArray); ps.setBinaryStream(4, bais, bArray.length); int cnt = ps.executeUpdate();
ps.setString(1, "UXYZ"); ps.setInt(2, 3); Reader ucReader = new CharArrayReader(ucArray); ps.setCharacterStream(3, ucReader, ucArray.length); ps.setBinaryStream(4, null, 0); cnt = ps.executeUpdate(); ..... Reader r = null; InputStream is = null; String query ="select FCLOB, FBLOB from " + TEST_TABLE + " " + "where FCHAR4 = 'A' and FINT = 1"; try { Statement stmt = getConnection().createStatement(); ResultSet rs = stmt.executeQuery(query);
142
if (rs.next()) { r = rs.getCharacterStream(1); r.read(cArray2); is = rs.getBinaryStream(2); is.read(bArray2); .... For the JCC driver, two properties are important with respect to LOBs when running on DB2 V8: fullyMaterializeLobData LOB locator support The DB2 Universal JDBC Driver can use LOB locators to retrieve data in LOB columns. To cause JDBC to use LOB locators to retrieve data from LOB columns, you need to set the fullyMaterializeLobData property to false. fullyMaterializeInputStreams The property above, fullyMaterializeLobData, only affects the streams coming from the server to the client, while the property fullyMaterializeInputStreams only affects the streams going from the client to the server. To use locators with the Java stack, both properties need to be set because the JCC driver is not reentrant. Otherwise, it would be possible that a stream is inserted that is constructed as a read of a LOB field from the database.
DB2LobTableCreator utility
If LOB locators are used to access DBCLOB or CLOB columns, the JCC driver uses the database tables SYSIBM.SYSDUMMYU, SYSIBM.SYSDUMMYA, and SYSIBM.SYSDUMMYE for fetching data. This can be achieved by either of the following: On the DB2 for z/OS servers: Customize and run job DSNTIJSG when you install a new DB2 9 or job DSNTIJMS for post-installation. These jobs are located in data set prefix.SDSNSAMP. On the client: Run the com.ibm.db2.jcc.DB2LobTableCreator utility against each of the DB2 for z/OS servers. See DB2LobTableCreator utility for details. Normally, this task is done on the server with job DSNTIJMS. For more information, go to: http://publib.boulder.ibm.com/infocenter/db2luw/v9/index.jsp?topic=/com.ibm.db2.ud b.apdv.java.doc/doc/r0023715.htm
143
However, huge LOBs must be read piece-wise, because otherwise, the client runs out of memory. In the SAP Portal, clients can store in principle any amount of data, for example, they can store complete videos with more than 500 MB. Because with DB2 V8, there is only the global property fullyMaterializeLobData, which applies to all statements executed using this connection, locators must always be used to retrieve any LOB within connections which access large LOBs. The Progressive streaming property specifies whether the JDBC driver uses progressive streaming when progressive streaming is supported on the database server. This is the case for DB2 9 but not V8. The value of the streamBufferSize parameter determines whether the data is materialized when it is returned. Valid values are DB2BaseDataSource.YES (1) and DB2BaseDataSource.NO (2). If the progressiveStreaming property is not specified, the progressiveStreaming value is DB2BaseDataSource.NOT_SET (0). If the connection is to a database server that supports progressive streaming, and the value of progressiveStreaming is DB2BaseDataSource.YES or DB2BaseDataSource.NOT_SET, the JDBC driver uses progressive streaming to return both LOBs and XML data. Therefore, by default progressive streaming is enabled. If the value of progressiveStreaming is DB2BaseDataSource.NO or the database server does not support progressive streaming, the way in which the JDBC driver returns LOB or XML data depends on the value of the fullyMaterializeLobData property. The streamBufferSize property specifies the size, in bytes, of the JDBC driver buffers for chunking LOB or XML data. The JDBC driver uses the streamBufferSize value whether or not it uses progressive streaming. The default is 1 MB. If the JDBC driver uses progressive streaming, LOB or XML data is materialized if it fits in the buffers and the driver does not use the fullyMaterializeLobData property. With the change to progressive streaming, attention has to be paid to the changed behavior when using progressive references as compared to the use of locators with V8 fullyMaterializeLobData=false. The progressive reference is freed when the cursor is closed, while in V8, it was only freed at commit. Example 5-7 shows a snippet from the code to be adapted for use with progressive references.
Example 5-7 Insert using progressive reference (c) SAP AG; 2006
Clob cl = null; Blob bl = null; // retrieve values via progressive reference // assuming length of FLOB and FBLOB is greater than streamBufferSize String query = "select FCLOB, FBLOB from TSTLOBTAB where FCHAR4 = 'A' and FINT = 1"; Statement stmt = getConnection().createStatement(); ResultSet rs = stmt.executeQuery(query); if (rs.next()) { cl = rs.getClob(1); bl = rs.getBlob(2); } rs.close(); // this will not work in DB2 9 with // Progressive Streaming
144
// DB2 will issue SQLCode -423 // update the second row with the LOB field values of the 1st row String updStmt = "update TSTLOBTAB set FCLOB = ?, FBLOB = ? where FCHAR4 = 'B' and FINT = 2"; ps = getConnection().prepareStatement(updStmt); ps.setClob(1, cl); ps.setBlob(2, bl); ps.executeUpdate(); ps.close(); // rs.close(); // DB2 9: close ResultSet here!
145
LOB fields are always created with a length of 1 GB, because this is the maximum length which can be logged in V8. With DB2 9, this length is increased to the maximum size of a LOB, 2 GB-1 bytes, and the SAP Data Dictionary is adapted accordingly. The LOB table spaces are always created with BP40. This buffer pool allocation is again an SAP specific choice that is part of a broader buffer pool management scheme. It does, however, demonstrate a broad recommendation to separate LOB objects into distinct separate buffer pools because of their different attributes. More information about buffer pool considerations can be found in 8.3, Buffer pools and group buffer pools on page 246.
LOBVALS
50000M
5.6.4 ROWID
DB2 V8 has introduced the concept of transparent ROWID. Prior to V8, the ROWID was visible to INSERT or SELECT statements, which did not specify a field list. It can be advantageous to normalize SELECT and INSERT statements to statements without a field list, because this cuts down the number of statements against a table and thus reduces stress on statement cache. This technique can be only used in SAP Unicode systems because the non-Unicode tables might have been created on DB2 V7 and then migrated to DB2 V8. Even with a transparent ROWID, the SAP data dictionary has to hide the ROWID field, because it is visible with catalog SELECTs. SAP in practice hides the visibility of this column from the ABAP programmers for the tables containing LOB columns. This is important for application portability across SAP systems using different underlying DBMSs.
146
<?xml version=1.0?> <Dbtable name=TSTLOBDDL creation-date=> <properties> <author> </author> <description language=></description> </properties> <predefined-action></predefined-action> <position-is-relevant></position-is-relevant> <deployment-status></deployment-status> <columns> <column name = F1> <position>1</position> <dd-type>string</dd-type> <java-sql-type>VARCHAR</java-sql-type> <length>10</length> <decimals>0</decimals> <is-not-null>true</is-not-null> <default-value> 1 </default-value> </column> <column name = F2> <position>17</position> <dd-type>binary</dd-type> <java-sql-type>BLOB</java-sql-type> <length>0</length> <decimals>0</decimals> <is-not-null>false</is-not-null> <default-value></default-value> </column> <column name = F3> <position>14</position> <dd-type>string</dd-type> <java-sql-type>CLOB</java-sql-type> <length>1334</length> <decimals>0</decimals> <is-not-null>false</is-not-null> <default-value></default-value> </column> </columns> <primary-key> <tabname>TSTLOBDDL</tabname> <columns> <column>F1</column> </columns> </primary-key> </Dbtable> With DB2 V8, this results in the DDL shown in Example 5-9.
(c) SAP AG; 2006
147
Example 5-9 DDL for LOB table DB2 V8 (c) SAP AG; 2006
SET CURRENT RULES = 'DB2'; CREATE TABLESPACE "TSTLOBD" IN "JD0XXTPB" USING STOGROUP SAPR3L FREEPAGE 20 PCTFREE 16 GBPCACHE CHANGED DEFINE YES BUFFERPOOL BP2 LOCKSIZE ROW LOCKMAX 1000000 CLOSE YES COMPRESS YES MAXROWS 255 SEGSIZE 20 CCSID UNICODE; COMMIT: CREATE TABLE "TSTLOBDDL"( "F1" VARGRAPHIC(10) DEFAULT ' 1' NOT NULL, "F2" BLOB (1G) , "F3" DBCLOB (500M) ); IN JD0XXTPB.TSTLOBD CCSID UNICODE; COMMIT; CREATE LOB TABLESPACE LTSTLOUX IN JD0XXTPB USING STOGROUP SAPR3L LOG YES LOCKMAX 0 GBPCACHE SYSTEM LOCKSIZE LOB DEFINE YES BUFFERPOOL BP40; COMMIT; CREATE AUX TABLE "#F2UX6" IN JD0XXTPB.LTSTLOUX STORES "TSTLOBDDL" COLUMN "F2" CREATE INDEX "#F2UX6" ON "#F2UX6" USING STOGROUP SAPR3L FREEPAGE 10 PCTFREE 10 GBPCACHE CHANGED PIECESIZE 2097152 K DEFINE YES BUFFERPOOL BP40; COMMIT; CREATE LOB TABLESPACE LTSTLO1W IN JD0XXTPB USING STOGROUP SAPR3L LOG YES LOCKMAX 0 GBPCACHE SYSTEM LOCKSIZE LOB DEFINE YES BUFFERPOOL BP40; COMMIT; CREATE AUX TABLE "#F31WO" IN JD0XXTPB.LTSTLO1W STORES "TSTLOBDDL" COLUMN "F3"; CREATE INDEX "#F31WO" ON "#F31WO" USING STOGROUP SAPR3L FREEPAGE 10 PCTFREE 10 GBPCACHE CHANGED PIECESIZE 2097152 K DEFINE YES BUFFERPOOL BP40; COMMIT; CREATE UNIQUE INDEX "#TSTLOBDDLP8P" ON "TSTLOBDDL" ( "F1" ASC ) NOT PADDED USING STOGROUP SAPR3L FREEPAGE 20 PCTFREE 16 GBPCACHE CHANGED DEFINE YES CLUSTER BUFFERPOOL BP2 CLOSE YES DEFER NO COPY YES PIECESIZE 2097152 K; COMMIT ALTER TABLE "TSTLOBDDL" ADD PRIMARY KEY ( F1 ); COMMIT; Note that SAP tends to compress most data, but in the statement in Example 5-9 on page 148, COMPRESS YES only works for the base table space, because as of DB2 9, LOB tables cannot be compressed. The table space names and database names have to be calculated and checked for possible namespace collisions by the dictionary interface. In this case, this is performed automatically as part of the database interface layer, but non-SAP applications need to consider their naming conventions to similarly ensure no overlapping in the name spaces of objects. With DB2 9, this DDL simplifies considerably, as shown in Example 5-10.
Example 5-10 DDL for LOB table DB2 9 (c) SAP AG; 2006
CREATE TABLE "TSTLOBDDL" ("F1" VARGRAPHIC(10) DEFAULT ' "F2" BLOB (1G) , "F3" DBCLOB (500M) ) CCSID UNICODE; 148
LOBs with DB2 for z/OS: Stronger and Faster
COMMIT; ALTER TABLE "TSTLOBDDL" ADD PRIMARY KEY ( F1 ); COMMIT; The new DB2 9 feature of implicitly created DB objects is a tremendous help when porting applications. This feature is described in 3.1.1, Example of automatic creation of objects on page 24. This feature will be used by SAP and will remove the need for special code in the database interface that previously handled this task. Some applications simply deliver SQL scripts, which contain the necessary DDL and which run on other DBMSs, such as DB2 for Linux, UNIX and Windows. With this new feature, these scripts run on DB2 for z/OS without modification. Differently from DB2 V8, tables can be assigned by default to databases other than DBSNDB04 and have attributes such as row locking instead of page locking.
Whats missing
What is still missing is just the feature to enable ALTER to hide ROWID, that is, the capability to change a non-transparent ROWID into a transparent one. This would allow tables within an SAP system, with LOBs created prior to the transparent ROWID, to be easily converted to take advantage of the new feature.
5.7 Unicode
There are some differences with respect to LOBs for Unicode and non-Unicode systems. Because SAP uses UTF16 as Unicode code page, character fields are stored in VARGRAPHIC instead VARCHAR, and CLOB data is stored in DBCLOB fields. As a consequence of this, the Bind for DB2 Connect CLI must use a different collection ID for non-Unicode and Unicode systems. See Example 5-11.
Example 5-11 Bind command for UNIX system (c) SAP AG; 2006
db2 bind <Instance directory>/sqllib/bnd/@ddcsmvs.lst ACTION REPLACE KEEPDYNAMIC YES GENERIC \"DEFER PREPARE\" REOPT ONCE COLLECTION SAP<FIXPAK><U> ISOLATION UR BLOCKING UNAMBIG RELEASE COMMIT SQLERROR CONTINUE DYNAMICRULES RUN <ENCODING UNICODE> All locator statements are bound regardless of the Encoding Bind Option with DB2 Connect 9.1 SP1. The same Collection ID can be used for Unicode and non-Unicode systems. Another important point is that long character fields that are naturally mapped to VARCHAR in a non-Unicode environment cannot be mapped to VARGRAPHIC in a Unicode environment if their character length exceeds the threshold of 16 KB (since their byte length then exceeds the 32 KB boundary). DB2 does not support buffer pools greater than 32 KB; therefore, they have to be mapped to DBCLOB fields. As a consequence, there are a greater number of LOB fields in a Unicode environment.
Compression
SAP recommends to use compression for Unicode systems. The potential of database compression for a Unicode system is considerably higher than for a non-Unicode system. The reason is that data stored in UTF16 still has a high percentage of data mapped to ASCII; this means that the first two bytes of the UTF16 character contain mostly x00. Currently, compression is not available for LOB columns.
(c) SAP AG; 2006
149
If the content of DBCLOB columns keeps increasing, the requirement for compression for LOB fields becomes more urgent.
150
151
Table 5-6 Comparison of different databases for aspects of LOBs (c) SAP AG; 2006 DB2 for z/OS ROWID column required? ROWID column supported? Auxiliary table spaces for LOBs? Read piece-wise supported? Read in one piece supported? Validity of locator? Maximum number of LOB fields per table? Search function on LOBs supported? Concatenation of LOBs supported? JDBC driver supports materialization of LOBs on client side? Can materialization be switched on and off? Yes Yes Must Yes Yes Until commit > 750 DB2 for LUW No No Can Yes Yes Until commit No restriction DB2 for iSeries No No No Yes Yes Until commit No restriction Others No Mostly no Some can Yes Most Some until close cursor Some only few
Yes
Yes
Yes
Some
Yes Yes
Yes Yes
Yes Yes
Yes
Yes
Yes
Some yes
DBSL trace
With dbsl trace level 3, all displayed data is truncated at 256 bytes. With dbsl trace 4, all LOB data is displayed. Go to transaction DB2 Traces/Logs DBSL to start the trace. See Figure 5-10 on page 153.
152
Figure 5-10 Starting the dbsl trace (c) SAP AG; 2006
All data is traced to the corresponding developer traces. This feature is particularly helpful if corrupted LOB data is suspected. Example 5-12 shows how a BLOB looks.
Example 5-12 DBSL trace displaying all LOB data (c) SAP AG; 2006 C DB2TRC: 0000000072 00 0015 000000 CLI_EXTENDED_PREPARE (18) SELECT "UNAM" , "UDAT" , "UTIME" , "L_DATALG" , "Q_DATALG" , "SDAT" , "STIME" , "MINOR_VERS" , "MAJOR_VERS" FROM "REPOLOAD" WHERE "PROGNAME" = ? AND "R3STATE" = ? AND "MACH" = ? FOR FETCH ONLY WITH UR C DB2TRC: 0000000007 00 0015 000000 CLI_EXTENDED_BIND IN 65552 C DB2TRC: 0000000004 00 0015 000000 CLI_EXTENDED_BIND OUT 65552 C DB2TRC: 0000008182 00 0015 000000 CLI_EXECUTE 65552 cursor_hold = off C DB2TRC: CLIDA-IN BEGIN C DB2TRC: CLIDA-IN PARAMETER 3 C DB2TRC: CLIDA-IN [0](SQL_VARCHAR,8,40):SAPMSSY6 C DB2TRC: CLIDA-IN [1](SQL_VARCHAR,1,1):A C DB2TRC: CLIDA-IN [2](SQL_SMALLINT,2,2):324 C DB2TRC: CLIDA-IN END C DB2TRC: 0000000009 00 0015 000000 CLI_FETCH 1/1 65552 C DB2TRC: CLIDA-OUT BEGIN C DB2TRC: CLIDA-OUT PARAMETER 9 C DB2TRC: CLIDA-OUT [0](SQL_VARCHAR,1,12): C DB2TRC: CLIDA-OUT [1](SQL_VARCHAR,8,8):20060728 C DB2TRC: CLIDA-OUT [2](SQL_VARCHAR,6,6):064459 C DB2TRC: CLIDA-OUT [3](SQL_INTEGER,4,4):16124 C DB2TRC: CLIDA-OUT [4](SQL_INTEGER,4,4):6397 C DB2TRC: CLIDA-OUT [5](SQL_VARCHAR,8,8):20060417 C DB2TRC: CLIDA-OUT [6](SQL_VARCHAR,6,6):062251 C DB2TRC: CLIDA-OUT [7](SQL_SMALLINT,2,2):1 C DB2TRC: CLIDA-OUT [8](SQL_INTEGER,4,4):1623 C DB2TRC: CLIDA-OUT END C DB2TRC: 0000000006 00 0015 000000 CLI_CLOSE_CURSOR 65552 C DB2TRC: 0000000008 00 0016 000000 CLI_ALLOC_STMT 65553 C DB2TRC: 0000000004 00 0016 000000 CLI_SET_ROWS_FETCHED_VAR 65553 C DB2TRC: 00 0016 000000 SQLESETI 65553 C DB2TRC: ( ) C DB2TRC: 0000000050 00 0016 000000 CLI_EXTENDED_PREPARE (18) SELECT length("LDATA") ,"LDATA" , "LDATA" FROM "REPOLOAD" WHERE "PROGNAME" = ? AND "R3STATE" = ? AND "MACH" = ? FOR FETCH ONLY WITH CS C DB2TRC: 0000000005 00 0016 000000 CLI_EXTENDED_BIND IN 65553 C DB2TRC: 0000000003 00 0016 000000 CLI_EXTENDED_BIND OUT 65553 C DB2TRC: 0000008069 00 0016 000000 CLI_EXECUTE 65553 cursor_hold = off C DB2TRC: CLIDA-IN BEGIN C DB2TRC: CLIDA-IN PARAMETER 3 C DB2TRC: CLIDA-IN [0](SQL_VARCHAR,8,40):SAPMSSY6 C DB2TRC: CLIDA-IN [1](SQL_VARCHAR,1,1):A C DB2TRC: CLIDA-IN [2](SQL_SMALLINT,2,2):324 C DB2TRC: CLIDA-IN END (c) SAP AG; 2006 C DB2TRC: 0000003566 00 0016 000000 CLI_FETCH 1/1 65553 Chapter 5. SAP usage of LOBs
153
C DB2TRC: CLIDA-OUT BEGIN C DB2TRC: CLIDA-OUT PARAMETER 3 C DB2TRC: CLIDA-OUT [0](SQL_INTEGER,4,4):16124 C DB2TRC: CLIDA-OUT [1](SQL_BLOB_LOCATOR,4,4):AF1B059B C DB2TRC: CLIDA-OUT [2](SQL_BLOB,16124,64000):FF0AD10000121F9D02B4EF25005215D7DAA76EDFEE59617A60403671D851417A8 64540C0E999E9611A7A669AEE1E04151B04141790006E7149AB68E29A7125BB9868824B12624C4C8C896D342E31 2F92C5C42426E16912CD62C4EC6A0CFF3955A7EEAD7BA7866062DECBFBDF3B7097F37DB59E3A75AAEE9DDB49800 71ED847 C DB2TRC: A77C32DB95CFAF9CD3F877A43991989398D57474624E73F3EC261000B1E3E0C821E96557C7D7DEF5A3D641CE5F3 61E07F0AD6AD0E2342F41BD0520DA88DA7C80481660549F2287DE82A749788C02A89B8A57CE278A74C2B2E7C2C0 B2409EE3300DA2F011BC136213E6111E2F8CF301449C1302BE0E70FA4E6CF86A8077E371 C DB2TRC: 171EBB7603DC99C563B57184F53E907205E21734025C82D85D253CCA009FDF0DF0A9B8E2DBF6E27D1FC071C8ADC 4EB86B2BADEC9C770E45B116B2BABB474505ADB713BF8F9CC83DA4CF585F1293341DA5AC9FEFDFA4E4A6540F3A4 58CCF7F302C508D1E4A512CAD286B5451F44D45D8A4EBB1CA0C1AA5F5852E0AEE11B9B61 C DB2TRC: 080C455DE0E17C46C1887FFB34C41BFAE3575F89F8B0FEB87B2AE2C3FBE3DB06217E487FFCF91F213EA23F5EF73 8E223FBE1B1CFDC0187C1A18C8F256C2180BB505DBD033DF62F6BF15A8A4004AF4EB91AE2559568906DE01E0F64 1944FEA6CABC2302434B682A898B727589CDB608A04638220251E14A1D6D26A265CFA852 C DB2TRC: 8F95D9ACAACE680394C0151B8A50861DF087577780A8B8876C3D4A54EE8843F41ECA3D1AB94B60CC8E4B41ECC04 11F0EF04351856539307A0ED225072AF03E3A9BEE232272295E5D2A7B0A968DD3EC4ED46354CE0858307B3F7C5B 548B9A28B94B23A4A231BC4E85EEE860BC1E05BD77623A2CB35AD4C2EB220A115D26636F C DB2TRC: 603D3BB08C2DE50A88C96B254477C01F9FC4760FC2F656C8F68E2DD7CAEB61E541F2DA581E4CED46FBEC108343F 6A9C39258A41E2F47037A7DD9736CA3DFE76CC0123E80DD2C41C9D5FC07A80FA6DEE2B8E5C1E5B8CF3B58A2AFA7 22CE27CAD172CCD3B166D2CB754A8F4461C61CF2857A3104EB241B407948C9A5FB89E07C C DB2TRC: BC3CB41C17D1FDBF4FC575094AC856E50631147B397607CCAB47DB34C8316D2C0F431B450618CBA1689F941816B 2CF7071882E57EA23C4C8803E4A7B1F008E078DD19BAED8FFCD68AC44069F2ADB1929BB2206B11BA01C990F6577 7E2D46F28A7215565211C084183DBF46715595983F018DD43E4CB95B08EEB35316D8D686 C DB2TRC: B7A9AD7FC5CC11BE7F5DD7297D1A7DCEB333D51905ED837FC5BE44F45C5569A5FF57E07C2DA14F4F459F2EA14FC FE572DFB8CFF57D3AE28083AA8B9C23C68808DE0FD7BEAD399AFF620CCCC0FB3A5D67884BE07D25736F321761AE E95D15C69C5B0023643B6A44B59C7329689473AE1BDB49FEDA0B47D19CA3F694015EDB01 C DB2TRC: 67ED467F3954C70079A5F91FF29BEB95196183538E7E85EF6D71ED206392A375E93773D86F9C7284FDC6994F7EA 2FCC665BFF131DF6F5CB67954DB57CE19B7E460EDF25E54971C87EF118F203EEC207D696C40B7F8921E1BE9B358 12FAAC5BE196E45603D598C2A7D4515B143EA5AED2455F19030BFEABC60BC724628E4F1F C DB2TRC: 4015AE4BEEC25209D421220B4B65984CF607E9D783EE70E1E812A65D81ED298168C40D938C9198B73A98B7846B5 CC931EAEAE70F14CFCBA264D68B79CAC252EFE03BA2309FAC8CD7634A406B29D62FA89E40DD9CBFE4E01119A89F 35980F17D11546BDDC66CAFBAFEBAFAE57F6DBE9D76FC752FFE8B7D06F47F79BF28B7118 .................................................... .................................................... C DB2TRC: CLIDA-OUT END C DB2TRC: 0000000812 00 0016 000000 CLI_CLOSE_CURSOR 65553
Examples for the DB2 Connect CLI traces are given in Example 5-1 on page 137 and in Figure 5-6 on page 135 for the ST05 trace. We now provide an example of the IFI DB Trace using the SAP Performance Optimizer. See Figure 5-11 on page 155. You can download the SAP Performance Optimizer tool from SAP note 908770.
154
Figure 5-11 SAP Performance Optimizer Tool (c) SAP AG; 2006
Figure 5-12 SAP Performance Optimizer Tool DB Trace (c) SAP AG; 2006
In Example 5-13 on page 156, we show the locking behavior for DB2 V8.
155
Example 5-13 Locks taken by simple SELECT on LOB table V8 (c) SAP AG; 2006
023921:646261 023921:646361 023921:646734 023921:647685 023921:647815 023921:647953 023921:648520 023921:649644 023921:649820 023921:875842 023921:876030 023921:876101 023921:876184 023922:079864 023922:080889 023922:081011 3.594 00000 00016448 PREPARE CURSOR SQL_CURLH200C2 00004 00000000 CHANGE L ANY MANUAL+1 Data Page BIND select FCLOB, FBLOB from TSTLOBTAB where FCHAR4 = ? and FINT = ? 00000 7DC5DAE0 LOCK S MANUAL Data Page ID=9 DSNDB06 00004 7DC5DAE0 LOCK S MANUAL Data Page ID=9 DSNDB06 00004 7DC5DAE0 LOCK S MANUAL Data Page ID=9 DSNDB06 00004 7DC5DAE0 LOCK S MANUAL Data Page ID=9 DSNDB06 00004 00000000 UNLOCK ANY MANUAL Data Page 35 00000 00016448 OPEN CURSOR SQL_CURLH200C2 CS 382 00000 00016448 FETCH SQL_CURLH200C2 00004 7DC55210 LOCK S MANUAL Data Page ID=117 DSNDB04 00004 7F3686B0 LOCK S COMMIT+1 LOB value L9KBRB0M DSNDB04 00004 7F3686B0 LOCK S COMMIT+1 Data Page 00000 7DC5DAE0 LOCK S COMMIT SKPT 2.685 00000 00016448 PREPARE CURSOR SQL_CURLN200C1 BIND SELECT LENGTH (CAST(? as DBCLOB)) FROM SYSIBM.SYSDUMMYU
Example 5-14 shows the locking behavior for DB2 9. It demonstrates that LOB locks are no longer taken.
Example 5-14 Locks taken by simple SELECT on LOB table with DB2 9 (c) SAP AG; 2006
024656:730414 024656:731023 024656:731114 024656:731222 024656:731726 024656:732879 024656:733073 024656:960803 C0 LOCK S 024657:165879 024657:165949 024657:165975 024657:166163 024657:166205 024657:166243 024657:166257 024657:166268 024657:166337 024657:166351 024657:191520 024657:202313 0 024657:257137 024657:257152 024657:257698 024657:258542 024657:258673 BIND select FCLOB, FBLOB from TSTLOBTAB where FCHAR4 = ? and FINT = ? 00004 7F5BFF80 LOCK S MANUAL Data Page ID=9 DSNDB06 00004 7F5BFF80 LOCK S MANUAL Data Page ID=9 DSNDB06 00004 7F5BFF80 LOCK S MANUAL Data Page ID=9 DSNDB06 00004 7F5BFF80 LOCK S MANUAL Data Page ID=9 DSNDB06 00004 00000000 UNLOCK ANY MANUAL Data Page 50 00000 00016448 OPEN CURSOR SQL_CURLH200C2 CS 277 00000 00016448 FETCH SQL_CURLH200C2 MANUAL Data Row TMPROSQL DSN02348 00004 00000000 CHANGE L ANY MANUAL+1 Data Page 00000 7F5BDB80 LOCK IS MANUAL+1 Page Set SYSPKAGE DSNDB06 00000 7F5BF340 LOCK IS MANUAL+1 Table SYSPACKAUTH 00000 7F5C3190 LOCK S MANUAL Data Page ID=143 DSNDB06 00000 7F5C3190 UNLOCK S COMMIT+1 Data Page 00004 00000000 UNLOCK ANY MANUAL Data Page 00000 00000000 UNLOCK IS MANUAL+1 Table SYSPACKAUTH 00000 00000000 UNLOCK IS MANUAL+1 Page Set SYSPKAGE DSNDB06 00000 7F5BDB80 LOCK IS COMMIT Page Set ID=127 ID=1 00000 7F5BF340 LOCK IS COMMIT Table ID=129 00000 7F5C3190 LOCK S MANUAL Data Page ID=129 ID=1 00000 7F5B9EB0 LOCK S COMMIT SKPT 00000 7F5C3190 UNLOCK 00000 7F5C3190 LOCK 00000 7F5C3190 UNLOCK 00016448 PREPARE BIND S MANUAL+1 Data Page S MANUAL Data Page ID=129 ID=1 S COMMIT+1 Data Page CURSOR SQL_CURLN200C1 SELECT LENGTH (CAST(? as DBCLOB)) FROM SYSIBM.SYSDUMMYU
156
Table 5-7 dbsl_lib profile parameters for LOB handling (c) SAP AG; 2006 Parameter dbs/db2/lob_buf_size dbs_db2_lob_buf_size dbs/db2/use_eda dbs_db2_use_eda dbs/db2/use_drda_lob_handling dbs_db2_use_drda_lob_handling dbs/db2/chaining dbs_db2_chaining Recommended value 64,000 bytes 1 0 Description Size of the local LOB buffer. Minimum value is 32,000 bytes, maximum 2,000,000 bytes. Possible values are [0,1]. Use 0 to turn off the extended da feature. Possible values are [0,1]. Use 1 to turn on the DB2 Connect CLI LOB streaming. Not supported with DB2 V8. Possible values [0,MAX_INT]. Use 0 to turn off chaining. For values greater than 0, this number gives the minimum value of rows which have to fit into the dbsl_lib array buffer before chaining is used. Possible values [0,MAX_INT]. Number of locators to fit into free locator buffer. Set to 0 to turn off the free locator buffer. Possible values [0,2048]. Threshold for storage which locators in locator free buffer can hold before freed. Possible values [0,4]. 0 corresponds to dbsl trace off. 1 corresponds to dbsl statement trace. 2 is unused. 3 corresponds to dbsl statement and data trace, data is truncated. 4 corresponds to dbsl statement and data trace, data is not truncated. Possible values [0,1]. Set to 1 to turn on CLI trace. Directory to which CLI traces should be written. If not set, no CLI traces are written.
20
1,000
1 GB
0
/usr/sap/<SAPSID>/<INSTANCE>/work
157
This improvement shows through in two distinct ways: first, in the CPU resource within DB2 processing, and secondly, the number of round-trips required between the remote client and DB2 was reduced. Both of these factors lead to reduced run time of the application task, and these improvements require no change to the application execution. It should be noted that this example uses an application and underlying table specifically chosen because it contains data predominantly in LOB columns, but nonetheless, it proves significant gains with DB2 9. The first measurement shown in Figure 5-13 shows the reduction in elapsed time of the test job, from 5,193 seconds to 4,459 seconds, a total 14% reduction.
14% Reduction
V9
Figure 5-14 shows the dramatic reduction in lock requests. The reduction is comprised entirely of the elimination of LOB-lock requests for lock and unlock of the LOB row.
5 4 3 2 1 0 V8 DB2 Version V9
67% Reduction
Figure 5-14 R3load test case reduced locks (c) SAP AG; 2006
What remains is the lock on the base table row as expected, so for each row processed, two of the three lock requests are eliminated. This demonstrates the significant improvement that this change makes, particularly in a DB2 data sharing environment. (c) SAP AG; 2006
158
The final measurement shown in Figure 5-15 demonstrates the reduction in network traffic between client and host running the R3load process.
12 10
Msg Received (Millions)
8 6 4 2 0 V8 DB2 Version V9
Figure 5-15 R3load test case reduced network round-trips (c) SAP AG; 2006
While the overall number of requests is still high, the 16% reduction in network round-trips actually contributes a significant portion of the elapsed run-time reduction. Again, this gain is entirely transparent to the user, and the gain comes entirely from the change to DB2 9.
159
160
Chapter 6.
161
6.1 UNLOAD
There are basically two ways to use the unload utility with LOB data: Unload LOB columns as normal data columns to the unload data set of the base table. Use file reference variables to unload each LOB to a separate file.
CREATE DATABASE NORMEN00 CCSID EBCDIC ; CREATE TABLESPACE NORMEN00 IN NORMEN00 USING STOGROUP PAOLOSG PRIQTY 100 SECQTY 28 ERASE NO LOGGED GBPCACHE CHANGED COMPRESS NO BUFFERPOOL BP1 LOCKSIZE PAGE LOCKMAX 0 CLOSE YES SEGSIZE 4 CCSID EBCDIC MAXROWS 255 ; CREATE TABLE ##T.NORMEN00 (DOC_ID VARCHAR(30) FOR SBCS DATA NOT ,PAGE_NUMBER SMALLINT NOT ,IMPORTER CHAR(8) FOR SBCS DATA NOT WITH DEFAULT USER ,IMPORT_TIME TIMESTAMP NOT
162
WITH DEFAULT CHAR(8) FOR SBCS DATA NOT NULL ROWID NOT NULL GENERATED ALWAYS ,IMAGE BLOB(2097152) WITH DEFAULT NULL) IN NORMEN00.NORMEN00 ; CREATE UNIQUE INDEX ##T.I_NORMEN00_1 ON ##T.NORMEN00 (DOC_ID ASC, PAGE_NUMBER ASC, FORMAT ASC) USING STOGROUP PAOLOSG PRIQTY 12 SECQTY 12 ERASE NO GBPCACHE CHANGED CLUSTER BUFFERPOOL BP2 CLOSE YES COPY YES PIECESIZE 2 G ; CREATE LOB TABLESPACE NORMLOB IN NORMEN00 USING STOGROUP PAOLOSG PRIQTY 20000 SECQTY 5000 ERASE NO GBPCACHE SYSTEM NOT LOGGED DSSIZE 4G BUFFERPOOL BP1 LOCKSIZE LOB LOCKMAX 0 CLOSE YES ; CREATE UNIQUE INDEX ##T.I_NORMEN00_AUX ON ##T.NORMEN00_AUX USING STOGROUP PAOLOSG PRIQTY 52 SECQTY 20 ERASE NO GBPCACHE CHANGED BUFFERPOOL BP2 CLOSE YES COPY YES PIECESIZE 2 G DEFINE YES ; ,FORMAT ,ROW_ID
In the first case, we try to unload the complete table into a sequential output file using the utility statement shown in Example 6-2.
Example 6-2 Unload LOB data as normal data columns with UNLOAD TABLESPACE
163
DISP(MOD,CATLG,CATLG) TEMPLATE TSYSREC DSN('PAOLOR2.&SS..&DB..&SN..UNLOAD.SYSRC1') DISP(MOD,CATLG,CATLG) UNLOAD TABLESPACE NORMEN00.NORMEN00 UNLDDN(TSYSREC) PUNCHDDN(TSYSPUN)
As expected, the utility ends with RC=8 as shown in Example 6-3, because the total record length of the table ##T.NORMEN00 exceeds 32 KB (message DSNU1218I).
Example 6-3 UNLOAD exceeding a 32 KB row size
DSNU000I 201 DSNU1044I 201 DSNU050I 201 CATLG, CATLG) DSNU1035I 201 DSNU050I 201 CATLG, CATLG) DSNU1035I 201 DSNU050I 201 DSNU1218I -DB9B ##T.NORMEN00 DSNU012I 201 17:48:30.53 DSNUGUTC - OUTPUT START FOR UTILITY, UTILID = UNLOAD.NORMEN00 17:48:30.67 DSNUGTIS - PROCESSING SYSIN AS EBCDIC 17:48:30.68 DSNUGUTC - TEMPLATE TSYSPUN DSN('PAOLOR2.&SS..&DB..&SN..UNLOAD.PUNCH1') DISP(MOD, 17:48:30.68 DSNUJTDR - TEMPLATE STATEMENT PROCESSED SUCCESSFULLY 17:48:30.68 DSNUGUTC - TEMPLATE TSYSREC DSN('PAOLOR2.&SS..&DB..&SN..UNLOAD.SYSRC1') DISP(MOD, 17:48:30.69 DSNUJTDR - TEMPLATE STATEMENT PROCESSED SUCCESSFULLY 17:48:30.69 DSNUGUTC - UNLOAD TABLESPACE NORMEN00.NORMEN00 UNLDDN(TSYSREC) PUNCHDDN(TSYSPUN) 201 17:48:30.72 DSNUULIA - LOGICAL RECORD LENGTH OF OUTPUT RECORD EXCEEDED THE LIMIT FOR TABLE 17:48:30.74 DSNUGBAC - UTILITY EXECUTION TERMINATED, HIGHEST RETURN CODE=8
TEMPLATE TSYSPUN DSN('PAOLOR2.&SS..&DB..&SN..UNLOAD.PUNCH2') DISP(MOD,CATLG,CATLG) TEMPLATE TSYSREC DSN('PAOLOR2.&SS..&DB..&SN..UNLOAD.SYSRC2') DISP(MOD,CATLG,CATLG) UNLOAD DATA FROM TABLE ##T.NORMEN00 UNLDDN(TSYSREC) PUNCHDDN(TSYSPUN) We now show what happens if we limit the fields we are interested in and use the DELIMITED keyword. See Example 6-5.
Example 6-5 Unload LOB data as normal data columns in DELIMITED format
TEMPLATE TSYSPUN DSN('PAOLOR2.&SS..&DB..&SN..UNLOAD.PUNCH4') DISP(MOD,CATLG,CATLG) TEMPLATE TSYSREC DSN('PAOLOR2.&SS..&DB..&SN..UNLOAD.SYSRC4') DISP(MOD,CATLG,CATLG) UNLOAD DATA FROM TABLE ##T.NORMEN00 (DOC_ID,FORMAT,IMAGE) DELIMITED UNLDDN(TSYSREC) PUNCHDDN(TSYSPUN) We get a different result but the UNLOAD still fails with message DSNU1233I as shown in the job output in Example 6-6 on page 165.
164
Example 6-6 Unload LOB data as normal data columns in DELIMITED format
.............. DSNU050I 201 DSNU650I -DB9B DSNU650I -DB9B DSNU650I -DB9B DSNU650I -DB9B DSNU1038I 201 19:03:57.57 DSNUGUTC - UNLOAD DATA 201 19:03:57.59 DSNUUGMS - FROM TABLE ##T.NORMEN00 201 19:03:57.59 DSNUUGMS (DOC_ID, 201 19:03:57.59 DSNUUGMS FORMAT, 201 19:03:57.59 DSNUUGMS IMAGE) DELIMITED UNLDDN(TSYSREC) PUNCHDDN(TSYSPUN) 19:03:57.64 DSNUGDYN - DATASET ALLOCATED. TEMPLATE=TSYSREC DDNAME=SYS00001 DSN=PAOLOR2.DB9B.NORMEN00.NORMEN00.UNLOAD.SYSRC4 DSNU1233I -DB9B 201 19:03:57.65 DSNUULVA - DATA IS TOO LONG FOR FIELD IMAGE, TABLE ##T.NORMEN00 DSNU1219I -DB9B 201 19:03:57.65 DSNUULVA - THE NUMBER OF RECORDS IN ERROR REACHED THE LIMIT 1 DSNU253I 201 19:03:57.69 DSNUUNLD - UNLOAD PHASE STATISTICS - NUMBER OF RECORDS UNLOADED=0 FOR TABLE ##T.NORMEN00 DSNU252I 201 19:03:57.69 DSNUUNLD - UNLOAD PHASE STATISTICS - NUMBER OF RECORDS UNLOADED=0 FOR TABLESPACE NORMEN00.NORMEN00 DSNU250I 201 19:03:57.69 DSNUUNLD - UNLOAD PHASE COMPLETE, ELAPSED TIME=00:00:00 DSNU568I -DB9B 201 19:03:57.70 DSNUGSRX - INDEX ##T.I_NORMEN00_AUX IS IN INFORMATIONAL COPY PENDING STATE DSNU012I 201 19:03:57.71 DSNUGBAC - UTILITY EXECUTION TERMINATED, HIGHEST RETURN CODE=8
The only way that we are able to UNLOAD some LOB data is by truncating the LOB data so that the output is less than 32 KB. This is illustrated in Example 6-7 where we use the TRUNCATE keyword to truncate the LOB data to 30,000 bytes.
Example 6-7 Unload LOB data as normal data columns in truncated format
TEMPLATE TSYSPUN DSN('PAOLOR2.&SS..&DB..&SN..UNLOAD.PUNCH5') DISP(MOD,CATLG,CATLG) TEMPLATE TSYSREC DSN('PAOLOR2.&SS..&DB..&SN..UNLOAD.SYSRC5') DISP(MOD,CATLG,CATLG) UNLOAD DATA FROM TABLE ##T.NORMEN00 (DOC_ID,FORMAT,IMAGE BLOB(30000) TRUNCATE) DELIMITED UNLDDN(TSYSREC) PUNCHDDN(TSYSPUN) The output of the resulting job is shown in Example 6-8.
Example 6-8 Unload LOB data as normal data columns in truncated format
....... DSNU050I DSNU650I DSNU650I DSNU650I DSNU650I TSYSPUN) DSNU1038I
12:02:26.97 DSNUGUTC - UNLOAD DATA 209 12:02:26.97 DSNUUGMS - FROM TABLE ##T.NORMEN00 209 12:02:26.97 DSNUUGMS (DOC_ID, 209 12:02:26.97 DSNUUGMS FORMAT, 209 12:02:26.97 DSNUUGMS IMAGE BLOB(30000) TRUNCATE) DELIMITED UNLDDN(TSYSREC) PUNCHDDN(
209 12:02:27.06 DSNUGDYN - DATASET ALLOCATED. TEMPLATE=TSYSREC DDNAME=SYS00001 DSN=PAOLOR2.DB9B.NORMEN00.NORMEN00.UNLOAD.SYSRC5 DSNU1038I 209 12:02:51.02 DSNUGDYN - DATASET ALLOCATED. TEMPLATE=TSYSPUN DDNAME=SYS00002 DSN=PAOLOR2.DB9B.NORMEN00.NORMEN00.UNLOAD.PUNCH5 DSNU253I 209 12:02:51.14 DSNUUNLD - UNLOAD PHASE STATISTICS - NUMBER OF RECORDS UNLOADED=5883 FOR TABLE ##T.NORMEN00 DSNU252I 209 12:02:51.14 DSNUUNLD - UNLOAD PHASE STATISTICS - NUMBER OF RECORDS UNLOADED=5883 FOR TABLESPACE NORMEN00.NORMEN00 DSNU250I 209 12:02:51.14 DSNUUNLD - UNLOAD PHASE COMPLETE, ELAPSED TIME=00:00:24 DSNU010I 209 12:02:51.15 DSNUGBAC - UTILITY EXECUTION COMPLETE, HIGHEST RETURN CODE=0
165
For a PDSE: The name of the PDSE is generated from the DSN specification of the template. Specify DSNTYPE LIBRARY. The member names are automatically generated. For a HFS file: The name of the HFS directory is generated from the DSN specification of the template. Specify DSNTYPE HFS. The HFS directory must exist and be mounted. The data set names in the directory are automatically generated. For a PDS, the default value of DIR is the estimated number of records divided by 20, which is sufficient to have as many members as the estimated number of records. If you do not specify a DSNTYPE, a PDS is created by default (DSORG = PS).
166
Note: Run RUNSTATS on the base table space before UNLOAD to allow DB2 to read a realistic value of the AVGROWLEN in the SYSIBM.SYSTABLESPACE used to determine the size of the base table. The size needed for LOB table space is calculated by DB2 from the high used relative page count. The member names that are generated for a PDS or PDSE or the data set names for a HFS directory have a length of 8 and are uniquely generated from the system clock. They have the same look as when using the &UNIQ. or &UQ. variable in a TEMPLATE definition. Important: Make sure that PTF UK13720 (DB2 V7) or UK13721 (DB2 V8) is installed in your system to use the file reference support for UNLOAD in DB2 V7 or DB2 V8.
Examples
To illustrate, we look at some examples based on the table ##T.NORMEN00 as described in Figure 6-1 on page 189. In Example 6-9, we try to unload the same data fields from table ##T.NORMEN00 as in Example 6-5 on page 164 or Example 6-7 on page 165, but this time we want to unload the whole LOB data of column IMAGE into a PDS. We specified a TEMPLATE TSYSLOB with DSNTYPE PDS and specified for field IMAGE a field specification as VARCHAR(54) BLOBF TSYSLOB (the maximum possible length for a PDS + membername being 54).
Example 6-9 Unload LOB data to a PDS
TEMPLATE TSYSPUN DSN('PAOLOR2.&SS..&DB..&SN..UNLOAD.PUNCH6') DISP(MOD,CATLG,CATLG) TEMPLATE TSYSREC DSN('PAOLOR2.&SS..&DB..&SN..UNLOAD.SYSRC6') DISP(MOD,CATLG,CATLG) TEMPLATE TSYSLOB DSN('PAOLOR2.&SS..&DB..&SN..UNLOAD.PDS6') DISP(MOD,CATLG,CATLG) DSNTYPE(PDS) UNLOAD DATA FROM TABLE ##T.NORMEN00 (DOC_ID,FORMAT,IMAGE VARCHAR(54) BLOBF TSYSLOB) UNLDDN(TSYSREC) PUNCHDDN(TSYSPUN) As a result, three files were created, as shown in the job output in Example 6-10. A punchfile containing the equivalent statements for the LOAD utility, a SYSREC file containing the non-LOB data values and the output file names of the LOB values, and a PDS containing the actual LOB values.
Example 6-10 Unload LOB data to a PDS
DSNU000I 205 18:00:05.58 DSNU1044I 205 18:00:05.64 DSNU050I 205 18:00:05.65 CATLG, CATLG) DSNU1035I 205 18:00:05.65 DSNU050I 205 18:00:05.65 CATLG, CATLG) DSNU1035I 205 18:00:05.65 DSNU050I 205 18:00:05.66 CATLG) DSNTYPE(PDS) DSNU1035I 205 18:00:05.66 DSNUGUTC - OUTPUT START FOR UTILITY, UTILID = UNLOAD.NORMEN00 DSNUGTIS - PROCESSING SYSIN AS EBCDIC DSNUGUTC - TEMPLATE TSYSPUN DSN('PAOLOR2.&SS..&DB..&SN..UNLOAD.PUNCH6') DISP(MOD, DSNUJTDR - TEMPLATE STATEMENT PROCESSED SUCCESSFULLY DSNUGUTC - TEMPLATE TSYSREC DSN('PAOLOR2.&SS..&DB..&SN..UNLOAD.SYSRC6') DISP(MOD, DSNUJTDR - TEMPLATE STATEMENT PROCESSED SUCCESSFULLY DSNUGUTC - TEMPLATE TSYSLOB DSN('PAOLOR2.&SS..&DB..&SN..UNLOAD.PDS6') DISP(MOD, CATLG, DSNUJTDR - TEMPLATE STATEMENT PROCESSED SUCCESSFULLY
167
18:00:05.66 DSNUGUTC - UNLOAD DATA 205 18:00:05.66 DSNUUGMS - FROM TABLE ##T.NORMEN00 205 18:00:05.66 DSNUUGMS (DOC_ID, 205 18:00:05.66 DSNUUGMS FORMAT, 205 18:00:05.66 DSNUUGMS IMAGE VARCHAR(54) BLOBF TSYSLOB) UNLDDN(TSYSREC) PUNCHDDN(TSYSPUN) 18:00:05.75 DSNUGDYN - DATASET ALLOCATED. TEMPLATE=TSYSREC DDNAME=SYS00001 DSN=PAOLOR2.DB9B.NORMEN00.NORMEN00.UNLOAD.SYSRC6 DSNU1038I 205 18:00:05.96 DSNUGDYN - DATASET ALLOCATED. TEMPLATE=TSYSLOB DDNAME=SYS00002 DSN=PAOLOR2.DB9B.NORMEN00.NORMLOB.UNLOAD.PDS6 DSNU1038I 205 18:02:20.07 DSNUGDYN - DATASET ALLOCATED. TEMPLATE=TSYSPUN DDNAME=SYS00003 DSN=PAOLOR2.DB9B.NORMEN00.NORMEN00.UNLOAD.PUNCH6 DSNU253I 205 18:02:20.16 DSNUUNLD - UNLOAD PHASE STATISTICS - NUMBER OF RECORDS UNLOADED=5883 FOR TABLE ##T.NORMEN00 DSNU252I 205 18:02:20.16 DSNUUNLD - UNLOAD PHASE STATISTICS - NUMBER OF RECORDS UNLOADED=5883 FOR TABLESPACE NORMEN00.NORMEN00 DSNU250I 205 18:02:20.16 DSNUUNLD - UNLOAD PHASE COMPLETE, ELAPSED TIME=00:02:14 DSNU568I -DB9B 205 18:02:20.18 DSNUGSRX - INDEX ##T.I_NORMEN00_AUX IS IN INFORMATIONAL COPY PENDING STATE DSNU010I 205 18:02:20.18 DSNUGBAC - UTILITY EXECUTION COMPLETE, HIGHEST RETURN CODE=0
If we take a closer look to the SYSREC file, it contains records similar to Example 6-11. The file name of the LOB value is stored in column 44 as a VARCHAR(54) starting with a 2-byte length field. On column 43, we have a null indicator field, which is xFF if the file name is NULL. The actual PDS with DSNAME = PAOLOR2.DB9B.NORMEN00.NORMLOB.UNLOAD.PDS6 is allocated as a PDS (DSORG=PO) with 1,287 directory blocks and 5,883 members. The DCB looks like RECFM=VB,LRECL=0,BLKSIZE=27998. Actually, only 281 directory blocks are used.
Example 6-11 Contents of the SYSREC file
....F0577 ....F0578 ....F0579 ....F0580 ....F0581 ....F0582 ....F0583 ....F0584 ....F0585 ....F0586 PDF PDF PDF PDF PDF PDF PDF PDF PDF PDF ...PAOLOR2.DB9B.NORMEN00.NORMLOB.UNLOAD.PDS6(A0HFYAD1) ...PAOLOR2.DB9B.NORMEN00.NORMLOB.UNLOAD.PDS6(A0HFYAEJ) ...PAOLOR2.DB9B.NORMEN00.NORMLOB.UNLOAD.PDS6(A0HFYAE2) ...PAOLOR2.DB9B.NORMEN00.NORMLOB.UNLOAD.PDS6(A0HFYAFN) ...PAOLOR2.DB9B.NORMEN00.NORMLOB.UNLOAD.PDS6(A0HFYAF6) ...PAOLOR2.DB9B.NORMEN00.NORMLOB.UNLOAD.PDS6(A0HFYAGR) ...PAOLOR2.DB9B.NORMEN00.NORMLOB.UNLOAD.PDS6(A0HFYAHA) ...PAOLOR2.DB9B.NORMEN00.NORMLOB.UNLOAD.PDS6(A0HFYAHS) ...PAOLOR2.DB9B.NORMEN00.NORMLOB.UNLOAD.PDS6(A0HFYAIC) ...PAOLOR2.DB9B.NORMEN00.NORMLOB.UNLOAD.PDS6(A0HFYAIW)
Note: APAR PK27029 changes the LRECL=0 to LRECL=27994, which makes more sense for a BLKSIZE=27998 data set. Furthermore, by default DB2 always creates the PDS or PDSE with a BLKSIZE of 27,998 bytes regardless of the device type. Because 27,998 bytes are the optimal BLKSIZE for 3390 devices, we recommend that you preallocate the PDS yourself if you are using device types different than 3390 (for example, the optimal BLKSIZE for 3380 devices is 23,040 bytes).
To unload the LOB data to a PDSE, we can use a utility input file as shown in Example 6-12.
Example 6-12 Unload LOB data to a PDSE
168
DSN('PAOLOR2.&SS..&DB..&SN..UNLOAD.SYSRC7') DISP(MOD,CATLG,CATLG) TEMPLATE TSYSLOB DSN('PAOLOR2.&SS..&DB..&SN..UNLOAD.PDSE7') DISP(MOD,CATLG,CATLG) DSNTYPE(LIBRARY) UNLOAD DATA FROM TABLE ##T.NORMEN00 (DOC_ID,FORMAT,IMAGE VARCHAR(54) BLOBF TSYSLOB) UNLDDN(TSYSREC) PUNCHDDN(TSYSPUN) The contents of the SYSREC file look as shown in Example 6-13. The member names are different because the job was run at a later time than in Example 6-11 on page 168.
Example 6-13 Contents of the SYSREC file
....F0677 ....F0678 ....F0679 ....F0680 ....F0681 ....F0682 ....F0683 ....F0684 ....F0685 ....F0686 PDF PDF PDF PDF PDF PDF PDF PDF PDF PDF ...PAOLOR2.DB9B.NORMEN00.NORMLOB.UNLOAD.PDSE7(A0IQCZXN) ...PAOLOR2.DB9B.NORMEN00.NORMLOB.UNLOAD.PDSE7(A0IQCZYL) ...PAOLOR2.DB9B.NORMEN00.NORMLOB.UNLOAD.PDSE7(A0IQCZZO) ...PAOLOR2.DB9B.NORMEN00.NORMLOB.UNLOAD.PDSE7(A0IQCZ0O) ...PAOLOR2.DB9B.NORMEN00.NORMLOB.UNLOAD.PDSE7(A0IQCZ1N) ...PAOLOR2.DB9B.NORMEN00.NORMLOB.UNLOAD.PDSE7(A0IQCZ2O) ...PAOLOR2.DB9B.NORMEN00.NORMLOB.UNLOAD.PDSE7(A0IQCZ3O) ...PAOLOR2.DB9B.NORMEN00.NORMLOB.UNLOAD.PDSE7(A0IQCZ4O) ...PAOLOR2.DB9B.NORMEN00.NORMLOB.UNLOAD.PDSE7(A0IQCZ5Q) ...PAOLOR2.DB9B.NORMEN00.NORMLOB.UNLOAD.PDSE7(A0IQCZ6S)
To unload the LOB data to a HFS directory, we can use a utility input file as shown in Example 6-14. Be sure that the userid associated with the utility job has the rights to add new files to the specified HFS directory. In this example, the HFS directory /u/DB9B was created and mounted before.
Example 6-14 Unload LOB data to a HFS directory
TEMPLATE TSYSPUN DSN('PAOLOR2.&SS..&DB..&SN..UNLOAD.PUNCH8') DISP(MOD,CATLG,CATLG) TEMPLATE TSYSREC DSN('PAOLOR2.&SS..&DB..&SN..UNLOAD.SYSRC8') DISP(MOD,CATLG,CATLG) TEMPLATE TSYSLOB DSN('/u/&SS.') DSNTYPE(HFS) UNLOAD DATA FROM TABLE ##T.NORMEN00 (DOC_ID,FORMAT,IMAGE VARCHAR(20) BLOBF TSYSLOB) UNLDDN(TSYSREC) PUNCHDDN(TSYSPUN) After the job is run, the HFS directory can be listed with a UNIX command cd /u/DB9B followed by ls -l as shown in Example 6-15 (we only show the last lines here).
Example 6-15 Contents of the HFS directory /u/DB9B -rwxrwx---rwxrwx---rwxrwx---rwxrwx---rwxrwx---rwxrwx---rwxrwx---rwxrwx--1 1 1 1 1 1 1 1 HAIMO HAIMO HAIMO HAIMO HAIMO HAIMO HAIMO HAIMO SYS1 SYS1 SYS1 SYS1 SYS1 SYS1 SYS1 SYS1 29350 29390 29357 29380 28939 28930 28987 29122 Jul Jul Jul Jul Jul Jul Jul Jul 25 25 25 25 25 25 25 25 15:10 15:10 15:10 15:10 15:10 15:10 15:10 15:10 A0IUJYZ3 A0IUJYZ7 A0IUJYZC A0IUJYZG A0IUJYZL A0IUJYZP A0IUJYZU A0IUJYZY Chapter 6. Utilities with LOBs
169
Tip: Keep in mind that HFS directories are case sensitive and that the outcome of TEMPLATE variables is always in uppercase. So, create your HFS directories partly in uppercase if you use template variables to map your HFS directories.
170
6.2 DSNTIAUL
Like the UNLOAD utility, the DSNTIAUL sample program also provides two ways to handle LOB data: Unload LOB columns as normal data columns to the SYSRECxx files (with truncation). Unload LOB columns to a separate file (DB2 9 only).
//DSNTIAUL EXEC PGM=IKJEFT01,DYNAMNBR=20,COND=(4,LT) //SYSTSPRT DD SYSOUT=* //SYSTSIN DD * DSN SYSTEM(DB9B) RUN PROGRAM(DSNTIAUL) PLAN(DSNTIB91) PARMS('SQL') LIB('DB9BU.RUNLIB.LOAD') //SYSPRINT DD SYSOUT=* //SYSREC00 DD DSN=PAOLOR2.DB9B.DSN8UNLD.SQL.SYSREC00, // DISP=(,CATLG),UNIT=3390, // SPACE=(CYL,(100,100)) //SYSPUNCH DD DSN=PAOLOR2.DB9B.DSN8UNLD.SQL.SYSPUNCH, // DISP=(,CATLG),UNIT=3390, // SPACE=(CYL,(1,1)) //SYSIN DD * SELECT DOC_ID,FORMAT,IMAGE FROM ##T.NORMEN00 ; As a result, we get an FB sequential data set SYSREC00 with a LRECL and BLKSIZE of 32,753 bytes with DOC_ID beginning in position 1, FORMAT beginning in position 33, and the IMAGE data starting in position 41 and truncated to 32,708 bytes as shown in Example 6-18.
Example 6-18 DSNTIAUL output with SQL parameter
DSNT490I SAMPLE DATA UNLOAD PROGRAM DSNT505I DSNTIAUL OPTIONS USED: SQLTOLWAR DSNT503I UNLOAD DATA SET SYSPUNCH RECORD LENGTH SET TO 80 DSNT504I UNLOAD DATA SET SYSPUNCH BLOCK SIZE SET TO 27920 DSNT506I INPUT STATEMENT WAS NOT A FULL SELECT ON A SINGLE TABLE. LOAD STATEMENT WILL NEED MODIFICATION. WARNING: DATA FROM COLUMN 3 WAS TRUNCATED TO 32755 BYTES FROM 2097152. WARNING: DATA FROM COLUMN 3 WAS TRUNCATED TO 32708 BYTES FROM 32755. DSNT503I UNLOAD DATA SET SYSREC00 RECORD LENGTH SET TO 32753 DSNT504I UNLOAD DATA SET SYSREC00 BLOCK SIZE SET TO 32753
171
With the SQL statement SELECT * FROM ##T.NORMEN00, we would get all the normal data columns (except for the ROWID column that is omitted when it is type GENERATED ALWAYS) and the IMAGE column truncated to 32,632 bytes.
//DSNTIAUL EXEC PGM=IKJEFT01,DYNAMNBR=20,COND=(4,LT) //SYSTSPRT DD SYSOUT=* //SYSTSIN DD * DSN SYSTEM(DB9B) RUN PROGRAM(DSNTIAUL) PLAN(DSNTIB91) PARMS('LOBFILE(PAOLOR2)') LIB('DB9BU.RUNLIB.LOAD') //SYSPRINT DD SYSOUT=* //SYSREC00 DD DSN=PAOLOR2.DB9B.DSN8UNLD.LOBF.SYSREC00, // DISP=(,CATLG),UNIT=3390, // SPACE=(CYL,(10,10)) //SYSPUNCH DD DSN=PAOLOR2.DB9B.DSN8UNLD.LOBF.SYSPUNCH, // DISP=(,CATLG),UNIT=3390, // SPACE=(CYL,(1,1)) //SYSIN DD * ##T.NORMEN00
In this case, the SYSIN input file contains the name of the base table. You can also specify SQL as first PARM: RUN PROGRAM(DSNTIAUL) PLAN(DSNTIB91) PARMS('SQL,LOBFILE(PAOLOR2)') -
172
And you can use an SQL statement as input to SYSIN: SELECT * FROM ##T.NORMEN00; In both cases, as a result we get a sequential data set SYSREC00 containing the normal data fields (except the ROWID column) and the name of the LOB output files and 5,883 new LOB files. See Example 6-20. All of the LOB output files have a name of the form PAOLOR2.Q0000000.C0000006.R000xxxx with xxxx from 0000 to 5882. They are dynamically allocated as sequential files with RECFM=VB,LRECL=27994,BLKSIZE=27998, which is the optimal BLKSIZE for 3390 devices.
Example 6-20 DSNTIAUL output with LOBFILE parameter DSNT490I DSNT503I DSNT504I DSNT503I DSNT504I DSNT495I SAMPLE DATA UNLOAD PROGRAM UNLOAD DATA SET SYSPUNCH RECORD LENGTH SET TO 80 UNLOAD DATA SET SYSPUNCH BLOCK SIZE SET TO 27920 UNLOAD DATA SET SYSREC00 RECORD LENGTH SET TO 162 UNLOAD DATA SET SYSREC00 BLOCK SIZE SET TO 27864 SUCCESSFUL UNLOAD 5883 ROWS OF TABLE ##T.NORMEN00
Afterwards, the SYSPUNCH file, the SYSREC00 file, and the 5883 LOB files can be used as input for the LOAD utility. Important: When the DSNTIAUL job is run again, and the LOB files from the previous run still exist, they are REPLACED by the new run with the same name.
6.3 LOAD
Depending on the way the LOB data is provided, there are three ways the load utility can be used to load LOB data: Loading LOB data as normal data fields from the LOAD input file Using file reference variables when each LOB value is stored in a separate input file Using the cross loader
173
Normally the provided input file is the result of: UNLOAD utility DSNTIAUL utility Generated by another application
buffer for LOB data and only stores 8 bytes per LOB column in the cursor result set buffer. The sum of the lengths of the non-LOB columns plus the sum of 8 bytes per LOB column cannot exceed 32 KB. The separate LOB buffer resides in storage above the 16 MB line and is only limited by the available memory above the 16 MB line. The message DSNU1178I is issued when: The sum of the lengths of all non-LOB columns + 8 bytes per LOB column exceeds 32 KB. The sum of the lengths of all LOB columns exceeds half of the above-the-line available memory. If a user gets message DSNU1178I, increasing the region size likely results in successful execution of the LOAD utility. See Example 6-26 on page 178 for a cross loader job execution. Important: Apply PTF UQ03226 (DB2 V7) or UQ03227 (DB2 V8) to use the cross loader support for LOBs in DB2 V7 or DB2 V8.
If the base table space is defined as NOT LOGGED and the LOB table spaces are defined as LOGGED, the LOB table spaces with the LOGGED logging attribute are changed to NOT LOGGED as well (however, this is recorded in the DB2 catalog, so that if the base table space is altered to LOGGED, the LOB table spaces are also changed back to LOGGED). If both base table space and LOB table spaces are NOT LOGGED, the LOG YES attribute of the LOAD utility also is changed to LOG NO during execution. Nothing is logged and the LOB table spaces are in the no pending state afterwards. When the LOB table space ends up being in COPYP status, you should take a full image copy afterwards to establish recoverability and allow update activity to the LOBs. Adding a COPYDDN statement to the LOAD utility (with REPLACE) does not help because this only takes an image copy of the base table space.
175
Examples
We demonstrate this with some examples. In Example 6-21, we use the output of DSNTIAUL from Example 6-19 on page 172 to load a newly created table ##T.NORMEN02. This table is created with the same DDL as the table ##T.NORMEN00 defined in Example 6-1 on page 162 with NORMEN00 replaced everywhere by NORMEN02.
Example 6-21 LOAD LOB data with input from DSNTIAUL
//LOAD EXEC PGM=DSNUTILB,PARM='DB9B,LOAD.NORMEN02',COND=(4,LT) //SYSTEMPL DD DUMMY //UTPRINT DD SYSOUT=* //SYSPRINT DD SYSOUT=* //SYSREC00 DD DSN=PAOLOR2.DB9B.DSN8UNLD.LOBF.SYSREC00,DISP=SHR //SYSIN DD * TEMPLATE TSORTOUT DSN('DB2RE.&SS..&DB..&SN..S&JU(3,5)..#&TI.') DISP(MOD,DELETE,CATLG) TEMPLATE TSYSUT1 DSN('DB2RE.&SS..&DB..&SN..U&JU(3,5)..#&TI.') DISP(MOD,DELETE,CATLG) LOAD DATA LOG NO INDDN SYSREC00 INTO TABLE ##T.NORMEN02 (DOC_ID POSITION(1) VARCHAR, PAGE_NUMBER POSITION(33) SMALLINT, IMPORTER POSITION(35) CHAR(8), IMPORT_TIME POSITION(43) TIMESTAMP EXTERNAL(26), FORMAT POSITION(69) CHAR(8), IMAGE POSITION(119) CHAR(34) BLOBF ) SORTNUM 8 SORTDEVT 3390 WORKDDN(TSYSUT1,TSORTOUT) The result of this job is shown in Example 6-22.
Example 6-22 LOAD LOB data with input from DSNTIAUL
DSNU000I 207 20:07:27.58 DSNUGUTC - OUTPUT START FOR UTILITY, UTILID = LOAD.NORMEN02 DSNU1044I 207 20:07:27.63 DSNUGTIS - PROCESSING SYSIN AS EBCDIC DSNU050I 207 20:07:27.64 DSNUGUTC - TEMPLATE TSORTOUT DSN('DB2RE.&SS..&DB..&SN..S&JU(3,5)..#&TI.') DISP(MOD, DELETE, CATLG) DSNU1035I 207 20:07:27.65 DSNUJTDR - TEMPLATE STATEMENT PROCESSED SUCCESSFULLY DSNU050I 207 20:07:27.65 DSNUGUTC - TEMPLATE TSYSUT1 DSN('DB2RE.&SS..&DB..&SN..U&JU(3,5)..#&TI.') DISP(MOD, DELETE, CATLG) DSNU1035I 207 20:07:27.65 DSNUJTDR - TEMPLATE STATEMENT PROCESSED SUCCESSFULLY DSNU050I 207 20:07:27.65 DSNUGUTC - LOAD DATA LOG NO INDDN SYSREC00 DSNU650I -DB9B 207 20:07:27.65 DSNURWI - INTO TABLE ##T.NORMEN02 DSNU650I -DB9B 207 20:07:27.65 DSNURWI (DOC_ID POSITION(1) VARCHAR, DSNU650I -DB9B 207 20:07:27.65 DSNURWI PAGE_NUMBER POSITION(33) SMALLINT, DSNU650I -DB9B 207 20:07:27.65 DSNURWI IMPORTER POSITION(35) CHAR(8), DSNU650I -DB9B 207 20:07:27.65 DSNURWI IMPORT_TIME POSITION(43) TIMESTAMP EXTERNAL(26), DSNU650I -DB9B 207 20:07:27.65 DSNURWI FORMAT POSITION(69) CHAR(8), DSNU650I -DB9B 207 20:07:27.65 DSNURWI IMAGE POSITION(119) CHAR(34) BLOBF) SORTNUM 8 SORTDEVT 3390 WORKDDN( TSYSUT1, TSORTOUT) DSNU1038I 207 20:07:28.01 DSNUGDYN - DATASET ALLOCATED. TEMPLATE=TSYSUT1 DDNAME=SYS00001 DSN=DB2RE.DB9B.NORMEN02.NORMEN02.U06208.#000727 DSNU1038I 207 20:07:28.04 DSNUGDYN - DATASET ALLOCATED. TEMPLATE=TSORTOUT DDNAME=SYS00002 DSN=DB2RE.DB9B.NORMEN02.NORMEN02.S06208.#000727 DSNU080I 207 20:07:28.04 DSNUGPRS - NO UTILITY STATEMENTS FOUND IN SYSTEMPL
176
DSNU304I -DB9B 207 20:09:23.10 DSNURWT - (RE)LOAD PHASE STATISTICS - NUMBER OF RECORDS=5883 FOR TABLE ##T.NORMEN02 DSNU1147I -DB9B 207 20:09:23.10 DSNURWT - (RE)LOAD PHASE STATISTICS - TOTAL NUMBER OF RECORDS LOADED=5883 FOR TABLESPACE NORMEN02.NORMEN02 DSNU302I 207 20:09:23.10 DSNURILD - (RE)LOAD PHASE STATISTICS - NUMBER OF INPUT RECORDS PROCESSED=5883 DSNU300I 207 20:09:23.10 DSNURILD - (RE)LOAD PHASE COMPLETE, ELAPSED TIME=00:01:55 DSNU042I 207 20:09:23.64 DSNUGSOR - SORT PHASE STATISTICS NUMBER OF RECORDS=5883 ELAPSED TIME=00:00:00 DSNU349I -DB9B 207 20:09:23.94 DSNURBXA - BUILD PHASE STATISTICS - NUMBER OF KEYS=5883 FOR INDEX ##T.I_NORMEN02_1 DSNU258I 207 20:09:23.95 DSNURBXD - BUILD PHASE STATISTICS - NUMBER OF INDEXES=1 DSNU259I 207 20:09:23.95 DSNURBXD - BUILD PHASE COMPLETE, ELAPSED TIME=00:00:00 DSNU381I -DB9B 207 20:09:24.01 DSNUGSRX - TABLESPACE NORMEN02.NORMEN02 IS IN COPY PENDING DSNU381I -DB9B 207 20:09:24.01 DSNUGSRX - TABLESPACE NORMEN02.NORMLOB IS IN COPY PENDING DSNU568I -DB9B 207 20:09:24.01 DSNUGSRX - INDEX ##T.I_NORMEN02_AUX IS IN INFORMATIONAL COPY PENDING STATE DSNU568I -DB9B 207 20:09:24.01 DSNUGSRX - INDEX ##T.I_NORMEN02_1 IS IN INFORMATIONAL COPY PENDING STATE DSNU010I 207 20:09:24.03 DSNUGBAC - UTILITY EXECUTION COMPLETE, HIGHEST RETURN CODE=4
In this case, nothing is logged (LOB table space defined as LOG NO, LOAD with LOG NO and both the base table space and LOB table space are put in COPY Pending). Similar tests were done if the input LOB files are members of a PDS, members of a PDSE, or HFS files on a HFS directory (created by the UNLOAD utility). When we do the same test again, but now, we create the base table space as NOT LOGGED and the LOB table space as LOGGED, the resulting entries in SYSIBM.SYSTABLESPACE look as shown in Example 6-23.
Example 6-23 Entries in SYSIBM.SYSTABLESPACE
TYPE ---O
LOG --N X
The value X in the LOG column means that the LOB table space currently has the value NOT LOGGED, because the base table space has the NOT LOGGED attribute. If we now do a LOAD with LOG YES we get message DSNU1153I as shown in Example 6-24, and nothing is logged. The base table space is put in INFORMATIONAL COPY PENDING STATE and the LOB table space has no pending states after the LOAD.
Example 6-24 LOAD with LOG YES on NOT LOGGED table spaces
DSNU050I 208 12:13:59.66 DSNUGUTC - LOAD DATA LOG YES INDDN SYSREC00 DSNU1153I -DB9B 208 12:13:59.66 DSNURWI - LOG YES SPECIFIED FOR THE NOT LOGGED TABLESPACE NORMEN02.NORMEN02 WILL BE IGNORED DSNU650I -DB9B 208 12:13:59.66 DSNURWI - INTO TABLE ##T.NORMEN02 DSNU650I -DB9B 208 12:13:59.66 DSNURWI (DOC_ID POSITION(1) VARCHAR, DSNU650I -DB9B 208 12:13:59.66 DSNURWI PAGE_NUMBER POSITION(33) SMALLINT, DSNU650I -DB9B 208 12:13:59.66 DSNURWI IMPORTER POSITION(35) CHAR(8), DSNU650I -DB9B 208 12:13:59.66 DSNURWI IMPORT_TIME POSITION(43) TIMESTAMP EXTERNAL(26), DSNU650I -DB9B 208 12:13:59.66 DSNURWI FORMAT POSITION(69) CHAR(8), DSNU650I -DB9B 208 12:13:59.66 DSNURWI IMAGE POSITION(119) CHAR(34) BLOBF) SORTNUM 8 SORTDEVT 3390 WORKDDN( TSYSUT1, TSORTOUT) DSNU1038I 208 12:14:00.11 DSNUGDYN - DATASET ALLOCATED. TEMPLATE=TSYSUT1 DDNAME=SYS00001 DSN=DB2RE.DB9B.NORMEN02.NORMEN02.U06208.#161359 DSNU1038I 208 12:14:00.20 DSNUGDYN - DATASET ALLOCATED. TEMPLATE=TSORTOUT DDNAME=SYS00002 DSN=DB2RE.DB9B.NORMEN02.NORMEN02.S06208.#161359 DSNU080I 208 12:14:00.20 DSNUGPRS - NO UTILITY STATEMENTS FOUND IN SYSTEMPL DSNU304I -DB9B 208 12:15:55.01 DSNURWT - (RE)LOAD PHASE STATISTICS - NUMBER OF RECORDS=5883 FOR TABLE ##T.NORMEN02 DSNU1147I -DB9B 208 12:15:55.01 DSNURWT - (RE)LOAD PHASE STATISTICS - TOTAL NUMBER OF RECORDS LOADED=5883 FOR
177
TABLESPACE NORMEN02.NORMEN02 DSNU302I 208 12:15:55.02 DSNURILD - (RE)LOAD PHASE STATISTICS - NUMBER OF INPUT RECORDS PROCESSED=5883 DSNU300I 208 12:15:55.02 DSNURILD - (RE)LOAD PHASE COMPLETE, ELAPSED TIME=00:01:54 DSNU042I 208 12:15:55.58 DSNUGSOR - SORT PHASE STATISTICS NUMBER OF RECORDS=5883 ELAPSED TIME=00:00:00 DSNU349I -DB9B 208 12:15:55.92 DSNURBXA - BUILD PHASE STATISTICS - NUMBER OF KEYS=5883 FOR INDEX ##T.I_NORMEN02_1 DSNU258I 208 12:15:55.93 DSNURBXD - BUILD PHASE STATISTICS - NUMBER OF INDEXES=1 DSNU259I 208 12:15:55.93 DSNURBXD - BUILD PHASE COMPLETE, ELAPSED TIME=00:00:00 DSNU568I -DB9B 208 12:15:55.98 DSNUGSRX - TABLESPACE NORMEN02.NORMEN02 IS IN INFORMATIONAL COPY PENDING STATE DSNU568I -DB9B 208 12:15:55.98 DSNUGSRX - INDEX ##T.I_NORMEN02_AUX IS IN INFORMATIONAL COPY PENDING STATE DSNU568I -DB9B 208 12:15:55.98 DSNUGSRX - INDEX ##T.I_NORMEN02_1 IS IN INFORMATIONAL COPY PENDING STATE DSNU010I 208 12:15:55.99 DSNUGBAC - UTILITY EXECUTION COMPLETE, HIGHEST RETURN CODE=0
If DB2 cannot find one or more of the LOB input files, a new SQLCODE-452 is issued as shown in Example 6-25.
Example 6-25 LOAD LOB input file not found
DSNU350I -DB9B 208 14:23:08.29 DSNURRST - EXISTING RECORDS DELETED FROM TABLESPACE DSNU283I -DB9B 208 14:23:08.43 DSNURWBF - LOB ERROR SQLCODE = -452 SQLERRM = PAOLOR2.Q0000000.C0000006.R0000000 3 SQLSTATE= 428A1 SQLERRP = DSNOLFRV SQLERRD = 0000000A 00000000 00000000 FFFFFFFF 00000000 00000000 DSNU017I 208 14:23:12.08 DSNUGBAC - UTILITY DATA BASE SERVICES MEMORY EXECUTION ABENDED, REASON=X'00E40350' CAUSE=X'00C90072
An example with the cross loader is shown in Example 6-26 where we LOAD ##T.NORMEN02 from ##T.NORMEN00 using a cursor.
Example 6-26 LOAD LOB data with cross loader
TEMPLATE TSORTOUT DSN('DB2RE.&SS..&DB..&SN..S&JU(3,5)..#&TI.') DISP(MOD,DELETE,CATLG) SPACE(10,10) CYL TEMPLATE TSYSUT1 DSN('DB2RE.&SS..&DB..&SN..U&JU(3,5)..#&TI.') DISP(MOD,DELETE,CATLG) SPACE(10,10) CYL EXEC SQL DECLARE C1 CURSOR FOR SELECT DOC_ID ,PAGE_NUMBER ,IMPORTER ,IMPORT_TIME ,FORMAT ,IMAGE FROM ##T.NORMEN00 ENDEXEC LOAD DATA INCURSOR C1 REPLACE WORKDDN(TSYSUT1,TSORTOUT) SORTDEVT 3390 SORTNUM 8 INTO TABLE ##T.NORMEN02 Because the ROWID column of table ##T.NORMEN00 is explicitly defined and the ROWID column of ##T.NORMEN02 is explicitly defined as GENERATED ALWAYS, we cannot use 178
LOBs with DB2 for z/OS: Stronger and Faster
SELECT * here. We could have used SELECT * if both ROWIDs were implicitly created or when the ROWID of ##T.NORMEN02 was created a GENERATED BY DEFAULT (and with a unique index defined on it).
You must perform these tasks separately. Using STATISTICS when loading a table with LOB columns only gathers statistics for the base table space but not for the LOB table spaces. You must perform these tasks separately. Since DB2 V8, the default value for SORTKEYS is SORTKEYS 0. If you plan to load a table that has LOB columns using LOAD RESUME YES SHRLEVEL NONE, and you might need to restart the LOAD job with RESTART(CURRENT), then you must specify SORTKEYS NO; otherwise, the utility cannot be restarted. If you use RESTART PHASE to restart a LOAD job which specified RESUME NO, the LOB table spaces and indexes on auxiliary tables are reset. If the SELECT statement in the cursor definition contains the ROWID column of the source table, the table to be loaded must have a ROWID column with the same name and defined as GENERATED BY DEFAULT (+ unique index defined on the ROWID column). If the ROWID column of the source table was implicitly created, SELECT * does not contain the ROWID of the table.
6.4 COPY
Both full and incremental image copies are supported for a LOB table space, as well as SHRLEVEL REFERENCE, SHRLEVEL CHANGE, and the CONCURRENT options. COPY without the CONCURRENT option does not copy empty or unformatted data pages of a LOB table space. You can also COPY the auxiliary indexes. You can copy both the base table space and the LOB table spaces at the same time to establish a common recoverable point of consistency. To create a common recoverable point of consistency, use SHRLEVEL REFERENCE. Note: A common recoverable point of consistency is a point where both base table data and LOB data are consistent and to which a point in time recovery can be done. If you copy a LOB table space that has a base table space with the NOT LOGGED attribute (new DB2 9), copy the base table space and the LOB table space ALWAYS together so that a RECOVER TOLASTCOPY of the entire set results in consistent data across the base table
Chapter 6. Utilities with LOBs
179
space and all of the associated LOB table spaces. You cannot copy the base table space or LOB table space with SHRLEVEL CHANGE if the base table space is defined as NOT LOGGED. If you take an inline image copy of a table with LOB columns (LOAD, REORG), DB2 makes a copy of the base table space, but does not copy the LOB table spaces.
SHRLEVEL options
In general, when you use SHRLEVEL CHANGE for image copies of your LOB table space, somebody can interfere with your job and manipulate the content of the table you are currently backing up. Consider the following example, an image copy job backs up your LOB table space and it takes a couple of minutes, depending on the number and size of your LOBs stored in the auxiliary table. When somebody inserts a LOB value, some pages can be placed in the already backed up area of your table space while other pages can be stored in an area of your LOB table space that your job has not backed up yet. When you have used LOG YES for the definition of the LOB table space, you can acquire a quiesce point after the image copy is taken to create a recoverable point in time. But when you have specified LOG NO for your LOB table space, you can be in trouble if you have to recover to an image copy taken with SHRLEVEL CHANGE. This means that you are not protected against an inconsistent status of your image copy when using SHRLEVEL CHANGE. We recommend using SHRLEVEL REFERENCE for copying the LOB table space, regardless of whether you take incremental or full image copies. You cannot copy the base table space or LOB table space with SHRLEVEL CHANGE if the base table space is defined as NOT LOGGED. Only SHRLEVEL REFERENCE is allowed to be able to create a recoverable point. If you try SHRLEVEL CHANGE, you get the message: DSNU447I - COPY SHRLEVEL CHANGE OF TABLESPACE ..... IS NOT ALLOWED BECAUSE IT HAS A LOGGING ATTRIBUTE OF NOT LOGGED
CONCURRENT copy
You might be able to gain improved availability by using the concurrent copy function of the DFSMSdss component of the Data Facility Storage Management Subsystem (DFSMS). You can subsequently run the DB2 RECOVER utility to restore those image copies and apply 180
LOBs with DB2 for z/OS: Stronger and Faster
the necessary log records to them to complete recovery. The CONCURRENT option of COPY invokes the DFSMSdss concurrent copy. The COPY utility records the resulting DFSMSdss concurrent copies in the catalog table SYSIBM.SYSCOPY with ICTYPE=F and STYPE=C or STYPE=J. STYPE=C indicates that the concurrent copy was taken of the I instance of the table space. STYPE=J indicates that the concurrent copy was taken of the J instance of the table space. To obtain a consistent offline backup copy outside of DB2: 1. Start the DB2 objects that are being backed up for read-only access by issuing the command: -START DATABASE(database-name) SPACENAM(table space name) ACCESS(RO) Allowing read-only access is necessary to ensure that no updates to data occur during this procedure. 2. Run QUIESCE with the WRITE(YES) option to quiesce all DB2 objects that are being backed up. 3. COPY CONCURRENT the DB2 objects. 4. Issue the following command to allow transactions to access the data: -START DATABASE(database-name) SPACENAM(table space name) If you specify COPY SHRLEVEL REFERENCE with the CONCURRENT option, and if you want to copy all of the data sets for a list of table spaces to the same dump data set, specify FILTERDDN in your COPY statement. This improves the table space availability, because if you do not specify FILTERDDN, COPY might force DFSMSdss to process the list of table spaces sequentially, which might limit the availability of some of the table spaces that are being copied.
Examples
In Example 6-27, we take a consistent backup for all objects of the table ##T.NORMEN00 as defined in Example 6-1 on page 162. We use the PARALLEL option to speed up the process. The SHRLEVEL REFERENCE results in a common recoverable point of consistency.
Example 6-27 COPY LOB data
TEMPLATE TSYSCOPY DSN('DB2IM.&SS..&DB..&SN..&IC.&JU(3,5)..#&TI.') DISP(MOD,CATLG,CATLG) LISTDEF MYLIST INCLUDE TABLESPACES TABLE ##T.NORMEN00 ALL INCLUDE INDEXSPACES COPY YES TABLE ##T.NORMEN00 ALL COPY LIST MYLIST FULL YES SHRLEVEL REFERENCE PARALLEL COPYDDN(TSYSCOPY) As a result, four image copies are taken with the same START_RBA in SYSIBM.SYSCOPY as shown in Example 6-28: One copy for each table space and one copy for each index space.
Example 6-28 Common START_RBA in SYSIBM.SYSCOPY
DBNAME -------NORMEN00 NORMEN00 NORMEN00 NORMEN00 TSNAME -------NORMEN00 NORMLOB IRNORMEN IRNO189G ICTYPE -----F F F F START RBA HEX ------------00005A542C27 00005A542C27 00005A542C27 00005A542C27 DSNAME -------------------------------------------DB2IM.DB9B.NORMEN00.NORMEN00.F06208.#230717 DB2IM.DB9B.NORMEN00.NORMLOB.F06208.#230717 DB2IM.DB9B.NORMEN00.IRNORMEN.F06208.#230717 DB2IM.DB9B.NORMEN00.IRNO189G.F06208.#230717 SHRLEVEL -------R R R R OTYPE ----T T I I ICBACKUP --------
181
In Example 6-29, we use the CONCURRENT copy option to invoke the DFSMSdss concurrent copy function and create a common recoverable point of consistency.
Example 6-29 CONCURRENT COPY of LOB data
TEMPLATE TSYSCOPY DSN('DB2IM.&SS..&DB..&SN..&IC.&JU(3,5)..#&TI.') DISP(MOD,CATLG,CATLG) LISTDEF MYLIST INCLUDE TABLESPACES TABLE ##T.NORMEN00 ALL INCLUDE INDEXSPACES COPY YES TABLE ##T.NORMEN00 ALL COPY LIST MYLIST CONCURRENT SHRLEVEL REFERENCE COPYDDN(TSYSCOPY) The resulting entries in SYSIBM.SYSCOPY are shown in Example 6-30. They all have the same START_RBA.
Example 6-30 CONCURRENT COPY entries in SYSIBM.SYSCOPY
DBNAME -------NORMEN00 NORMEN00 NORMEN00 NORMEN00 TSNAME -------NORMEN00 NORMLOB IRNORMEN IRNO189G ICTYPE -----F F F F START RBA HEX ------------00005A575C9D 00005A575C9D 00005A575C9D 00005A575C9D DSNAME ------------------------------------------DB2IM.DB9B.NORMEN00.NORMEN00.F06208.#234445 DB2IM.DB9B.NORMEN00.NORMLOB.F06208.#234445 DB2IM.DB9B.NORMEN00.IRNORMEN.F06208.#234445 DB2IM.DB9B.NORMEN00.IRNO189G.F06208.#234445 SHRLEVEL -------R R R R STYPE ----C C C C ICBACKUP --------
In Example 6-31, we use the FILTERDDN option to copy all of the objects to the same dump data set. We use the &LI. template variable, because &SN. makes little sense here.
Example 6-31 CONCURRENT COPY of LOB data to one dump data set
TEMPLATE TSYSCOPY DSN('DB2IM.&SS..&DB..&LI..&IC.&JU(3,5)..#&TI.') DISP(MOD,CATLG,CATLG) TEMPLATE TFILTER DSN('DB2IM.&SS..&DB..&LI..Z&JU(3,5)..#&TI.') DISP(MOD,CATLG,CATLG) LISTDEF MYLIST INCLUDE TABLESPACES TABLE ##T.NORMEN00 ALL INCLUDE INDEXSPACES COPY YES TABLE ##T.NORMEN00 ALL COPY LIST MYLIST CONCURRENT SHRLEVEL REFERENCE COPYDDN(TSYSCOPY) FILTERDDN(TFILTER) If you specify FILTERDDN, the SYSCOPY records for all objects in the list have the same data set name and START_RBA as shown in Example 6-32.
Example 6-32 CONCURRENT COPY entries in SYSIBM.SYSCOPY with FILTERDDN
DBNAME -------NORMEN00 NORMEN00 NORMEN00 NORMEN00 TSNAME -------NORMEN00 NORMLOB IRNORMEN IRNO189G ICTYPE -----F F F F START RBA HEX ------------00005A95B112 00005A95B112 00005A95B112 00005A95B112 DSNAME ------------------------------------------DB2IM.DB9B.NORMEN00.MYLIST.F06209.#172934 DB2IM.DB9B.NORMEN00.MYLIST.F06209.#172934 DB2IM.DB9B.NORMEN00.MYLIST.F06209.#172934 DB2IM.DB9B.NORMEN00.MYLIST.F06209.#172934 SHRLEVEL -------R R R R STYPE ICBACKUP ----- -------C C C C
6.5 COPYTOCOPY
COPYTOCOPY can also be run on image copies of LOB table spaces.
182
The COPYTOCOPY utility makes image copies from an image copy that was taken by the COPY utility. This includes inline copies that the REORG or LOAD utilities make. Starting with either the local primary or recovery-site primary copy, COPYTOCOPY can make up to three copies of one or more of the following types of copies: Local primary Local backup Recovery site primary Recovery site backup However, you cannot run COPYTOCOPY on concurrent copies. In Example 6-33, you see how to take a set of recovery site primary image copies starting from the last local primary image copies (because you cannot COPYTOCOPY from concurrent copies, we first had to take a new set of FULL image copies as in Example 6-27 on page 181).
Example 6-33 COPYTOCOPY
TEMPLATE TSYSCOPY DSN('DB2IM.&SS..&DB..&SN..&IC.&JU(3,5)..#&TI.') DISP(MOD,CATLG,CATLG) LISTDEF MYLIST INCLUDE TABLESPACES TABLE ##T.NORMEN00 ALL INCLUDE INDEXSPACES COPY YES TABLE ##T.NORMEN00 ALL COPYTOCOPY LIST MYLIST FROMLASTCOPY RECOVERYDDN(TSYSCOPY) Both sets of primary and recovery site image copies have the same START_RBA as shown in Example 6-34.
Example 6-34 Primary and COPYTOCOPY entries in SYSIBM.SYSCOPY
DBNAME -------NORMEN00 NORMEN00 NORMEN00 NORMEN00 NORMEN00 NORMEN00 NORMEN00 NORMEN00 TSNAME -------NORMEN00 NORMLOB IRNORMEN IRNO189G NORMEN00 NORMLOB IRNORMEN IRNO189G ICTYPE -----F F F F F F F F START RBA HEX ------------00005A9E3DE6 00005A9E3DE6 00005A9E3DE6 00005A9E3DE6 00005A9E3DE6 00005A9E3DE6 00005A9E3DE6 00005A9E3DE6 DSNAME ------------------------------------------DB2IM.DB9B.NORMEN00.NORMEN00.F06209.#174842 DB2IM.DB9B.NORMEN00.NORMLOB.F06209.#174842 DB2IM.DB9B.NORMEN00.IRNORMEN.F06209.#174842 DB2IM.DB9B.NORMEN00.IRNO189G.F06209.#174842 DB2IM.DB9B.NORMEN00.NORMEN00.F06209.#174904 DB2IM.DB9B.NORMEN00.NORMLOB.F06209.#174904 DB2IM.DB9B.NORMEN00.IRNORMEN.F06209.#174904 DB2IM.DB9B.NORMEN00.IRNO189G.F06209.#174904 SHRLEVEL -------R R R R R R R R STYPE ----ICBACKUP --------
RP RP RP RP
6.6 QUIESCE
The QUIESCE utility establishes a quiesce point for a table space, partition, table space set, or list of table spaces and table space sets. A quiesce point is the current log RBA or log record sequence number (LRSN). QUIESCE then records the quiesce point in the SYSIBM.SYSCOPY catalog table. A successful QUIESCE improves the probability of a successful RECOVER or COPY. if you want to establish a quiesce point for the point in time recovery of a base table and all of its related LOB objects, you have to look at these objects as a table space set (like tables related with referential integrity). The Quiesce utility drains all writers on the table space objects. The default is to write the changed pages from the table spaces and index spaces to disk (WRITE YES).
Chapter 6. Utilities with LOBs
183
Because a non-partitioned or partitioned base table can contain many auxiliary table space objects (one LOB table space per LOB column and per partition), we recommend that you use a LISTDEF to generate a list of all the table space objects with the ALL LOB indicator keyword, as shown in Example 6-35. This creates a common quiesce point.
Example 6-35 QUIESCE a base table space and all LOB table spaces
LISTDEF MYLIST INCLUDE TABLESPACES TABLE ##T.NORMEN00 ALL QUIESCE LIST MYLIST The resulting SYSIBM.SYSCOPY entries are shown in Example 6-36. STYPE=W means that the QUIESCE was done with WRITE(YES). All table spaces have the same START_RBA resulting in a common quiesce point.
Example 6-36 QUIESCE entries in SYSIBM.SYSCOPY DBNAME -------NORMEN00 NORMEN00 NORMEN00 NORMEN00 TSNAME -------NORMEN00 NORMLOB IRNORMEN IRNO189G ICTYPE -----Q Q Q Q START RBA HEX ------------00005AABD468 00005AABD468 00005AABD468 00005AABD468 STYPE ----W W W W OTYPE ----T T I I
A valid alternative to create a common quiesce point is to use the TABLESPACESET keyword with the base table space or one of the involved LOB table spaces as shown in Example 6-37.
Example 6-37 QUIESCE a table space set
QUIESCE TABLESPACESET NORMEN00.NORMEN00 A common quiesce point is a common recoverable point of consistency when both the base table space and LOB table spaces were created as LOG YES (V7 and V8) or LOGGED (DB2 9). Be aware that to recover to a common quiesce point is not being able to recover the LOBS if the LOB table is defined as LOG NO (V7 and V8) or NOT LOGGED (DB2 9), because of the missing log records. Also, if the base table space is defined as NOT LOGGED, the quiesce point is not a common recoverable point of consistency. See Recovering to a prior point in time on page 198 for more details.
6.7 REPORT
The REPORT utility provides information about table spaces, tables, and indexes. Use REPORT TABLESPACESET to find the names of all the table spaces and tables in a referential structure, including LOB table spaces. The REPORT utility also provides information about the LOB table spaces that are associated with a base table space. Use REPORT RECOVERY to find information that is necessary for recovering a base table space and its indexes, and LOB table space and its indexes. The REPORT TABLESPACESET is also useful when the base and LOB table spaces have been created by using the automatic creation of objects (DB2 9 only). In Example 6-38 on page 185, we show how to use the REPORT TABLESPACESET on the underlying table spaces of the table ##T.NORMEN00 defined in Example 6-1 on page 162. Because the REPORT TABLESPACESET command does not support the use of a LISTDEF, the name of the base table space must first be retrieved from SYSIBM.SYSTABLES.
184
BASE TABLE : ##T.NORMEN01 PART: 0001 COLUMN : IMAGE LOB TABLESPACE : DSN00030.L96UX60E AUX TABLE : ##T.NORMEIMAGE96UXYNM9 AUX INDEXSPACE : DSN00030.INORMEIM AUX INDEX : ##T.INORMEIMAGE96UXYYX DSNU580I DSNU010I 209 15:06:45.20 DSNUPORT - REPORT UTILITY COMPLETE - ELAPSED TIME=00:00:00 209 15:06:45.20 DSNUGBAC - UTILITY EXECUTION COMPLETE, HIGHEST RETURN CODE=0
A report on the recovery information about all automatically created objects related to table ##T.NORMEN01 can be obtained as shown in Example 6-40.
Example 6-40 REPORT RECOVERY
LISTDEF MYLIST INCLUDE TABLESPACES TABLE ##T.NORMEN01 ALL REPORT RECOVERY TABLESPACE LIST MYLIST INDEX ALL
6.8 RUNSTATS
When dealing with LOBs, you can run the RUNSTATS utility against the base table space, the LOB table space, or the index on the auxiliary table. We do not discuss the HISTORY catalog tables in this paragraph, but they contain similar statistics when RUNSTATS is run to collect historical data. You can run RUNSTATS on the auxiliary objects, but the statistics do not have any effect on access paths and there are no column statistics. The statistics can be used to monitor space usage (such as number of extents) and ORGRATIO to schedule a REORG of the LOB table space. ORGRATIO is used for LOBs to indicate the percentage of LOBs that are properly chunked (that is, allocated in contiguous sets of 16 pages). This is explained in more detail at Monitoring ORGRATIO on page 193.
185
In SYSIBM.SYSCOLSTATS, the cardinality of a LOB column, COLCARDF, is determined by counting only non-null and non-zero length columns. HIGHKEY, LOWKEY, HIGH2KEY, and LOW2KEY are not applicable for the LOB column and contain blanks.
LISTDEF BASETS INCLUDE TABLESPACES TABLE ##T.NORMEN00 BASE RUNSTATS TABLESPACE LIST BASETS TABLE (ALL) INDEX(ALL KEYCARD FREQVAL NUMCOLS 1 COUNT 10 FREQVAL NUMCOLS 2 COUNT 10 FREQVAL NUMCOLS 3 COUNT 10 FREQVAL NUMCOLS 4 COUNT 10 FREQVAL NUMCOLS 5 COUNT 10) SHRLEVEL CHANGE REPORT YES HISTORY ALL LISTDEF LOBTS INCLUDE TABLESPACES TABLE ##T.NORMEN00 LOB RUNSTATS TABLESPACE LIST LOBTS INDEX (ALL) SHRLEVEL CHANGE REPORT YES HISTORY ALL
When using REPORT YES, you can actually see which statistics are gathered and what their values are.
186
6.9 REORG
In this section, we discuss the REORG of LOB objects. As with normal table spaces and indexes, the REORG utility can be used to: Reorg a LOB table space to reclaim fragmented space and improve access performance Reorg an auxiliary index to reclaim fragmented space and improve access performance For REORG TABLESPACE on a LOB table space, there are two kinds of REORG possible: REORG TABLESPACE SHRLEVEL NONE (this is the only one possible in DB2 V7 and DB2 V8) REORG TABLESPACE SHRLEVEL REFERENCE (new and recommended in DB2 9) For REORG INDEX on an auxiliary index, three REORG methods are allowed: REORG INDEX SHRLEVEL NONE REORG INDEX SHRLEVEL REFERENCE REORG INDEX SHRLEVEL CHANGE (recommended) Tip: Remember that it is possible to combine REORG and RUNSTATS in one run using the STATISTICS in-line options in the REORG command.
187
This REORG method has three utility phases: UTILINIT, REORGLOB, and UTILTERM. During the REORGLOB phase, the LOB table space is rebuilt in place without unloading and reloading the LOB data to and from an external data set. The utility is not restartable during the REORGLOB phase, and it is left in RECP status if a failure happens. You have to run RECOVER to recover the LOB table space. No records are inserted in SYSIBM.SYSCOPY for REORG SHRLEVEL NONE. Tip: With REORG SHRLEVEL NONE, we always recommend that you take a full image COPY SHRLEVEL REFERENCE before and after the REORG to assure recoverability. As with the other utilities, because a non-partitioned or partitioned base table can contain many auxiliary table space objects (one LOB table space per LOB column and per partition), you can use a LISTDEF to generate a list of all the LOB table spaces. However in this case, this implies a REORG of all the LOB table spaces, and this might not be what you want. An example of REORG SHRLEVEL NONE is shown in Example 6-42.
Example 6-42 REORG SHRLEVEL NONE of one LOB table space
REORG TABLESPACE NORMEN00.NORMLOB LOG YES SHRLEVEL NONE An example of REORG with a LISTDEF is shown in Example 6-43.
Example 6-43 REORG SHRLEVEL NONE of all LOB objects
LISTDEF LOBTS INCLUDE TABLESPACES TABLE ##T.NORMEN00 LOB REORG TABLESPACE LIST LOBTS LOG YES SHRLEVEL NONE
188
is therefore no longer needed to resize a LOB table space but could still be useful as described in Use of RECOVERY for reallocating LOB table spaces on page 201. As with the pre-DB2 9 REORG of LOB table spaces, the new solution has no dependency on the base table or base table indexes. Therefore, REORG of a LOB table space continues to have no impact on access to base table data. LOG YES is not valid for REORG SHRLEVEL REFERENCE of a LOB table space. This results in reduced logging requirements for LOB table spaces with no loss of recoverability. An example of the differences between REORG SHRLEVEL NONE in DB2 V8 (and prior releases) is shown in Figure 6-1, Figure 6-2 on page 190, and Figure 6-3 on page 190. We assume we have an auxiliary table space for a LOB column and a heavy update workload has taken place since the initial allocation. Note, we are focusing entirely on the auxiliary table space and not the accompanying auxiliary index for this example.
extent 1
extent 2
extent 3
extent 4
extent 5,6,7....
This shows a LOB auxiliary table space that has undergone significant change activity, leading both to disorganization of pages, as well as allocation of many extents for the underlying data sets.
189
extent 1
extent 2
extent 3
extent 4
extent 5,6,7....
Figure 6-2 shows that while the data within the table space has been reordered, and holes between objects removed, the physical layout of the data set has not been altered. If there is significant free space, this effectively means a lot of disk space remains unusable, because it is still allocated. The space can be used for subsequent expansion only with data of rows within the table in the auxiliary table space. There is also the residual inefficiency of the data spanning many extents.
extent 1 (resized)
Figure 6-3 shows a table space where REORG SHRLEVEL REFERENCE has been performed. It is assumed that an ALTER of the primary quantity of the table space has been issued before the REORG reflecting the correct allocation for the table space size required for the present data volume, allowing for anticipated growth if desired, and a suitable secondary quantity also determined and ALTERed to take effect. 190
LOBs with DB2 for z/OS: Stronger and Faster
An inline copy is always taken to ensure recoverability. This is required and the COPYDDN parameter is needed unless a SYSCOPY DD card is specified in the utility JCL. As with a normal REORG SHRLEVEL REFERENCE, the REORG of a LOB table space now inserts two SYSCOPY records. The first SYSCOPY record represents the REORG itself, which is a nonrecoverable event, and the second SYSCOPY record represents the inline image copy. The switch from original to shadow data sets is a nonrecoverable event requiring an inline copy to be taken during the REORG. During recovery, DB2 cannot apply log records across the switch from the original data set to the shadows. Recovery to a point after the REORG must rely upon the inline copy taken during the REORG process. In the event of a failure during the REORG, the shadow copy is discarded. The utility cannot be restarted. The implications of using shadow data sets are: Before the new REORG, LOB table spaces and the associated auxiliary indexes could only have an instance of "I". The new REORG causes LOB table space instances and auxiliary index instances to alternate between "I" and "J". Any tools or applications, which assume that LOB table spaces are "I" data sets, have to change to also tolerate "J" data sets. This REORG method has four utility phases: UTILINIT, REORGLOB, SWITCH, and UTILTERM. During the REORGLOB phase, the LOB table space is unloaded to the shadow data set and any error during this phase leaves the original data set intact. The utility is not restartable during the REORGLOB phase, but the original data set is never put in RECP status if a failure happens. You no longer have to run RECOVER to recover the LOB table space afterwards. The inline image copy assures recoverability. As with the other utilities, because a non-partitioned or partitioned base table can contain many auxiliary table space objects (one LOB table space per LOB column and per partition), you can use a LISTDEF to generate a list of all the LOB table spaces. However in this case, you do a REORG of all the LOB table spaces, which might not be the intention. An example of REORG SHRLEVEL REFERENCE is shown in Example 6-44.
Example 6-44 REORG SHRLEVEL REFERENCE
TEMPLATE TSYSCOPY DSN('DB2IM.&SS..&DB..&SN..&IC.&JU(3,5)..#&TI.') DISP(MOD,CATLG,CATLG) REORG TABLESPACE NORMEN00.NORMLOB LOG NO COPYDDN(TSYSCOPY) SHRLEVEL REFERENCE The resulting job output is shown in Example 6-45.
Example 6-45 REORG SHRLEVEL REFERENCE output
DSNU000I 212 DSNU1044I 212 DSNU050I 212 CATLG, CATLG) DSNU1035I 212 DSNU050I 212 REFERENCE DSNU1038I 212 19:44:43.16 DSNUGUTC - OUTPUT START FOR UTILITY, UTILID = REORG.NORMEN00 19:44:43.22 DSNUGTIS - PROCESSING SYSIN AS EBCDIC 19:44:43.22 DSNUGUTC - TEMPLATE TSYSCOPY DSN('DB2IM.&SS..&DB..&SN..&IC.&JU(3,5)..#&TI.') DISP(MOD, 19:44:43.22 DSNUJTDR - TEMPLATE STATEMENT PROCESSED SUCCESSFULLY 19:44:43.23 DSNUGUTC - REORG TABLESPACE NORMEN00.NORMLOB LOG NO COPYDDN(TSYSCOPY) SHRLEVEL
19:44:45.01 DSNUGDYN - DATASET ALLOCATED. TEMPLATE=TSYSCOPY DDNAME=SYS00001 DSN=DB2IM.DB9B.NORMEN00.NORMLOB.F06212.#234443 DSNU1151I -DB9B 212 19:45:16.29 DSNURLOB - REORGLOB PHASE COMPLETE - NUMBER OF RECORDS PROCESSED=5883 DSNU387I 212 19:45:16.67 DSNURSWT - SWITCH PHASE COMPLETE, ELAPSED TIME = 00:00:00 DSNU428I 212 19:45:16.68 DSNURSWT - DB2 IMAGE COPY SUCCESSFUL FOR TABLESPACE NORMEN00.NORMLOB
191
DSNU400I
212 19:45:16.69 DSNURBID - COPY PROCESSED FOR TABLESPACE NORMEN00.NORMLOB NUMBER OF PAGES=50057 AVERAGE PERCENT FREE SPACE PER PAGE = 0.00 PERCENT OF CHANGED PAGES =100.00 ELAPSED TIME=00:00:31 -DB9B 212 19:45:16.58 DSNURWT - FULL IMAGE COPY SHOULD BE TAKEN FOR BOTH LOCAL SITE AND RECOVERY SITE FOR TABLESPACE NORMEN00.NORMLOB -DB9B 212 19:45:17.10 DSNUGSRX - INDEX ##T.I_NORMEN00_AUX IS IN INFORMATIONAL COPY PENDING STATE 212 19:45:17.11 DSNUGBAC - UTILITY EXECUTION COMPLETE, HIGHEST RETURN CODE=4
Message DSNU406I is issued, because previously we took image copies for a recovery site. An example of REORG with a LISTDEF is shown in Example 6-46.
Example 6-46 REORG SHRLEVEL REFERENCE with LISTDEF
LISTDEF LOBTS INCLUDE TABLESPACES TABLE ##T.NORMEN00 LOB REORG TABLESPACE LIST LOBTS LOG NO SHRLEVEL REFERENCE
TEMPLATE TSYSUT1 DSN('DB2RE.&SS..&DB..&SN..U&JU(3,5)..#&TI.') DISP(MOD,DELETE,CATLG) REORG INDEX ##T.I_NORMEN00_AUX SHRLEVEL CHANGE MAXRO 20 DRAIN ALL DRAIN_WAIT 20 RETRY 120 RETRY_DELAY 60 TIMEOUT TERM SORTDEVT 3390 SORTNUM 6 WORKDDN(TSYSUT1) Be aware that REORG TABLESPACE of a LOB table space also rebuilds the auxiliary index, and in this case, there is no need to run a separate REORG INDEX utility on the auxiliary index.
Impact of logging
REORG forces you to specify LOG YES for REORG SHRLEVEL NONE and LOG NO with COPYDDN for SHRLEVEL REFERENCE. A LOB table space can also be defined with LOG YES or LOG NO. In DB2 9 also, the base table space can be defined as LOGGED or NON LOGGED. Table 6-2 on page 193 shows the effect on logging output and LOB table space in case the base table space is LOGGED.
192
Table 6-2 Impact of logging if base table space is LOGGED Impact of logging on REORG REORG LOG keyword LOG YES LOG YES LOG NO LOG NO LOB table space LOG attribute LOG YES LOG NO LOG YES LOG NO What is logged LOB table space status after utility completes No pending status No pending status No pending status because of inline copy No pending status because of inline copy
If the base table space is defined as NOT LOGGED and the LOB table spaces are defined as LOGGED, the LOB table spaces with the LOGGED logging attribute are changed to NOT LOGGED as well. However, this is recorded in the DB2 catalog so that if the base table space is altered to LOGGED, the LOB table spaces are also changed back to LOGGED. If both base table space and LOB table spaces are NOT LOGGED, the LOG YES attribute of the REORG SHRLEVEL NONE utility is also changed to LOG NO during execution. Nothing is logged.
Monitoring ORGRATIO
ORGRATIO is the percent of organization of the LOB table space. A value of 100 indicates perfect organization. A value of 1 indicates that the LOB table space is disorganized. A value of 0 means that the LOB table space is totally disorganized. A LOB table space is considered to be perfectly organized if all the LOB groups of 16 pages (called chunks) belonging to a single LOB are stored in contiguous pages. A LOB column always has an auxiliary index, which locates the LOB within the LOB table space. Access path is not an issue, because LOB access is always done through an index probe using the auxiliary index. However, performance can be affected if LOBs are scattered into more physical pieces than necessary, therefore, involving more I/O to scan and materialize. Figure 6-4 on page 194 shows that there are four LOBs accessed via the auxiliary index. These LOBs are stored in chunks of pages. A chunk consists of 16 contiguous pages of LOB data. If the size of a LOB is smaller than a chunk (smaller than 16 pages), then the LOB is
Chapter 6. Utilities with LOBs
193
expected to fit in one chunk. If the size of the LOB is greater than a chunk (greater than 16 pages), then it is optimized to fit into the minimum number of chunks (LOB size divided by chunk size). If, because of fragmentation within chunks, LOBs are split up to store in more chunks than optimal, the ORGRATIO decreases. In our example, the first part of LOB 1 (accessed by ROWID 1) is stored in chunk 1, the remaining bytes are placed in data pages of chunk number 2. Because of its size, LOB number 1 could fit into one chunk, but two chunks are used to store its value. This means that one extra chunk is used to store LOB number 1. Because of its size, LOB number 2 needs at least two chunks to be stored, and this is what is used by DB2 to store LOB number 2. So, there are no extra chunks for LOB number 2. The value of LOB number 3 should fit into one chunk and is also stored in one chunk, which means that there are no extra chunks used for its storage. Things are different for LOB number 4. The value of LOB number 4 is expected to fit in two chunks, but DB2 uses three chunks. So there is another extra chunk used for LOB number 4. In this case, ORGRATIO would be 50, since two out of four LOBs are properly chunked.
chunk 1
chunk 2
chunk 3
chunk 4
chunk 5
As shown in Figure 6-5 on page 195, after reorganization of the LOB space, the LOBs are placed in the optimal number of chunks. Since there are no extra chunks allocated, the ORGRATIO is 100.
194
chunk 1
chunk 2
chunk 3
chunk 4
chunk 5
orgratio=100
Based on chunking considerations, you could decide to REORG a LOB table space when either: ORGRATIO < 10 REORGDISLOB (number of LOBs inserted since the last REORG that are not perfectly chunked)/TOTALROWS > 10% The threshold value is set pretty low, because the impact of low ORGRATIO is less than one of the other factors not related to chunking. In the case of a large LOB being read, DB2 uses list prefetch, which always reads pages in ascending page number sequence after sorting. DB2 V8 has removed the 180 CI limit in list prefetch. For small LOBs, which can fit in a page, they are considered perfectly chunked and give ORGRATIO 100. Notes: APAR PQ96460 (PTFs UQ9617, UQ96148, and UQ96149 respectively for V6, V7 and V8) changed the ratio of organization in the LOB table space from 1 meaning perfect organization of the LOB table space to 100, more in line with other ratios generally expressed in percentages. APAR PK29750 corrects the new ORGRATIO calculations (PTFs UK25088, UK25089, and UK25090 repectively for DB2 V7, V8, and V9).
Monitoring FREESPACE
As explained before, FREESPACE gives the number of kilobytes of free space in extents with respect to high used relative byte address (RBA) or (HURBA). The FREESPACE gives you an indication of how much allocated space is available for more LOBs.
195
For LOB table spaces, an updated LOB is written without immediately reclaiming the old version of the LOB. The old version of the LOB becomes free space at commit time and when no more readers claim these old versions. The same is true for deleted LOBs. When FREESPACE approaches zero for a LOB table space, it might be a good idea to resize the LOB table space using REORG SHRLEVEL REFERENCE. FREESPACE can also be used to reduce the size of the LOB table space if a much too large PQTY was used to create the LOB table space or to reclaim physical space after many DELETEs. ALTER PQTY followed by REORG SHRLEVEL REFERENCE resizes the LOB table space.
(((QueryType='REORG' OR QueryType='ALL') AND (ObjectType='TS' OR ObjectType='ALL')) AND (REORGLASTTIME IS NULL AND LOADRLASTTIME IS NULL) OR (NACTIVE IS NULL OR NACTIVE > 5) AND ((((REORGINSERTS*100)/TOTALROWS>RRTInsertPct) AND REORGINSERTS>RRTInsertAbs) OR (((REORGDELETE*100)/TOTALROWS>RRTDeletePct) AND REORGDELETE>RRTDeleteAbs) OR (REORGUNCLUSTINS*100)/TOTALROWS>RRTUnclustInsPct OR (REORGDISORGLOB*100)/TOTALROWS>RRTDisorgLOBPct OR (SPACE*1024)/DATASIZE>RRTDataSpaceRat OR ((REORGNEARINDREF+REORGFARINDREF)*100)/TOTALROWS>RRTIndRefLimit OR REORGMASSDELETE>RRTMassDelLimit OR EXTENTS>ExtentLimit)) OR ((QueryType='RESTRICT' OR QueryType='ALL') AND (ObjectType='TS' OR ObjectType='ALL') AND The table space is in advisory or informational reorg pending status) OR ((QueryType='RESTRICT' OR QueryType='ALL') AND (ObjectType='IX' OR ObjectType='ALL')) AND An index on the tablespace is in advisory-REBUILD-pending stats (ARBDP))) The new formula that DSNACCOX is planned to execute when deciding to REORG an index is listed in Example 6-49.
Example 6-49 RTS DSNACCOX query for REORG INDEX
(((QueryType='REORG' OR QueryType='ALL') AND (ObjectType='IX' OR ObjectType='ALL') AND (REORGLASTTIME IS NULL AND REBUILDLASTTIME IS NULL) OR (NACTIVE IS NULL OR NACTIVE > 5) AND 196
LOBs with DB2 for z/OS: Stronger and Faster
((((REORGINSERTS*100)/TOTALENTRIES>RRIInsertPct) AND REORGINSERTS>RRIInsertAbs) OR (((REORGDELETE*100)/TOTALENTRIES>RRIDeletePct) AND REORGDELETE>RRIDeleteAbs) OR (REORGAPPENDINSERT*100)/TOTALENTRIES>RRIAppendInsertPct OR (REORGPSEUDODELETES*100)/TOTALENTRIES>RRIPseudoDeletePct OR REORGMASSDELETE>RRIMassDeleteLimit OR (REORGLEAFFAR*100)/NACTIVE>RRILeafLimit OR REORGNUMLEVELS>RRINumLevelsLimit OR EXTENTS>ExtentLimit)) OR ((QueryType='RESTRICT' OR QueryType='ALL') AND (ObjectType='IX' OR ObjectType='ALL') AND An index is in advisory-REBUILD-pending stats (ARBDP)))
197
198
recorded in SYSIBM.SYSCOPY (for example, the START_RBA of a full SHRLEVEL REFERENCE image copy). If you specify a TOLOGPOINT or LOGRBA, which is not recorded as a recoverable point in SYSIBM.SYSCOPY, you get this message: DSNU1504I DSNUCASA - RECOVERY OF NOT LOGGED TABLESPACE ..........CANNOT PROCEED BECAUSE THE TOLOGPOINT OR TORBA SPECIFIED IS NOT A RECOVERABLE POINT.
199
For the recovery of the index, you should use RECOVER INDEX or REBUILD INDEX. Use RECOVER INDEX when you regularly take full image copies of all your indexes. Use REBUILD INDEX if you do not have full image copies of all your indexes or when you take them so infrequently that RECOVER INDEX would take a long time to finish when scanning the log (Remember that DB2 does not support incremental copies of indexes). You can also try to mix RECOVER and REBUILD index, but this can become very confusing at the end. If you have regular full image copies of all your normal and auxiliary indexes, a typical RECOVERY job could look as shown in Example 6-50.
Example 6-50 Recover table spaces an indexes
recovery to the current point in time: LISTDEF MYLIST INCLUDE TABLESPACES TABLE ##T.NORMEN00 ALL INCLUDE INDEXSPACES TABLE ##T.NORMEN00 ALL RECOVER LIST MYLIST PARALLEL point in time recovery to previous RBA: LISTDEF MYLIST INCLUDE TABLESPACES TABLE ##T.NORMEN00 ALL INCLUDE INDEXSPACES TABLE ##T.NORMEN00 ALL RECOVER LIST MYLIST TORBA X'0000729D9B16' PARALLEL (non-data sharing) or RECOVER LIST MYLIST TOLOGPOINT X'0000729D9B16' PARALLEL (data sharing) You cannot use the keywords TOLASTCOPY or TOLASTFULLCOPY with LISTDEF. They must be seen as extensions of the TOCOPY data set name keyword. If you do not have regular full image copies of all your normal and auxiliary indexes, you should use the REBUILD INDEX command as shown in Example 6-51.
Example 6-51 Recover table spaces and rebuild indexes
recovery to the current point in time: LISTDEF MYTSLIST INCLUDE TABLESPACES TABLE ##T.NORMEN00 ALL LISTDEF MYIXLIST INCLUDE INDEXSPACES TABLE ##T.NORMEN00 ALL RECOVER LIST MYTSLIST PARALLEL REBUILD INDEX LIST MYIXLIST SORTDEVT 3390 SORTNUM 6 point in time recovery to previous RBA: LISTDEF MYTSLIST INCLUDE TABLESPACES TABLE ##T.NORMEN00 ALL LISTDEF MYIXLIST INCLUDE INDEXSPACES TABLE ##T.NORMEN00 ALL RECOVER LIST MYTSLIST TORBA X'0000729D9B16' PARALLEL REBUILD INDEX LIST MYIXLIST SORTDEVT 3390 SORTNUM 6
200
Although this feature is not very useful for auxiliary indexes, because the LOB data is always accessed through the auxiliary index, you can still specify it to use the same REBUILD INDEX syntax for all the indexes (LISTDEF), provided that the LOB table space has the LOGGED attribute. An example is shown in Example 6-52.
Example 6-52 REBUILD SHRLEVEL CHANGE of the indexes
LISTDEF MYIXLIST INCLUDE INDEXSPACES TABLE ##T.NORMEN00 ALL REBUILD INDEX LIST MYIXLIST SHRLEVEL CHANGE SORTNUM 8 SORTDEVT 3390 DRAIN_WAIT 20 RETRY 120 RETRY_DELAY 60 MAXRO 20
TEMPLATE TSYSCPP1 DSN('DB2IM.&SS..&DB..&SN..&IC.&JU(3,5)..#&PA.') DISP(MOD,CATLG,CATLG) COPY TABLESPACE NORMEN00.NORMLOB DSNUM 3 COPYDDN(TSYSCPP1) SHRLEVEL REFERENCE FULL YES RECOVER TABLESPACE NORMEN00.NORMLOB DSNUM 3 TOLASTCOPY REPAIR OBJECT SET iNDEX (##T.I_NORMEN00_AUX) NORBDPEND REPAIR OBJECT SET TABLESPACE NORMEN00.NORMEN00 NOAUXCHKP The REPAIR statements are necessary to remove the pending states without running additional utilities.
201
time recovery where base tables and auxiliary tables might not be synchronized or when the base table space is in the auxiliary check pending state (ACHKP) or auxiliary warning state (AUXW). The CHECK DATA utility can only be run on a base table space, not on a LOB table space. The CHECK DATA utility accesses the base table space and all related auxiliary indexes of the LOB table spaces. CHECK DATA relies on information in the LOB table space and the auxiliary indexes being correct. It might be necessary to first run CHECK LOB on the LOB table space and CHECK INDEX and REBUILD INDEX on the auxiliary indexes to ensure the validity of the LOB table spaces and auxiliary indexes. CHECK DATA can be run in two modes: SHRLEVEL REFERENCE: Applications can read but cannot write. SHRLEVEL CHANGE: Applications can read and write (This is new with DB2 9). CHECK DATA reports the following errors: Orphan LOBs An orphan LOB column is a LOB entry found in the auxiliary index but not referenced by the base table space. An orphan can result if you recover the base table space and auxiliary index to a point in time prior to the insertion of the base table row or prior to the definition of the LOB column. An orphan can also result if you recover the LOB table space and auxiliary index to a point in time prior to the deletion of a base table row. Missing LOBs A missing LOB column is a LOB referenced by the base table space, but the LOB entry is not in the auxiliary index. A missing LOB can result if you recover the LOB table space and auxiliary index to a point in time when the LOB column is not in the LOB table space. This could be a point in time prior to the first insertion of the LOB into the base table, or when the LOB column is null or has a zero length. Out-of-sync LOBs An out-of-sync LOB error occurs when DB2 detects a LOB that is found in both the base table and the auxiliary index, but the LOB entry in the auxiliary index is at a different version. A LOB column is also out-of-sync if the base table LOB column is null or has a zero length, but the LOB is found through the auxiliary index. An out-of-sync LOB can occur anytime you recover the LOB table space and auxiliary index or the base table space to a prior point in time. Invalid LOBs in the base table space An invalid LOB is an uncorrected LOB column error found by a previous execution of CHECK DATA AUXERROR INVALIDATE. An invalid LOB in the base table space has the invalid flag set in the base table space. Note: CHECK DATA does not report invalid LOBs in the LOB table space. CHECK DATA does not invalidate LOBs in the base table space that are marked invalid in the LOB table space. CHECK DATA only inspects the auxiliary index and does not access the LOB table space itself. CHECK LOB must be run on the LOB table space to find invalid LOBs in the LOB table space.
CHECK DATA SHRLEVEL REFERENCE removes the ACHKP and AUXW status on a base table space if no errors are found, and it sets ACHKP or AUXW status on the base table space if there was no pending state before and errors are found. CHECK DATA SHRLEVEL CHANGE never sets or resets the ACHKP or AUXW states. 202
LOBs with DB2 for z/OS: Stronger and Faster
CHECK DATA fails if the LOB table space is in check pending (CHKP) status or recovery pending (RECP) status or when the auxiliary index is in the rebuild pending (RBDP) status. You can use the SCOPE AUXONLY to limit the checks for LOBs only; otherwise, the CHECK DATA also checks the referential integrity constraints and table constraints. With DB2 9, the CHECK DATA keywords AUXERROR and AUXONLY cover both LOB data and XML data. With DB2 9, as for the online REORG utility, you can specify drain options such as DRAIN_WAIT, RETRY, and RETRY_DELAY to have the utility retry the drain operation if it fails (both SHRLEVEL REFERENCE and CHANGE).
203
The AUXW pending state on the base table space can be reset by: Fix invalid LOBs and rerun CHECK DATA. REPAIR SET NOAUXWARN or START ACCESS(FORCE). Fixing the reported LOBS can be done by using SQL, the REPAIR utility, or the RECOVER utility to recover the data to another point in time, depending on which is the most appropriate.
statements to a PUNCHDDN data set to invalidate the LOBs in the base table space that you can execute later on. If CHECK DATA does not encounter any more invalid LOBs, the base table space is not reset in no pending state if it was in ACHKP and the table remains unavailable for applications. If invalid LOB columns remain, CHECK DATA does not set the base table space to the auxiliary warning (AUXW) status.
Examples
CHECK DATA does not allow the use of LISTDEFS and the name of the base table space must be explicitly specified. If it was automatically created, the name of the base table space must first be retrieved from SYSIBM.SYSTABLES. Examples for SHRLEVEL REFERENCE (V8 syntax) and SHRLEVEL CHANGE (DB2 9 syntax) are shown in Example 6-54.
Example 6-54 Examples of CHECK DATA
TEMPLATE TSORTOUT DSN('DB2RE.&SS..&DB..&SN..S&JU(3,5)..#&TI.') DISP(MOD,DELETE,CATLG) TEMPLATE TSYSUT1 DSN('DB2RE.&SS..&DB..&SN..U&JU(3,5)..#&TI.') DISP(MOD,DELETE,CATLG) TEMPLATE TSYSERR DSN('DB2RE.&SS..&DB..&SN..E&JU(3,5)..#&TI.') DISP(MOD,DELETE,CATLG) -- check data shrlevel reference CHECK DATA TABLESPACE NORMEN00.NORMEN00 SCOPE AUXONLY AUXERROR REPORT or INVALIDATE SORTNUM 8 SORTDEVT 3390 WORKDDN(TSYSUT1,TSORTOUT) ERRDDN(TSYSERR) -- check data shrlevel change TEMPLATE TSYSPUN DSN('DB2RE.&SS..&DB..&SN..E&JU(3,5)..#&TI.') DISP(MOD,CATLG,CATLG) CHECK DATA TABLESPACE NORMEN00.NORMEN00 SHRLEVEL CHANGE SCOPE AUXONLY AUXERROR REPORT or INVALIDATE SORTNUM 8 SORTDEVT 3390 WORKDDN(TSYSUT1,TSORTOUT) ERRDDN(TSYSERR) DRAIN_WAIT 20 RETRY 120 RETRY_DELAY 60 PUNCHDDN(TSYSPUN)
205
Important: If you want to run CHECK DATA when you suspect LOB errors, and you do not want your base table space to become unavailable for applications when errors are found, run CHECK DATA with SHRLEVEL CHANGE.
206
When the LOB table space is in no pending state and errors are found, the CHECK LOB SHRLEVEL REFERENCE sets the CHKP or AUXW pending states, but CHECK LOB SHRLEVEL CHANGE does not. CHECK LOB fails if the LOB table space is in recovery pending (RECP) status. You must first run the RECOVER utility on the LOB table space. Since DB2 9, as with the online REORG utility and CHECK DATA utility, you can now specify drain options such as DRAIN_WAIT, RETRY, and RETRY_DELAY to have the utility retry the drain operation if it fails (both SHRLEVEL REFERENCE and CHANGE).
207
such as DRAIN_WAIT, RETRY, and RETRY_DELAY to have the utility retry the drain operation if it fails. After the snapshot is complete, the LOB table space is put in UTRW. Important: If your DASD hardware does not support the FlashCopy Version 2 capabilities needed for SHRLEVEL CHANGE, DFSMSDSS uses the standard REPRO utility to copy the shadow data set and the utility does not fail. However, the UTRO phase, in which SQL writers are not allowed to update the data, is significantly longer. The following actions are performed when using CHECK LOB SHRLEVEL CHANGE after the snapshot: CHECK LOB runs on the snapshot data set, and during its execution, the LOB table space remains available for applications if it was not yet in the CHKP status. CHECK LOB issues message DSNU743I whenever it finds a LOB value with the invalid flag set in the LOB table space. The violation is identified by the ROWID and version number of the LOB, a reason code for the error, and the page number where the error was found. If you provide a SYSPUNCH data set, the CHECK LOB utility generates REPAIR DELETE statements to delete the bad LOBs afterwards. You can also use SQL to update or delete these LOB columns. CHECK LOB SHRLEVEL CHANGE never sets or resets CHKP or AUXW states on the LOB table space.
Examples
CHECK LOB does not allow the use of LISTDEFS and the name of the LOB table space must be explicitly specified. If it was automatically created, the name of the LOB table space must first be retrieved from the DB2 catalog. It resides in the same database as the base table space. Remember that each LOB column and each partition have their own LOB table spaces. Examples for SHRLEVEL REFERENCE (V8 syntax) and SHRLEVEL CHANGE (DB2 9 syntax) are shown in Example 6-55.
Example 6-55 Examples of CHECK LOB
-- check LOB shrlevel reference CHECK LOB TABLESPACE NORMEN00.NORMLOB SORTNUM 8 SORTDEVT 3390 -- check LOB shrlevel change TEMPLATE TSYSPUN DSN('DB2RE.&SS..&DB..&SN..E&JU(3,5)..#&TI.') DISP(MOD,CATLG,CATLG) CHECK LOB TABLESPACE NORMEN00.NORMLOB SHRLEVEL CHANGE SORTNUM 8 SORTDEVT 3390 DRAIN_WAIT 20 RETRY 120 RETRY_DELAY 60 PUNCHDDN(TSYSPUN) Important: If you want to run CHECK LOB when you suspect LOB errors and you do not want your LOB table space to become unavailable for applications when errors are found, run CHECK LOB with SHRLEVEL CHANGE.
208
209
Note: For user-managed table spaces, it is your responsibility to create the shadow data sets and delete them afterwards. See DB2 Version 9.1 for z/OS Utility Guide and Reference, SC18-9855, for how to allocate them. Once CHECK INDEX has created the shadow data sets, it drains all writers until the snapshot is complete. The LOB table space and auxiliary index are in UTRO during that time. You can specify drain options such as DRAIN_WAIT, RETRY, and RETRY_DELAY to have the utility retry the drain operation if it fails. After the snapshot is complete, the LOB table space is put in UTRW. Important: If your DASD hardware does not support the FlashCopy Version 2 capabilities needed for SHRLEVEL CHANGE, DFSMSDSS uses the standard REPRO utility to copy the shadow data sets, and the utility does not fail. However, the UTRO phase, in which SQL writers are not allowed to update the data, is significantly longer. The following actions are performed when using CHECK INDEX SHRLEVEL CHANGE after the snapshot: CHECK INDEX runs on the snapshot data sets, and during its execution, the LOB table space and auxiliary index remain available for SQL writers. It then unloads all the entries from the LOB table space shadow data set and compares them with the entries in the auxiliary index shadow data set. Invalid entries in the LOB table space can be deleted by using REPAIR LOCATE DELETE specifying the ROWID and VERSION of the LOB or by doing a point in time recovery of the LOB table space to bring it in sync again with the auxiliary index. Invalid entries in the auxiliary index can be removed by doing a REBUILD INDEX.
Examples
CHECK INDEX does allow the use of a LISTDEF if you do not explicitly want to name the auxiliary index. This is very convenient if the auxiliary index was automatically created, because the name must be retrieved from the DB2 catalog. See Example 6-56.
Example 6-56 Example of CHECK INDEX using a LISTDEF
LISTDEF MYLIST INCLUDE INDEXSPACES TABLE ##T.NORMEN00 LOB CHECK INDEX LIST MYLIST SHRLEVEL REFERENCE or CHANGE SORTNUM 8 SORTDEVT 3390 DRAIN_WAIT 20 RETRY 120 RETRY_DELAY 60
6.14 REPAIR
The REPAIR utility can be used to: Reset pending states on a base or LOB table space DUMP or DELETE LOBs from the LOB table space Verify and replace the contents of data areas in LOB table spaces and auxiliary indexes (including the invalidation of LOBs by setting the invalid flag) Rebuild object descriptors (OBDs) for a LOB table space We describe the first two options briefly. 210
LOBs with DB2 for z/OS: Stronger and Faster
a. A base table space can be set in check pending state only for non-LOB related reasons.
Important: The DELETE statement does not remove any reference to the deleted LOB in the base table space.
One LOCATE statement is required for each unit of data to be repaired. Several LOCATE statements can appear after each REPAIR statement. Typically, the ROWID and VERSION values are displayed in warning or error messages issued by the CHECK DATA or CHECK LOB utilities when reporting orphaned or out-of-sync LOBs. See Example 6-57 for the syntax of how to DUMP or DELETE a LOB from a LOB table space.
Example 6-57 DUMP or DELETE an entire LOB value
REPAIR OBJECT LOCATE TABLESPACE NORMEN00.NORMLOB ROWID X'6B8F05C204CFDE392104015C56300100000000000201' VERSION X0001 DUMP or DELETE
211
212
Chapter 7.
213
CREATE DATABASE NORMEN00 CCSID EBCDIC ; CREATE TABLESPACE NORMEN00 IN NORMEN00 USING STOGROUP PAOLOSG PRIQTY 100 SECQTY 28 ERASE NO LOGGED GBPCACHE CHANGED COMPRESS NO BUFFERPOOL BP1 LOCKSIZE PAGE LOCKMAX 0 CLOSE YES SEGSIZE 4 CCSID EBCDIC MAXROWS 255 ; CREATE TABLE ##T.NORMEN00 (DOC_ID VARCHAR(30) FOR SBCS DATA NOT NULL ,PAGE_NUMBER SMALLINT NOT NULL ,IMPORTER CHAR(8) FOR SBCS DATA NOT NULL WITH DEFAULT USER ,IMPORT_TIME TIMESTAMP NOT NULL WITH DEFAULT ,FORMAT CHAR(8) FOR SBCS DATA NOT NULL ,ROW_ID ROWID NOT NULL GENERATED ALWAYS ,IMAGE BLOB(2097152) WITH DEFAULT NULL) IN NORMEN00.NORMEN00 ; CREATE UNIQUE INDEX ##T.I_NORMEN00_1 ON ##T.NORMEN00 (DOC_ID ASC, PAGE_NUMBER ASC, FORMAT ASC) 214
LOBs with DB2 for z/OS: Stronger and Faster
USING STOGROUP PAOLOSG PRIQTY 12 SECQTY 12 ERASE NO GBPCACHE CHANGED CLUSTER BUFFERPOOL BP2 CLOSE YES COPY YES PIECESIZE 2 G ; CREATE LOB TABLESPACE NORMLOB IN NORMEN00 USING STOGROUP PAOLOSG PRIQTY 20000 SECQTY 5000 ERASE NO GBPCACHE CHANGED NOT LOGGED DSSIZE 4G BUFFERPOOL BP1 LOCKSIZE LOB LOCKMAX 0 CLOSE YES ; CREATE UNIQUE INDEX ##T.I_NORMEN00_AUX ON ##T.NORMEN00_AUX USING STOGROUP PAOLOSG PRIQTY 52 SECQTY 20 ERASE NO GBPCACHE CHANGED BUFFERPOOL BP2 CLOSE YES COPY YES PIECESIZE 2 G DEFINE YES ;
SYSIBM.SYSAUXRELS
The table SYSIBM.SYSAUXRELS contains one row per auxiliary table and shows the relationship with the corresponding base table. When you have a partitioned base table space, the partition number is also indicated. The columns of interest are: TBOWNER, authorization ID of the owner of the base table TBNAME, name of the base table COLNAME, name of the LOB column in the base table PARTITION, partition number when the base table space is partitioned, otherwise it is 0 AUXTBOWNER, authorization ID of the owner of the auxiliary table AUXTBNAME, name of the auxiliary table RELCREATED, the release of DB2 that was used to create the object (new DB2 9) Example 7-2 shows what we can find for table ##T.NORMEN00.
Example 7-2 Select from SYSIBM.SYSAUXRELS
TBOWNER ------##T
TBNAME ----NORMEN00
COLNAME -----IMAGE
PARTITION --------0
AUXTBOWNER ---------##T
AUXTBNAME --------NORMEN00_AUX
RELCREATED ---------M
215
SYSIBM.SYSCOLUMNS
The LOB columns defined within a base table can be found in the catalog table SYSIBM.SYSCOLUMNS as listed in Example 7-3.
Example 7-3 Select from SYSIBM.SYSCOLUMNS
NAME -----------DOC_ID PAGE_NUMBER IMPORTER IMPORT_TIME FORMAT ROW_ID IMAGE AUXID AUXVER AUXVALUE
TBNAME -----------NORMEN00 NORMEN00 NORMEN00 NORMEN00 NORMEN00 NORMEN00 NORMEN00 NORMEN00_AUX NORMEN00_AUX NORMEN00_AUX
COLTYPE -------VARCHAR SMALLINT CHAR TIMESTMP CHAR ROWID BLOB VARCHAR SMALLINT BLOB
LENGTH -----30 2 8 10 8 17 4 17 2 4
HIDDEN -----N N N N N N N N N N
The columns of interest are: The TBNAME specified within the SYSIBM.SYSCOLUMNS row indicates the name of the base table, because the LOB column is logically part of the base table. The field COLTYPE in the table is set to indicate the data types of BLOB, CLOB, and DBCLOB. The LENGTH catalog column also is set to a value of four for all LOB columns, because four bytes of internally defined information is stored within each row of the base table for every defined LOB. The LENGTH2 column is set to the actual maximum length of the LOB column. The HIDDEN column contains a value P (partially hidden) when the ROWID column is implicitly generated. The catalog table SYSIBM.SYSCOLUMNS always contains three column entries: AUXID, AUXVER, and AUXVALUE for an auxiliary table.
SYSIBM.SYSCOLUMNS_HIST
The catalog table SYSIBM.SYSCOLUMNS_HIST contains similar rows for LOB columns as SYSIBM.SYSCOLUMNS when RUNSTATS has been run to collect historical data.
SYSIBM.SYSLOBSTATS
The catalog table SYSIBM.SYSLOBSTATS contains one row for each LOB table space. It holds statistics to manage the space of the LOB table space. It is populated by running RUNSTATS on the LOB table space. The columns of interest are: FREESPACE, kilobytes of free space in extents with respect to high used RBA (HURBA) AVGSIZE, average size of a LOB in bytes ORGRATIO, the percent of organization of the LOB table space. A value of 100 indicates perfect organization. A value of 1 indicates that the LOB table space is disorganized. A value of 0 means that the LOB table space is totally disorganized.
216
Note: An empty LOB table space has a value of 100 after running RUNSTATS. After creation and the initial load of the table ##T.NORMEN00, there are no entries in SYSIBM.SYSLOBSTATS. Only after running RUNSTATS on LOB table space NORMEN00.NORMLOB can we find the entries shown in Example 7-4.
Example 7-4 Select from SYSIBM.SYSLOBSTATS
DBNAME -------NORMEN00
NAME -------NORMLOB
FREESPACE --------68
AVGSIZE -------29920
ORGRATIO -------60.81
SYSIBM.SYSLOBSTATS_HIST
The catalog table SYSIBM.SYSLOBSTATS_HIST contains similar rows as SYSIBM.SYSLOBSTATS for LOB table spaces when RUNSTATS has been run with the option HISTORY SPACE or HISTORY ALL to collect historical data.
SYSIBM.SYSTABLEPART
There are some more fields from SYSIBM.SYSTABLEPART, already used for regular table spaces, that can also be used to manage your LOB table spaces: CARDF, the number of LOBs in the LOB table space SPACEF, KB of space allocated DSNUM, number of linear data sets for the LOB table space EXTENTS, number of extents of the last DSNUM of the LOB table space The results after running RUNSTATS on all table spaces of database NORMEN00 are shown in Example 7-5.
Example 7-5 Select from SYSIBM.SYSTABLEPART
DSNUM ----1 1
EXTENTS ------2 20
SYSIBM.SYSTABLEPART_HIST
The catalog table SYSIBM.SYSTABLEPART_HIST contains similar rows as SYSIBM.SYSTABLEPART for LOB table spaces when RUNSTATS has been run with the option HISTORY SPACE or HISTORY ALL to collect historical data.
SYSIBM.SYSTABLES
The rows contained in SYSIBM.SYSTABLES describe the base table and the auxiliary table as listed in Example 7-6.
Example 7-6 Select from SYSIBM.SYSTABLES NAME -------NORMEN00 NORMEN00 CREATOR ------##T ##T TYPE RECLENGTH ---- --------T 93 X 0 CARDF --------5.88E+03 5.88E+03 NPAGESF --------1.00E+02 -1.00E+00 SPACEF --------4.00E+02 1.92E+05
217
The fields from SYSIBM.SYSTABLES used to manage your LOB table spaces are: NAME, the name of the base table or auxiliary table CREATOR, the schema of the base table or auxiliary table TYPE, contains T for a base table, X for an auxiliary table RECLENGTH is set to 0 for an auxiliary table. For a base table containing LOB columns, it includes the actual four bytes of internally defined information that are stored within the base table for each defined LOB column. CARDF, total number of rows in the base table or number of LOBs in the auxiliary table NPAGESF, number of pages used by the table (always -1.00E+00 for auxiliary table!) SPACEF, number of KB of disk storage If some of the auxiliary objects have not been defined for a base table, this is reflected in: STATUS, contains 'I' if the base table definition is complete. The reason the table is incomplete is defined in the TABLESTATUS column. TABLESTATUS, contains 'L' if the base table definition is incomplete, because an auxiliary table or auxiliary index has not been defined for a LOB column.
SYSIBM.SYSTABLES_HIST
The catalog table SYSIBM.SYSTABLES_HIST contains similar rows as SYSIBM.SYSTABLES for base tables and auxiliary tables when RUNSTATS has been run to collect historical data.
SYSIBM.SYSTABLESPACE
The catalog table SYSIBM.SYSTABLESPACE contains one row for each LOB table space. The columns of interest are: NAME, the name of the LOB table space DBNAME, the database containing the base table and auxiliary objects BPOOL, buffer pool used for the LOB table space LOCKRULE, locksize of the LOB table space (can be A, L, S for ANY, LOB, or TABLESPACE) IMPLICIT, whether the LOB table space was created implicitly (can be N or Y) SPACEF, number of KB of disk storage (populated only by STOSPACE utility) LOCKMAX, maximum number of LOB locks per user before escalation to TABLESPACE lock (0 means no escalation, -1 means LOCKMAX SYSTEM) TYPE, always O for LOB table space LOG, whether the changes to the LOB table space are logged: Y when LOB table space is defined with LOGGED (DB2 9) or LOG YES (V8) N when LOB table space is defined with NOT LOGGED (DB2 9) or LOG NO (V8) X when base table space is defined with NOT LOGGED and LOB table space is defined with LOGGED (in this case, the changes to the LOB table space are NOT LOGGED because of the base table space having NOT LOGGED - DB2 9 only) Example 7-7 on page 219 shows the entries we get after running the RUNSTATS STOSPACE utility.
218
LOCKRULE -------P L
IMPLICIT -------N N
LOCKMAX ------0 0
TYPE ---O
LOG --Y N
Here it is also interesting to see what happens if we let DB2 create all underlying objects automatically by not specifying a table space for the base table. See Example 7-8 (DB2 9 only).
Example 7-8 DB2 9, automatic creation of objects CREATE TABLE ##T.NORMEN01 (DOC_ID ,PAGE_NUMBER ,IMPORTER ,IMPORT_TIME ,FORMAT ,IMAGE VARCHAR(30) FOR SBCS DATA NOT NULL SMALLINT NOT NULL CHAR(8) FOR SBCS DATA NOT NULL WITH DEFAULT USER TIMESTAMP NOT NULL WITH DEFAULT CHAR(8) FOR SBCS DATA NOT NULL BLOB(2097152) WITH DEFAULT NULL) ;
In this case, DB2 creates a base table space and LOB table space in a new database as shown in SYSIBM.SYSTABLESPACE in Example 7-9.
Example 7-9 Select from SYSIBM.SYSTABLESPACE
LOCKRULE -------R A
IMPLICIT -------Y Y
LOCKMAX ------0 -1
TYPE ---G O
LOG --Y Y
Both base and LOB table spaces are created with default settings for buffer pool, locksize, lockmax, and logging (and others not shown here).
SELECT TBOWNER,TBNAME,COLNAME,AUXTBOWNER,AUXTBNAME,RELCREATED FROM SYSIBM.SYSAUXRELS WHERE TBOWNER = 'SYSIBM' ; AUX TBOWNER ------SYSIBM SYSIBM SYSIBM SYSIBM SYSIBM REL CREATED -------
M M
219
SYSIBM SYSIBM
SYSIBM SYSIBM
XSRCOMPONENT XSRPROPERTY
M M
The first two tables are related to the JAVA stored procedures implementation within DB2: SYSIBM.SYSJARCLASS_SOURCE has a 10 MB CLOB for the contents of the class in JAR files and is the auxiliary table for column CLASS_SOURCE of catalog table SYSIBM.SYSJARCONTENTS. SYSIBM.SYSJARDATA has a 100 MB BLOB column for the contents of JAR files and is the auxiliary table for column JAR_DATA of table SYSIBM.SYSJAROBJECTS. SYSIBM.SYSROUTINESTEXT contains a 2 MB CLOB to contain the source text of the CREATE statement or ALTER statement with the body for the routine and is the auxiliary table for column TEXT of table SYSIBM.SYSROUTINES (new with DB2 9). The SYSIBM.XSR tables are the new catalog tables to support storing XML documents in DB2 9.
SYSIBM.SYSTABLESPACESTATS
The RTS table SYSIBM.SYSTABLESPACESTATS contains real-time statistics for base and LOB table spaces. For LOB table spaces, you might be interested in columns such as: REORGINSERTS, the number of LOBs that have been inserted since the last REORG or LOAD REPLACE REORGDELETES, the number of LOBs that have been deleted since the last REORG or LOAD REPLACE REORGUPDATES, this value does not include LOB updates, because LOB updates are really deletions followed by insertions REORGDISORGLOB, the number of imperfectly chunked LOBs that were inserted since the last REORG or LOAD REPLACE (a LOB is perfectly chunked if the allocated pages are in the minimum number of chunks) REORGMASSDELETE, the number of mass deletes on the base table since the last REORG or LOAD REPLACE STATSINSERTS, the number of LOBs that have been inserted since the last RUNSTATS STATSDELETES, the number of LOBs that have been deleted since the last RUNSTATS STATSUPDATES, this value does not include LOB updates, because LOB updates are really deletions followed by insertions STATSMASSDELETE, the number of mass deletes on the base table since the last RUNSTATS TOTALROWS, the total number of LOBs in the LOB table space Other columns, such as NACTIVE, EXTENTS, and DATASIZE can also be examined to monitor the space statistics of the LOB table space or columns such as COPYLASTTIME and
220
COPYUPDATEDPAGES, to decide when to take a new image copy. See the DB2 Version 9.1 for z/OS SQL Reference, SC18-9854, Appendix D, for a complete description of the columns of SYSIBM.SYSTABLESPACESTATS.
SYSIBM.SYSINDEXSPACESTATS
The RTS table SYSIBM.SYSINDEXSPACESTATS contains real-time statistics for normal indexes and auxiliary indexes. There are no special columns dedicated to auxiliary indexes. See the DB2 Version 9.1 for z/OS SQL Reference, SC18-9854, Appendix D for a complete description of the columns of SYSIBM.SYSINDEXSPACESTATS. Important: Before DB2 9, the RTS tables were called SYSIBM.TABLESPACESTATS and SYSIBM.INDEXSPACESTATS. The RTS tables resided in database DSNRTSDB, which had to be installed and activated optionally. Starting with DB2 9, the RTS tables are part of the DB2 catalog in a new table space DSNDB06.SYSRTSTS, and RTS is always enabled.
7.2.1 LOGGED base table space with LOGGED LOB table space
In the first scenario, we create both the base and LOB table space as LOGGED and LOAD the data with the same contents as table ##T.NORMEN00 (5,883 rows). We can use UNLOAD+RELOAD, DSNTIAUL+RELOAD, or the cross loader as demonstrated in 6.3, LOAD on page 173. We then create a common recoverable point of consistency using the COPY utility with LISTDEF and SHRLEVEL REFERENCE as shown in Example 7-11.
Example 7-11 Creating a common recoverable point of consistency using COPY
TEMPLATE TSYSCOPY DSN('DB2IM.&SS..&DB..&SN..&IC.&JU(3,5)..#&TI.') DISP(MOD,CATLG,CATLG) VOLUMES(SBOX61) LISTDEF MYLIST INCLUDE TABLESPACES TABLE ##T.NORMEN03 ALL INCLUDE INDEXSPACES TABLE ##T.NORMEN03 ALL COPY LIST MYLIST FULL YES SHRLEVEL REFERENCE PARALLEL COPYDDN(TSYSCOPY) We can verify that all objects have the same START_RBA = X'000072988DE6' by looking at SYSIBM.SYSCOPY as shown in Example 7-12.
Example 7-12 Common START_RBA in SYSIBM.SYSCOPY
DBNAME -------NORMEN03 NORMEN03 NORMEN03 NORMEN03 NORMEN03 TSNAME -------NORMEN03 NORMLOB NORMEN03 NORMEN03 IRNORMEN ICTYPE -----C C Z F F START RBA HEX ------------0000677E731A 0000677F173F 0000677FE4CA 000072988DE6 000072988DE6 DSNAME -------------------------------------------NORMEN03.NORMEN03 NORMEN03.NORMLOB NORMEN03.NORMEN03 DB2IM.DB9B.NORMEN03.NORMEN03.F06214.#220426 DB2IM.DB9B.NORMEN03.IRNORMEN.F06214.#220426
221
NORMEN03 NORMEN03
NORMLOB F IRNO1OS7 F
000072988DE6 000072988DE6
DB2IM.DB9B.NORMEN03.NORMLOB.F06214.#220426 DB2IM.DB9B.NORMEN03.IRNO1OS7.F06214.#220426
Afterwards, we delete some LOBs using SPUFI as shown in Example 7-13 to create some log activity.
Example 7-13 SPUFI delete DELETE FROM ##T.NORMEN03 WHERE DOC_ID LIKE '%E%' ; ---------+---------+---------+---------+---------+---------+----DSNE615I NUMBER OF ROWS AFFECTED IS 6 DSNE616I STATEMENT EXECUTION WAS SUCCESSFUL, SQLCODE IS 0 ---------+---------+---------+---------+---------+---------+-------------+---------+---------+---------+---------+---------+----DSNE617I COMMIT PERFORMED, SQLCODE IS 0 DSNE616I STATEMENT EXECUTION WAS SUCCESSFUL, SQLCODE IS 0 ---------+---------+---------+---------+---------+---------+----DSNE601I SQL STATEMENTS ASSUMED TO BE BETWEEN COLUMNS 1 AND 72 DSNE620I NUMBER OF SQL STATEMENTS PROCESSED IS 1 DSNE621I NUMBER OF INPUT RECORDS READ IS 1 DSNE622I NUMBER OF OUTPUT RECORDS WRITTEN IS 14
We then stopped and started all spaces of database NORMEN03 and deleted the VSAM clusters using ISPF 3.4 as shown in Example 7-14:
Example 7-14 Delete VSAM clusters delete = = = DB9BU.DSNDBC.NORMEN03.IRNORMEN.I0001.A001 DB9BU.DSNDBC.NORMEN03.IRNO1OS7.I0001.A001 DB9BU.DSNDBC.NORMEN03.NORMEN03.I0001.A001 DB9BU.DSNDBC.NORMEN03.NORMLOB.I0001.A001 DB9BU.DSNDBD.NORMEN03.IRNORMEN.I0001.A001 DB9BU.DSNDBD.NORMEN03.IRNO1OS7.I0001.A001 DB9BU.DSNDBD.NORMEN03.NORMEN03.I0001.A001 DB9BU.DSNDBD.NORMEN03.NORMLOB.I0001.A001 *VSAM* *VSAM* *VSAM* *VSAM* SBOX49 SBOX49 SBOX49 SBOX49
Then, we try to recover the VSAMs back to the current point in time as shown in Example 7-15.
Example 7-15 RECOVER to current point in time
LISTDEF MYLIST INCLUDE TABLESPACES TABLE ##T.NORMEN03 ALL INCLUDE INDEXSPACES TABLE ##T.NORMEN03 ALL RECOVER LIST MYLIST PARALLEL The result of the RECOVER is shown in Example 7-16.
Example 7-16 RECOVER to current point in time
DSNU000I DSNU1044I DSNU050I INDEXSPACES DSNU1035I DSNU050I DSNU1033I DSNU1033I DSNU1033I DSNU1033I DSNU427I 214 18:34:30.94 DSNUGUTC - OUTPUT START FOR UTILITY, UTILID = RECOV.NORMEN03 214 18:34:31.00 DSNUGTIS - PROCESSING SYSIN AS EBCDIC 214 18:34:31.01 DSNUGUTC - LISTDEF MYLIST INCLUDE TABLESPACES TABLE ##T.NORMEN03 ALL INCLUDE TABLE ##T.NORMEN03 ALL 214 18:34:31.01 DSNUILDR - LISTDEF STATEMENT PROCESSED SUCCESSFULLY 214 18:34:31.01 DSNUGUTC - RECOVER LIST MYLIST PARALLEL 214 18:34:31.02 DSNUGULM - PROCESSING LIST ITEM: TABLESPACE NORMEN03.NORMEN03 214 18:34:31.02 DSNUGULM - PROCESSING LIST ITEM: TABLESPACE NORMEN03.NORMLOB 214 18:34:31.02 DSNUGULM - PROCESSING LIST ITEM: INDEXSPACE NORMEN03.IRNORMEN 214 18:34:31.02 DSNUGULM - PROCESSING LIST ITEM: INDEXSPACE NORMEN03.IRNO1OS7 214 18:34:31.04 DSNUCBMT - OBJECTS WILL BE PROCESSED IN PARALLEL, NUMBER OF OBJECTS = 4
222
DSNU532I 214 18:34:31.04 DSNUCBMT - RECOVER INDEXSPACE NORMEN03.IRNORMEN START DSNU515I 214 18:34:31.04 DSNUCBAL - THE IMAGE COPY DATA SET DB2IM.DB9B.NORMEN03.IRNORMEN.F06214.#220426 WITH DATE=20060802 AND TIME=180427 IS PARTICIPATING IN RECOVERY OF INDEXSPACE NORMEN03.IRNORMEN DSNU532I 214 18:34:31.48 DSNUCBMT - RECOVER INDEXSPACE NORMEN03.IRNO1OS7 START DSNU515I 214 18:34:31.48 DSNUCBAL - THE IMAGE COPY DATA SET DB2IM.DB9B.NORMEN03.IRNO1OS7.F06214.#220426 WITH DATE=20060802 AND TIME=180427 IS PARTICIPATING IN RECOVERY OF INDEXSPACE NORMEN03.IRNO1OS7 DSNU504I 214 18:34:31.62 DSNUCBRT - MERGE STATISTICS FOR INDEXSPACE NORMEN03.IRNORMEN NUMBER OF COPIES=1 NUMBER OF PAGES MERGED=43 ELAPSED TIME=00:00:00 DSNU532I 214 18:34:31.78 DSNUCBMT - RECOVER TABLESPACE NORMEN03.NORMEN03 START DSNU515I 214 18:34:31.78 DSNUCBAL - THE IMAGE COPY DATA SET DB2IM.DB9B.NORMEN03.NORMEN03.F06214.#220426 WITH DATE=20060802 AND TIME=180427 IS PARTICIPATING IN RECOVERY OF TABLESPACE NORMEN03.NORMEN03 DSNU504I 214 18:34:31.98 DSNUCBRT - MERGE STATISTICS FOR INDEXSPACE NORMEN03.IRNO1OS7 NUMBER OF COPIES=1 NUMBER OF PAGES MERGED=65 ELAPSED TIME=00:00:00 DSNU532I 214 18:34:32.17 DSNUCBMT - RECOVER TABLESPACE NORMEN03.NORMLOB START DSNU515I 214 18:34:32.17 DSNUCBAL - THE IMAGE COPY DATA SET DB2IM.DB9B.NORMEN03.NORMLOB.F06214.#220426 WITH DATE=20060802 AND TIME=180440 IS PARTICIPATING IN RECOVERY OF TABLESPACE NORMEN03.NORMLOB DSNU504I 214 18:34:32.36 DSNUCBRT - MERGE STATISTICS FOR TABLESPACE NORMEN03.NORMEN03 NUMBER OF COPIES=1 NUMBER OF PAGES MERGED=102 ELAPSED TIME=00:00:00 DSNU504I 214 18:34:58.85 DSNUCBRT - MERGE STATISTICS FOR TABLESPACE NORMEN03.NORMLOB NUMBER OF COPIES=1 NUMBER OF PAGES MERGED=46308 ELAPSED TIME=00:00:26 DSNU513I -DB9B 214 18:34:58.88 DSNUCALA - RECOVER UTILITY LOG APPLY RANGE IS RBA 00007299C000 LRSN 00007299C000 TO RBA 00007299DF72 LRSN 00007299DF72 DSNU1510I 214 18:34:58.90 DSNUCBLA - LOG APPLY PHASE COMPLETE, ELAPSED TIME = 00:00:00 DSNU500I 214 18:34:59.03 DSNUCBDR - RECOVERY COMPLETE, ELAPSED TIME=00:00:28 DSNU010I 214 18:34:59.04 DSNUGBAC - UTILITY EXECUTION COMPLETE, HIGHEST RETURN CODE=0
As a result, all of the objects have been recovered and the data is in perfect shape again (no pending states) as shown in the output of the -DISPLAY DATABASE(NORMEN03) SPACENAM(*) command in Example 7-17.
Example 7-17 Display database command DSNT360I DSNT361I -DB9B *********************************** -DB9B * DISPLAY DATABASE SUMMARY * GLOBAL DSNT360I -DB9B *********************************** DSNT362I -DB9B DATABASE = NORMEN03 STATUS = RW DBD LENGTH = 4028 DSNT397I -DB9B NAME TYPE PART STATUS PHYERRLO PHYERRHI CATALOG PIECE -------- ---- ----- ----------------- -------- -------- -------- ----NORMEN03 TS RW NORMLOB LS RW IRNO1OS7 IX RW IRNORMEN IX RW ******* DISPLAY OF DATABASE NORMEN03 ENDED ********************** DSN9022I -DB9B DSNTDDIS 'DISPLAY DATABASE' NORMAL COMPLETION ***
223
We can now establish a quiesce point using the commands shown in Example 7-18 to create a new common recoverable point of consistency.
Example 7-18 Creating a common recoverable point of consistency using QUIESCE
LISTDEF MYLIST INCLUDE TABLESPACES TABLE ##T.NORMEN03 ALL QUIESCE LIST MYLIST WRITE YES We then delete again some LOBs as shown in Example 7-19. In the QUIESCE job, we get the message: DSNU474I -DB9B 214 19:00:38.24 DSNUQUIA - QUIESCE AT RBA 0000729D9B16 AND AT LRSN 0000729D9B16
Example 7-19 SPUFI delete
DELETE FROM ##T.NORMEN03 WHERE DOC_ID LIKE '%D%' ; ---------+---------+---------+---------+---------+---------+-----DSNE615I NUMBER OF ROWS AFFECTED IS 8 DSNE616I STATEMENT EXECUTION WAS SUCCESSFUL, SQLCODE IS 0 ---------+---------+---------+---------+---------+---------+--------------+---------+---------+---------+---------+---------+-----DSNE617I COMMIT PERFORMED, SQLCODE IS 0 DSNE616I STATEMENT EXECUTION WAS SUCCESSFUL, SQLCODE IS 0 Because both the base table space and LOB table space are created with LOGGED, we have now established two common recoverable points of consistency (one with COPY at LOGRBA = X'000072988DE6'and one with QUIESCE at LOGRBA = X'0000729D9B16') to which we can do a point in time recovery using statements as shown in Example 7-20.
Example 7-20 Point in time recovery to a common recoverable point of consistency
LISTDEF MYLIST INCLUDE TABLESPACES TABLE ##T.NORMEN03 ALL INCLUDE INDEXSPACES TABLE ##T.NORMEN03 ALL RECOVER LIST MYLIST TORBA X'000072988DE6' PARALLEL LISTDEF MYLIST INCLUDE TABLESPACES TABLE ##T.NORMEN03 ALL INCLUDE INDEXSPACES TABLE ##T.NORMEN03 ALL RECOVER LIST MYLIST TORBA X'0000729D9B16' PARALLEL An example job output is shown in Example 7-21.
Example 7-21 Point in time recovery to a recoverable quiesce point
DSNU000I DSNU1044I DSNU050I INDEXSPACES DSNU1035I DSNU050I DSNU1033I DSNU1033I DSNU1033I DSNU1033I DSNU427I 214 19:40:30.12 DSNUGUTC - OUTPUT START FOR UTILITY, UTILID = RECOV.NORMEN03 214 19:40:30.18 DSNUGTIS - PROCESSING SYSIN AS EBCDIC 214 19:40:30.18 DSNUGUTC - LISTDEF MYLIST INCLUDE TABLESPACES TABLE ##T.NORMEN03 ALL INCLUDE TABLE ##T.NORMEN03 ALL 214 19:40:30.19 DSNUILDR - LISTDEF STATEMENT PROCESSED SUCCESSFULLY 214 19:40:30.19 DSNUGUTC - RECOVER LIST MYLIST TORBA X'0000729D9B16' PARALLEL 214 19:40:30.19 DSNUGULM - PROCESSING LIST ITEM: TABLESPACE NORMEN03.NORMEN03 214 19:40:30.19 DSNUGULM - PROCESSING LIST ITEM: TABLESPACE NORMEN03.NORMLOB 214 19:40:30.19 DSNUGULM - PROCESSING LIST ITEM: INDEXSPACE NORMEN03.IRNORMEN 214 19:40:30.19 DSNUGULM - PROCESSING LIST ITEM: INDEXSPACE NORMEN03.IRNO1OS7 214 19:40:30.21 DSNUCBMT - OBJECTS WILL BE PROCESSED IN PARALLEL, NUMBER OF OBJECTS = 4 DSNU532I 214 19:40:30.21 DSNUCBMT - RECOVER INDEXSPACE NORMEN03.IRNORMEN START DSNU515I 214 19:40:30.21 DSNUCBAL - THE IMAGE COPY DATA SET DB2IM.DB9B.NORMEN03.IRNORMEN.F06214.#220426 WITH DATE=20060802 AND TIME=180427 IS PARTICIPATING IN RECOVERY OF INDEXSPACE NORMEN03.IRNORMEN
224
DSNU532I 214 19:40:30.81 DSNUCBMT - RECOVER INDEXSPACE NORMEN03.IRNO1OS7 START DSNU515I 214 19:40:30.81 DSNUCBAL - THE IMAGE COPY DATA SET DB2IM.DB9B.NORMEN03.IRNO1OS7.F06214.#220426 WITH DATE=20060802 AND TIME=180427 IS PARTICIPATING IN RECOVERY OF INDEXSPACE NORMEN03.IRNO1OS7 DSNU504I 214 19:40:30.97 DSNUCBRT - MERGE STATISTICS FOR INDEXSPACE NORMEN03.IRNORMEN NUMBER OF COPIES=1 NUMBER OF PAGES MERGED=43 ELAPSED TIME=00:00:00 DSNU532I 214 19:40:31.37 DSNUCBMT - RECOVER TABLESPACE NORMEN03.NORMEN03 START DSNU515I 214 19:40:31.37 DSNUCBAL - THE IMAGE COPY DATA SET DB2IM.DB9B.NORMEN03.NORMEN03.F06214.#220426 WITH DATE=20060802 AND TIME=180427 IS PARTICIPATING IN RECOVERY OF TABLESPACE NORMEN03.NORMEN03 DSNU504I 214 19:40:31.55 DSNUCBRT - MERGE STATISTICS FOR INDEXSPACE NORMEN03.IRNO1OS7 NUMBER OF COPIES=1 NUMBER OF PAGES MERGED=65 ELAPSED TIME=00:00:00 DSNU532I 214 19:40:31.92 DSNUCBMT - RECOVER TABLESPACE NORMEN03.NORMLOB START DSNU515I 214 19:40:31.92 DSNUCBAL - THE IMAGE COPY DATA SET DB2IM.DB9B.NORMEN03.NORMLOB.F06214.#220426 WITH DATE=20060802 AND TIME=180440 IS PARTICIPATING IN RECOVERY OF TABLESPACE NORMEN03.NORMLOB DSNU504I 214 19:40:32.13 DSNUCBRT - MERGE STATISTICS FOR TABLESPACE NORMEN03.NORMEN03 NUMBER OF COPIES=1 NUMBER OF PAGES MERGED=102 ELAPSED TIME=00:00:00 DSNU504I 214 19:40:58.89 DSNUCBRT - MERGE STATISTICS FOR TABLESPACE NORMEN03.NORMLOB NUMBER OF COPIES=1 NUMBER OF PAGES MERGED=46308 ELAPSED TIME=00:00:26 DSNU513I -DB9B 214 19:40:58.93 DSNUCALA - RECOVER UTILITY LOG APPLY RANGE IS RBA 00007299C000 LRSN 00007299C000 TO RBA 00007299DF72 LRSN 00007299DF72 DSNU1510I 214 19:40:59.02 DSNUCBLA - LOG APPLY PHASE COMPLETE, ELAPSED TIME = 00:00:00 DSNU535I -DB9B 214 19:40:59.03 DSNUCATM - FOLLOWING TABLESPACES RECOVERED TO A CONSISTENT POINT NORMEN03.NORMLOB DSNU599I -DB9B 214 19:40:59.03 DSNUCATM - INDEXSPACE NORMEN03.IRNORMEN HAS BEEN RECOVERED TO A CONSISTENT POINT IN TIME WITH TABLESPACE NORMEN03.NORMEN03 DSNU599I -DB9B 214 19:40:59.03 DSNUCATM - INDEXSPACE NORMEN03.IRNO1OS7 HAS BEEN RECOVERED TO A CONSISTENT POINT IN TIME WITH TABLESPACE NORMEN03.NORMLOB DSNU500I 214 19:40:59.15 DSNUCBDR - RECOVERY COMPLETE, ELAPSED TIME=00:00:28 DSNU010I 214 19:40:59.16 DSNUGBAC - UTILITY EXECUTION COMPLETE, HIGHEST RETURN CODE=0
We get message DSNU599I, and no objects are put in a pending state. This is the ideal situation, because no additional CHECK utilities must be run. Tip: The easiest point in time RECOVERY of LOB data is to recover all objects together to a recoverable point of consistency. In the next step, we try to recover to an in-between log point, which is not a common recoverable point of consistency, specifying TORBA X'00007299D000' in the RECOVER job. This is an RBA in the middle of the delete statement from Example 7-13 on page 222. Here we can see the effect of the new DB2 9 RECOVER point time with consistency feature, where DB2 detects that the RBA is in the middle of an active UR and backs out all of the updates of this active UR so that the data is at least consistent from the transaction point of view after the RECOVER. During the new LOGSCR phase, DB2 reads the log forward from the last checkpoint prior to the recovery point and identifies the URs that were both active (INFLIGHT, INABORT, INDOUBT, or POSTPONED ABORT) during the recovery point and also changed the objects being recovered. During the new LOGUNDO phase, the RECOVER utility backs out the changes made on the recovered objects by the active URs. No objects are put in a pending state. See the new messages DSNU1550I up to DSNU1557I in the job output in Example 7-22 on page 226.
Chapter 7. Data administration with LOBs
225
DSNU532I 215 12:59:28.35 DSNUCBMT - RECOVER INDEXSPACE NORMEN03.IRNORMEN START DSNU515I 215 12:59:28.35 DSNUCBAL - THE IMAGE COPY DATA SET DB2IM.DB9B.NORMEN03.IRNORMEN.F06214.#220426 WITH DATE=20060802 AND TIME=180427 IS PARTICIPATING IN RECOVERY OF INDEXSPACE NORMEN03.IRNORMEN DSNU532I 215 12:59:28.94 DSNUCBMT - RECOVER INDEXSPACE NORMEN03.IRNO1OS7 START DSNU515I 215 12:59:28.94 DSNUCBAL - THE IMAGE COPY DATA SET DB2IM.DB9B.NORMEN03.IRNO1OS7.F06214.#220426 WITH DATE=20060802 AND TIME=180427 IS PARTICIPATING IN RECOVERY OF INDEXSPACE NORMEN03.IRNO1OS7 DSNU504I 215 12:59:29.11 DSNUCBRT - MERGE STATISTICS FOR INDEXSPACE NORMEN03.IRNORMEN NUMBER OF COPIES=1 NUMBER OF PAGES MERGED=43 ELAPSED TIME=00:00:00 DSNU532I 215 12:59:29.33 DSNUCBMT - RECOVER TABLESPACE NORMEN03.NORMEN03 START DSNU515I 215 12:59:29.33 DSNUCBAL - THE IMAGE COPY DATA SET DB2IM.DB9B.NORMEN03.NORMEN03.F06214.#220426 WITH DATE=20060802 AND TIME=180427 IS PARTICIPATING IN RECOVERY OF TABLESPACE NORMEN03.NORMEN03 DSNU504I 215 12:59:29.53 DSNUCBRT - MERGE STATISTICS FOR INDEXSPACE NORMEN03.IRNO1OS7 NUMBER OF COPIES=1 NUMBER OF PAGES MERGED=65 ELAPSED TIME=00:00:00 DSNU532I 215 12:59:29.87 DSNUCBMT - RECOVER TABLESPACE NORMEN03.NORMLOB START DSNU515I 215 12:59:29.87 DSNUCBAL - THE IMAGE COPY DATA SET DB2IM.DB9B.NORMEN03.NORMLOB.F06214.#220426 WITH DATE=20060802 AND TIME=180440 IS PARTICIPATING IN RECOVERY OF TABLESPACE NORMEN03.NORMLOB DSNU504I 215 12:59:30.09 DSNUCBRT - MERGE STATISTICS FOR TABLESPACE NORMEN03.NORMEN03 NUMBER OF COPIES=1 NUMBER OF PAGES MERGED=102 ELAPSED TIME=00:00:00 DSNU504I 215 12:59:56.84 DSNUCBRT - MERGE STATISTICS FOR TABLESPACE NORMEN03.NORMLOB NUMBER OF COPIES=1 NUMBER OF PAGES MERGED=46308 ELAPSED TIME=00:00:26 DSNU513I -DB9B 215 12:59:56.88 DSNUCALA - RECOVER UTILITY LOG APPLY RANGE IS RBA 00007299C000 LRSN 00007299C000 TO RBA 00007299D000 LRSN 00007299D000 DSNU1510I 215 12:59:57.17 DSNUCBLA - LOG APPLY PHASE COMPLETE, ELAPSED TIME = 00:00:00 DSNU1550I -DB9B 215 12:59:57.17 DSNUCALC - LOGCSR IS STARTED FOR MEMBER , PRIOR CHECKPOINT RBA = X'000072439CFE' DSNU1551I -DB9B 215 12:59:57.24 DSNUCALC - LOGCSR IS FINISHED FOR MEMBER , ELAPSED TIME = 00:00:00 DSNU1552I -DB9B 215 12:59:57.24 DSNUCALC - LOGCSR PHASE COMPLETE, ELAPSED TIME = 00:00:00 DSNU1553I -DB9B 215 12:59:57.24 DSNUCALC - RECOVER DETECTS THE FOLLOWING ACTIVE URS: INFLIGHT = 1, INABORT = 0, INDOUBT = 0, POSTPONED ABORT = 0 MEM T CONNID CORRID AUTHID PLAN S URID DATE TIME B TSO PAOLOR2 PAOLOR2 DSNESPCS F 00007299C4BC 2006-08-02 22.16.02 DBNAME SPACENAME DBID/PSID PART RBA NORMEN03 NORMLOB 014D/0007 0000 00007299CD90 NORMEN03 IRNORMEN 014D/0005 0000 00007299C57B NORMEN03 NORMEN03 014D/0002 0000 00007299C9A1 DSNU1554I -DB9B 215 12:59:57.52 DSNUCALU - LOGUNDO IS STARTED FOR MEMBER DSNU1556I -DB9B 215 12:59:57.55 DSNUCALU - LOGUNDO IS FINISHED FOR MEMBER , ELAPSED TIME = 00:00:00 DSNU1557I -DB9B 215 12:59:57.55 DSNUCALU - LOGUNDO PHASE COMPLETE, ELAPSED TIME = 00:00:00 DSNU535I -DB9B 215 12:59:57.56 DSNUCATM - FOLLOWING TABLESPACES RECOVERED TO A CONSISTENT POINT NORMEN03.NORMEN03
226
NORMEN03.NORMLOB -DB9B 215 12:59:57.56 DSNUCATM - INDEXSPACE NORMEN03.IRNORMEN HAS BEEN RECOVERED TO A CONSISTENT POINT IN TIME WITH TABLESPACE NORMEN03.NORMEN03 -DB9B 215 12:59:57.56 DSNUCATM - INDEXSPACE NORMEN03.IRNO1OS7 HAS BEEN RECOVERED TO A CONSISTENT POINT IN TIME WITH TABLESPACE NORMEN03.NORMLOB 215 12:59:57.67 DSNUCBDR - RECOVERY COMPLETE, ELAPSED TIME=00:00:29 215 12:59:57.68 DSNUGBAC - UTILITY EXECUTION COMPLETE, HIGHEST RETURN CODE=0
After this RECOVERY, the LOB table space contains 5,883 LOBs, which proves that the delete statement has been backed out and is in its initial state after the LOAD utility. In the next step, we first redo the deletes as in Example 7-13 on page 222 and Example 7-19 on page 224 as shown in Example 7-23. As expected, 14 rows are now deleted.
Example 7-23 SPUFI delete
DELETE FROM ##T.NORMEN03 WHERE DOC_ID LIKE '%D%' OR DOC_ID LIKE '%E%' ; ---------+---------+---------+---------+---------+---------+--DSNE615I NUMBER OF ROWS AFFECTED IS 14 DSNE616I STATEMENT EXECUTION WAS SUCCESSFUL, SQLCODE IS 0 ---------+---------+---------+---------+---------+---------+-----------+---------+---------+---------+---------+---------+--DSNE617I COMMIT PERFORMED, SQLCODE IS 0 DSNE616I STATEMENT EXECUTION WAS SUCCESSFUL, SQLCODE IS 0
We now do a point in time recovery of the base table only to the initial state as shown in Example 7-24, which results in 14 missing LOBs in the LOB table space. This is a situation which often occurs in client sites when the DBA wants to back out the changes of an invalid transaction on the base data but forgets about the LOB table space.
Example 7-24 Point in time recovery of base table only
LISTDEF MYLIST INCLUDE TABLESPACES TABLE ##T.NORMEN03 BASE INCLUDE INDEXSPACES TABLE ##T.NORMEN03 BASE RECOVER LIST MYLIST TORBA X'000072988DE6' PARALLEL As a result of the point in time recovery, the base table space is put in auxiliary check pending (ACHKP) status as shown in Example 7-25. The base table is unavailable for applications (resource unavailable with reason code 00C900C5).
Example 7-25 Base table space in ACHKP DSNT360I -DB9B *********************************** DSNT361I -DB9B * DISPLAY DATABASE SUMMARY * GLOBAL DSNT360I -DB9B *********************************** DSNT362I -DB9B DATABASE = NORMEN03 STATUS = RW DBD LENGTH = 4028 DSNT397I -DB9B NAME TYPE PART STATUS PHYERRLO PHYERRHI CATALOG PIECE -------- ---- ----- ----------------- -------- -------- -------- ----NORMEN03 TS RW,ACHKP NORMLOB LS RW IRNO1OS7 IX RW IRNORMEN IX RW ******* DISPLAY OF DATABASE NORMEN03 ENDED ********************** DSN9022I -DB9B DSNTDDIS 'DISPLAY DATABASE' NORMAL COMPLETION Chapter 7. Data administration with LOBs
227
***
To find the bad LOBs, we must now run a CHECK DATA. It makes little sense to run CHECK LOB on the LOB table space here because the LOB table space is not in a pending state, and missing LOBs are not found by the CHECK LOB utility. We first run CHECK DATA with the AUXERROR REPORT as shown in Example 7-26 just to report the bad LOBs. Because the table space is already in ACHKP, we use SHRLEVEL REFERENCE because the table space is already unavailable for applications.
Example 7-26 CHECK DATA SHRLEVEL REFERENCE AUXERROR REPORT
TEMPLATE TSORTOUT DSN('DB2RE.&SS..&DB..&SN..S&JU(3,5)..#&TI.') DISP(MOD,DELETE,CATLG) TEMPLATE TSYSUT1 DSN('DB2RE.&SS..&DB..&SN..U&JU(3,5)..#&TI.') DISP(MOD,DELETE,CATLG) TEMPLATE TSYSERR DSN('DB2RE.&SS..&DB..&SN..E&JU(3,5)..#&TI.') DISP(MOD,DELETE,CATLG) CHECK DATA TABLESPACE NORMEN03.NORMEN03 SHRLEVEL REFERENCE SCOPE AUXONLY AUXERROR REPORT SORTNUM 8 SORTDEVT 3390 WORKDDN(TSYSUT1,TSORTOUT) ERRDDN(TSYSERR) As a result, we get 14 missing LOBs as indicated by message DSNU809I as shown in Example 7-27. The base table space remains in ACHKP and is still unavailable for applications.
Example 7-27 Result of CHECK DATA AUXERROR REPORT
........... DSNU809I 216 14:35:32.93 DSNUKERK - TABLE=##T.NORMEN03 COLUMN=IMAGE IS MISSING IN INDEX ##T.I_NORMEN03_AUX ROWID=X'6B8F05C204CFDE392104015C56300100000000000201' VERSION=X'0001' DSNU809I 216 14:35:32.93 DSNUKERK - TABLE=##T.NORMEN03 COLUMN=IMAGE IS MISSING IN INDEX ##T.I_NORMEN03_AUX ROWID=X'A9DB85C204CFD7052104015C56300100000000000202' VERSION=X'0001' ..............
We can also do a REPAIR OBJECT SET TABLESPACE NORMEN03.NORMEN03 NOAUXCHKP to remove the ACHKP state on the base table to make it available immediately for the applications, and run a CHECK DATA SHRLEVEL CHANGE afterwards (DB2 9 only) as shown in Example 7-28.
Example 7-28 CHECK DATA SHRLEVEL CHANGE AUXERROR REPORT
............ CHECK DATA TABLESPACE NORMEN03.NORMEN03 SHRLEVEL CHANGE SCOPE AUXONLY AUXERROR REPORT SORTNUM 8 SORTDEVT 3390 WORKDDN(TSYSUT1,TSORTOUT) ERRDDN(TSYSERR) DRAIN_WAIT 20 RETRY 120 RETRY_DELAY 60
228
PUNCHDDN(TSYSPUN) The CHECK DATA is now run on a snapshot copy of the base table space without disturbing the applications. The same 14 LOB errors are reported, and the base table space is set in ACHKP at the end of the utility. To make the table space available for applications when in ACHKP status, run CHECK DATA with AUXERROR INVALIDATE and with SHRLEVEL REFERENCE or CHANGE (DB2 9). As a result, the base table space is set in the auxiliary warning state (AUXW), which makes the data available again for the applications. The 14 bad LOBS are invalidated in the base table space as shown in Example 7-29.
Example 7-29 CHECK DATA AUXERROR INVALIDATE ............... DSNU806I -DB9B 219 12:43:04.95 DSNUKRDN - TABLE=##T.NORMEN03 COLUMN=IMAGE WAS SET INVALID ROWID=X'2D1165C204CFD30A2104015C5630010000000000020A' VERSION=X'0001' DSNU806I -DB9B 219 12:43:04.95 DSNUKRDN - TABLE=##T.NORMEN03 COLUMN=IMAGE WAS SET INVALID ROWID=X'50C8D45204CFD00D2104015C56300100000000005105' VERSION=X'0001' DSNU816I -DB9B 219 12:43:05.81 DSNUGSRX - TABLESPACE NORMEN03.NORMEN03 IS IN AUX WARNING STATE DSNU749I 219 12:43:05.81 DSNUK001 - CHECK DATA COMPLETE,ELAPSED TIME=00:00:29 DSNU010I 219 12:43:05.89 DSNUGBAC - UTILITY EXECUTION COMPLETE, HIGHEST RETURN CODE=4
We can now manually populate the missing LOBs using SQL update statements. However, in this test case, because no applications have touched the table spaces since the base table has been point in time recovered, we can also do a point in time recovery of the LOB table space to the same RBA as the base table space as shown in Example 7-30.
Example 7-30 Point in time recovery of the LOB table space
LISTDEF MYLIST INCLUDE TABLESPACES TABLE ##T.NORMEN03 LOB INCLUDE INDEXSPACES TABLE ##T.NORMEN03 LOB RECOVER LIST MYLIST TORBA X'000072988DE6' PARALLEL As a result, base and LOB table space are in sync again. However, the base table space is now set in the ACHKP and AUXW states as shown in Example 7-31.
Example 7-31 State of the table spaces afterwards
DSNT360I -DB9B *********************************** DSNT361I -DB9B * DISPLAY DATABASE SUMMARY * GLOBAL DSNT360I -DB9B *********************************** DSNT362I -DB9B DATABASE = NORMEN03 STATUS = RW DBD LENGTH = 4028 DSNT397I -DB9B NAME TYPE PART STATUS PHYERRLO PHYERRHI CATALOG PIECE -------- ---- ----- ----------------- -------- -------- -------- ----NORMEN03 TS RW,ACHKP,AUXW NORMLOB LS RW IRNO1OS7 IX RW IRNORMEN IX RW,ICOPY ******* DISPLAY OF DATABASE NORMEN03 ENDED ********************** DSN9022I -DB9B DSNTDDIS 'DISPLAY DATABASE' NORMAL COMPLETION
229
*** The only thing left now to remove the pending states is run CHECK DATA again with AUXERROR REPORT and SHRLEVEL REFERENCE. Because no more inconsistencies are found, the pending states are reset as shown in Example 7-32.
Example 7-32 State of the table spaces after CHECK DATA
DSNT360I DSNT361I
-DB9B *********************************** -DB9B * DISPLAY DATABASE SUMMARY * GLOBAL DSNT360I -DB9B *********************************** DSNT362I -DB9B DATABASE = NORMEN03 STATUS = RW DBD LENGTH = 4028 DSNT397I -DB9B NAME TYPE PART STATUS PHYERRLO PHYERRHI CATALOG PIECE -------- ---- ----- ----------------- -------- -------- -------- ----NORMEN03 TS RW NORMLOB LS RW IRNO1OS7 IX RW IRNORMEN IX RW,ICOPY ******* DISPLAY OF DATABASE NORMEN03 ENDED ********************** DSN9022I -DB9B DSNTDDIS 'DISPLAY DATABASE' NORMAL COMPLETION *** This is a good time to create a new common recoverable point of consistency with the same job as in Example 7-11 on page 221. The common START_RBA in SYSIBM.SYSCOPY is now x0000877165D0. We now demonstrate the use of the REPAIR utility to delete orphan rows in the LOB table space. We first delete again six rows as shown in Example 7-33.
Example 7-33 SPUFI delete
---------+---------+---------+---------+---------+---------+----DELETE FROM ##T.NORMEN03 WHERE DOC_ID LIKE '%E%' ; ---------+---------+---------+---------+---------+---------+----DSNE615I NUMBER OF ROWS AFFECTED IS 6 DSNE616I STATEMENT EXECUTION WAS SUCCESSFUL, SQLCODE IS 0 ---------+---------+---------+---------+---------+---------+-------------+---------+---------+---------+---------+---------+----DSNE617I COMMIT PERFORMED, SQLCODE IS 0 DSNE616I STATEMENT EXECUTION WAS SUCCESSFUL, SQLCODE IS 0 ---------+---------+---------+---------+---------+---------+----DSNE601I SQL STATEMENTS ASSUMED TO BE BETWEEN COLUMNS 1 AND 72 DSNE620I NUMBER OF SQL STATEMENTS PROCESSED IS 1 DSNE621I NUMBER OF INPUT RECORDS READ IS 1 DSNE622I NUMBER OF OUTPUT RECORDS WRITTEN IS 14
We then perform a point in time recovery of the LOB table space to our most recent consistency point as shown in Example 7-34 on page 231.
230
LISTDEF MYLIST INCLUDE TABLESPACES TABLE ##T.NORMEN03 LOB INCLUDE INDEXSPACES TABLE ##T.NORMEN03 LOB RECOVER LIST MYLIST TORBA X'0000877165D0' PARALLEL
As a result, the base table space NORMEN03.NORMEN03 is again put in the ACHKP restrictive pending state making it unavailable for applications. The LOB table space now contains six orphan LOBs. We can identify these orphans by running CHECK DATA as in Example 7-35, which resets the ACHKP pending state. Because the base table does not contain invalid LOBs, it is not set in the AUXW status and is available again for the applications.
Example 7-35 CHECK DATA AUXERROR INVALIDATE SHRLEVEL REFERENCE
..... CHECK DATA TABLESPACE NORMEN03.NORMEN03 SCOPE AUXONLY AUXERROR INVALIDATE SORTNUM 8 SORTDEVT 3390 WORKDDN(TSYSUT1,TSORTOUT) ERRDDN(TSYSERR)
The CHECK data gives us the ROWID and VERSION of the orphan LOBs as shown in Example 7-36.
Example 7-36 Identification and Invalidation of orphan LOBs
........................... DSNU730I 221 14:55:23.80 DSNUKDST - CHECKING TABLE ##T.NORMEN03 DSNU042I 221 14:55:24.41 DSNUGSOR - SORT PHASE STATISTICS NUMBER OF RECORDS=5877 ELAPSED TIME=00:00:00 DSNU042I 221 14:55:25.08 DSNUGSOR - SORT PHASE STATISTICS NUMBER OF RECORDS=6 ELAPSED TIME=00:00:00 DSNU813I 221 14:55:25.08 DSNUKERK - LOB IN TABLE SPACE NORMEN03.NORMLOB WITH ROWID=X'05A455C204CFD1062104015C5630' AND VERSION=X'0001' HAS NO BASE TABLE ROW DSNU813I 221 14:55:25.08 DSNUKERK - LOB IN TABLE SPACE NORMEN03.NORMLOB WITH ROWID=X'2D1165C204CFD30A2104015C5630' AND VERSION=X'0001' HAS NO BASE TABLE ROW DSNU813I 221 14:55:25.08 DSNUKERK - LOB IN TABLE SPACE NORMEN03.NORMLOB WITH ROWID=X'3E8FB7D204CFDA0F2104015C5630' AND VERSION=X'0001' HAS NO BASE TABLE ROW DSNU813I 221 14:55:25.08 DSNUKERK - LOB IN TABLE SPACE NORMEN03.NORMLOB WITH ROWID=X'50C8D45204CFD00D2104015C5630' AND VERSION=X'0001' HAS NO BASE TABLE ROW DSNU813I 221 14:55:25.08 DSNUKERK - LOB IN TABLE SPACE NORMEN03.NORMLOB WITH ROWID=X'6B8F05C204CFDE392104015C5630' AND VERSION=X'0001' HAS NO BASE TABLE ROW DSNU813I 221 14:55:25.08 DSNUKERK - LOB IN TABLE SPACE NORMEN03.NORMLOB WITH ROWID=X'9B4177D204CFD50B2104015C5630' AND VERSION=X'0001' HAS NO BASE TABLE ROW DSNU739I 221 14:55:25.08 DSNUKDAT - CHECK TABLE ##T.NORMEN03 COMPLETE, ELAPSED TIME=00:00:00 DSNU749I 221 14:55:25.10 DSNUK001 - CHECK DATA COMPLETE,ELAPSED TIME=00:00:01 DSNU010I 221 14:55:25.18 DSNUGBAC - UTILITY EXECUTION COMPLETE, HIGHEST RETURN CODE=4
We can now use the REPAIR utility to delete the six orphan rows as shown in Example 7-37 on page 232 followed by the same CHECK DATA as in Example 7-35 to check if the orphan LOBs are gone.
Chapter 7. Data administration with LOBs
231
REPAIR OBJECT LOCATE TABLESPACE NORMEN03.NORMLOB ROWID X'05A455C204CFD1062104015C5630' REPAIR OBJECT LOCATE TABLESPACE NORMEN03.NORMLOB ROWID X'2D1165C204CFD30A2104015C5630' REPAIR OBJECT LOCATE TABLESPACE NORMEN03.NORMLOB ROWID X'3E8FB7D204CFDA0F2104015C5630' REPAIR OBJECT LOCATE TABLESPACE NORMEN03.NORMLOB ROWID X'50C8D45204CFD00D2104015C5630' REPAIR OBJECT LOCATE TABLESPACE NORMEN03.NORMLOB ROWID X'6B8F05C204CFDE392104015C5630' REPAIR OBJECT LOCATE TABLESPACE NORMEN03.NORMLOB ROWID X'9B4177D204CFD50B2104015C5630'
The REPAIR deletes the six orphan LOBs, and the base table space and the LOB table space are in sync again.
7.2.2 LOGGED base table space with NOT LOGGED LOB table space
In the second scenario, we create the base table space as LOGGED and the LOB table space as NOT LOGGED. We then redo the following steps as in the first scenario: 1. LOAD the data. 2. Create a common recoverable point of consistency using the COPY utility with LISTDEF and SHRLEVEL REFERENCE as shown in Example 7-11 on page 221. In SYSIBM.SYSCOPY, we now get a common START_RBA = X'00008927CDE6. 3. Delete six LOBs using SPUFI as shown in Example 7-13 on page 222 to create some update activity. As a result, the LOB table space is put in the informational copy (ICOPY) status, because the changes to the LOB table spaces have not been logged. 4. Stop and start all spaces of database NORMEN03 and delete the VSAM clusters using ISPF 3.4 as shown in Example 7-14 on page 222. 5. Recover the VSAM clusters back to the current point with the same statements as shown in Example 7-15 on page 222. Because of the logged system pages, the recovery of the LOB table space succeeds without problems. DB2 is able to delete the six LOBS again from the full image copy of the LOB table space, even when the LOB table space is created as NOT LOGGED. 6. We then reinsert the six rows with SPUFI as shown in Example 7-38.
Example 7-38 SPUFI Insert
INSERT INTO ##T.NORMEN03 (DOC_ID,PAGE_NUMBER,FORMAT,IMAGE) SELECT DOC_ID,PAGE_NUMBER,FORMAT,IMAGE FROM ##T.NORMEN00 WHERE DOC_ID LIKE '%E%' ; ---------+---------+---------+---------+---------+---------+DSNE615I NUMBER OF ROWS AFFECTED IS 6 DSNE616I STATEMENT EXECUTION WAS SUCCESSFUL, SQLCODE IS 0 ---------+---------+---------+---------+---------+---------+-
232
---------+---------+---------+---------+---------+---------+DSNE617I COMMIT PERFORMED, SQLCODE IS 0 DSNE616I STATEMENT EXECUTION WAS SUCCESSFUL, SQLCODE IS 0 7. Now it is interesting to see what happens if we stop, start, and delete all VSAM clusters again and try to recover them back to the current point with the same statements as in Example 7-15 on page 222. Because the inserts of the LOBs were not logged, the LOB table space is put in AUXW and the six LOBs are invalidated in the LOB table space by the RECOVER utility as shown in Example 7-39.
Example 7-39 LOB table space in AUXW
DSNT360I DSNT361I
-DB9B *********************************** -DB9B * DISPLAY DATABASE SUMMARY * GLOBAL DSNT360I -DB9B *********************************** DSNT362I -DB9B DATABASE = NORMEN03 STATUS = RW DBD LENGTH = 4028 DSNT397I -DB9B NAME TYPE PART STATUS PHYERRLO PHYERRHI CATALOG PIECE -------- ---- ----- ----------------- -------- -------- -------- ----NORMEN03 TS RW NORMLOB LS RW,ICOPY,AUXW IRNO1BNY IX RW IRNORMEN IX RW ******* DISPLAY OF DATABASE NORMEN03 ENDED ********************** DSN9022I -DB9B DSNTDDIS 'DISPLAY DATABASE' NORMAL COMPLETION *** The invalid LOBS can be shown by running a CHECK LOB utility on the LOB table space. The job output is shown in Example 7-40.
Example 7-40 CHECK LOB output
.......
DSNU743I DSNU743I DSNU743I DSNU743I DSNU743I DSNU743I DSNU796I DSNU568I DSNU816I DSNU010I 222 17:03:36.39 DSNUKLBD - LOB IS INVALID. ROWID X'00E0C2EC03CFD4062104015C5630' VERSION X'0001' 222 17:03:36.40 DSNUKLBD - LOB IS INVALID. ROWID X'554542EC03CFD1372104015C5630' VERSION X'0001' 222 17:03:36.41 DSNUKLBD - LOB IS INVALID. ROWID X'94EF82EC03CFD5092104015C5630' VERSION X'0001' 222 17:03:36.41 DSNUKLBD - LOB IS INVALID. ROWID X'D3FD82EC03CFD4272104015C5630' VERSION X'0001' 222 17:03:36.41 DSNUKLBD - LOB IS INVALID. ROWID X'D578C2EC03CFD4222104015C5630' VERSION X'0001' 222 17:03:36.41 DSNUKLBD - LOB IS INVALID. ROWID X'F20AC2EC03CFD41F2104015C5630' VERSION X'0001' 222 17:03:36.42 DSNUKLBD - REPRTLOB PHASE COMPLETE, ELAPSED TIME=00:00:00 -DB9B 222 17:03:36.62 DSNUGSRX - TABLESPACE NORMEN03.NORMLOB IS IN INFORMATIONAL COPY PENDING STATE -DB9B 222 17:03:36.62 DSNUGSRX - TABLESPACE NORMEN03.NORMLOB IS IN AUX WARNING STATE 222 17:03:36.63 DSNUGBAC - UTILITY EXECUTION COMPLETE, HIGHEST RETURN CODE=4
These LOBs can now be populated using SQL update. CHECK DATA on the base table space does not report or invalidate these LOBs in the base table space. We now use SPUFI to update these invalid LOBs as shown in Example 7-41 on page 234.
233
UPDATE ##T.NORMEN03 SET IMAGE = BLOB('INVALID LOB') WHERE DOC_ID LIKE '%E%' ; ---------+---------+---------+---------+---------+---------+ DSNE615I NUMBER OF ROWS AFFECTED IS 6 DSNE616I STATEMENT EXECUTION WAS SUCCESSFUL, SQLCODE IS 0 ---------+---------+---------+---------+---------+---------+ ---------+---------+---------+---------+---------+---------+ DSNE617I COMMIT PERFORMED, SQLCODE IS 0 DSNE616I STATEMENT EXECUTION WAS SUCCESSFUL, SQLCODE IS 0 Afterwards, CHECK LOB SHRLEVEL REFERENCE does not find invalid LOBs anymore and the AUXW pending status on the LOB table space is reset. More complicated scenarios could involve point in time recovery, but here the same techniques apply as in the first scenario. The basic principles remain: LOBs with missing log records between the used image copy and the recovery point are marked invalid by RECOVERY and the LOB table space is put in the auxiliary warning state (AUXW). CHECK LOB is needed to identify the invalid LOBs, and SQL can be used to populate them again using update or by deleting the entire row. If you do not recover the base table space and LOB table spaces together to a common point of consistency, the base table space is marked as auxiliary check pending (ACHKP). CHECK DATA is needed to identify and invalidate the LOBs, which are no longer synchronized between the base and LOB table space, and SQL can be used to populate them again using update or by deleting the entire row.
7.2.3 NOT LOGGED base table space with NOT LOGGED LOB table space
In the third scenario, we create both the base table space as NOT LOGGED and the LOB table space as NOT LOGGED. We then redo the following steps: 1. LOAD the data. 2. Create a common recoverable point of consistency using the COPY utility with LISTDEF and SHRLEVEL REFERENCE as shown in Example 7-11 on page 221. In SYSIBM.SYSCOPY, we now get a common START_RBA = X'0002BB16C862. 3. Delete six LOBs using SPUFI as shown in Example 7-13 on page 222 to create some update activity. As a result, both the base table space and the LOB table space and all underlying indexes are put in the informational copy (ICOPY) status, because no changes have been logged at all. 4. Stop and start all spaces of database NORMEN03 and delete the VSAM clusters using ISPF 3.4 as shown in Example 7-14 on page 222. 5. Recover the VSAM clusters back to the current point with the same statements as shown in Example 7-15 on page 222. The job output is shown in Example 7-42.
Example 7-42 RECOVER of NOT LOGGED objects
DSNU000I DSNU1044I DSNU050I INDEXSPACES DSNU1035I DSNU050I DSNU1033I 223 18:37:16.58 DSNUGUTC 223 18:37:16.64 DSNUGTIS 223 18:37:16.65 DSNUGUTC TABLE ##T.NORMEN03 ALL 223 18:37:16.65 DSNUILDR 223 18:37:16.65 DSNUGUTC 223 18:37:16.67 DSNUGULM - OUTPUT START FOR UTILITY, UTILID = RECOV.NORMEN03 - PROCESSING SYSIN AS EBCDIC - LISTDEF MYLIST INCLUDE TABLESPACES TABLE ##T.NORMEN03 ALL INCLUDE - LISTDEF STATEMENT PROCESSED SUCCESSFULLY - RECOVER LIST MYLIST PARALLEL - PROCESSING LIST ITEM: TABLESPACE NORMEN03.NORMEN03
234
18:37:16.67 DSNUGULM - PROCESSING LIST ITEM: TABLESPACE NORMEN03.NORMLOB 18:37:16.67 DSNUGULM - PROCESSING LIST ITEM: INDEXSPACE NORMEN03.IRNORMEN 18:37:16.67 DSNUGULM - PROCESSING LIST ITEM: INDEXSPACE NORMEN03.IRNO1RLT 18:37:16.68 DSNUCBMT - OBJECTS WILL BE PROCESSED IN PARALLEL, NUMBER OF OBJECTS = 4 DSNU532I 223 18:37:16.68 DSNUCBMT - RECOVER INDEXSPACE NORMEN03.IRNORMEN START DSNU515I 223 18:37:16.68 DSNUCBAL - THE IMAGE COPY DATA SET DB2IM.DB9B.NORMEN03.IRNORMEN.F06223.#222751 WITH DATE=20060811 AND TIME=182751 IS PARTICIPATING IN RECOVERY OF INDEXSPACE NORMEN03.IRNORMEN DSNU532I 223 18:37:17.18 DSNUCBMT - RECOVER INDEXSPACE NORMEN03.IRNO1RLT START DSNU515I 223 18:37:17.18 DSNUCBAL - THE IMAGE COPY DATA SET DB2IM.DB9B.NORMEN03.IRNO1RLT.F06223.#222751 WITH DATE=20060811 AND TIME=182751 IS PARTICIPATING IN RECOVERY OF INDEXSPACE NORMEN03.IRNO1RLT DSNU504I 223 18:37:17.28 DSNUCBRT - MERGE STATISTICS FOR INDEXSPACE NORMEN03.IRNORMEN NUMBER OF COPIES=1 NUMBER OF PAGES MERGED=43 ELAPSED TIME=00:00:00 DSNU532I 223 18:37:17.62 DSNUCBMT - RECOVER TABLESPACE NORMEN03.NORMEN03 START DSNU515I 223 18:37:17.62 DSNUCBAL - THE IMAGE COPY DATA SET DB2IM.DB9B.NORMEN03.NORMEN03.F06223.#222751 WITH DATE=20060811 AND TIME=182751 IS PARTICIPATING IN RECOVERY OF TABLESPACE NORMEN03.NORMEN03 DSNU504I 223 18:37:17.72 DSNUCBRT - MERGE STATISTICS FOR INDEXSPACE NORMEN03.IRNO1RLT NUMBER OF COPIES=1 NUMBER OF PAGES MERGED=63 ELAPSED TIME=00:00:00 DSNU532I 223 18:37:18.07 DSNUCBMT - RECOVER TABLESPACE NORMEN03.NORMLOB START DSNU515I 223 18:37:18.07 DSNUCBAL - THE IMAGE COPY DATA SET DB2IM.DB9B.NORMEN03.NORMLOB.F06223.#222751 WITH DATE=20060811 AND TIME=182756 IS PARTICIPATING IN RECOVERY OF TABLESPACE NORMEN03.NORMLOB DSNU504I 223 18:37:18.17 DSNUCBRT - MERGE STATISTICS FOR TABLESPACE NORMEN03.NORMEN03 NUMBER OF COPIES=1 NUMBER OF PAGES MERGED=102 ELAPSED TIME=00:00:00 DSNU504I 223 18:37:24.06 DSNUCBRT - MERGE STATISTICS FOR TABLESPACE NORMEN03.NORMLOB NUMBER OF COPIES=1 NUMBER OF PAGES MERGED=46308 ELAPSED TIME=00:00:05 DSNU513I -DB9B 223 18:37:24.10 DSNUCALA - RECOVER UTILITY LOG APPLY RANGE IS RBA 0002BBB98311 LRSN 0002BBB98311 TO RBA 0002BBB98DC5 LRSN 0002BBB98DC5 DSNU1510I 223 18:37:24.11 DSNUCBLA - LOG APPLY PHASE COMPLETE, ELAPSED TIME = 00:00:00 DSNU1505I -DB9B 223 18:37:24.12 DSNUCATM - RECOVERY OF NOT LOGGED INDEXSPACE NORMEN03.IRNORMEN WAS TO THE LAST RECOVERABLE POINT: RBA/LRSN X'0002BB16C862'. THE OBJECT HAS BEEN CHANGED SINCE THAT POINT DSNU815I -DB9B 223 18:37:24.18 DSNUGSRX - TABLE SPACE NORMEN03.NORMEN03 IS IN AUX CHECK PENDING STATE DSNU568I -DB9B 223 18:37:24.18 DSNUGSRX - TABLESPACE NORMEN03.NORMLOB IS IN INFORMATIONAL COPY PENDING STATE DSNU500I 223 18:37:24.18 DSNUCBDR - RECOVERY COMPLETE, ELAPSED TIME=00:00:07 DSNU010I 223 18:37:24.19 DSNUGBAC - UTILITY EXECUTION COMPLETE, HIGHEST RETURN CODE=4
DB2 is only able to recover the data to the last recoverable point 0002BB16C862 and issues message DSN1505I. No effort is made to recover the lost data and the base table space is put in the ACHKP status, making it unavailable for applications. We can now run CHECK DATA SHRLEVEL REFERENCE as in Example 7-26 on page 228 to remove the pending state and be sure that the LOB data is in good shape again. We are back now in the initial position with the six deleted LOBS being back in the data.
235
The RESTORE SYSTEM utility invokes z/OS DFSMShsm (Version 1 Release 5 or above) to recover a DB2 subsystem or a data sharing group to a previous point in time. To perform the recovery, the utility uses data that is copied by the BACKUP SYSTEM utility. All data sets that you want to recover must be SMS-managed data sets. You must use the change log inventory utility DSNJU003 to record the log point to which you want to recover the system: CRESTART CREATE,SYSPITR=log-truncation-point: Specifies the log RBA (non-data sharing system) or the log LRSN (data sharing system) that represents the log truncation point for the point in time for system recovery. CRESTART CREATE,SYSPITRT=log-truncation-timestamp: Specifies the timestamp value that represents the point in time log truncation point for system recovery. Log-truncation-timestamp specifies a timestamp value that is to be used as the log truncation point. A valid log truncation point is any GMT timestamp for which there exists a log record with a timestamp that is greater than or equal to the specified timestamp value. Any log information in the bootstrap data set, the active logs, and the archive logs with a timestamp greater than SYSPITRT is discarded. If you omit SYSPITRT, DB2 determined the end of the log range. The SYSPITRT keyword is new in DB2 9. The RESTORE SYSTEM utility uses the most recent system-level backup of the database copy pool that DB2 took prior to the SYSPITR or SYSPITRTlog truncation point. Complete the following steps prior to running RESTORE SYSTEM: 1. Stop DB2. 2. Run DSNJU003 (Change Log Inventory) with the CRESTART SYSPITR or SYSPITRT option. For SYSPITR or SYSPITRT, specify the log truncation point that corresponds to the previous point in time to which the system is to be recovered. 3. Start DB2. When the restart that is specified by CRESTART SYSPITR or SYSPITRT completes, DB2 enters system RECOVER-pending and access maintenance mode. During system RECOVER-pending mode, you can run only the RESTORE SYSTEM utility. 4. Ensure that the ICF catalog volumes for DB2 data are not active. The ICF catalog for the data must be on a separate volume that the ICF catalog for the logs. Important: If RESTORE SYSTEM determines that a NOT LOGGED base table space or NOT LOGGED LOB table space was updated after the point at which the system level copy was taken, the table space is marked RECOVER-pending. Use the RECOVER utility and/or the REBUILD INDEX utility afterwards to recover all objects in RECOVER-pending (RECP) or REBUILD-pending (RBDP) status. There are no other special considerations when your DB2 data contains LOB table spaces in regard to the BACKUP SYSTEM and RESTORE SYSTEM utilities.
REPAIR utility SQL update and delete of LOB columns To be prepared for recovery to the current point in time: Take image copies of all base and LOB table spaces using LISTDEFs. Eventually take image copies of the underlying indexes. Use LOGGED or LOG YES if possible to avoid missing log records when recovering. To be prepared for point in time recovery: Take image copies of all base and LOB table spaces using LISTDEFs. Take quiesce point for all base and LOB table spaces using LISTDEFs to establish meaningful recovery points from the application point of view. Use LOGGED or LOG YES if possible to avoid missing log records when recovering. To make your life easy when doing point in time recovery: Create common recoverable points of consistency by taking full image copies with SHRLEVEL REFERENCE and using LISTDEFs to include all objects. Create common recoverable quiesce points. Always recover all your objects together to a common recoverable consistency point. All this avoids the use of CHECK DATA, CHECK LOB, REPAIR, and so forth. If LOGGED or LOG YES is not acceptable: Take image copies of all base and LOB table spaces using LISTDEFs before and after updating the LOB data. Keep new LOB data, that is not yet included in a full image copy, aside to be able to correct LOBs using SQL update when needed. Take only image copies with SHRLEVEL CHANGE when you have no windows available for taking image copies with SHRLEVEL REFERENCE. Image copies with SHRLEVEL CHANGE do not create common recoverable points of consistency. As a consequence during point in time recovery, the base table space can be set in the auxiliary check pending (ACHKP) state, which makes it unavailable for applications as explained before.
The same was true for a change of the base or LOB table spaces that required a drop and recreate of the table space.
237
So there are several ways to perform this task: Write your own program. This requires a DB2 user or administrator to write a custom program for unloading and loading LOBs. The programs would usually read the LOB columns of the tables and write them to flat files. When the change is completed, the program inserts these LOB values back into the tables. You could speed up the process by altering the LOB table spaces to LOG NO and LOCKSIZE TABLESPACE to consume less of your system resources. Afterwards, a recoverable point of consistency should be taken in the form of an Image Copy. This process has some disadvantages, because you have to code your programs and set up the recoverable step. This also had a tremendous impact on logs, because massive LOB writes were recorded in them, and you could prevent it only by changing LOG attributes and again by setting up proper controls. And of course, the data was inaccessible for a long period of time during this maintenance. Use shadow tables. The recommended way was creating a shadow set of the objects, identical to the original ones. Use DSN1COPY with OBIDXLAT to copy the original objects into the shadow ones. Recreate the original table with new definitions and then use SQL INSERT INTO original-table SELECT FROM shadow-table... to copy the data from the shadow table back into the original one. In the end of the process, a recoverable point of consistency could be taken in the form of a DB2 COPY. You could speed up the process by altering the LOB table spaces to LOG NO and LOCKSIZE TABLESPACE to consume less of your system resources. Also be careful not to copy the ROWID values when the ROWID in the target table is defined as GENERATED ALWAYS. This process is usually faster than the one described before. And of course, there was a great impact in the log I/O, so this process should have been made during the quiet hours of the system. A great improvement to this method was using DB2 cross loader to load the data back into the original changed table. For more information about cross loader, refer to 6.3, LOAD on page 173. Today clients using DB2 V7 and DB2 V8 are encouraged to use the UNLOAD and LOAD utilities to perform these changes that disrupt their business, because the new maintenance allows UNLOAD and LOAD LOB to deal with values larger than 32 KB together with the other columns of the base table. For more information, refer to the following sections: 6.1, UNLOAD on page 162 6.2, DSNTIAUL on page 171 6.3, LOAD on page 173
238
Chapter 8.
239
240
Materialized LOBs
2G bar
Buffer Manager
LOB Manager
Disk environment
SELECT
We assume we have three applications that select a LOB for further processing. This could be printing a LOB that contains a book or storing it into a non-DB2 data set. Let us say we have application A using a LOCATOR, application B using neither a LOCATOR nor file reference variables, but rather a host variable, and application C using LOB file reference
Chapter 8. Performance with LOBs
Data Manager
241
variables. From the point of view of DB2 LOB materialization, application A, application B, and application C do not materialize the LOB in DB2 virtual storage when they only select a LOB value. See Figure 8-2.
Space
B
DB2 DBM1 Address
Space
Virtual Pool User Address Space
2G bar
User Address Space Buffer Manager LOB Manager Data Manager
Disk environment
Figure 8-2 LOB Materialization In user address space in case of data retrieval
Application A uses a locator and might just use the space it needs for the chunks of data pointed to through the defined locator. Application B might require the complete LOB data. Therefore, the private user address space might require, based on the size of the LOB, a huge amount of storage. Application C uses LOB file reference variables, eliminating any need to allocate any kind of variable for storing chunks of the LOB in its local address space. If you have applications in a distributed environment selecting LOB values through the network, they involve the DB2 DDF address space. You can minimize the servers storage consumption by utilizing the DRDA flow optimization functionality. See 4.3, DRDA LOB flow optimization on page 81. If you use stored procedures, the selected LOB data is not materialized within a DBM1 address space. Stored procedures use LOCATORs and move the data in small chunks from disk through the stored procedure address space.
INSERT
Assume a scenario where your application A and application B INSERT into your LOB table space. From the point of view of materialization, the picture is different. Now there are space allocations in virtual storage involved. The materialization in DB2 virtual storage occurs if you are using LOCATORs, and it probably does not occur if you use other techniques. However, not using LOCATORs, like in application B, causes you to require more storage in your private user address space, and depending on the size of your LOB, this could consume a large amount of storage. See Figure 8-3 on page 243.
242
Space
Materialized LOBs
A
DB2 DBM1 Address
Space
Virtual Pool
2G bar
B
Buffer Manager LOB Manager Data Manager
Disk environment
If LOB file reference variables are used, as in application C, the materialization is avoided. On the other hand, if an application INSERTs LOB values using the network (this implicates the use of the DB2 DDF address space), or it uses a stored procedure, or it uses some kind of conversion (for example from one CCSID to another), LOB materialization occurs in the DBM1 address space.
243
application storage. LOB file reference variables bypass host language limitations on the maximum allowed size for LOB values located in working storage as well. This technique is recommended when no manipulation on the LOB has to be performed. See 2.1, Introduction to LOB data types on page 10 and 4.2, LOB locators on page 75 for syntax examples and explanations.
LOB locators
When the whole LOB is not needed in the program, you can use locators to operate on the LOBs. Explanation about locators and the programming techniques is at 2.3, LOB locators on page 16 and 4.2, LOB locators on page 75. Note: When partial continuous retrieval of a LOB is required, you can use FETCH CONTINUE instead of locators. It does not prevent LOBs from materializing. The data still needs to be materialized in the server, but this new DB2 9 functionality enables writing applications in a less complicated way. The technique is used to stream the data into the application. After the original FETCH is performed and there is more of the LOB to retrieve, it uses as many subsequent FETCH CONTINUE statements as necessary to finish retrieving the data, using the same buffer area. This assumes that the data in the buffer is processed after each FETCH or FETCH CONTINUE operation. The function is explained in 4.6.2, Using FETCH CONTINUE on page 115.
DBM1 STORAGE ABOVE 2 GB -------------------------------------------FIXED STORAGE (MB) GETMAINED STORAGE (MB) COMPRESSION DICTIONARY (MB) CACHED DYNAMIC SQL STATEMENTS (MAX) (MB) DBD CACHE (MAX) (MB) VARIABLE STORAGE (MB) VIRTUAL BUFFER POOLS (MB) VIRTUAL POOL CONTROL BLOCKS (MB) CASTOUT BUFFERS (MB)
QUANTITY -----------------0.01 79.00 0.00 14.46 14.46 50.05 179.69 0.07 0.00
244
(MB)
0.00
DSNTIPD ===>
Check numbers and reenter to change: 1 2 3 4 5 6 7 8 9 10 11 12 DATABASES TABLES COLUMNS VIEWS TABLE SPACES PLANS PLAN STATEMENTS PACKAGES PACKAGE STATEMENTS PACKAGE LISTS EXECUTED STMTS TABLES IN STMT ===> ===> ===> ===> ===> ===> ===> ===> ===> ===> ===> ===> 200 20 10 3 20 200 30 300 10 2 15 2 In this subsystem Per database (average) Per table (average) Per table (average) Per database (average) In this subsystem SQL statements per plan (average) In this subsystem SQL statements per package (average) Package lists per plan (average) SQL statements executed (average) Tables per SQL statement (average) Max KB storage per user for LOB values Max MB storage per system for LOB values Maximum tokens at any time. 0-50 HELP for more information . . . . . . . . .
13 USER LOB VALUE STG ===> 10240 14 SYSTEM LOB VAL STG ===> 2048 15 MAXIMUM LE TOKENS ===> 20 PRESS: ENTER to continue . . . . . . . . .
RETURN to exit . . . . .
. .
Both DSNZPARMs can be changed without stopping DB2. For details, refer to -SET SYSPARM in the DB2 UDB for z/OS Version 8 Command Reference, SC18-7416, or DB2 Version 9.1 for z/OS Installation Guide, GC18-9846.
Table 8-1 LOB linked subsystem parameters Parameter LOBVALA LOBVALS Macro DSN6SYSP DSN6SYSP Panel DSNTIPD DSNTIPD Values range 1 - 2,097,152 KB 1 - 51,200 MB Default 10,240 KB 2,048 MB
The value LOBVALA establishes an upper limit for the amount of variable storage that each user can have for storing LOB values. The specified value indicates the numbers of kilobytes.
245
The value LOBVALS establishes an upper limit for the amount of variable storage per system that can be used for storing LOB values. The specified value indicates the numbers of megabytes. Because these definitions can have an impact on your DB2 subsystem (for example, if you exceed the virtual storage backed up by real storage, the DB2 subsystem abends) and operating system, specifically on paging and auxiliary storage, and these definitions depend on how heavy the use of LOBs is within your DB2 subsystem, the values of these settings represent a safeguard for your other workload. Set these values after consulting with your z/OS system programmer. If you run into a resource unavailable situation (SQLCODE -904) with virtual storage allocations (resource 00000907), the reason codes you can expect are 00C900Dx (x = 1, 2, and 3). The reason codes mean respectively: User limit exceeded System limit exceeded Out of space condition in the virtual storage above the bar (this one would be hard to reach!) Note: Some messages in DB2 V8 and DB2 9 might still use the term data space, but they do not really mean data space. We include this just to remind you that since V8, data spaces are no longer in use.
246
updating large LOBs. In this case, if the write thresholds are high, the buffer pool might become overwhelmed, and the number of dirty pages might reach levels where critical data manager thresholds are triggered. The result of this would be for I/Os to become synchronous. This could have a dramatic impact on the performance of the updates. Note that this recommendation is based on the data length of the LOB values being quite large, that is, you are using real LOBs. One major factor affecting the design and setup of buffer pools for LOB objects relates to whether you expect the LOB objects to be re-referenced, and the hit ratio for pages in the buffer pool becomes significant to increase performance. The opposite scenario is that you expect the re-reference of objects to be very low. See Figure 8-5.
Scenario 1
Expected re-reference of LOB data Buffer pool setup is expected to give performance gains by caching data
Scenario 2
Low expected re-reference of LOB data Buffer pool setup is required to allow LOB operations while minimizing impact on "other" activity in the DB2 subsystem
With the advancement of 64-bit addressing, it is possible to provide large buffer pools for LOB objects. But the availability of physical memory to back the allocated buffer pools must still be carefully considered, so as not to cause paging problems with overallocation of real storage. If re-reference of objects is not expected, it follows that storage resources can probably be better utilized by other buffer pools to avoid I/O. The considerations for the buffer pool for these LOBs is to allow prefetching and determine a minimum size to avoid effects such as different threads stealing pages of LOB objects prior to their materialization. If re-reference of objects is expected, the buffer pool for the LOBs is probably increased to greater than the minimum. What then follows is the trade-off of what resources to allocate to the respective buffer pools, within the available physical memory constraints. This is a topic beyond the scope of this book as it is obviously a major DB2-wide issue. What is needed with respect to LOBs is to determine the importance performance plays for the LOB tables involved relative to the entire DB2 subsystem content. Sizing the LOB buffer pools is an important issue. Due to LOBs being prefetched into virtual pools for further processing, you would prefer having the buffer pool big enough to satisfy the needs of all of the parallel executing threads, and avoid prefetched pages being paged out in order to free enough space for some other LOB currently being read in. When DB2 9 is prefetching LOBs, it is done using list prefetch in blocks of up to 64 pages of 4 KB. To prevent
247
active threads stealing pages from each other, you would prefer to have at least three prefetched blocks to stay in the virtual buffer pool for processing. Example 8-2 shows an algorithm to estimate the allocation for LOB buffer pool.
Example 8-2 LOB buffer pool allocation size
IOB - I/O read block for prefetch 3 * 32 pages * 4 KB = 384 KB PT - Maximum number of active parallel threads reading\writing LOBs TOTAL SIZE = PT * IOB Example for LOB buffer pool: PT = 100 TOTAL SIZE = 100 * 384 KB= 38400 KB Figure 8-6 shows the separation of LOB buffer pools for better performance and monitoring. In the figure, we have omitted BP7, associated to work files, and BP8K0, BP16K0, BP32K needed for DB2 catalog access besides BP0.
BP32K1
BP10
BP20 Index
VPSIZE
BP0
VPSEQT
Buffer Pool
Buffer Pool
DWQT
VDWQT
DWAT VDWAT
Separate
System
Random
Sequential
VPSEQT
degree of inter-DB2 read interest are good candidates for GBPCACHE ALL. Keep in mind that allowing GBPCACHE ALL demands increased coupling facility resources: processing power, storage, and channel utilization.
GBP
Member A ssnmDBM1
Member B ssnmDBM1
Buffer Pools
Figure 8-7 LOB group buffer pool
Buffer Pools
When the LOB table space is NOT LOGGED, we recommend using GBPCACHE CHANGED for LOB table spaces. In this case, if the coupling facility fails, the LOB table space is placed in GRECP. When group buffer pool recovery occurs, all LOB values that were in the coupling facility at the time of the failure are marked invalid, because the log records that are necessary to perform the recovery for those values are missing due to the NOT LOGGED attribute. In DB2 9, consider specifying GBPCACHE CHANGED to flush changed pages to the CBP rather than flushing changed pages to disk and delaying the release of LOB locks. When extremely large objects are used, you might consider using GBCACHE SYSTEM to avoid having large LOB values overwhelm the group buffer pool.
249
For more information about DB2 Data Sharing, refer to DB2 Version 9.1 for z/OS Data Sharing: Planning and Administration, SC18-9845.
LOB INSERT
As with read processing, the greater the LOB length, the greater the efficiency of insert processing. To insert 100 times the data does not require 100 times the resources. The relative improvement of insert efficiency with respect to LOB size results, however, are less dramatic than for SELECT processing. The reason is that the cost of preformatting disk space to accommodate the newly inserted LOB can increase with the size of the LOB, and it accounts for most of the elapsed time. With V9, depending on the allocation quantity, DB2 250
LOBs with DB2 for z/OS: Stronger and Faster
triggers the preformatting earlier and preformats 16 rather than 2 cylinders. This reduces the impact of preformatting. There is relatively little difference in insert performance if a LOB locator is used. When the LOB file reference variables are used, the I/O operation of writing the data to disk can be done at the device speed. Application logic needed to use the method is minimal.
LOB update
A LOB update is equivalent to a LOB insert and a LOB delete. Most of the cost of a LOB update can, therefore, be attributed to the cost of the LOB insert.
LOB delete
A LOB delete is a logical delete, and therefore, it is relatively inexpensive and gives consistently good performance. The CPU cost is somewhat independent of the size of the LOB column. The larger the LOB column, the greater the number of space map pages that have to be updated to reflect the logically deleted row, but the relationship between elapsed time and LOB size for deletes is not linear. The larger the LOB column, the greater the efficiency of the delete operation. DB2 can delete 833 KB per second if the LOB is 20 KB in length. With a 2 MB LOB, DB2 can delete 45,511 KB per second, which is more than 50 times faster.
251
Selecting 30K LOBS AVERAGE APPL(CL.1) DB2 (CL.2) ------------ ---------- ---------ELAPSED TIME 0.032034 0.012463 CPU TIME 0.015927 0.010114
Selecting 5K LOBS AVERAGE APPL(CL.1) DB2 (CL.2) ------------ ---------- ---------ELAPSED TIME 0.076652 0.041317 CPU TIME 0.055328 0.039350
Selecting VARCHARs AVERAGE APPL(CL.1) DB2 (CL.2) ------------ ---------- ---------ELAPSED TIME 0.045266 0.013610 CPU TIME 0.027320 0.012744
Figure 8-8 Accounting trace report for LOB and VARCHAR applications
The values shown for DB2 Class 2 elapsed time clearly indicates that when dealing with small LOBs (<32 KB), it would be better to implement the VARCHAR, VARBINARY, and VARGRAPHIC strategy. If you decide to span your LOB over several non-LOB columns (in the example, we simulate dividing a 30 KB LOB into six 5 KB VARCHAR fields), you might want to reconsider the spanning and use LOBs instead to avoid the whole process of merging VARCHARs into one whole object in your application and save some application CPU time and DB2 CPU time.
252
STRIPED LOBs - 100 5Mb inserts AVERAGE APPL(CL.1) DB2 (CL.2) ------------ ---------- ---------ELAPSED TIME 16.485975 16.462227 CPU TIME 1.842678 1.834109 SUSPEND TIME 0.000000 13.665551 NON STRIPED LOBs - 100 5Mb inserts AVERAGE APPL(CL.1) DB2 (CL.2) ------------ ---------- ---------ELAPSED TIME 50.755741 50.731716 CPU TIME 2.036847 2.027694 SUSPEND TIME 0.000000 46.740564
Figure 8-9 Striped versus non-striped LOB table spaces
You can see that striping is extremely beneficial to performance. Though you do not save much in terms of CPU, the elapsed time is considerably shorter. In this example, the reduction of time is almost the same as the number of stripes (four), indicating that the parallel access available to the different stripes was almost entirely concurrent. However, the largest improvement is with 2 stripes. When increasing the stripes (in pairs), diminishing returns apply. This example is an isolated test case, so in an environment with a greater workload, you would expect a smaller reduction. The value of striping is very sensitive to the speed of the device and channel. Path utilization can be the limiting factor. Striping is especially recommended in case you are running on older disk controller technology as a means to obtain relief from performance constraints. The greatest performance gain can be seen when massive sequential reads and writes are performed, which should reflect the I/O associated with LOBs providing you are using the LOB data type for truly large objects. Tip: Consider using striping for your active logs as well to speed up log writes, especially when heavy sequential data updating is involved (large batch or busy OLTP environment). With introduction of z9 and new I/O controllers, MIDAW technology was introduced to optimize the I/O stream and maximize channel throughput. It does not increase the bandwidth of your FICON channel, but it increases the efficiency of the channels (efficiency in this case is the ratio of throughput to channel utilization). More information is available in the redpaper How does the MIDAW facility improve the performance of FICON channels using DB2 and other workloads?, REDP-4201.
253
A collection of the current IFCIDs providing information regarding LOBs is listed in Table 8-2.
Table 8-2 Current IFCIDs providing information regarding LOBs IFCID 0002 Fields Description
DB2 statistical data on the database services address space QXSTLOBV QXCRATB QXHLDLOC QXFRELOC Maximum storage used for LOB values Number of CREATE AUXILIARY TABLE statements Number of HOLD LOCATOR statements Number of FREE LOCATOR statements
0003
DB2 accounting record QXSTLOBV QWACLRN QWACLRAB Maximum storage used for LOB values Number of log records written Total number of bytes of log records written
0018
Ends sequential scan, index scan, or insert. The additional pages scanned in a LOB table space and for a count of the number of LOBs updated. Other fields in IFCID 18 are only applicable to the base table. QW0018PL QW0018UL Additional pages scanned in a LOB table space Count of LOB data pages updated (either by an SQL INSERT or an SQL UPDATE)
0020
Summary of page, row, and LOB locks held and lock escalation QW0020TP QW0020PL QW0020F5 QW0020R3 Maximum number of page, row, and LOB locks held Maximum number of either page, row, or LOB locks held for the thread LOB table space LOB lock
0021
Detail lock trace LOB lock type QW0021ML QW0021KX QW0021K6 QW0021K7 LOB lock type (value '30 'x) ID of resource for LOB locks ROWID Version number
0023
Record utility start information QW0023PH CHECKLOB is a new phase for the CHECK LOB utility.
0024
Record utility object or phase change record QW0024PH CHECKLOB is a new phase for the CHECK LOB utility.
0025
Record utility start information QW0025PH CHECKLOB is a new phase for the CHECK LOB utility.
254
IFCID 0044
Fields
Description
Records lock suspension. LOB lock type record utility start information QW0044ML QW0044KX QW0044K6 QW0044K7 LOB lock type (value '30 'x) ID of resource for LOB locks ROWID Version number
0058
End of SQL statement execution. Add fields for the additional pages scanned in a LOB table space and for a count of the number of LOBs updated. Other fields in IFCID 58 are only applicable to the base table. QW0058PL QW0058UL Additional pages scanned in a LOB table space Count of LOB data pages updated (either by an SQL INSERT or an SQL UPDATE)
0059
DB2 performance record. Records the start of the execution of a fired SQL statement. QW0059CTU Continue clause x0000 - CONTINUE not specified x0001 - WITH CONTINUE specified x0002 - CURRENT CONTINUE specified
0062
DDL (and other) execution statement start QW0062CX QW0062HL QW0062FL Create auxiliary table. Value x'F2' Hold locator. Value x'CE'. Free locator. Value x'CF'.
0105
Maps the DBID and OBID to the database and table space name. Also maps the DBID and OBID of the LOB table space and index on the auxiliary table to the LOB table space name and name of the index on the auxiliary table. DDL (and other) execution statement start. System initialization parameters QWP1LVA QWP1LVS QWP1MOFR Bytes for LOB values - per user Bytes for LOB values - per system Maximum number of concurrently open data sets for processing LOB file references. This value corresponds to "max open file refs" on installation panel DSNTIPE, or DSNZPARM name: MAXOFILR in DSN6SYSP.
0106
0107 0141
Open and close information. Also records open and close for LOB table spaces and indexes on auxiliary tables. Records grants and revokes QW0140BS QW0140BT For a LOB table space For an auxiliary table
0148
255
IFCID 0150
Fields
Description
Lock information for a given agent QW0150ML QW0150KX QW0150K6 QW0150K7 LOB lock type (value '30 'x) ID of resource for LOB locks ROWID Version number
0172
Deadlock trace QW0172MO QW0172KX QW0172K6 QW0172K7 LOB lock type (value '30 'x) ID of resource for LOB locks ROWID Version number
0185
Data capture information deadlock trace QW0185ST QW0185LE For a LOB column, this is the data type of the LOB. For a LOB column, this is the length of the indicator column.
0196
Time-out trace. Lock types are not explicitly specified for this trace. QW0196FR QW0196KX QW0196K6 QW0196K7 This value represents a LOB lock '30 'X. ID of resource for LOB locks ROWID Version number
0225
Historical storage usage. Used to determine which areas are responsible for the REAL frames buildup. QW0225VA TOTAL VARIABLE STORAGE ABOVE THE 31-BIT BAR
Records log records. Note that when NOT LOGGED has been specified for a LOB table space, log records are not written for the value of the LOB. Trace record to trace the beginning of a force-at-commit Trace record to trace the end of a force-at-commit QW0322NP Number of pages written
0337
256
IFCID 321 and 322 Respectively begin and end force-at-commit Belong to the same classes as other I/O wait events: Accounting classes 3 and 8 Monitor classes 3 and 8 Performance class 4 QXSTLOBV - Maximum storage used for LOB values Value is in KB for accounting Value is in MB for statistics Tip: You can find the IFCID field descriptions in the member of the installation library HLQ.SDSNIVPD(DSNWMSGS).
257
Note: The highest performance improvement is seen when selecting a large number of rows in one cursor. For singleton selects, only minimal performance improvement is seen.
258
To avoid complicated recovery, do not put rarely, massively updated LOBs with frequently updated non-LOB data (in the same base table). For example, in case we have online logged updates of employee personal details, and a weekly not logged batch updated picture, you might want to separate this data to avoid complicated point in time recovery scenarios. Do not use LOBS as a means of normalizing data. We do not recommend that you use LOBs as a technique to obtain performance improvements that normalization and proper physical design can achieve. Note that: Any improvements are entirely application dependent. At the physical design stage, you should have been able to identify the columns that are infrequently accessed and the relationship across the columns. Depending on the application, there might be a net benefit in placing some columns into its own base table, that is keyed on application unique identifier and holding the 20 KB VARCHAR and possibly other infrequently accessed columns.
The additional cost, particularly when processing small LOBs, means you are likely to create a different bottleneck from the perceived one of logging that you were trying to solve. Use LOBs only for their intended purpose. Use LOAD and UNLOAD for massive LOB update and retrieval. Notice that DB2 9 introduced a lot of changes to the LOAD and UNLOAD utilities. These changes were retrofitted to earlier versions as well, making massive LOB updating and retrieval faster and more efficient. Tune VSAM and GRS with data sharing. In data sharing environments, we observed some contention during drop LOB table space and unusually high Coupling Facility (CF) CPU activity. We could attribute this to VSAM making use of GRS. When we specified GRS=STAR, these problems were eliminated. We recommend that you investigate the GRS setting in data sharing environments if you are observing high CF CPU activity. Use REORG SHRLEVEL REFERENCE. Starting from DB2 9, you can keep your LOBs readable even during maintenance while the objects are being reorganized. Use CHECK DATA and CHECK LOB with SHRLEVEL CHANGE. CHECK DATA and CHECK LOB utilities are available with SHRLEVEL CHANGE in DB2 9.
259
260
Appendix A.
Additional material
This IBM Redbooks publication refers to additional material that can be downloaded from the Internet as described below.
CLOB examples
File name SGDBC BASETSC BASETC BASEIXC AUXTSC AUXTC AUXIXC BINDC SAMPnC Description DDL for database and storage group DDL for base table space DDL for base table DDL for base table unique index DDL for auxiliary table space DDL for auxiliary table DDL for auxiliary index BIND member for BLOB samples JCL to execute SAMPLEnC, (n between 1 and 9, B)
261
SAMPLE1C SAMPLE2C SAMPLE3C SAMPLE4C SAMPLE5C SAMPLE6C SAMPLE7C SAMPLE8C SAMPLE9C SAMPLEAC SAMPLEBC
Insert a CLOB using a large host variable Insert a CLOB using a large host variable and one locator chain Insert a CLOB using a large host variable and two locator chains Unload a CLOB using a large host variable Unload a CLOB using a large host variable and one locator chain Delete parts of a CLOB using locators Update parts of a CLOB using locators Load a CLOB using a file-reference-variable Unload a CLOB using a file-reference-variable Update a CLOB using a file-reference-variable FETCH WITH/CURRENT CONTINUE example
All the above files are contained in: CLOBSAMPLES.zip Zipped Code Samples
BLOB examples
File name SGDBB BASETSB BASETB BASEIXB AUXTSB AUXTB AUXIXB BINDB SAMPnB SAMPLE1B SAMPLE2B SAMPLE3B SAMPLE4B SAMPLE5B SAMPLE6B SAMPLE7B SAMPLE8B SAMPLE9B SAMPLEAB SAMPLEAB Description DDL for database and storage group DDL for base table space DDL for base table DDL for base table unique index DDL for auxiliary table space DDL for auxiliary table DDL for auxiliary index BIND member for CLOB samples JCL to execute SAMPLEnB, (n between 1 and 9, B) Insert a BLOB using a large host variable Insert a BLOB using a large host variable and one locator chain Insert a BLOB using a large host variable and two locator chains Unload a BLOB using a large host variable Unload a BLOB using a large host variable and one locator chain Delete parts of a BLOB using locators Update parts of a BLOB using locators Load a BLOB using a file-reference-variable Unload a BLOB using a file-reference-variable Update a BLOB using a file-reference-variable FETCH WITH/CURRENT CONTINUE example
All the above files are contained in: BLOBSAMPLES.zip Zipped Code Samples
262
263
264
Related publications
The publications listed in this section are considered particularly suitable for a more detailed discussion of the topics covered in this book.
IBM Redbooks
For information about ordering these publications, see How to get IBM Redbooks on page 267. Note that some of the documents referenced here may be available in softcopy only. Data Integrity with DB2 for z/OS, SG24-7111 DB2 UDB for z/OS: Design Guidelines for High Performance and Availability, SG24-7134 DB2 UDB for z/OS Version 8 Performance Topics, SG24-6465 Disk storage access with DB2 for z/OS, REDP-4187 DB2 UDB for z/OS Version 8: Everything You Ever Wanted to Know, ... and More, SG24-6079 DB2 for z/OS and OS/390 Version 7 Performance Topics, SG24-6129 DB2 for z/OS Application Programming Topics, SG24-6300 DB2 for z/OS Stored Procedures: Through the CALL and Beyond, SG24-7083 WebSphere Information Integrator Q Replication: Fast Track Implementation Scenarios, SG24-6487 SAP on DB2 Universal Database for OS/390 and z/OS: Multiple Components in One Database (MCOD), SG24-6914 How does the MIDAW facility improve the performance of FICON channels using DB2 and other workloads?, REDP-4201
Other publications
These publications are also relevant as further information sources:
DB2 Version 8
Enterprise COBOL for z/OS Programming Guide, SC27-1412-04 DB2 UDB for z/OS Version 8 Data Sharing: Planning and Administration, SC18-7417-03 DB2 UDB for z/OS Version 8 Administration Guide, SC18-7413-03 DB2 UDB for z/OS Version 8 Application Programming and SQL Guide, SC18-7415-03 DB2 UDB for z/OS Version 8 Application Programming Guide and Reference for Java, SC18-7414-02 DB2 UDB for z/OS Version 8 Command Reference, SC18-7416-03 DB2 UDB for z/OS Version 8 Installation Guide, GC18-7418-04 DB2 UDB for z/OS Version 8 Codes, GC18-9603-01 DB2 UDB for z/OS Version 8 Messages, GC18-9602-01
265
DB2 UDB for z/OS Version 8 SQL Reference, SC18-7426-03 DB2 UDB for z/OS Version 8 Utility Guide and Reference, SC18-7427-03 DB2 UDB for z/OS Version 8 Internationalization Guide, available from: http://www.ibm.com/software/data/db2/zos/v8books.html
Online resources
These Web sites are also relevant as further information sources: Unicode site http://www.unicode.org/ The Unicode character code charts http://www.unicode.org/charts/
266
Related publications
267
268
269
DWDM DWT EA EAI EAS EBCDIC ECS ECSA EDM EJB ELB ENFM ERP ERP ESA ESP ESS ETR
dense wavelength division multiplexer deferred write threshold extended addressability enterprise application integration Enterprise Application Solution extended binary coded decimal interchange code enhanced catalog sharing extended common storage area environmental descriptor manager Enterprise JavaBean extended long busy enable-new-function mode enterprise resource planning error recovery procedure Enterprise Systems Architecture Enterprise Solution Package Enterprise Storage Server external throughput rate, an elapsed time measure, focuses on system capacity Entry Workload License Charges Enterprise Workload Manager first in first out fast log apply functional track directory File Transfer Program gigabyte (1,073,741,824 bytes) group buffer pool Geographically Dispersed Parallel Sysplex Gramm-Leach-Bliley Act of 1999 global resource serialization graphical user interface High Availability Large Databases high performance Java Hypertext Transfer Protocol hardware input/output International Business Machines Corporation internal coupling facility integrated catalog facility integrated coupling migration facility
ICSF IDE IFCID IFI IFL IGS IMS IORP IPLA IRD IRLM IRWW ISPF ISV IT ITR
Integrated Cryptographic Service Facility integrated development environments instrumentation facility component identifier Instrumentation Facility Interface Integrated Facility for Linux IBM Global Services Information Management System I/O Request Priority IBM Program Licence Agreement Intelligent Resource Director internal resource lock manager IBM Relational Warehouse Workload interactive system productivity facility independent software vendor information technology internal throughput rate, a processor time measure, focuses on processor capacity International Technical Support Organization installation verification process Java 2 Enterprise Edition Java Database Connectivity journaled file systems
EWLC EWLM FIFO FLA FTD FTP GB GBP GDPS GLBA GRS GUI HALDB HPJ HTTP HW I/O IBM ICF ICF ICMF
ITSO IVP J2EE JDBC JFS JNDI JTA JTS JVM KB LCU LDAP LOB LPAR LPL LRECL LRSN LRU LSS LUW
270
LVM MAC MB MBps MLS MQT MTBF MVS NALC NFM NFS NPI NPSI NVS ODB ODBC ODS OLE OLTP OP OS/390 OSC PAV PCICA PCICC PDS PIB PPRC PR/SM PSID PSP PTF PUNC PWH QA QMF QoS QPP RACF RAS RBA RBLP
logical volume manager mandatory access control megabyte (1,048,576 bytes) megabytes per second multi-level security materialized query table mean time between failures Multiple Virtual Storage New Application License Charge new-function mode Network File System non-partitioning index nonpartitioned secondary index non volatile storage object descriptor in DBD Open Database Connectivity Operational Data Store Object Link Embedded online transaction processing Online performance Operating System/390 optimizer service center parallel access volume Peripheral Component Interface Cryptographic Accelerator PCI Cryptographic Coprocessor partitioned data set parallel index build Peer-to-Peer Remote Copy Processor Resource/System Manager pageset identifier preventive service planning program temporary fix possibly uncommitted Performance Warehouse Quality Assurance Query Management Facility Quality of Service Quality Partnership Program Resource Access Control Facility reliability, availability and serviceability relative byte address recovery base log point
RDBMS RDS RECFM RI RID ROI RPO RR RRS RRSAF RS RTO RTS SAN SBCS SCUBA SDM SDP SLA SMIT SOA SOAP SPL SQL SQLJ SRM SSL SU TCO TPF UA UCB UDB UDF UDT UOW UR USS vCF VIPA VLDB
relational database management system relational data system record format Referential Integrity record identifier return on investment recovery point objective repeatable read resource recovery services resource recovery services attach facility read stability recovery time objective real-time statistics storage area networks store single byte character set self contained underwater breathing apparatus System Data Mover Software Development Platform service-level agreement System Management Interface Tool service-oriented architecture Simple Object Access Protocol selective partition locking Structured Query Language Structured Query Language for Java Service Request Manager Secure Sockets Layer Service Unit total cost of ownership Transaction Processing Facility Unit Addresses Unit Control Block Universal Database user-defined functions user-defined data types unit of work unit of recovery UNIX System Services virtual coupling facility Virtual IP Addressing very large database
271
VM VSE VSIP VWLC wizards WLC WLM WSDL WTO XA XML XRC z800 z890 z990 zAAP zELC
virtual machine Virtual Storage Extended Visual Studio Integrator Program Variable Workload License Charges Web-based assistants Workload License Charges Workload Manager Web Services Definition Language write to operator Extended Architecture Extensible Markup Language eXtended Remote Copy zSeries 800 zSeries 890 zSeries 990 zSeries Application Assist Processor zSeries Entry License Charge
272
Index
Numerics
00C900A3 207 00C900D0 207 00C900Dx 246 -423 140 -857 33 -904 203 BLOB_FILE 18 BLOBs 1112, 34, 55, 90, 110112, 122, 128 BP40. 146 BPOOL 218 buffer pools 24, 35, 5758, 125, 146, 149, 240, 244, 247
C
Call Level Interface 81 CARDF 217218 CAST 11, 7374 CCSID 11, 19, 21, 28, 34, 5556, 86, 148, 162, 166, 174, 214, 240, 243 Character Large Objects 10 check constraints 36, 41, 62 CHECK DATA xix, 7, 125, 198, 201, 259 CHECK DATA SHRLEVEL CHANGE 204 CHECK INDEX 209 CHECK INDEX SHRLEVEL CHANGE 209 CHECK INDEX SHRLEVEL REFERENCE 209 CHECK LOB 206 CHECK LOB SHRLEVEL CHANGE 207 CHECK LOB SHRLEVEL REFERENCE 207 CHECK LOB sort 6 check pending 198 CHECK-pending 206, 209 CHKP 198 choosing a page size 58 chunk 6365, 80, 114, 119, 135, 193 chunking 144 CLI 81 CLOB 1011, 1719, 2425, 3233, 35, 56, 68, 7374, 86, 8990, 109, 111, 116, 122123, 128, 131, 138, 143, 147, 166, 173174, 216, 220, 261262 CLOB_FILE 18 codepage 149 COLNAME 215 COLTYPE 32, 216 compression 28, 35, 62, 149, 244 CONCAT 72, 75, 80, 91, 93, 123124 CONCURRENT copy 180182 COPY 48, 50, 52, 102, 105, 141, 148, 162163, 165, 168, 214215, 220221 COPY NO 31 COPYDDN 175, 179, 181182, 187, 191 COPYLASTTIME 220 COPYTOCOPY 182183 COPYUPDATEDPAGES 221 creating a LOB table space 35 creating a new table with ROWID 41 creating auxiliary table 35 creating LOBs 37 DDL statement 32 CREATOR 218 Cross Loader xix, 5, 85, 87, 96, 173174, 178
A
ABAP 128131 ABAP reports 133134 ACHKP 198, 202, 231 adding a LOB column 3839 adding a ROWID 43 Advanced Business Application Programming 128, 131 Altering table 213 APIs 20 application programming xix, 2, 109, 128 ASCII 34, 5556, 86, 149, 166, 174 Automatic creation of objects xix, 6, 2426, 29, 184, 219 autorel duration 104 aux table 185 AUX WARNING state 51, 229, 233 AUXERROR 203 AUXERROR INVALIDATE 203204 AUXERROR REPORT 203204 auxiliary check pending 198199 auxiliary check pending state 202 auxiliary column 13, 40 auxiliary index 14, 2426, 2931, 3437, 40, 105, 150, 179180, 187188, 197, 218, 261262 DDL 37 auxiliary LOB table 40 auxiliary table 1215, 24, 3940, 62, 71, 7374, 85, 89, 92, 98, 107, 145, 152, 215218, 220, 254255, 261262 auxiliary warning 198 auxiliary warning state 202 AUXONLY 203 AUXTBNAME 215 AUXTBOWNER 215, 219 AUXW 48, 51, 198, 202 AVGSIZE 216217
B
backup and recovery 213 base table 1215, 24, 32, 3940, 45, 62, 71, 7374, 85, 89, 92, 9798, 145, 158, 162, 214218, 261262 base table locks 97 Binary Large Objects 10 BIT 11, 34, 41, 5556, 121, 133, 244, 256 BLOB 2, 1011, 1720, 2425, 3233, 35, 38, 62, 68, 73, 81, 109110, 116, 119, 121, 123, 128, 130131, 144, 147148, 162163, 165, 214, 216, 219220, 261262
273
cross-loader xix CS 105, 113, 137, 153 CURRENT RULES 24, 3031, 61, 114, 148 impact on CREATE and DROP 30 CURRENT RULES = STD 30 CURRENT RULES DB2 30, 61 CURRENT RULES STD 30, 61, 114 CURRENTAPPENSCHEM 21 cursor stability 113
D
data conversion 53, 55 Data length 19 data propagation 63 data sharing 61, 104105, 125, 158, 248, 250, 259 database management system xix, 95 DATASIZE 220 DB2 Connect 85, 95, 129, 137138, 143 DB2 Extender 5 DB2-generated file reference variable construct 19 DBCLOB 1011, 1719, 56, 68, 74, 86, 109, 116, 119, 121, 128, 130131, 143, 148149, 166, 173174, 216 DBCLOB_FILE 18 DBMS xix, 128, 146, 149, 151 DBNAME 218 dbsl 153 dbsl profile 141 DBSL trace 152 DBSNDB06 219 DDL 2425, 128, 141, 147149, 162, 176, 214, 255, 261262 Defective LOBs 206 deferred write threshold 246 delete 34, 45, 51, 57, 77, 99101, 113, 122123, 140, 176, 178, 187, 241, 262 deleting a LOB 50, 57, 100, 105 deleting part of a LOB 122 DFSMS 60, 180 DFSMSDSS 208 displaying LOB objects 38 Distributed 129 Distributed Data Facility 129 Double Byte Character Large Objects 10 DRDA flow optimization 242 DRDA LOB flow optimization 6 Dropping implicitly created objec 26 DSN1505I 235 DSN1COPY 212 DSN1PRNT 212 DSNACCOR 197 DSNDB06 221 DSNJU003 236 DSNT408I 33 DSNTEJ7 7 DSNTEP2 115 DSNTIAUL 7, 8586, 171172 DSNTIJMS 143 DSNTIP7 245 DSNTIPE 21 DSNU1178I 175
DSNU1218I 164 DSNU1504I 199 DSNU1505I 199 DSNU297I 197 DSNU406I 192 DSNU599I 225 DSNU743I 207 DSNUM 217 DSNZPARM 28, 30, 245 DSSIZE 2829, 31, 35, 5960, 163, 201, 215 DWQT 59, 246 Dynpro 128, 131, 139 Dynpros 131132
E
efficiency 253 encoding systems 54 Enterprise Resource Planning 127 Exclusive LOB lock 62 exclusive LOB lock 97 extenders 23, 85 EXTENTS 220 EXTENTS, 217
F
FETCH xix, 61, 104, 114, 116, 137139, 240241, 244 fetch 61, 68, 114116, 137, 139, 153, 244 FETCH CONTINUE 6, 115116, 244 File name length 19 file option variable 20 File reference variables xix, 5, 7, 10, 1819, 87, 110, 125, 162, 166, 170, 241, 243, 258 file reference variables 109 FOR BIT DATA 11 FREE LOCATOR 68, 76, 91, 94, 112, 123, 139, 157, 254255 FREESPACE 35, 193, 195, 216217 full Imag Copy 50
G
GBPCACHE 2829, 31, 35, 60, 125, 145, 148, 162163, 214215, 248 GBPCACHE SYSTEM 61, 125, 148, 163, 215, 248 GENERATED ALWAYS 38, 4043, 163, 172, 178, 214 GENERATED BY DEFAULT 24, 34, 3941, 96, 179 GRS 259
H
HIDDEN 216 Hierarchical File System 21 HISTORY SPACE 217 host variable 1619, 43, 61, 68, 73, 75, 8789, 98, 109, 111112, 124, 240241, 262 host variables 10, 18, 6869, 72, 89, 93, 109, 112, 114, 119, 140, 258 HURBA 195, 216
274
I
IAV Extenders 3 ICLI 129 ICTYPE 49 II13767 125 Image Copy 51, 175, 180, 183, 221 IMPLICIT 218 INCURSOR 178 INSERT 33, 45, 5152, 77, 8891, 94, 124125, 136, 138, 141, 232, 243, 262 insert 5, 19, 3334, 45, 51, 69, 81, 8991, 99, 101, 109, 112, 124125, 135, 138, 140142, 179, 191, 197, 242243, 254255, 262 inserting LOBs using a host-variable 88 using locators 90 intent exclusive 99 intent-share lock 98 internal resource lock manager 101 Invalid LOBs 202, 206 IRLM 62, 101102 IS xix, 2, 53, 5556, 62, 64, 85, 8990, 98, 109111, 122, 128129, 161162, 214, 240241, 261, 263 ISO-10646 55 ISOLATION (UR) 57, 99 IX 25, 38, 99101, 223, 227
J
Java 5, 81, 83, 85, 128130, 135 Java enhanced LOB 6 Java stored procedures 220 JCC driver 142143 JDBC driver 115, 129, 142144 JDBC functions 5
L
large objects xix, 14, 910, 12, 1516, 18, 5354, 58, 6162, 7273, 80, 85, 97, 109, 125, 133, 138, 219 LENGTH 5, 11, 20, 25, 3132, 34, 38, 4041, 48, 56, 58, 62, 72, 7475, 82, 8890, 102, 110112, 116, 122, 129, 133, 162, 164, 167168, 171, 216, 256 LENGTH2 41, 80, 216 LIKE 2, 11, 34, 39, 54, 57, 62, 64, 72, 7475, 128, 162, 168, 171, 214, 222, 242 list 7273, 96, 114, 121, 124, 146, 180183 list prefetch 114 LISTDEF 180183, 199 LISTDEFs 237 LOAD xix, 5, 7, 21, 23, 41, 46, 85, 87, 95, 125, 130131, 133, 167, 171173, 217, 220, 259, 262 loading a LOB column 85 LOB column 10, 1213, 15, 20, 24, 27, 29, 31, 3940, 62, 68, 7273, 85, 87, 89, 101, 109, 115, 118, 121, 128, 132, 134, 145, 157, 173, 175, 180, 215216, 218, 256 LOB data 7, 1516, 19, 31, 39, 45, 6869, 76, 85, 89, 109, 111112, 138, 146, 151153, 162, 164, 241242, 246 LOB database 7, 35 LOB indicator 14, 34, 180, 184, 198
LOB locators 10, 1618, 20, 68, 73, 76, 90, 92, 109, 114116, 136, 143, 241, 258 LOB lock 57, 7677, 9799, 113114, 254256 LOB lock serialization 99 LOB locks 97 LOB locks avoidance 6 LOB Manager 74, 114, 240, 245 LOB manipulation 122 LOB map page 6465 LOB materialization 18, 56, 91, 240244 LOB table 13, 15, 24, 3940, 97102, 125, 145146, 148, 150, 156, 214, 216217, 249 LOB table space 6, 1213, 15, 24, 27, 3940, 6264, 99102, 104, 125, 145, 150, 162, 214, 216218, 240, 242, 249 DDL statement 35 LOBFILE 172173 LOBs xix, 12, 4, 6, 1011, 15, 1718, 20, 23, 3940, 5556, 6768, 72, 85, 109, 111, 114115, 123, 127129, 161, 213214, 217, 239240, 243244 allocation 50, 59, 188 delete 123, 198199, 203 insert 45, 90, 104, 123, 141, 254 processing 81, 89, 104, 111, 247, 249 recommendations 258 update 45, 57, 62, 104, 175, 258 LOBs creation 24 LOBVALA 5, 88, 146, 245 LOBVALS 5, 88, 146, 245246 LOCATE 211 locator 76 locators 1617, 68, 73, 75, 80, 82, 87, 90, 109, 111112, 114, 122123, 135136, 139, 241242, 262 COBOL syntax 17, 20 concatenating 80 concatenation 93 materialization 79 multiple units of work 78 precompiler conversion 17, 20 types 1718 Locking DB2 9 103 DB2 V8 97 locking 57, 62, 9697, 99, 102, 113, 133, 149, 155 LOCKMAX 145, 148, 162163, 214215, 218 LOCKRULE 218 locks xix, 57, 62, 76, 78, 90, 9899, 113, 156, 158, 218, 254256 locks with DELETE 100, 107 locks with INSERT 99, 107 locks with UPDATE 101, 107 LOCKSIZE LOB 57, 145, 148, 163, 215 LOCKSIZE TABLESPACE 57, 97 LOG 218 LOGGED 213 combinations of attributes 46 logging 4546, 124125, 149, 175, 180, 187, 189, 192, 219, 250 Logical Page List 199 Longer SQL statement 6
Index
275
M
maintenance xix, 4, 125, 128129, 150 map page 5153, 6465, 105106 mass delete 99101 mass delete statements 99 materialization 16, 18, 56, 75, 79, 91, 112, 152, 240242 INSERT 241242 SELECT 241 MAXOFILR 21 MCOD 130131 MGEXTSZ 150 Missing LOBs 202 Multiple Components in One Database 130
PK29750 xvii, 195 PK44133 xvii, 196 POSSTR 11, 7273, 75, 116, 121124 PQ90263 5, 87 PQ96460 xvii, 195 PQ96956 209 PRIQTY 35, 37, 5960, 145, 162163, 187188, 201, 214215 progressive references 138, 143144 Progressive Streaming 138, 143144, 257
Q
QUIESCE 180181, 183184
R
RBDP 198 read performance 250 Real 214 Real Time Statistics 196, 213214, 220 REBUILD INDEX 200 rebuild pending 198 REBUILD-pending 206, 209 RECLENGTH 217218 record identifier 33 RECOVER-pending 206, 209 recovery pending 207 RECP 49, 207 Redbooks Web site 261, 267 Contact us xxii RELCREATED 215 Reordered Row Format 42 REORG xix, 6, 125, 150, 220, 259 REORGDELETES 220 REORGDISORGLOB 220 REORGINSERTS 220 REORGMASSDELETE 220 REORGUPDATES 220 REPAIR 210 REPORT 36, 184186, 244 REPORT TABLESPACESET 184 REPORT utility 184 resource 00000907 246 RID 33 row locking 133 ROWID 5, 11, 1315, 2426, 3033, 3941, 43, 62, 96, 146, 149, 151, 162163, 172173, 178179, 194, 214, 216 adding the column 38 assigning 33 GENERATED BY DEFAULT 39, 41, 179 ROWIDs 10 RUNSTATS 185, 216218
N
NACTIVE 220 NAME, 218 NetWeaver 128 NOT LOGGED 35, 4546, 50, 162163, 213215, 249 NOT LOGGED LOB table space 6, 47, 232, 234 NOT PADDED 148 NPAGESF 218 NULL 20, 25, 3234, 38, 4142, 73, 86, 102, 118, 137, 148, 162, 168, 214, 219
O
object-relational 2 occurrence of a string 73, 121 Online CHECK DATA 7 Online CHECK LOB 6 optimization xix, 127, 139140 ORGRATIO 150, 185, 187, 193194, 216217 Orphan LOBs 202 Out-of-synch LOBs 202
P
PADDED 148 page size 15, 2829, 40, 5859, 64, 258 pageset structure 64, 113 PARTITION 215 Partition Data Set 21 Partition Data Set Extended 21 partition-by-growth table spaces 29 partitioned base table 13, 35, 60, 180, 184, 186, 188, 191, 199, 215 partitioning 35, 41, 45 partitions 13, 1516, 41, 45, 60, 62, 197 performance xix, 4, 15, 17, 5657, 68, 72, 84, 9394, 103, 115, 127128, 130, 166, 187, 241, 244, 257 PK10278 5, 21 PK13287 22 PK22887 5, 159 PK22910 21 PK25241 5, 159 PK27029 168 PK29281 22
S
Samples for LOBs 6 SAP ABAP 131 CLI array input chaining 140
276
CLI streaming interface 136 Computing Center Management System 150 dbsl_lib profile parameter 156 DSNZPARMs 146 Integrated Call Level Interface 129 LOB INSERT performance 159 LOB UPDATE performance 159 LOB usage 128 locator access 135 measurement results 157 monitoring and tracing 152 performance measurements 152 portability 151 programming techniques for ABAP 135 programming techniques with JDBC 142 query rewrite 138 REORG 150 ROWID 146 SGEN 140 Unicode 149 SAP Cluster 130 SAP Data Dictionary 146 SAP Enterprise 130 SAP NetWeaver 2004s 130 SAP Web Application Server 128, 133 SECQTY 35, 37, 5960, 145, 162163, 187188, 201, 214215 SELECT SUBSTR 113 sequential files 21 Shared LOB lock 62 SHRLEVEL 125, 150, 179182, 259 SHRLEVEL options 180 side 81 single LOB DELETE 100 singleton 45, 258 singleton delete 100 S-LOB 57, 76, 97, 99103, 105, 113114 S-LOB lock 57, 62, 76, 9899, 101102, 104, 108, 113114 space map pages 45, 50, 64, 107, 198, 248 SPACEF 217218 SPACEF, 218 spanning pages 15 SPUFI 115 SQL accounting 251 SQL stored procedures 6, 75 SQLCODE - 904 203 SQLCODE -104 21 SQLCODE -171 18 SQLCODE -747 34 SQLCODE -763 46 SQLCODE -766 71 SQLCODE -767 37 SQLCODE -803 39 SQLCODE -904 51, 60, 246 SQLCODE-452 178 SQLSTATE 560A1 46 STAR 245, 259 STATSDELETES 220 STATSINSERTS 220
STATSMASSDELETE 220 STATSUPDATES 220 STATUS 25, 38, 4849, 74, 175, 180, 187188, 191, 193, 218, 223 values X and I 218 STORES 10, 24, 36, 58, 87, 105, 175 STOSPACE 218 STYPE 49 SUBSTR 11, 7273, 75, 82, 112113, 122124 SYSIBM.SYSAUXRELS 215, 219 SYSIBM.SYSCOLUMNS 185186, 216 SYSIBM.SYSCOPY 49 SYSIBM.SYSINDEXSPACESTATS 221 SYSIBM.SYSJARCLASS_SOURCE 220 SYSIBM.SYSJARDATA 220 SYSIBM.SYSLGRNX 49 SYSIBM.SYSLOBSTATS 186, 193, 216217 SYSIBM.SYSLOBSTATS_HIST 217 SYSIBM.SYSROUTINESTEXT 220 SYSIBM.SYSSTRINGS 5556 SYSIBM.SYSTABLEPART 217218 SYSIBM.SYSTABLEPART_HIST 217 SYSIBM.SYSTABLES 34, 184, 186, 205, 208, 217218 SYSIBM.SYSTABLES_HIST 218 SYSIBM.SYSTABLESPACE 47, 218 SYSIBM.SYSTABLESPACESTATS 220 SYSIBM.XSR 220 SYSTABLEPART 186, 193, 217218
T
table space partition sizes 59 table space scans 15 TABLESTATUS 34, 218 values L and P 218 TBNAME 37, 215216, 219 TBOWNER 215 TBSBPLOB 26 TEMPLATES 180 Templates 5 Text Extender 3 The 218 TOTALROWS 220 traces 152154, 244, 253, 256 transparent ROWID 146, 149, 151 triggers 13, 62 TRUNCATE 162, 165, 171 TS 25, 38, 48, 60, 170, 223, 227 TYPE 218
U
UCS-2 55 UCS-4 55 UDFs 12, 72, 75 UDTs 12 UK03226 5 UK03227 5 UK13720 5, 167, 174 UK13721 5, 167, 174
Index
277
UK15036 5 UK15037 5 undo log records 50 UNICODE 5556, 80, 86, 148149, 166, 174 Unicode 5556, 74, 80, 128, 136, 146, 149 UNICODE support 56 UNIQUE 24, 26, 55, 148, 163, 170, 214215, 259, 261262 UNLOAD xix, 5, 21, 8586, 109111, 125, 162164, 166, 259, 262 unload parts of LOB using locators 114 unloading a LOB 109 unloading a LOB using a host variable 111 unloading an entire LOB using locators 111 UPDATE 5, 19, 34, 41, 43, 45, 48, 5153, 62, 92, 97, 101, 104105, 107, 122124, 136, 188, 198199, 203, 241, 254255, 262 user defined functions 12 user defined types 2 UTF-16 5556, 74 UTF-8 11, 5556, 74, 80 UTRW 208, 210
V
VALUE 11, 1416, 18, 28, 30, 3233, 6263, 65, 7273, 78, 8789, 109111, 122123, 166, 216, 220, 240241, 245246 VARCHAR 2, 10, 12, 3334, 37, 4143, 56, 74, 8182, 86, 133, 138, 147, 149, 162, 166167, 214, 216, 219, 258 VARGRAPHIC 2, 56, 74, 148149, 171, 258 VDWQT 59, 246 version number 36, 62, 207208, 254256 vertical deferred write threshold 246 VPSEQT 246
W
write performance 250
X
X-LOB 57, 99, 104, 107 X-LOB lock 57, 62, 97, 101, 105, 107108 XML 3, 74, 8384, 115116, 144, 147, 179, 203, 220 XML support 3 XML2CLOB 5, 74
Z
z/OS Conversion Services 56
278
Back cover