Professional Documents
Culture Documents
Paolo Bruni
Patric Becker
Michael Dewert
Bob Riehle
ibm.com/redbooks
International Technical Support Organization
June 2002
SG24-6571-00
Note: Before using this information and the product it supports, read the information in “Notices” on
page xiii.
This edition applies to Version 7 of IBM DATABASE 2 Universal Database Server for z/OS and OS/390 (DB2
UDB for z/OS and OS/390 Version 7), program number 5675-DB2.
Figures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . vii
Tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ix
Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xi
Notices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xiii
Trademarks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xiv
Summary of changes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xv
June 2002, First Edition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .xv
November 2004, First Update . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xv
Preface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xvii
The team that wrote this redbook. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xvii
Become a published author . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xviii
Comments welcome. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xix
Chapter 1. Introduction. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.1 Summary of considerations. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163
Contents v
vi Large Objects with DB2 for z/OS and OS/390
Figures
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 illustrates 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. 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 IBM's application programming interfaces.
The following terms are trademarks of International Business Machines Corporation and Lotus Development
Corporation in the United States, other countries, or both:
Lotus® Lotus Notes® Notes®
ActionMedia, LANDesk, MMX, Pentium and ProShare are trademarks of Intel Corporation in the United
States, other countries, or both.
Microsoft, Windows, Windows NT, and the Windows logo are trademarks of Microsoft Corporation in the
United States, other countries, or both.
Java and all Java-based trademarks and logos are trademarks or registered trademarks of Sun Microsystems,
Inc. in the United States, other countries, or both.
C-bus is a trademark of Corollary, Inc. in the United States, other countries, or both.
UNIX is a registered trademark of The Open Group in the United States and other countries.
SET, SET Secure Electronic Transaction, and the SET Logo are trademarks owned by SET Secure Electronic
Transaction LLC.
Other company, product, and service names may be trademarks or service marks of others.
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-6571-00
for Large Objects with DB2 for z/OS and OS/390
as created or updated on November 9, 2004.
With the incorporation of object-orientation into DB2 for z/OS and OS/390 (simply referred to
as DB2 throughout this redbook), you can define new data types and functions. Some of the
data objects you want to model may well be very large and complex. The foundation of
object-relational extension, introduced with DB2 UDB Server for OS/390 Version 6 has two
major functions. On one hand it has support for large objects (LOB); and, on the other hand it
has support for user defined functions, user defined distinct types, and triggers. These large
objects can contain pictures, images, text-documents or even movies, and can be stored
directly in the DBMS with sizes up to 2 gigabytes per object and 4,000 terabytes per LOB
column. The largest available size in DB2 before LOBs was 32 kilobytes, for data defined as a
varchar.
Normally, large objects are used and manipulated through graphical user interfaces from a
workstation. So with the implementation of LOBs we can exploit the functionalities of the DB2
family and the enterprise server capacity that DB2 for z/OS provides today. The introduction
of these new data types implies some changes in the administration processes and
programming techniques.
In this IBM Redbook we describe the new data types, and provide some useful information on
how to design and implement LOBs. We also offer examples of their use, programming
considerations, and the new processes which are necessary for administration and
maintenance.
Patric Becker is an Application Programmer with Sparkassen Informatik GmbH and Co. KG
in Germany. Since joining the company in 1997, Patric has been responsible for several, high
availability, Customer Relationship Management, DB2 and IMS applications. For DB2, he has
also assumed the role of a database administrator and he was involved in evaluating and
applying the new functions of DB2 for OS/390 Version 6 and Version 7.
Michael Dewert is a Systems Programmer with more than 12 years experience with DB2 for
OS/390. Before joining IBM Germany in 2001, Michael has worked for a consortium of
Savings Banks in Northern Germany and his responsibilities included IMS and CICS as well
as DB2. More recently he was involved in DB2 Quality Partnership Programs and his area of
expertise has been expanded to include performance tools, data sharing, disaster recovery,
and distributed platforms.
Emma Jacobs
Yvonne Lyon
Bart Steegmans
International Technical Support Organization, San Jose Center
Rich Conway
Bob Haimowitz
International Technical Support Organization, Poughkeepsie Center
Gabrielle Velez
International Technical Support Organization, Rochester Center
Chuck Bonner
Karelle Cornwell
Chris Crone
Willie Favero
Susan Malaika
Roger Miller
Akira Shibamyia
Kalpana Shyam
Dave Wang
Jane Wang
Jay Yothers
Gary Wilmot
IBM Silicon Valley Laboratory, San Jose
Ian Cook
Sarah Ellis
IBM PIC, Hursley, UK
Bernhard Baumgartner
IBM Switzerland
Toine Michielse
Independent Consultant, The Netherlands
Your efforts will help increase product acceptance and customer satisfaction. As a bonus,
you'll develop a network of contacts in IBM development labs, and increase your productivity
and marketability.
Comments welcome
Your comments are important to us!
We want our Redbooks to be as helpful as possible. Send us your comments about this or
other Redbooks in one of the following ways:
Use the online Contact us review redbook form found at:
ibm.com/redbooks
Send your comments in an Internet note to:
redbook@us.ibm.com
Mail your comments to:
IBM Corporation, International Technical Support Organization
Dept. QXXE Building 80-E2
650 Harry Road
San Jose, California 95120-6099
Preface xix
xx Large Objects with DB2 for z/OS and OS/390
1
Chapter 1. Introduction
With the incorporation of object-orientation into DB2 for OS/390, you can define new data
types and functions. Some of the data objects you want to model may well be very large and
complex. The foundation of object-relational extension, introduced with DB2 for OS/390
Version 6 is, on one hand, support for large objects (LOBs); and, on the other, support for
user defined functions (UDFs), user defined distinct types (UDTs), and triggers.
For more information on UDFs, UDTs, and triggers, please refer to DB2 for z/OS Application
Programming Topics, SG24-6300. This redbook describes the major enhancements that
affect application programming when accessing DB2 data on S/390 or z/Series platform, and,
while not dealing directly with LOBs, it includes the object-oriented extensions such as
triggers, user-defined function and user-defined distinct types, the use of temporary tables,
savepoints, and the numerous functions of the SQL language that can help you build
powerful, reliable and scalable applications, whether it be in a traditional environment or on an
e-business platform.
Large objects can contain pictures, images, text-documents or even movies, and can now be
stored directly in DB2 with sizes up to 2 GB per object and 4,000 Terabytes per LOB column.
The largest available size in DB2 before LOBs was 32 Kilobytes, for data defined as a
varchar.
Normally, large objects are used and manipulated through graphical user interfaces (GUI) via
a Workstation. So with the implementation of LOBs, we can exploit the server capacity that
DB2 for OS/390 and z/OS provides today while displaying and feeding them through a user
friendly interface.
The introduction of these new data types, with their peculiarities, in a traditional environment
has some impact on the current, established, administration processes and programming
techniques.
In this book we describe the various new data types introduced for LOBs support, and provide
useful information on how to design and use them. We offer some examples of their use,
programming considerations, and the new processes which are necessary for their
implementation, administration, and maintenance.
Client/server solution
Since you are dealing with new large objects, like text or images, it is likely that you need the
GUI capabilities of a front end workstation for presenting them. In this type of client/server
solution you may also consider the added value of DRDA connectivity for dealing with data
conversion, and the file reference variables supported by SQL when feeding data to the host
via SQL INSERTs from the distributed DB2. For this type of solution, bandwidth and the
speed of your connections become critical, and, with different platforms involved and maybe
several geographies, data conversion needs to be verified.
MVS considerations
Verify that you have adequate memory, disk space, and processor capacity before introducing
the new LOBs application. When accessing LOBs, DB2 can and will activate data spaces.
The activation of data spaces will introduce new messages at the system console and it may
influence paging, and you need to talk to your MVS system programmer and agree before
hand on the set up of the few new, but important, DB2 and MVS parameters. Before you start
implementing LOBs, you should evaluate the DSNZPARMs LOBVALA (maximum data space
size per user), and LOBVALS (maximum data space size per system), they will help you in
gauging the virtual storage utilized by the data spaces created by DB2 when dealing with
LOBs.
CURRENT RULES
The value of your CURRENT RULES special register has a major influence when you deal
with LOBs. The system default is set to DB2, unless you have specified SQLRULES STD
when binding your local plan. You need to evaluate the implication of the value specified for
this parameter because it influences the way LOBs are created and dropped. It also has an
impact on how applications can deal with LOBs when they use cursors for accessing their
values. You may also consider using the CURRENT RULES special register for temporarily
overwriting the default value specified for the plan. You need the STD DB2 option active if you
want to define objects with your own naming standards.
Impact of logging
You have the option of de-activating logging for LOBs. This makes sense for very large
objects which, when inserted or updated, may affect your system with very heavy logging. If
you plan to log all changes being made on your LOB values, check back with your database
administrator for relieving bottlenecks on DB2’s log data sets by using fast devices and
striping. On the other hand, if you do not log, you should be aware of the restrictions imposed
Chapter 1. Introduction 3
on recovery and availability of your LOBs data. Do not define objects as large to simply avoid
logging. The disadvantages for your operational data will certainly outweigh the uncertain
savings with non-logging. For instance, a full image copy taken with SHRLEVEL CHANGE
stays permanently fuzzy without the log.
Table 2-1 shows some representative sizes of various objects. These are outlined just for
comparison purposes. Overall they just give you some idea of the storage requirements of
various types of objects that you may have to deal with.
Object From To
Bank checks 30 KB 40 KB
Small image 30 KB 50 KB
Color image 20 MB 40 MB
Radiology image 40 MB 60 MB
Video 1 GB / hour -
The data types previously provided by DB2, such as VARCHAR, are not large enough to hold
this amount of data, the limit being 32 KB. LOBs support is based on the new set of data
types which were introduced with DB2 V6. With large objects support, DB2 stores and
manipulates data objects that are much larger.
Starting with V6, DB2 provides three 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.
New techniques for storing these huge amounts of data have also been created within DB2.
The three new data types allow you to store directly in DB2 tables objects in size of up to
2 GB, and 4,000 Terabytes (TB) per LOB column. Their characteristics depend on the way
they are stored in your DB2 subsystem:
Character Large Objects, called CLOBs
Binary Large Objects, called BLOBs
Double Byte Character Large Objects, called DBCLOBs
DB2 also provides new kinds of data types that are used for better storing and manipulating
LOBs:
LOB locators
ROWIDs
CLOBs
A character large object (CLOB) is a varying length string measured in bytes that can be up to
2 GB long. A CLOB is used to store large SBCS or mixed character-based data, such as
documents written with a single coded character set identifier (CCSID). A CLOB is
considered to be a character string.
BLOBs
A binary large object (BLOB) is a varying length string measured in bytes that can be up to
2 GB long. A BLOB is primarily intended to hold non-traditional data such as pictures or
images, sounds or voices, or other types of mixed-media. All these objects eventually consist
of unreadable binary data strings. When you create BLOBs, the data is stored in a LOB
column as it is passed to DB2, without any data conversion. The same rule applies when you
retrieve the data. Differently from CLOBs, the values stored in BLOB columns do not go
through conversion routines when accessed by DB2.
Another use of BLOBs is to hold data for exploitation by distinct types and user-defined
functions.
Normal character strings defined with the FOR BIT DATA option cannot be assigned a
CCSID, and the same rule applies to BLOB strings.
A BLOB contains a binary string representing binary data, a sequence of bytes, normally
being unreadable. Common character strings defined FOR BIT DATA, which may be used for
similar purposes, are not compatible with data type BLOB. However, the CAST specification
can be used to cast a character string to a binary string.
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,824 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 like Japanese (extended Katakana or Katakana-Kanji),
Korean, or Chinese (simplified or traditional).
You can consider locators roughly as cursors that reference remote data. Locators, and the
structures associated to them, are contained in virtual storage blocks allocated by DB2 in the
DBM1 address space. The LOB data referenced by the locators is allocated by DB2 in data
spaces which are dynamically created for the duration the request.
Application DB2
1 GB BOOK_TEXT
SELECT BOOK_TEXT
INTO :BOOK_TEXT_LOCATOR
FROM BOOK_BASE_TABLE
WHERE BOOK_NO = :HV_BOOK_NO
987654321
987654321
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 will soon lead you to the conclusion that it is a good idea for
the applications to use them, since 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 definition of a LOB locator depends on the language you choose for developing programs
for LOBs usage. The syntax for defining LOB locators in COBOL is shown in Example 2-1.
The DB2 precompiler converts the locator structure into the COBOL structure as reported in
Example 2-2.
The locator 4-byte value is then stored in a host variable; the program, as already shown in
Figure 2-1, can use it to refer to a LOB value. Even if every LOB locator shows up identical for
all definitions of host variables, DB2 knows the associated LOB type and will 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 on LOB locators refer to 4.2, “LOB locators” on page 46.
LOB data is contained in a LOB column which is conceptually part of the base table, but it is
physically stored in a separate table. Because it is not part of the base table, it is called LOB
table or auxiliary table. The auxiliary table resides in a separate LOB table space.
A base table may 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 row’s ROWID value.The auxiliary index, whose key is based
on the ROWID, is used to navigate to LOB data associated with the row.
More information about ROWIDs is reported in 4.6, “Details about ROWID” on page 68.
CCSID
273
CCSID
850
CCSID
500
Figure 3-1 Mixed client /server environment with different data types
One area where this sort of environment exists is in data centers of multinational companies.
Another example is e-commerce. 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 its languages. Even for a single language like English, no
single encoding was adequate for all the letters, punctuation, and technical symbols in
common use.
These encoding systems also conflict with one another. That is, two encoding schemes can
use the same number for two different characters, or use different numbers for the same
character.
As we mentioned in 2.3, “The new data types” on page 8, a LOB is a string data element just
like the more familiar string data elements, such as CHAR or VARCHAR, except that a large
object may be as much as 2 GB long. The three new data types that are used to identify large
objects are CLOBs, BLOBs, and DBCLOBs.
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.
For encoding and decoding, DB2 uses the table SYSIBM.SYSSTRINGS for conversion to and
from CCSIDs. This has not changed from the past releases of DB2.
Within DB2 V7 there is Unicode support. This also requires OS/390 Version 2.8 or above.
Example 3-2 gives an idea of the impact using Unicode.
France
United States
Germany
China
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.
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 does not use the table SYSIBM.SYSSTRINGS for conversion
to and from UNICODE CCSIDs. Instead DB2 uses OS/390 Conversion Services, a feature
shipped with OS/390 Version 2 Release 8, to manage all the conversions to and from
UNICODE CCSIDs.
Setting up the new UNICODE support using OS/390 Conversion Services needs some
planning and investigation before you enable it. Appendix B, “Unicode implementation” on
page 147 provides an example of how to set it up.
Vala Valb
Valc Vald
Picture
2
Each LOB column in a base table requires its own LOB table space, so LOB columns are also
separated from other LOB columns belonging to the same base table. It is important to
understand that a page never contains values of two LOB columns. For a pictorial view of the
different LOB columns and its associated LOB table spaces see Figure 3-4.
LO B Table Space 2
Auxiliary
B ase Table Space
Table
M ovie
B ase Table 1
Col 1 C ol 2 LO B C ol 1 LO B C ol 2
LO B Table Space 1
Auxiliary
Picture Table
1
Picture
2
Figure 3-4 Base table with two LOB columns and the two associated LOB table spaces
Vala Valb
Movie
Valc Vald 2
Picture
2
Vale Valf
Movie
Valg Valh 4
Picture
4
The table where the rows of a LOB column live, and which is embedded in the LOB table
space, is called an auxiliary table (aux table). The LOB column itself is referred to as an
auxiliary column, because it is not stored in the base table. The rows in the base table are
associated to the LOB columns residing in the auxiliary table in the LOB table space using the
ROWID. For further information about ROWIDs, see 4.6, “Details about ROWID” on page 68.
In order to quickly locate the proper LOB value in the auxiliary table, an auxiliary index must
be created on the auxiliary table. This index includes the ROWID. Additionally a LOB indicator
is also stored in the base table. You can find more information about this indicator in “A few
more details on the base table” on page 20. See Figure 3-6 for a summary picture of all the
objects mentioned here and how they work together.
Base Table
LOB Col 1
Col 1 Col 2 LOB Col 1
Flags
ABCDEFG... Picture 1
1234567... Picture 2
Row ID
Auxiliary Table
Auxiliary
Index
Figure 3-6 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 objects 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 they would reside in the same table as the non-LOB
columns. DB2’s Data Manager (DM) only handles column-sizes up to 32 KB. For this purpose
a new LOB Manager (LOBM) was introduced in DB2 V6.
Based on the nature of LOBs, they can be larger than the biggest available page size (32 KB
in DB2 V6 and V7) which is also valid for LOB table spaces. Therefore a single LOB value can
span pages. For further information on storing LOBs, see 4.4.1, “Storage of LOBs” on
page 60.
Because each data set of a LOB table space may grow up to 64 GB, and there may 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. As the number of partitions can grow up to 254 in the base table,
there will be 254 single LOB table spaces, each holding up to 16 TB of data as a maximum
size. This gives a grand total of 254 x 16 TB = 4,064 TB available for a single column of LOB
data.
Note: The table space containing the base table has to be in the same database as every
associated LOB table space.
As an example, we create a base table containing information about a book, storing the book
itself as a CLOB, and the image of the book cover as a BLOB.
The base table is created with the DDL statement reported in Example 3-1.
For CLOBs you can also specify the parameters FOR SCBS, MIXED or BIT DATA. A CCSID
EBCDIC or ASCII may 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.
Sizes of LOBs can be assigned in kilobytes (K), megabytes (M) or even gigabytes (G). For
syntax on CREATE TABLE statements regarding LOBs, refer to DB2 UDB for OS/390 and
z/OS Version 7 SQL Reference, SC26-9944.
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 a new data type and 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.
More information on ROWIDs is reported in 4.6, “Details about ROWID” on page 68.
In the table definitions of the new data types CLOB (500 MB) and BLOB (1 MB) in
Example 3-1 on page 20, DB2 will implicitly put two LOB indicators into the base table
definition. Only indicator columns are stored in the base table in place of the actual LOB
columns.
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. They are made up of 2-bytes flag and 2-bytes 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. Another 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 is true. Figure 3-7 illustrates the catalog
information for the created table.
Catalog description
CHAR (10) CHAR (32) ROWID (17) CLOB (4) BLOB (4)
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 on
possible mismatches, see 6.2.8, “CHECK LOB” on page 104.
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.
Note: You cannot access the base table via SQL until all dependent objects (LOB table
space, auxiliary table, and the auxiliary index) are defined.
If the CURRENT RULES special register is set to STD, DB2 creates the dependent objects by
itself during the processing of the base table DDL. The naming of the automatically created
objects are determined by DB2’s default algorithms. We talk about CURRENT RULES in 3.3,
“The CURRENT RULES special register” on page 31. You can use the REPORT utility to find
out which names DB2 has assigned to your auxiliary objects, but you can also have a look at
the catalog as usual. For more information about the REPORT utility, see 6.2.5, “REPORT
TABLESPACESET” on page 99.
Both LOB table spaces can be created using the sample statement shown in Example 3-2.
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 space (for instance the generic LARGE table space).
Specifying 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 4.4.1, “Storage of LOBs” on page 60.
Specifying LOG YES for a LOB table space tells DB2 to log almost all data manipulations on
LOB columns stored in the associated LOB table space, except delete operations. When you
delete a LOB value, no LOB data is written to the log, only LOB system pages are written to
the log data sets, because a LOB delete internally is translated into only de-allocation of the
pages where the LOB is stored. The de-allocation of a LOB is flagged in the space map
pages for all pages containing the LOB information, including the LOB map pages. For more
information about the structure of a LOB table space, refer to 4.4.1, “Storage of LOBs” on
page 60.
When you insert a LOB, DB2 writes the entire LOB value to the log. The entire LOB is also
written to the log even when you update a LOB value, because updates consist of one
singleton delete (where DB2 does not write data in the log) and one insert into the auxiliary
table.
Depending on the size of your LOBs and the frequency you regularly insert or update them,
the data to be logged may grow rapidly. When you plan to use LOG YES, make sure that
writing the redo logs will not become a critical factor!
To prevent your system from the probable bottleneck caused by logging large LOB data, DB2
allows you to turn off logging for large objects. LOG NO simply tells your DB2 subsystem to
suppress writing redo logs for every LOB column in your LOB table space. The force at
commit protocol ensures that LOB values persist after a unit of work is committed, because
LOG NO LOB values are written at COMMIT. LOB data associated with a LOB table space
defined with LOG YES is written to disk as usual for other data when buffer pool thresholds
are reached.
If you specify LOG YES for a LOB table space where the LOB size exceeds 1 GB, DB2 issues
SQLCODE -355 when creating the auxiliary table. This indicates that a LOB column is too
large to be logged. Keep in mind that LOG YES is the default value when you create your
LOB table space without specifying the LOG clause.
Note: LOBs larger than 1 GB cannot be logged. Changes to the base table are not affected
by specifying the LOG clause on the LOB table space.
You can find a detailed description of LOG impact between LOG YES and LOG NO in 7.3.1,
“Logging with LOBs” on page 128. For information about the logging impact when running the
Load utility, see 6.2.1, “LOAD” on page 94.
Because of allocation and de-allocation of data pages, no UNDO logs are written for LOBs,
regardless what LOG parameter you use.
Header pages, space map pages, and the new LOB map pages (see “LOB table space
organization” on page 61) are logged even if LOG NO is specified. They are backed out using
the same procedure used for other types of table spaces. The same rule applies if an
application terminates abnormally after changing the database. Even in this case, those
changes made in the current unit of work are backed out along with all other changes, too.
If LOG NO is specified, DB2 does not log any changes applied to any LOBs in the associated
LOB table space. Therefore recovery of LOB table spaces can be more difficult than
recovering any other table space. Let us assume the scenario depicted in Figure 3-8.
Vala Valb
Valc Vald
Picture
2
Figure 3-8 Applying changes to a LOB table space created with LOG NO
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 one
more 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 LOG NO option. 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. The next important log point is deleting LOB number two.
DB2 knows from the logged system pages what has happened and marks the pages formerly
used by LOB number two as available. The next point on the log brings us to a LOB update.
Since UPDATE consists of DELETE and INSERT, the pages are deallocated in the LOB table
space and for not having a log 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. Trying to access an invalid LOB value results in SQLCODE -904. For more
information on recovery scenarios, see 6.2.13, “RECOVERY” on page 109.
With DB2 V6 and V7, the LOG NO clause can be provided for LOB table spaces, but no other
types of table spaces support this option.
There is no support for Uncommitted Read (UR) on LOBs. Assuming LOCKSIZE LOB,
selecting a LOB acquires an S-LOB lock on the accessed LOB, even if you use ISOLATION
(UR) in a package or WITH UR in your SQL statement. This is because of the new table
space format where physical correctness has to be guaranteed while retrieving the LOB
value, which may be spanned over many pages. Acquiring S-LOB locks prevents the
application from retrieving only partial LOB data.
Deleting a LOB also requests an S-LOB lock on a specific LOB. But how does this work with
other transactions selecting the same LOB? A transaction can delete a LOB that another
transaction is reading at the same time, but the space is not reused until all readers of the
LOB have committed their work.
Inserting a LOB acquires an X-LOB lock on the new LOB, the lock is released at COMMIT as
usual. If a single LOB is locked by an X-LOB lock, no readers can access them before it is
committed.
As every LOB lock is like a row lock, the number of acquired locks can increase dramatically,
especially when mass-updates occur on LOBs, or many LOBs are inserted via subselect.
You can find more details about locking for LOBs in 4.5, “Locking” on page 62.
Choosing a page size is the common trade-off between minimizing the number of getpages,
which simply maximizes performance, and not wasting space. Because one data page in a
LOB table space never stores data of more than one LOB value, the space not used by the
LOB value in the last page remains unused. To estimate a good average size of a LOB value,
use the formula:
Size of a LOB = (Average length of all LOBs) * 1.1
Use the rule-of-thumb shown in Table 3-1 to choose a page size that minimizes the number of
getpages.
ALS ≤ 4 KB 4 KB
4 KB < ALS ≤ 8 KB 8 KB
8 KB < ALS ≤ 16 KB 16 KB
16 KB < ALS 32 KB
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.
If your LOB data is all the same size, it may be easier to choose a page size that makes more
efficient use of data pages without impacting performance. For LOBs that have all the same
size, consider Table 3-2, which maximizes space savings without sacrificing performance.
Table 3-2 Choosing a LOB page size for LOBs all of the same size
LOB size (LS) Recommended page size for LOB table space
LS ≤ 4 KB 4 KB
4 KB < LS ≤ 8 KB 8 KB
8 KB < LS ≤ 12 KB 4 KB
12 KB < LS ≤ 16 KB 16 KB
16 KB < LS ≤ 24 KB 8 KB
24 KB < LS ≤ 32 KB 32 KB
32 KB < LS ≤ 48 KB 16 KB
48 KB < LS 32 KB
Also see buffer pool considerations and buffer pool thresholds (DWQT and VDWQT) in 7.2,
“Buffer pools and group buffer pools” on page 125 for more detailed information on this topic.
If you have decided 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-3
provides information of the minimum space requirements for primary (PRIQTY) and
secondary (SECQTY) quantity and how they may change from your specification.
Table 3-4 summarizes the partition and partitioned table space sizes for the current DB2
versions.
Table 3-4 Summary of data set, partition, and partitioned table space sizes
DB2 Version Number of partitions Maximum size each Total maximum size
Note: ** Requires DSSIZE and DFSMS/MVS 1.5 and SMS-managed table space
Up to DB2 V4 the total maximum size of a partitioned table space was 64 GB. Starting with
DB2 V5, with the introduction of the LARGE parameter at creation time, partitioned table
spaces may have a total size of 1,016 GB, corresponding to up to 254 partitions each with a
data set size of 4 GB. DB2 V6 introduced the DSSIZE parameter to replace LARGE, and in
combination with the extended addressability function of SMS managed VSAM data sets, can
extend the data set size to 64 GB.
Since each LOB table space may 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 254 partitions, these 16,256 GB can occur up to
254 times (one LOB table space for each partition of the base table), so you can have
4,129,024 GB or 4,129 TB for one single LOB column.
The default value passed to DB2, if DSSIZE is not specified, is 4 GB per data set. 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 you can specify is at least
4,194,304 KB. So make sure that your 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.
Starting with DFSMS Version 1 Release 4, 254 extends are supported. 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 will issue SQLCODE -904.
GBPCACHE parameter
A new 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.
See 7.2, “Buffer pools and group buffer pools” on page 125 for more information.
The DDL for creating an auxiliary table in a LOB table space is shown in Example 3-3.
This statement creates the auxiliary table BLOB_AUX_TABLE_1 in the LOB table space
created in 3.2.3, “Creating the LOB table spaces” on page 22. 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, new with Version 6, DB2 is told 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 will be 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-4
shows sample DDL for creating the auxiliary table.
Example 3-4 DDL for an auxiliary table containing data of one base table partition
CREATE AUXILIARY TABLE BLOB_AUX_TABLE_1
IN LOBDB.BLOBATS1
STORES BOOK_BASE_TABLE
COLUMN BOOK_COVER
PART n;
The PART clause indicates which partition’s BOOK_COVER column you want to store in this
auxiliary table, where n is the number of the partition.
A U X ID A U X VA L U E AUXVER
VA R C H A R (1 7 ) B L O B (4 ) S M A L L IN T (2 )
L E N G T H 2 = 1 ,04 8,57 6
As you can see, 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 will issue SQLCODE
-767, missing or invalid column specification for an index. Figure 3-10 shows the key columns
of an auxiliary index.
AUXVER SMALLINT
Auxiliary Index
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 will automatically be defined as a unique index, fed by a
ROWID from the base table. The buffer pool you may want to assign to this index does not
need any special considerations, because the index only contains two relatively small
columns.
Before a LOB column can be added, we have to be sure that a column of data type ROWID is
already in the table. If it is not, we have to add it using the statement reported in Example 3-7.
A table can only have one ROWID column and you cannot add a ROWID column to a created
temporary table.
We recommend that ROWIDs are always generated by using DB2’s 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 may happen, that
Once a column of data type ROWID is added, you can proceed with creating the LOB
column(s) using the alter table statement shown in Example 3-8.
Adding a LOB column is not allowed for created temporary tables. The same is true when
adding ROWID columns.
Instead of specifying BLOB (1M), like in this example, you can use the ALTER to define any
other possible LOB column type to DB2.
After you have added to the base table the designated LOB columns, you should continue
with the same actions shown earlier starting with 3.2.4, “Creating the auxiliary tables” on
page 28. 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.
The CURRENT RULES register influences the following activities within your system:
CREATE and DROP the auxiliary objects as LOB table space, auxiliary table, and auxiliary
index
Application development for LOBs using CURSORs
Table 3-5 LOB table space created using CURRENT RULES STD
TSNAME BUFFERPOOL LOCKSIZE LOG CLOSE
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 less than five characters, DB2 adds underscore characters to the name
to pad it to a length of five characters.
4,194,304 12 / 12 0 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 chosen, you have to create the objects on your own.
If you have created the auxiliary objects by yourself, only the auxiliary table and the auxiliary
index are dropped when you either drop the base table space or the base table. The LOB
table space remains in your system.
Although a CURRENT RULES special register set to STD gives you more flexibility to let your
application program switch between both methods, you can get better performance if you use
a value of DB2 in distributed environments. When you use the STD option, the server has to
send and receive network messages for each FETCH to indicate whether the data being
transferred is a LOB locator or a LOB value. With the DB2 option, the server knows the size of
the LOB data after the first FETCH, so an extra message about the LOB data size is
unnecessary. The server can send multiple blocks of data to the requester at one time, which
reduces the total time for data transfer.
Using the STD option, DB2 cannot make any assumptions about what the requesting
application may want on the next fetch.
If you are going to use the LOAD utility to load a base table, consider that the maximum row
size of a row being loaded cannot exceed 32 KB. Every LOB data type (BLOB, CLOB and
DBCLOB) in the input data set has to be preceded by its length in a 4-byte binary field. The
length field does not include itself, only the length of the LOB data to be loaded. The length
field must start at the column given as start-position in the LOAD statement.
For CLOB columns you can also specify MIXED when it contains mixed SBCS and DBCS
data. If you specify MIXED, then any required CCSID conversions use the mixed CCSID for
the input data, otherwise any conversions will use the SBCS CCSID for the input data. For
further information regarding data conversions, see 3.1, “Data conversion” on page 14.
The LOAD statement may look like the one reported in Example 3-9 for loading a base table
containing a simple CLOB column.
If your base table is partitioned, you need to add the PART n clause to the LOAD statement.
For more information on the LOG clause, see 6.2.1, “LOAD” on page 94 and specifically
Table 6-1 on page 95.
Since the maximum record length of a data set is 32,760, this is not a very likely way to feed
your LOBs in the database, especially if there is more than one LOB column in your base
table.
IF NOT EOF-INPUT
MOVE LENGTH OF INPUTRECORD TO LENGTH
MOVE INPUTRECORD TO HV-LOB-DATA (HV-LOB-LENGTH + 1:LENGTH)
ADD LENGTH TO HV-LOB-LENGTH
END-IF
END-PERFORM
The definition of a host variable, large enough to contain an entire LOB value, is reported in
Example 3-11. 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.
Using this syntax, DB2 generates the definition reported in Example 3-12 for your application
program.
Example 3-12 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 31 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 you are
allowed to acquire, regarding your JCL and your system. You must acquire buffers large
enough to store your LOBs. This may be difficult for very large LOBs. For an example, IBM
COBOL for OS/390 and VM 2.2.1 supports up to 16,777,215 bytes (16 MB minus one byte)
for one item in the WORKING-STORAGE SECTION or in the LINKAGE-SECTION. Because
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 — this is DB2’s job. From the application programmer’s point of view there is
only one table containing all the columns being used for LOB processing. The statement
shown in Example 3-13 is a possible way for inserting your LOB data.
Example 3-13 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)
END-EXEC
It is recommended that an application commits after completing the unit of work while
inserting a LOB, because COMMIT releases X-LOB locks taken during insert and frees
allocated storage in the data space used by the LOB. A sample program showing how to
insert a LOB using one host variable is included in the SAMPLE1.TXT file described in
Appendix D, “Additional material” on page 155. You can find more information on inserting
LOB values and DB2 data spaces in “INSERT” on page 122.
This method is one of the fastest to feed your LOBs, because SQL does not have to be
invoked many times. 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, please refer to the section “Inserting LOBs using locators” on page 36.
Example 3-14 Pseudo-code inserting LOBs > 32 KB with one locator chain
Definitions:
Pseudo-Code:
MOVE 0 TO HV-LOB-LENGTH
EXEC SQL
SET :LOB-LOCATOR-1 = ‘’
END-EXEC
IF NOT EOF-INPUT
PERFORM BUILD-HOST-VARIABLE
END-IF
END-DO
PERFORM FINAL-INSERT
:BUILD-HOST-VARIABLE
MOVE LENGTH OF INPUTRECORD TO LENGTH
MOVE INPUTRECORD TO HV-LOB-DATA (HV-LOB-LENGTH + 1:LENGTH)
ADD LENGTH TO HV-LOB-LENGTH
MOVE 0 TO HV-LOB-LENGTH
MOVE SPACE TO HV-LOB-DATA
END-IF
: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
: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
At the top of Example 3-14 you can find the declaration of a CLOB host variable. In this case
the size is 1 MB because we assume 1 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 1 MB CLOB host variable. After the host variable is nearly filled
up (CURRENT-SIZE > 1000000, the correct value depends on the possible length of your
If the host variable is filled with some data even after an end-of-file condition was 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 for providing the needed host variable for
the LOB value.
Attention should be paid to the FREE LOCATOR statement. If you do not FREE the used
locators, DB2 will tend to keep them around in buffers allocated out of the DBM1 address
space where the locators reside, and this may cause problems in already virtual storage
constrained 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 the data space containing the data referenced by the locator. Unless the LOCATOR has
been defined with HOLD, an SQLCOMMIT will also free the locator as well as the related and
allocated entry in LOB data space. If you do not free the locators after using them, the storage
will remain allocated until COMMIT. If you are trying to insert really large LOBs, your
application could fail for having reached the limit of virtual storage set for the allocated data
space, or the DBM1 address space could reach its limit because of heavy usage of storage
caused by the storage structures associated with active locators.
Make sure to issue the FREE LOCATOR statement for each append within the concatenation
loop as well, this decreases an internal 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 for you to 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 would be 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. The
exclusive lock on the base table probably prevents 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 SAMPLE2.TXT file described in Appendix D, “Additional
material” on page 155.
Each time a concatenation is added to the chain, the entire chain is interrogated via
recursion. Let us consider the chains we build using the concatenation technique as
secondary chains. See Figure 3-11 for a better understanding of what happens in a data
space when you use the appending mechanism as mentioned above.
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, but you may
probably run into this situation.
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 3-12 for a visualization of
primary and secondary chains.
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
locator does not satisfy your performance requirements after a large number of
concatenations for a secondary chain.
The pseudo-code reported in Example 3-15 shows you how to perform the same insert as
above including a technique dealing with primary and secondary chains.
Example 3-15 Pseudo-code inserting LOBs > 32 KB with multiple locator chains
Definitions:
Pseudo-Code:
:APPEND-LOCATOR
ADD 1 TO APPEND-LOCATOR-COUNTER
EXEC SQL
SET :LOB-LOCATOR-1 = CONCAT (:LOB-LOCATOR-1, :HV-LOB)
END-EXEC
MOVE 0 TO APPEND-LOCATOR-COUNTER
END-IF
: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, :HV-LOB-LOCATOR-1)
END-EXEC
EXEC SQL
FREE LOCATOR :LOB-LOCATOR-1,:LOB-LOCATOR-2
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 1 GB 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 good programming practice to free both locators after the final insert statement in order to
release the virtual storage allocated out of the data 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 data space.
Before you start coding your application, consider that every invocation of SQL takes a certain
amount of time. So try to keep SQL calls at 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 allocations issues if you do not
free your locators.
A sample program showing how to insert a LOB using a 10 MB host variable and two locator
chains is included in the SAMPLE3.TXT file described in Appendix D, “Additional material” on
page 155.
In general, LOBs can be referenced in all the string functions with the exception of those that
relate to date and time. LOBs have the same set of restrictions as other long strings. Some
functions cannot be used on LOB columns for obvious reasons. You cannot use the following
functions on LOB columns:
GROUP BY clause
HAVING clause
ORDER BY clause
SELECT DISTINCT clause
Column function
Datetime function
DECIMAL or NULLIF function
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.
In the following sections we discuss the most important of the functions listed above.
An SQL statement without any data access like this one uses about 7,500 machine
instructions more than the same MOVE statement without any SQL invocation. The amount
of data being moved is nearly the same, so you can assume the mentioned overhead for
concatenating variables using SQL compared to a MOVE statement.
IFNULL is identical to the COALESCE and VALUE functions, except that IFNULL is limited to
two arguments instead of multiple arguments. Because a NULL indicator is one of the two
stored flags in the base table, DB2 does not need to access the auxiliary table at all, if a LOB
column is stored as a null value.
You could expect that the statement returns you all the LOB values which start with ‘IBM
Redbook’. Because large objects are subject to long string column restrictions, DB2 issues
SQLCODE -134, complaining about an improper use of a long string column. To solve this
problem, you can replace the statement using the following syntax:
This statement delivers the result you could have expected when you issued the first
statement.
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.
In general, after issuing an SQL statement against the base table, all base table columns
appearing in the WHERE clause of your statement are checked before a condition on the
auxiliary table is checked, even if the columns in the base table are not indexed. This avoids
unnecessary scans of your LOB values and only those LOB values are scanned which
already have qualified from the base table point of view.
Once a locator is set to a particular LOB value, there is no action you can take within the data
base to change that value from the application’s 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. When you assign a locator to a specific LOB value, an S-LOB lock (see 4.5,
“Locking” on page 62 for a description of LOB locks) is acquired on the LOB value, and it is
only released at COMMIT or when you explicitly free the locator. 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 will release the S-LOB lock taken on the LOB value in the auxiliary table.
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 to 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 de-allocates 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 on how a LOB is updated: Updating a LOB consists of DELETE
and INSERT, so the pages are de-allocated again and the data still remains in the auxiliary
table.
The INSERT statement cannot use the de-allocated pages because of the S-LOB lock on the
LOB value acquired by the former issued SELECT statement into the LOB locator.
The conclusion is that these data pages where a locator is pointing to cannot be allocated
again, even if they are going to be de-allocated by a DELETE statement, as long as an S-LOB
lock persists on the referenced LOB value.
EXEC SQL
HOLD LOCATOR :HV-LOCATOR-1, :HV-LOCATOR-2
END-EXEC
EXEC SQL
FREE LOCATOR :HV-LOCATOR-1, :HV-LOCATOR-2
END-EXEC
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 will be 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
will not be held.
You cannot use any of the locators mentioned above in mathematical operations. The reason
is due to the need of preventing the locators from being corrupted by the application.
The same statement can also be issued even if LOB1 and LOB2 are referenced by locators.
You are also able to use other LOB functions for further reference in an expression.
Regarding this implementation, DB2 for OS/390 and z/OS provides you with the opportunity
to build new locators using other locators and expressions of LOBs or locators. This gives you
the flexibility to deal with large objects in various scenarios without allocating huge amounts
of storage when you deal with LOBs.
The new value of both strings, now a total 20 MB, is assigned to the new locator LOCATOR-3
where you can now refer to. 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 like SUBSTR.
You can determine the end of the chapter you want to deal with in the same way using the
POSSTR function. In our example the position of the beginning of Chapter 9:
EXEC SQL
SET :END-POSITION = POSSTR (:LOB-LOCATOR, ‘Chapter 9’)
END-EXEC
After issuing this statement, the locator END-LOCATOR points to the beginning of Chapter 9.
When your application wants to deal with Chapter 8 directly, you can set the content of the
chapter to a host variable being large enough to contain the entire text for Chapter 8.
Otherwise simply set the string containing Chapter 8 to a new LOB locator as shown below:
EXEC SQL
SET :CHAPTER-8-LOCATOR = SUBSTR (:LOB-LOCATOR
,:START-POSITION
,:END-POSITION - START-POSITION)
END-EXEC
The SUBSTR function uses the LOB locator (instead of the whole LOB value) as a
string-expression, the START-POSITION represents a starting-position and the expression
END-POSITION - START-POSITION is provided as a length value.
Note: Try to avoid the use of string expressions (such as SUBSTR) of BLOB values,
because binary documents may not be usable in parts, such as pictures, executable files
or even movies. The use of parts for further processing depends on the type of data you
store in your LOB columns.
Pseudo-Code:
EXEC SQL
SELECT LOB
INTO :LOB-LOCATOR-1
FROM BASE_TABLE
WHERE KEYCOL1 = :HV-KEYCOL1
END-EXEC
EXEC SQL
SET :START-POSITION = POSSTR (:LOB-LOCATOR-1, ‘Chapter 8’)
END-EXEC
EXEC SQL
SET :END-POSITION = POSSTR (:LOB-LOCATOR-1, ‘Chapter 9’)
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
the SAMPLE6.TXT file described in Appendix D, “Additional material” on page 155.
You can easily compare updating a part of a LOB with deleting a part of a LOB as shown in
case one, except that the new locator is set up in a different way.
After determining the start and end position of your update, the only difference to
Example 4-2 is the changed assignment of LOCATOR-2.
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 a certain 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 SAMPLE7.TXT file described in Appendix D, “Additional material” on page 155.
In this example the NEW-TEXT variable can also be a host variable or another LOB locator.
Pseudo-Code:
EXEC SQL
SELECT LOB
INTO :HV-LOB
FROM BASE_TABLE
WHERE KEYCOL1 = :HV-KEYCOL1
END-EXEC
PERFORM WRITE-DATA
:WRITE-DATA
MOVE 1 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 you are allowed to acquire. If you are not able to acquire a host variable of
the size of your maximum LOB value, you can use locators for unloading your data as
ontinued in Case 2.
A sample program showing how to unload a LOB using a host variable is included in the
SAMPLE4.TXT file described in Appendix D, “Additional material” on page 155.
Pseudo-Code:
EXEC SQL
SELECT LENGTH(LOB), LOB
INTO :CURRENT-LENGTH, :LOB-LOCATOR-1
FROM BASE_TABLE
WHERE KEYCOL1 = :HV-KEYCOL1
END-EXEC
PERFORM WRITE-DATA
END-PERFORM
PERFORM WRITE-DATA
END-IF
EXEC SQL
FREE LOCATOR :LOB-LOCATOR-1
END-EXEC
A sample program showing how to unload a LOB using a host variable of 1 MB and locators is
included in the SAMPLE5.TXT file described in Appendix D, “Additional material” on
page 155.
The variable AMOUNT-FULL-SUBSTR tells your program how often it has to perform the
SUBSTR to retrieve a part of the LOB value of 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 one.
This example for retrieving your LOB data avoids materialization of the LOB, because DB2
knows where the parts you want to retrieve via the SUBSTR function are stored. Therefore,
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 4.4.1, “Storage of LOBs” on page 60.
Figure 4-2 shows you how a delete can affect your unit of work when you do not use a locator
technique to freeze a LOB value from your application’s view, or 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).
T1 T2
Figure 4-2 Accessing a LOB without a locator reference using ISOLATION (CS)
As you can see, every SELECT SUBSTR acquires an S-LOB lock for the time 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.
T1 T2
SELECT LOB INTO :LOB-LOCATOR S-LOB Lock
WHERE KEYCOL = Vala
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.
EXEC SQL
SET :POS = POSSTR (SUBSTR (:LOB-LOCATOR, :POS-START), :SEARCH-STRING)
END-EXEC
The first POSSTR statement returns as usual the first search string position in the LOB value
‘hiding’ behind a LOB locator.
Note: You always LOAD the data into the base table and DB2 will automatically store the
LOB data in the associated auxiliary table.
These new types of locks are also acquired via 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. For a more
detailed description on locking for large objects and lock sequences, see 4.5, “Locking” on
page 62.
Compression
DB2 does not allow you to specify COMPRESS YES for LOB table spaces. Most objects
stored in a BLOB column are already compressed anyway, like 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 row’s
content in a table.
Replication is not supported for DB2 Extenders for Text, Audio, Video and Image or other
extenders where additional control files associated with the extender’s LOB column data are
maintained outside of the database.
For further details on DpropR replicating LOBs, refer to DB2 UDB Replication Guide and
Reference Version 7, SC26-9920.
. 16
. 28
. . . .
4 24
3 23
2 11 22 11
1 11 01 21 11 01
11 01 10 11 01 10
1001101011 01 10 11 01 10 11
10 01101011
01011001 10 11 00 10 11 00
01 011001
011001 11 00 01 1001 11 00
.
. .
. 00 00
. .
.
. . .
. .
. 64
. .
52 86
51 85
50 11 84 11
49 11 01 83 11 01
11 01 10 11 01 10
1001101011 01 10 11 1001101011 01 10 11
01011001 10 11 00 01011001 10 11 00
011001 11 00 011001 11 00
. 00 . . 00
. . . .
. .
Figure 4-4 LOB value spanned over pages using chunks and non-chunks
As in every other table space, a LOB table space has only one header page. The header
page contains DB2 internal control information which is needed when you access your LOB
data. The new type of pages are LOB space map pages. They are structured like a multi level
index (an index containing several levels of leaf pages and are basically pointers to chunks
and pages. You can find at least one LOB map page for every version of every single LOB
value in your LOB table space. When we talk about de-allocation of LOB pages, the space
map pages have set the invalid flag for all pages containing the LOB information, which
includes both LOB map pages and LOB data pages.
LOB map pages contain descriptive information about LOB values, the chunk information
itself is stored in LOB map pages, which point to the associated data pages for a LOB value.
After reading the information stored in the LOB map pages, DB2 knows where to find the
information it has to retrieve to access a particular LOB value. See Figure 4-5 for a possible
LOB map page information about a single value.
Chunk 104 16
Chunk 410 16
Page 602 8
Page 664 3
16
} 106
105
9
104
. .
. } 505
504
LOB Data Page 503
.
. .
Figure 4-5 LOB data pages chunked together via space map and LOB map pages
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 4-4). 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.
Note: When using DSN1PRNT, you may also see pages referring to LOB values that have
been already deleted and whose space was not reused up to now.
4.5 Locking
Locking considerations for LOBs are different from normal locking techniques for other DB2
objects. Because a single LOB can grow up to 2 GB and therefore it’s data is spanned over
many pages, a new mechanism was introduced to ensure row consistency and data integrity
while users are accessing LOB values. This is done using a combination of base table locks
and the new LOB-locks, which were introduced in DB2 V6.
For the following examples and explanations we assume LOCKSIZE ANY. If you specify other
lock sizes in your environment, the locked objects may differ.
There is no locking for untouched LOBs, because a data page cannot contain values of more
than one single LOB value. But if you look at lock escalation mechanisms or if you explicitly
specify LOCKSIZE TABLESPACE, you can find more locks than the number accessed by
your application. Lock on LOB values are only escalated to the table space level, because
there is only one table in each LOB table space which can be ignored for locking purposes.
See Figure 4-6.
escalation
Auxiliary Table
LOB lock
For this access to the base table, an intent-share (IS) lock is needed on the table space
containing the base table, on the base table itself and a share (S) lock on the page accessed
while retrieving or validating the rows of the base table. After the particular LOB is located, a
IS-lock on the LOB table space and a single S-LOB lock is acquired on the LOB value to
ensure row consistency. The lock is held by DB2 until the whole value is delivered to your host
variable, so that no updating transactions can interfere with your application and the LOB will
not disappear while your application is reading it. Figure 4-7 gives you an idea of how DB2
serializes locks when accessing a single LOB value.
The numbers indicated in the figures in this section reflect the sequence in which the locks
are taken.
Using lock avoidance or uncommitted read does not lock the accessed row in the base table
while you are retrieving the LOB value. In this case, the part of a ‘logical row’ (containing the
entry in the base table and the associated LOB value) which resides in the base table can be
updated by concurrent transactions while you retrieve the associated LOB value.
Page: LO B:
S (3) 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.
LOB:
S (3)
Page: LOB:
X (5) X (4)
Page: LOB:
X (3) S (5)
After establishing the usual IX locks on the base table space and the base table, 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 internally means de-allocating 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 S-LOB lock exists for
a LOB value, the de-allocation is done after all other locks acquired by readers (see 4.5.1,
“Locks with simple reads” on page 63 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.
Old New
Changes on base table rows are logged as usual, only indicator column changes are logged
with the base table log record.
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 purposes of moving data.
The recommended usage is GENERATED ALWAYS.
As mentioned above, you have to create a unique index on the ROWID column when you
specify GENERATED BY DEFAULT.
Make sure that there is no way to use the GENERATED ALWAYS clause before implementing
GENERATED BY DEFAULT, because the additional index on a table may increase your
response time for inserting and deleting transactions on the base table. The index is not
affected by an UPDATE statement since 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.
Attention: 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 can not be assigned to ROWID columns.
EDITPROCs, FIELDPROCs and CHECK CONSTRAINTs are not provided 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.
To give you a better understanding of the different occurrences of a ROWID consider the
following scenarios:
Now you insert a row into the CUSTOMER table, as shown in Example 4-9, without providing
the ROWID column, because it will be generated by DB2 at insert time.
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 on ROWID returns the following result set, as shown in
Example 4-10.
As you can see, the generated ROWID is externalized as a 44-byte value, but stored as
VARCHAR (17).
When you use the DSN1PRNT utility, you can see the following HEX values for the above
mentioned ROWID shown in Example 4-11:
The value ‘000E’ declares the length of the ROWID column, which is currently 000E in hex
and 14 in decimal. Comparing to the information stored in the DB2 catalog that ROWIDs are
stored as VARCHAR (17) columns, there are three bytes left for future extensions of ROWIDs.
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 ROWID, you will receive a result set like the one in
Example 4-13.
Example 4-13 ROWID value of a table where a ROWID column was added
CUSTNO CUSTNAME ROW_ID
---------+---------+---------+---------+---------+---------+---------+
0000000018 ANNIKA THOMAS 40000000800001300022020100000000000201
---------+---------+---------+---------+---------+---------+---------+
As you can see, 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 will 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.
When you use DSN1PRNT again after you performed an UPDATE on the row, you will see
results similar to Example 4-14.
Example 4-14 DSN1PRNT of ROWID in hex value after adding and updating a row
000B 40000000 80000130 002202
Now the value ‘000B’ declares the length of the ROWID column, which means 11 in a decimal
value. Adding the two bytes 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 bytes 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 inserted after the ROWID column was added to the table
have a ROWID of length X’000E’. This means 14 bytes plus two additional bytes for the length
field.
The first row shown in Example 4-15 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.
In Example 4-16 you can find the DSN1PRNT output for both ROWID values:
As indicated above, the pre-existing row has a ROWID length of ‘000B’ which is 11 bytes, the
newly inserted row uses 14 bytes (‘000E’ as length field) to store the ROWID.
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 occurrences 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.
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, makes a ROWID column a good choice
for a partitioning key if you want to spread your data randomly across partitions.
Note: 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!
They can be divided into text and AVI extenders for text, audio, video, image, and XML
extenders for XML.
These extenders define new data types and functions using DB2 UDB for OS/390’s built-in
support for user defined functions (UDF) and user distinct types (UDT).
They handle new non traditional data types in advanced applications, improving application
development and reducing complexity.
SQ
S QL DB 2 Client Stream ed
Fu nctio n Data
D ata
D B2 C lient/C AE
E xten
xtendded
ed SQ
S QL AP I
C AP I
D B 2 U DB
D B Server
Static S ervers
D ata
Externally
Stored
UDT U DF S tored
Proc. M M D ata
B
Buusin ess
siness Static
D ata D ata
B LO B
MM
Bu siness
Business S earch Internally
Data
Attributes
D ata Support Stored
D ata M M Data
Data
The installation of the audio, video, image extenders involves some effort in configuring the
environment, both on the desktop, and the OS/390 platform.
5.2.1 Desktop
The desktop configuration includes the use of DB2 connect either Personal or Enterprise
edition, and the installation of the AVI extenders. After the installation, the environmental
variables must be set up through Win NT Settings-> Control Panel-> Environment Tab to
define the path which contains the multimedia files.This path is used by the extender to
retrieve and store multimedia files.
5.2.2 Database
On the mainframe, the configuration includes building a database MMDBSYS for holding the
administration tables for use by the extenders. Then binding the plans and packages used by
the extenders.
After installing the extenders, you must bind the packages through DB2 connect issuing the
following command from the CLP:
bind path/dmbmvsb3.lst grant public isolation cs
The table spaces used for storing the LOB data should be defined in the MMDBSYS
database.
Important: PTF UQ63855 for APAR PQ54511 resolves a problem on ENABLE COLUMN
encountered going through the DB2CLP Extender accessing from the workstation.
Table definitions include these UDT's as the column characteristics. Table 5-1 shows the
UDT’s used with the AVI extenders.
The DB2 Image and Audio Extenders define user-defined types (UDTs), or distinct types, and
user-defined functions (UDFs) for storing and manipulating image and audio files. By using
the DB2 support for large object types (LOBs), the extenders define the distinct data types
DB2IMAGE, DB2AUDIO,and DB2VIDEO. For each of these types, the actual contents of the
image, audio, or video file that they encapsulate can be stored as a binary large object
(BLOB) in the database table, or outside of the database in a file system. In both cases, the
contents of these distinct types are stored in an administrative support table that is
maintained by the extenders. Only a character string called a handle that represents the type
is actually stored in the user table. If the file is stored as a BLOB, it is stored in a column of an
administrative support table. If the file is stored outside of the database, a file identifier (or
pointer) to that file on the file system is stored in an administrative support table.
The UDFs will run in the MVS Workload Manager (WLM) environment that is named
DMBWLM1.
The tablespace name is the name of a table space used to store support tables and their
indexes. It must be defined in the MMDBSYS database. The external security parameter is
either:
USER: This allows each UDF to execute as if the primary authid is the owner of the
function.
Or,
DB2: This uses the internal DB2 security and it is the default.
To enable tables to use the extender functions, the UDFs, UDTs, and TRIGGERS need to be
created to administer the use of LOB columns in tables.
The extenders provide UDFs for storing these media data types. Through parameters to the
supplied functions, you specify the content of the media file, its file format, and whether to
store the file as a BLOB in the database or outside the database in the file system. The
content of a file can be a buffer or file located on the client machine from where the function is
called or a file on the file system where the database server resides.
When insert, update, and delete operations are performed on the tables defined within the
extender, triggers update various administrative support tables in response. These support
tables contain additional information about the extenders. Some of the tables identify user
tables and columns that are enabled for the Extender. Other support tables contain attribute
information about objects in enabled columns.
You use extender application programming interfaces to display images and play audio or
video objects. You code these APIs using client function calls in C. The functions are run in
the client.
Example 5-8 shows C statements which include an API that is named DBiBrowse. The API
retrieves the data for an image handle and starts a browser to display the image.
If the actual files are stored as BLOBs, they are provided the same security, concurrency, and
integrity constraints as any other type of data inside the control of DB2. Users must have the
required privilege to select, insert, or update the contents or the files, as well as the additional
metadata that the extenders store about the image or audio data. These files and their
metadata also can be backed up and recovered in the same way as any other data in DB2.
Table 5-2 shows the default UDTs and the length assignment after enabling the XML
SERVER. If the CLOB length must be expanded, you need to drop each stored procedure,
and recreate them with an increased CLOB limit.
All the XML Extender facilities supplied for application programs run in the OS/390 MVS
environment as stored procedures or user-defined functions (UDFs). User-defined types
(UDT) are data types created by a DB2 application or tool. These data types are used to
identify the storage type of XML documents in the application table. You can also store XML
documents as files on a local file system specifying a file name.
All the XML Extender's user-defined types have the qualifier DB2XML, which is the schema
name of the DB2 XML Extender user-defined types. For example:
db2xml.XMLVarchar
The XML Extender provides storage functions to be used with the XML Column storage type.
Table 5-3 shows the storage functions and the base file type associated with each.
The DB2 XML Extender provides powerful UDFs to store and retrieve XML documents in
XML columns, as well as to extract XML element or attribute values. A UDF is a function that
is defined to the database management system and can be referenced thereafter in SQL
statements.
Some of the UDFs that refer to the XMLFILE data type, require access to an HFS system.
The DB2 XML trace file, is also written to an HFS file. Table 5-4 identifies the XML Extender
storage UDFs, and their functions.
Table 5-5 identifies the XML Extender extract UDFs, their functions, and returned values.
RRS is required for XML Extender stored procedures and UDFs that run in WLM managed
address spaces.
The PTF UQ52836 is highlighted as a requirement. It upgrades XML/390 beta code to GA.
This is a must requirement.
The Administration Wizard also requires the following software on the client desktop:
DB2 UDB Connect Personal or Enterprise Edition
JAVA Development Kit 1.1.7 or higher
The initial environment for XML Extenders is now complete for OS/390 or z/OS.
With the content of your structured XML documents in a DB2 database, you can combine
structured XML information with traditional relational data. Based on the application, you can
choose whether to store entire XML documents in DB2 as in user-defined types provided for
XML data (XML data types), or you can map the XML content as base data types in relational
tables. For XML data types, the XML Extender adds the power to search rich data types of
XML element or attribute values, in addition to the structural text search that the DB2 Text
Extender for OS/390 provides.
Side tables are DB2 tables containing only a subset of the original tables, used to extract the
content of an XML document that will be searched frequently. The location path of the
element or attribute is mapped to a table and column, indexed, and used for searches. When
the XML document is updated in the application table, the values in the side tables are
automatically updated.
Figure 5-2 depicts the relationship between the XML document stored in the XML COLUMN
and the side tables created to improve search performance.
For elements or attributes in an XML document that have multiple occurrences, you must
create a separate side table for each XML element or attribute with multiple occurrences, due
to the complex structure of XML documents. This means that elements or attributes that have
multiple occurring location paths must be mapped to a table with only one column, the column
for that location path. You cannot have any other columns in the table, whether or not they
have multiple occurrences
The advantage of querying the default view is that it provides a virtual single view of the
application table and side tables.
However, the more side tables are created, the more expensive the query. Therefore, creating
the default view is only recommended when the total number of side-table columns is small.
Applications can create their own views, joining the important side table columns.
The XML Extender provides three UDTs: XMLVARCHAR, XMLCLOB, and XMLFILE.
XMLVARCHAR and XMLCLOB stores the XML document as a VARCHAR and CLOB
respectively, while XMLFILE stores the XML document as a file on a local file system.
The XML Extender allows you to store DTDs, the set of declarations for XML elements and
attributes. When a database server is enabled for XML, a DTD repository table (DTD_REF) is
created. Each row of this table represents a DTD with additional metadata information. Users
can access this table to insert their own DTDs. The DTDs are used for validating the structure
of XML documents.
You specify how structured XML documents are to be processed by the XML EXTENDER
using a document access definition (DAD) file. The DAD file is an XML-formatted document
that maps the XML document structure to a DB2 table. The DAD file specifies whether you
are storing documents using the XML COLUMN method, or defining an XML COLLECTION
for composition or decomposition.
These methods have very different uses, but can be used in the same application.
Storing whole XML documents as column data is known as the XML COLUMN method of
storage and access. Composing or decomposing the contents of XML documents with one or
more relational tables, uses the XML COLLECTION method of storage and access
XML column
This method helps you store intact XML documents in DB2. The XML column method works
well for archiving documents. The documents are inserted into columns that are enabled for
XML and can be updated, retrieved, and searched. Element and attribute data can be
mapped to DB2 tables (side tables), which can be indexed for fast search.
Figure 5-3 shows how DB2 can store a complete, tagged document in a CLOB column of a
table using the XMLCLOB data type.
In Example 5-10 below, a small C program segment with embedded SQL (SQL statements
coded within an application program) illustrates how an XML document is retrieved from a file
to memory.
Figure 5-4 shows how DB2 stores data in the XML Collection which stores separate elements
and attributes in different tables used in composing or decomposing documents.
.
DTD
The Document Type Definition (DTD) lets us define the different pieces of data we plan to
model, along with the relationships between them. The ability to include this semantic
information is the source of XML's power, and its main advantage over HTML.
DAD
One of the inputs into both storage and retrieval is the user specified mapping file that creates
the relationship between relational data and the XML document structure. This mapping file is
called a document access definition (DAD) and provides a way to produce an XML document
with the XML attributes and elements that you name as you please, and in any shape you
want.
UDTs
The XML Extender provides XML user defined types in which you define a column to hold
XML documents. Table 5-6 defines these UDTs.
UDFs
Here are a list of the UDFs in use by the XML extender for the manipulation of XML data
within the RDMS.
Storage
It stores intact XML documents in XML-enabled columns at XML data types.
Extract
It extracts XML documents, or the values specified for elements and attributes as base
data types.
Retrieval
It retrieves data to either a CLOB stored in a database or to an external server file.
Update
It updates the entire XML document or specified element and attribute values.
Security
XML Documents stored as columns in DB2 tables are afforded the same security as any
other user table column. When an administrator enables a database server for use with the
XML Extender, he can specify which type of security to use. Either SECURITY USER, which
assigns the primary ID of the process which calls the function to the XML UDF execution
environment, or SECURITY DB2 which uses the ID of the WLM to access the XML UDF
execution environment.
SECURITY DB2 requires less administration in that the you need to assign an authorization
ID, USERID, and Group ID to the WLM address spaces which run the UDFs. When you use
the SECURITY USER you must assign a USERID and Group ID for every legitimate user of
the files. In both cases you must coordinate the file system permissions with the Group and
USERIDs.
Administrative functions
The ENABLE or DISABLE SERVER command should be executed by the DB2XML userid
which has SYSADM or DBADM.
When issuing the ENABLE or DISABLE COLUMN commands the administrator must have
table owner privileges on the table which contains the column to be enabled. The
administrator also has to have privileges for table spaces and buffer pools.
When using the ENABLE COLLECTION administrative command, the administrator must
have table owner privileges on all tables in the collection and use of buffer pools and table
spaces.
In conclusion, DB2 extenders provide the functionality to make LOBs useful within your
application. By using the Extender APIs, it makes application development using these
multimedia files easier and more structured.
SYSIBM.SYSAUXRELS
The table SYSIBM.SYSAUXRELS shows you all relationships between your base tables and
their related auxiliary tables created in your system to store LOB columns. When you have a
partitioned base table space, the partition number is also indicated. The columns you can
retrieve from the table 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
AUXRELOBID, internal identifier of the relationship between base table and auxiliary table
IBMREQD, internal DB2 release dependency indicator, for internal use only
SYSIBM.SYSCOLUMNS
If there are LOB columns defined within a base table, you will find them in the catalog table
SYSIBM.SYSCOLUMNS as listed in Example 6-1.
The TBNAME specified within the SYSIBM.SYSCOLUMNS row will indicate the name of
the base table, because the LOB column is logically part of the base table.
The field COLTYPE in the table will be set to indicate the data types of BLOB, CLOB, and
DBCLOB.
The LENGTH catalog column also will be set to a value of four for all LOB columns,
because four bytes of internally defined information will be stored within each row of the
base table for every defined LOB.
The LENGTH2 column is set to the specified maximum length of the LOB column.
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 and its partitions:
CARDF, the number of LOBs
SPACEF, KB of space allocated
PQTY, 4 KB primary extent allocation
SQTY, 4 KB secondary extent allocation
DSNUM, number of linear data sets for table space
EXTENTS, total primary and secondary extents
SYSIBM.SYSTABLES
The rows contained in SYSIBM.SYSTABLES which describe the auxiliary table and the base
table are listed in Example 6-2.
RECLENGTH indicates the length of the stored record in the base table pages. It includes
the actual four bytes of internally defined information that are stored within the base table
for each defined LOB column. For the row describing an auxiliary table, the RECLENGTH
field is set to 0.
The value blank for the STATUS column indicates that the table has no parent index, and
the definition is complete. The 'X’ instead indicates that the table has a parent index and
that the table definition is complete. The value 'I’ indicates that the table definition is
incomplete. The reason the table is incomplete is defined in the TABLESTATUS column.
The TABLESTATUS contains 'L’ if the table definition is incomplete because an auxiliary
table or auxiliary index has not been defined for a LOB column. It contains 'P’ if the table
definition is incomplete because it lacks a parent index.
Both tables are related to the JAVA stored procedures implementation within DB2.
SYSIBM.SYSJARDATA has a 100 MB BLOB column for the contents of JAR files and it is the
auxiliary table for SYSIBM.SYSJAROBJECTS. The SYSIBM.SYSJARCLASS_SOURCE has
a 10 MB CLOB for the contents of the class in JAR files and it is the auxiliary table for
SYSIBM.SYSJARCONTENTS.
6.2 Utilities
In this section we discuss considerations related to LOBs when using the following utilities:
LOAD
DSNTIAUL (this is a sample program, not a utility, but often used for unloading)
UNLOAD
COPY
REPORT TABLESPACESET
RUNSTATS
REORG
CHECK LOB
CHECK DATA
CHECK INDEX
DSN1COPY
RECOVERY
6.2.1 LOAD
Because there is a limit of 32 KB for the size of the input record of the LOAD utility, you can
use it only to LOAD LOB columns of 32 KB or less.
When the input record is greater than 32 KB, you have to load the LOB data separately. See
the sample job DSN8DLPL in the SDSNSAMP DB2 distribution libraries for an example.
If you restart a LOAD job for a table with LOB columns that specified the RESUME YES
option, you must use RESTART CURRENT.
If you use RESTART PHASE to restart a LOAD job which specified RESUME NO, the LOB
table spaces and indexes on auxiliary tables will be reset.
For a table with LOB columns, you cannot restart a LOAD job that specifies the INCURSOR
option.
Indexes on the auxiliary tables are not built during the BUILD phase. Instead, LOB values are
inserted (not loaded) into auxiliary tables during the RELOAD phase as each row is loaded
into the base table, and each index on the auxiliary table is updated as part of the INSERT
operation. Because the LOAD utility inserts keys into an auxiliary index, free space within the
index may be consumed and index page splits may occur. Consider reorganizing an index on
the auxiliary table after LOAD completes to introduce free space into the index for future
INSERTs and LOADs.
LOAD allows you to specify LOG YES or NO during their execution. A LOB table space can
also be defined with LOG YES or LOG NO and this will affect logging while updating or
loading a LOB column. Table 6-1 shows the effect on logging output and LOB table space
with the possible combinations of the two parameters.
Loading LOB columns with input records that are < 32 KB works just like loading other
non-LOB columns.
Example 6-4 shows you the output from a LOAD job, loading data into a table with a CLOB
column defined. Notice that even though NOCOPYPEND was specified in the input cards, the
load job places both the base and aux table in copy pending. Notice also that the base table
had been defined in a compressed table space. This is allowed for the table space containing
the base table, but not for the LOB table space. In this specific case the compression is not of
much help because of the small number of rows and their small size. The LOB table space
was defined with LOG NO.
Example 6-4 Output for Load job inserting into table with CLOB column
DSNU000I DSNUGUTC - OUTPUT START FOR UTILITY, UTILID = POLOR3LD
DSNU050I DSNUGUTC - LOAD DATA LOG NO REPLACE INDDN SYSREC00 NOCOPYPEND
DSNU650I -DB2G DSNURWI - INTO TABLE "PAOLOR3"."CLOB_BASE_TABLE"
DSNU650I -DB2G DSNURWI - (DOCUMENT_NR POSITION(1) CHAR(10),
DSNU650I -DB2G DSNURWI - DESCRIPTION POSITION(11) CHAR(32),
DSNU650I -DB2G DSNURWI - DOCUMENT POSITION(43) CLOB)
DSNU350I -DB2G DSNURRST - EXISTING RECORDS DELETED FROM TABLESPACE
DSNU231I -DB2G DSNURBDC - DICTIONARY WITH 512 ENTRIES HAS BEEN SUCCESSFULLY BUILT FROM
21 ROWS FOR TABLESPACE PAOLOR3.CLOBBTS1
DSNU234I -DB2G DSNURWT - COMPRESSION REPORT FOR TABLE SPACE PAOLOR3.CLOBBTS1
1 KB WITHOUT COMPRESSION
1 KB WITH COMPRESSION
0 PERCENT OF THE BYTES SAVED FROM COMPRESSED DATA ROWS
6.2.2 DSNTIAUL
If you select a LOB column in a list of field specifications when unloading a table, or select a
LOB column by default (by omitting a list of field specifications), LOB data is materialized in
the output, if the definition of the field is less than or equal to (<=) 32 KB. Any column greater
than (>) 32 KB cannot be unloaded using this program. DSNTIAUL returns truncated data.
Unloading data from an image copy data set is not available for LOB columns.
DSNTIAUL works fine for unloading tables containing LOB columns with a size less than (<)
32 KB as shown in Example 6-5.
When using DSNTIAUL on LOB tables with columns > 32 KB, the output is truncated to about
32 KB. Below in Example 6-6 is the output from an unload of a LOB table with rows > 32 KB.
6.2.3 UNLOAD
The UNLOAD utility was introduced in DB2 V7. It can provide better performance, enhanced
functionality, higher availability, improved concurrency, and low cost of operation, compared to
previous methods used for unloading data.
You can use the UNLOAD utility for unloading your LOB data, but the maximum size is also
represented by the maximum record length of your output file. When you want to truncate
your data to fit in your output data set, you can use the syntax in Example 6-7.
The TRUNCATE keyword tells DB2 to truncate after the given number of bytes. If you are
dealing with BLOBs, truncation of BLOB values normally results in unusable data in the case
of images, movies or audio data. This data truncation occurs only when you explicitly specify
the TRUNCATE option, this prevents you from being unaware of possible data truncation.
If you do not specify the truncation option for your LOB data, the message reported in
Example 6-8 is issued by DB2 whenever your composite record size is greater than 32 KB.
Example 6-8 Using the UNLOAD utility on a base table with row size > 32 KB
DSNU000I DSNUGUTC - OUTPUT START FOR UTILITY, UTILID = UNLOAD
DSNU050I DSNUGUTC - UNLOAD TABLESPACE PAOLO.CLOBBTS
DSNU1218I -DB2G DSNUULIA - LOGICAL RECORD LENGTH OF OUTPUT RECORD EXCEEDED THE LIMIT FOR
TABLE PAOLO.CLOB_BASE_TABLE
DSNU012I DSNUGBAC - UTILITY EXECUTION TERMINATED, HIGHEST RETURN CODE=8
When you specify BLOB, CLOB or DBCLOB as a field type, a four byte binary length field is
placed in the output record prior to the actual data field. If your LOB column is nullable, a
NULL indicator byte is placed before the length field.
Any CCSID conversion is applied first, before the data is considered for encoding in output.
For CLOBs, no conversion is applied if the subtype is BIT. For more information on data
truncation and conversion purposes, refer to DB2 UDB for OS/390 and z/OS Version 7 Utility
Guide and Reference, SC26-9945.
The UNLOAD utility does not support full image copies of LOB table spaces in input.
6.2.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
with CONCURRENT option copies empty or unformatted allocated data pages for a LOB
table space.
You can quiesce and copy both the base table space and the LOB table space at the same
time to establish a recoverable point of consistency. Be aware that QUIESCE does not create
a recoverable point for a LOB table space that contains LOBs defined with LOG NO.
Another way is to run the COPY UTILITY for the base table space and the LOB table space in
one UTILITY control statement as listed in Example 6-9.
This will create a single RBA in SYSIBM.SYSCOPY for recovery purposes. Querying the
SYSCOPY table you get the common RBA recorded with the above image copy as shown in
Example 6-10.
If you take an inline image copy of a table with LOB columns, DB2 makes a copy of the base
table space, but does not copy the LOB table spaces.
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 if you take incremental or full image copies.
Example 6-11 REPORT TABLESPACESET with CURRENT RULES STD created LOBs
DSNU000I DSNUGUTC - OUTPUT START FOR UTILITY, UTILID = PAOLOR2
0DSNU050I DSNUGUTC - REPORT TABLESPACESET TABLESPACE PAOLO.CLOBBTS
DSNU587I -DB2G DSNUPSET - REPORT TABLESPACE SET WITH TABLESPACE PAOLO.CLOBBTS
TABLESPACE TABLE DEPENDENT TABLE INDEXSPACE INDEX
PAOLO.CLOBBTS PAOLO.CLOB_BASE_TABLE
6.2.6 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.
Only the keywords in Table 6-3 are allowed if the table space specified by the TABLESPACE
keyword is a LOB table space.
REPORT YES / NO
Note: Apply the PTF for PQ42864 to allow RUNSTATS on a LOB table space to produce
correct statistics values for FREESPACE, ORGRATIO, PERCACTIVE, and
PCTROWCOMP.
6.2.7 REORG
The REORG utility for LOB table spaces is different from the normal table space REORG
utility.
In fact a REORG of a LOB table space is not compatible with any other utility: the LOB table
space is unavailable to other applications during REORG processing.
For REORG on non-LOB table spaces you may use OFFPOSLIMIT or INDREFLIMIT catalog
query options to decide when to trigger your Reorg. If you specify the REPORTONLY option,
REORG will produce a report detailing if a REORG is recommended; a REORG will not be
performed. You cannot run REORG with the keyword REPORTONLY on a LOB table space.
While LOAD allows LOG YES or NO for LOBs, REORG requires LOG YES.
To get information on when to run a REORG on LOB table spaces you can view
SYSIBM.SYSLOBSTATS. This table contains information about how the data in the table
space is physically stored. The pertinent columns are AVGSIZE, FREESPACE, and
ORGRATIO.
Running RUNSTATS updates the SYSLOBSTATS table. If you then select from it, you get
results similar to those shown in Example 6-12.
As you can see in Figure 6-1, 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 it is expected to fit in
one chunk. If the size 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 will increase.
The small e at the bottom of a chunk in Figure 6-1 marks the end of a single LOB value.
Auxiliary index
rowid 1
rowid 2
rowid 3
rowid 4
E E E E
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 should 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 can
at least be stored in two chunks which are also used by DB2 to store it. 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
look different when you look at LOB number 4. The value behind 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.
If a LOB should fit in a number of n chunks, but n + m chunks are used to store its value, the
number of m is referred to as extra chunks.
After reorganization of the LOB space, Figure 6-2, the LOBs are placed in the optimal number
of chunks. Since there are no extra chunks allocated, the ORGRATIO is 1.0 according to the
formula shown below.
E E E E
Running REORG
Running the REORG table space utility on a LOB table space will help increase the
effectiveness of prefetch. For a LOB table space, REORG table space performs these
actions:
Removes embedded free space
Attempts to make LOB pages contiguous
Consider running REORG on the LOB table space when the value in the ORGRATIO column
of SYSLOBSTATS is 2 or higher. The value is set by running the RUNSTATS utility. After
inserting LOBs into your LOB table spaces and running the RUNSTATS utility, you may see
values in ORGRATIO like 40.00 or 100.00. This depends on the size of the LOBs, and how
many space map pages they span; small LOBs tend to show the ORGRATIO of 1. Running
the REORG utility on these LOB table spaces that have been inserted with big LOBS will
reset the value. Running the RUNSTATS utility on the ‘big’ reorged LOB table space will show
the desired 1.00.
REORG on a LOB table space will free embedded space and will attempt to make the LOB
PAGES contiguous. Reorg will not do a delete and define for the LOB table space itself. It will
not get rid of the empty data sets.
If you want to adjust the primary allocation or to get rid of secondary extents, you can use
RECOVER. That is, you change PRIQTY and SECQTY, then run RECOVER , and
RECOVER will do a delete/define. However RECOVER will not get rid of secondary data sets.
The only way to get rid of A002, A003, ... is by using an explicit drop/recreate of the object.
If you use REORG SHRLEVEL NONE on a LOB table space and the LOB Manager
determines that nothing needs to be done to the table space, no COPY pending status is set.
For LOB table spaces, an updated LOB will be written without reclaiming the old version of
the LOB immediately.
When FREESPACE approaches zero for a LOB table space, it is a good time to reclaim the
space, but there are no direct statistics indicating how much will be reclaimed. You can
calculate the percentage of free space for LOB table spaces based on the values of
FREESPACE in SYSLOBSTATS and SPACEF in SYSTABLEPART:
(FREESPACE / SPACEF) * 100
We recommend that you reorganize LOB table spaces, if the percent of free space is less
than 10%.
REORG does honor the PCTFREE and FREEPAGE values specified at CREATE
TABLESPACE time, but they do not make much sense with LOBs, and should be set to zero.
REORG will not delete and redefine the data set during reorganization of a LOB table space.
If the number of extents are a problem, they can be changed, if DB2 managed, by altering the
PRIQTY and SECQTY values, and then running RECOVER TOCOPY to delete and redefine
the data sets with the new space quantities.
Example 6-13 Trying to use REORG UNLOAD EXTERNAL on a base table row > 32 KB
DSNU000I DSNUGUTC - OUTPUT START FOR UTILITY, UTILID = REORG
DSNU050I DSNUGUTC - REORG TABLESPACE PAOLO.CLOBBTS UNLOAD EXTERNAL
DSNU297I -DB2G DSNURFTB - COMPOSITE RECORD SIZE TOO LARGE FOR PAOLO.CLOB_BASE_TABLE
DSNU012I DSNUGBAC - UTILITY EXECUTION TERMINATED, HIGHEST RETURN CODE=8
You must first recover a LOB table space that is in RECOVER-pending status before running
CHECK LOB.
If you plan to run CHECK DATA on a base table space containing at least one LOB column,
complete the following steps prior to running CHECK DATA:
If the LOB table space is in either the CHECK-pending or RECOVER-pending status, or if the
index on the auxiliary table is in REBUILD-pending status, CHECK DATA will issue an error
message and fail.
Run the CHECK LOB online utility against a LOB table space that is marked CHECK pending
(CHKP) to identify structural defects. If none is found, the CHECK LOB utility turns the CHKP
status off.
Run the CHECK LOB online utility against a LOB table space that is in auxiliary warning
(AUXW) status to identify invalid LOBs. If none exists, the CHECK LOB utility turns AUXW
status off.
Run CHECK LOB after a conditional restart or a point-in-time recovery on all table spaces
where LOB table spaces may not be synchronized.
After successful execution, CHECK LOB resets the CHECK pending (CHKP) and auxiliary
warning (AUXW) statuses.
Note: Apply PTF UQ64673 for APAR PQ46137 to eliminate several errors while
executing CHECK DATA.
If you use exception tables, the exception table for the base table must have a similar LOB
column and a LOB table space for each LOB column. If an exception is found, DB2 moves the
base table row with its LOB column to the exception table, and moves the LOB column into
the exception table's LOB table space. If you specify DELETE YES, DB2 deletes the base
table row and the LOB column.
An auxiliary table cannot be an exception table. A LOB column check error is not included in
the exception count. A row with a LOB column check error only does not participate in
exception processing.
You must complete all LOB column definitions for a base table before running CHECK DATA.
A LOB column definition is not complete until the LOB table space, auxiliary table and index
on the auxiliary table have been created. If any LOB column definition is not complete,
CHECK DATA will fail and issue error message DSNU075E.
If you terminate CHECK LOB during the CHECKLOB phase, it sets the table space to
CHECK-pending status. Otherwise, CHECK LOB resets the CHECK-pending status at the
end of the phase if no errors are detected.
You can restart a CHECK LOB utility job, but it starts from the beginning again.
Auxiliary warning (AUXW) status is set on when at least one base table LOB column has an
invalidated LOB as a result of running CHECK DATA AUXERROR INVALIDATE. An attempt to
retrieve an invalidated LOB results in a -904 SQL return code.
The RECOVER utility also sets AUXW status if it finds an invalid LOB column. Invalid LOB
columns may result from the following actions (all three must apply):
LOB table space was defined with LOG NO.
LOB table space was recovered.
LOB was updated since the last image copy.
If you run CHECK LOB, and LOB table space errors are found, the table space is placed in
CHECK-pending status.
Table 6-4 summarizes the actions for resetting the AUXW status.
Auxiliary AUXW Base table 1) Update or delete invalid LOBs through SQL 1, 2, 3
Warning space 2) Run CHECK DATA utility to verify the validity of
LOBs and reset the AUXW status.
Notes
1) A base table space or LOB table space in the AUXW status is available for processing by SQL, even though it
contains invalid LOBS However, an attempt to retrieve an invalid LOB returns a -904.
2) DB2 can access all rows of a base table space that is in the AUXW status. SQL can update the invalid LOB
column and delete base table rows, but the value of the LOB column cannot be retrieved. If DB2 attempts to
access an invalid LOB column, a -904 SQL code is returned. The AUXW status remains on the base table space
even when SQL deletes or updates the last invalid LOB column
3) If CHECK DATA AUXERROR REPORT encounters only invalid LOB columns and no other LOB column errors,
the base table space is set to auxiliary warning status.
CHECK LOB issues message DSNU743I whenever a LOB value is invalid. The violation is
identified by:
The row ID and version number of the LOB
A reason code for the error
The page number where the error was found
You can resolve LOB violations by using the UPDATE or DELETE SQL statements to update
the LOB column or delete the row associated with the LOB (use the rowid given in message
DSNU743I).
If CHECK LOB issues either message DSNU785I or DSNU787I, it has detected a logical
inconsistency within the LOB table space. Contact IBM Support Center for assistance with
diagnosing and resolving the problem.
Auxiliary Check ACHKP Base table Run the Check Data utility with the 1)
Pending space Appropriate scope option to verify
the validity of LOBS and reset
ACHKP status.
Notes
1) A base table space in the ACHKP status is unavailable for processing by SQL.
To run this utility, the privilege set of this process must include one of the following authorities:
STATS privilege for the database
DBADM, DBCTRL, or DBMAINT authority for the database
SYSCTRL or SYSADM authority
6.2.11 DSN1COPY
The standalone utility DSN1COPY works on LOB table spaces just as with other types, with
the exception that, when working with LOB table spaces, the parm field LOB must be
specified.
LOB specifies that the SYSUT1 data set is a LOB table space. Empty pages in the table
space are copied, but no error messages are issued. You cannot specify the SEGMENT and
INLCOPY options with the LOB parameter.
DB2 attempts to determine if the input data set is a LOB data set. If you specify the LOB
option but the data set is not a LOB data set, or if you omit the LOB option but the data set is
a LOB data set, DB2 issues an error message and terminates.
Example 6-14 shows the error you receive when not using the LOB parameter for a LOB table
space.
We used DSN1COPY to restore data to a different base and auxiliary table from a full image
copy data set. The JCL for the LOB table space DSN1COPY restore is reported in
Example 6-15.
Example 6-15 JCL for DSN1COPY OBIDXLAT for LOB table space
//PH01S01 EXEC PGM=DSN1COPY,
// PARM=('FULLCOPY,RESET,LOB,32K,OBIDXLAT')
//STEPLIB DD DSN=DB2G7.SDSNLOAD,DISP=SHR
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSUT1 DD DSN=PAOLOR3.IMAGE.CLOBATS1.IC0322,DISP=OLD
//SYSUT2 DD DSN=DB2V710G.DSNDBC.PAOLOR3.CLOBATS2.I0001.A001,DISP=OLD
//SYSXLAT DD *
307 307
5 14
6 15
***********************************************************************************
DSN1COPY IS PROCESSED WITH THE FOLLOWING OPTIONS:
NO CHECK/NO PRINT/32K/FULLCOPY /NON-SEGMENT/NUMPARTS = 0/ OBIDXLAT/NO VALUE/
RESET/ /LOB/PIECESIZ= /
DSSIZE=
INPUT DSNAME = PAOLOR3.IMAGE.CLOBATS1.IC0322 , SEQ
6.2.12 REPAIR
When dealing with LOBs, the LOCATE table space statement locates data to be repaired
within a table space.
When you specify LOCATE ROWID for a LOB table space, with the delete option, the LOB
specified by ROWID is deleted with its index entry. All pages occupied by the LOB are
converted to free space. The DELETE statement will not remove any reference to the deleted
LOB from 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.
With ROWID X'byte-string' you can specify that the data to be located is a LOB in a LOB table
space. The byte-string is the row ID that identifies the LOB column.
The most likely source of a row ID is an orphaned LOB that is reported by the CHECK LOB
utility. If you specify the ROWID keyword, the specified table space must be a LOB table
space.
With VERSION X'byte-string' you can specify that the data to be located is a LOB in a LOB
table space. The byte-string is the version number that identifies the version of the LOB
column.
The most likely source of a version number is an orphaned LOB that is reported by the
CHECK LOB utility, or an out-of-synch LOB that is reported by the CHECK DATA utility. If you
specify the VERSION keyword, the specified table space must be a LOB table space.
6.2.13 RECOVERY
In some ways, planning for LOB recovery is similar to that for user defined referential integrity
since you have to remember that there is a relationship between a table with a LOB column
and the associated LOB table space. It is true that tables involved in referential integrity
relationships must be considered as part of the same table space set for recovery purposes.
Similarly, a LOB table space and its associated base table space are part of a table space set.
That set, too, is reported using REPORT table space.
Thus, if the LOB table space was defined with LOG NO, any log records written for the LOB
table space between its last image copy and the recover-to-point means the AUX WARNING
will be turned on. Then you have to run the CHECK LOB utility to find any invalid LOBs. For
more details see 6.3, “Recovery scenario” on page 111.
In general
You should quiesce and copy both the base table space and the LOB table space at the same
time to establish a recoverable point of consistency. Be aware that QUIESCE does not create
a recoverable point for a LOB table space that contain LOBs defined with LOG NO.
The RECOVER utility sets AUXW status if it finds an invalid LOB column. Invalid LOB
columns may result from the following actions (all three must apply):
LOB table space was defined with LOG NO
LOB table space was recovered
LOB was updated since the last image copy
LOB table space Current RBA or LRSN, none none AUXW (1)
LOB table space
defined with LOG(NO)
LOB table space TOCOPY, copy was CHKP RBDP CHKP, AUXW
taken with
SHARELEVEL
CHANGE
Note: (1) If at any time a log record is applied to a LOB table space that results in a LOB being marked invalid,
the LOB table space is set to AUXILIARY Warning Status.
LO B Table Space:
C LO B AT S
R ow ID LO B Value
A B C D E F G ... Picture 1
Picture 2
1234567...
R ow ID
LO B Table
A uxiliary
C L O B _ A U X _TA B LE
In d ex:
CL O B A IX
Row ID LO B Value
Gone
Row ID
LOB Table
Auxiliary
CLOB_A UX_TABLE
Index:
C LO BAIX
Figure 6-4 Recovering the auxiliary table with full image copy
The recover has left the base table and index at a different point in time, compared to the
auxiliary table. Because of the special relationship of base and auxiliary table, the row entries
are now more on the base table and the auxiliary index than in the aux table, since inserts
have occurred. A display on our database, after recovering the LOB table space, shows the
status reported in Example 6-16.
Example 6-16 Display database after recovery, using last full image copy
DSNT360I -DB2G ***********************************
DSNT361I -DB2G * DISPLAY DATABASE SUMMARY
* GLOBAL
DSNT360I -DB2G ***********************************
DSNT362I -DB2G DATABASE = PAOLO STATUS = RW
DBD LENGTH = 16142
DSNT397I -DB2G
NAME TYPE PART STATUS PHYERRLO PHYERRHI CATALOG PIECE
-------- ---- ---- ------------------ -------- -------- -------- -----
CLOBATS LS RW
CLOBBTS TS RW,ACHKP,COPY
CLOBAIX IX RW,RBDP
******* DISPLAY OF DATABASE PAOLO ENDED **********************
The display also gives us the information that the table space (CLOBBTS) is in aux check
pending (ACHKP). This requests to run CHECK DATA on the auxiliary table. It also shows
that the entire auxiliary index is in rebuild pending status (RBDP).
LO B Table Space:
C LO B ATS
R ow ID LOB Value
Row ID
LO B Table
Rebuild A uxiliary
C LOB _A UX _TA B LE
Index:
index utility C LO B AIX
After successfully running the rebuild index utility, the DISPLAY DATABASE command gives
us the status information listed in Example 6-17.
After running the Check Data utility, the status of the base table space (CLOBBTS) has
changed from ACHKP,COPY to COPY,AUXW, as listed in Example 6-19. The CHECK DATA
also gives us the information we need to clean up the base table row that still was pointing to
an invalid LOB.
ABCDEFG... Picture 1
Row ID
LOB Table
Auxiliary CLOB_AUX_TABLE
Index:
CLOBAIX
This is done by using normal SQL, pointing to the invalid ROWID in the SQL where clause
and the statement look like:
DELETE FROM BASE_TABLE
WHERE ROW_ID = ROWID(X'41C48DDCC1CED26F260401D37018010000000000032D’)
..
FIC FIC
R ow ID LOB Value
R ow ID
LOB Table
Auxiliary
CLOB_AUX_TA BLE
Index:
CLOBAIX
Another means is through the use of the DB2 Extenders, which use UDFs to accomplish the
insert.
The extender model uses DRDA to connect workstations to the mainframe through a normal
n-tier architecture.
When using DB2 Connect PE, it is built in the normal 2- tier approach. This may be desirable
if the environment has native TCP/IP support available, and an intermediate server is not
desirable.
When using DB2 connect in the EE configuration, it is a normal 3-tier architecture which
connect LAN based workstations to the mainframe host databases. Some good uses for this
are when the host system doesn't support native TCP/IP and needs support for JAVA
APPLETS, or supporting workstations on platforms where PE cannot exist (UNIX).
The Unlimited edition of EE avoids the necessity of counting users which must happen when
using EE. It is an MSU based licensing model, which lends itself well to Web based
applications.
Backup considerations
Data administration with LOBs is challenging, especially when you have to deal with LOG NO
definitions on your LOB table spaces. DB2’s recovery process is built on log data sets by
definition, but using large objects allows you to turn off logging mechanisms or even forces
you to turn them off when you use them in a size bigger than 1 GB.
Backing up a high availability scenario having a LOG YES LOB table space can be compared
with copying and recovering referential integrity tables from the logical point of view, except
the amount of data is probably much higher for a single table space.
When your scenario requests high availability and you have to specify LOG NO for the LOB
table space for whatever reasons and it is not necessary to apply updates during the day on
your LOBs, you can consider collecting your LOB updates during the day and process them in
your batch window. When you take a full image copy of your base table space and the LOB
table space after your batch job is done, you are prepared again for the day. This helps you
minimizing outage times during the day when you have to recover a LOG NO LOB table
space.
Where the LOB is materialized depends on the way the LOB data is retrieved. In general,
because LOB values can be very large, DB2 will do the utmost to try to avoid the DB2
materialization of LOB data until it is absolutely necessary. DB2 will materialize the LOB in the
following different cases:
When your application calls a user-defined function with a LOB as an argument
When it moves a LOB into or out of a stored procedure
When it assigns a LOB host variable to a LOB locator host variable
When it converts a LOB from one CCSID to another
With or without the use of a locator, retrieving a LOB value will always go through the buffer
pools associated with the LOB table space. Basically, from the DB2 point of view, if a LOB
needs to be materialized in storage, it will be placed in a data space.
The amount of storage used in data spaces for LOB materialization depends upon a number
of factors. They include the size of the LOB, the number of LOBs in a statement that need to
be materialized, and the use of cursors to hold position in an application. Figure 7-1 provides
an overview of the materialization process.
DB2 DDF
Address Data Spaces
Space
User
Address Space
Buffer Manager
Data Manager
LOB Manager
Disk environment
SELECT
First we assume you have two applications that will 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. However,
let us say we have application A using a LOCATOR and application B not using a LOCATOR,
but rather a host variable. From the point of view of DB2 LOB materialization, application A
and application B will not materialize the LOB in DB2 data spaces when they only select a
LOB value. See Figure 7-2.
User
A d d re s s S p a c e
D B 2 D B M 1 A d d re s s
B Space
L o c a l B u ffe r P o o l
U ser
A d d re s s S p a c e
A
Buffer Manager
LOB Manager
Data Manager
D is k e n v iro n m e n t
As you can see in these cases, application B may require the complete LOB data. Therefore
the private user address space may require, based on the size of the LOB, a huge amount of
storage within its user address space. Application A uses a locator and may just use the
space it needs for the chunks of data pointed to through the defined locator.
INSERT
Assume a scenario where your application A and B INSERT into your LOB table space. From
the point of view of materialization, it will show a different picture. Now there are data spaces
involved. The materialization in DB2 data spaces will occur if you are using LOCATORs, and it
will not if you do not use them. Still, not using LOCATORS, like in application B, will cause you
to use more storage in your private user address space and again depending on the size of
your LOB, this could be quite storage consuming. See Figure 7-3.
.
Data Spaces
User
Address Space
DB2 DBM1 Address
Space
A Local Buffer Pool
User
Address Space
B
Buffer Manager
Data Manager
LOB Manager
Disk environment
If your application will INSERT LOB values via the network (this implicates the use of DB2’s
DDF address space), or it will use a STORED PROCEDURE, or converts from one CCSID to
another, LOB materialization will occur in a DB2 data space.
As mentioned, LOBs are stored in data spaces for various situations. Again this will appear
when a LOB is a parameter of a UDF, when it is needed to be converted, or when passing
LOBs in a distributed environment and also when it has to be moved into a stored procedure.
If you want to see the number of data spaces created by DB2 (for instance as a result of
materialization), you can use the MVS console command:
D A,xxxxDBM1 (xxxx = subsystem id)
As you can see in Example 7-1, the MVS console command will give you the number and the
name of the data spaces DB2 has created.
If you may want to monitor the maximum storage used for LOBs in a data space, there is the
IFCID 2 record for accounting and the IFCID 3 record for statistics. Both records contain the
field QXSTLOBV, that provides the values.
If you have activated the statistics trace with IFCID 2 and the accounting traces with IFCID 3
in your DB2 subsystem, you will find the values within DB2 PM accounting and statistics
record printout. In the report you will find the values in the miscellaneous part. The values
shown there are in kilobytes as you can see in the Example 7-2 printout.
You can find the values within DB2 PM statistics record printout. They are also pointed out in
miscellaneous. The values shown there are in megabytes as you can see in Example 7-3.
__________________________________________________________________________________
1 USER LOB VALUE STORAGE ===> 2048 Max storage per user for LOB
values in kilobytes
2 SYSTEM LOB VALUE STORAGE ===> 2048 Max storage per system for LOB
values in megabytes
3 MAXIMUM LE TOKENS ===> 20 Maximum tokens at any time. 0-50
The value LOBVALA field establishes an upper limit for the amount of storage each user
can have for storing LOB values. The value specified gives the numbers of kilobytes.
The value LOBVALS field establishes an upper limit for the amount of storage per system
that can be used for storing LOB values. The value specified gives the numbers of
megabytes.
Because these definitions can have an impact on your operating system, specifically on
paging and auxiliary storage, and depend on how heavy is the use of LOBs within your DB2
subsystem, the values of these settings should be chosen with care. Before setting the values
of these new ZPARMs, you should consult your z/OS system programmer.
Buffer pools
Depending upon how you have planned to use LOBs in your shop, you will most likely want to
put LOB data in separate buffer pools, so as to not interfere with data used by online
transactions or other work. If the LOBs have their own buffer pools, you have the capability of
setting different thresholds than with your other buffer pools, without affecting other work. For
example, you may want to set the virtual pool sequential steal threshold to 100%, taking full
advantage of the sequential access, knowing that this buffer pool is only used for LOB pages.
Also minimizing the buffer pool wide deferred write threshold (DWQT) almost to 0, this will
force to asynchronously write buffers out of the buffer pool. At the data set level, the vertical
deferred write threshold (VDWQT), will force write upon a data set level. It is expressed as a
percentage of the virtual pool size for a single data set. This value should always be less than
DWQT. In regards to dealing with LOB buffer pools, all three are worthwhile looking into. So
again, it is not only meaningful but also a good advise to have your LOB buffer pools isolated
from your other ‘normal’ buffer pools in your environment. See Figure 7-5.
BP32K1
BP3 BP32K
BP1 BP10
Buffer
DWQT
Pool
VDWQT
DWQT
VDWQT
D B 2 d a ta s h a rin g e n v iro n m e n t
G
GBBP
P CACHE ESS Y S TT E M
fo
fo rr LL O B
B
GRRO
OUUP
P BUU FF FF E R P OOO OL
ssnm DB M 1 ssnm D B M 1
B u ffe r P o o ls B u ffe r P o o ls
As mentioned GBPCACHE SYSTEM is the default for a LOB table space and we
recommended to use it. In a data sharing environment, if GBPCACHE CHANGED or
GBPCACHE ALL is used instead for a LOG NO LOB table space, then a coupling facility
failure could result in the table space being marked GRECP. Any kind of recovery of the table
space will mark the LOB values as invalid and place the table space in the AUXW state. Again
for LOB table spaces, choose GBPCACHE SYSTEM to avoid having large LOB values
overwhelm the group buffer pool. Also, for LOB table spaces with the LOG NO attribute,
GBPCACHE SYSTEM ensures that LOB values are written to DASD by commit time, thereby
avoiding possible recovery problems caused by missing log data.
Coming up with the formula, there are different values used and they have to be explained.
Starting with the Data_entries = (U * D / 10) * R: The value U is the estimated degree of data
sharing. The value D is based upon the number of data pages written to disk per second and
the value of 1/10 is the estimate of LOB system pages that are written for every LOB data
page. The value R is the average page residency time in the group buffer pool in seconds.
Note about the value D: Do not use the number of pages written to the group buffer pool
as D. Instead it must be a count of distinct pages. This value can be determined by using
field QBSTPWS from IFCID 0002. You can find it using the DB2 PM and looking into the
statistics report (PAGES WRITTEN field). This will give you the right value.
The Data(MB) = Data_entries * P / 1024: The value P is the page size (4, 8, 16, or 32)
depending on the local buffer pool page size. At last the Dir_entries = Data_entries + (U *
(HP + VP)): where HP The number of data pages defined for the hiperpool (the sum across
all the members). VP The number of data pages defined for the virtual pool (the sum across
all the data sharing members). Because the calculations are a little intricate, the following will
step through a model. Assume that you have a two-member data sharing group for which you
have determined the following information. See Example 7-5.
The above calculation indicates that the group buffer pool should be defined with an INITSIZE
of 21.2 MB. The ratio is greater than the maximum value, which is not unusual with
GBPCACHE(SYSTEM), so use the command ALTER GROUPBUFFERPOOL to change the
ratio to 255.
The measurements shown were implemented with DB2 V6 in 1999 and were included in DB2
UDB for OS/390 Version 6 Performance Topics, SG24-5351. They are shown here because
they still provide meaningful comparisons. More measurements are currently under way with
DB2 V7 and more current disk technology, the results will be included as soon as available.
There are no UNDO records for LOB updates (except for system pages, space map) even
with LOG YES. LOBs always insert the new value at a different place and delete the old one at
commit, marking the old space as free.
To give you an idea of the amount of data being written to the log, look at Example 7-6 which
shows the DSN1LOGP output for a LOB insert of a using LOG YES.
The log entries marked as bold text, occurring n times where n depends on the size of your
LOB value, represent the additional overhead for specifying LOG YES for the LOB table
space. Every LOB DATA PAGE CHANGE log entry contains data of a single LOB data page
with those values you insert into your LOB column. You have as many LOB DATA PAGE
CHANGE log entries in your log as needed for storing your LOB value.
You will not find the bold text log entries if you have created your LOB table space using LOG
NO. This means that only system pages for the LOB value are written to the log, no LOB data
is written to the log.
The amount of data to be logged can grow rapidly when you use the LOG YES clause.
Although you can manipulate LOB columns like any other data type, there are a number of
issues:
They are subject to the same restrictions as long strings. Substrings of LOBs which are
less than 256 bytes can be CAST as CHAR to avoid these restrictions.
Acquiring buffers in a program to accommodate a large LOB can be difficult.
Since LOBs are essentially long strings, you can use string functions to manipulate them and
parts of them. For example, SUBSTR(LOB,1,200) will retrieve the first 200 bytes of the LOB.
This can more easily be managed in an application program.
LOBs are inserted, selected, deleted, and updated using standard SQL, although there are
some special considerations:
A LOB locator, which is a 4-byte value stored in a host variable, can be used to reference
the LOB, and can be used wherever you would use a LOB. The locator essentially acts as
a pointer to the LOB. For full details, refer to DB2 UDB for OS/390 and z/OS Version 7
Application Programming and SQL Guide, SC26-9933.
The LOB update operation does not update in place, it performs a LOB delete followed by
an insert.
The LOB delete is a logical delete: it flags the space as available.
non-LOB 20 KB 20 KB 200 KB 2 MB
Select into :HV 0.025 0.027 0.117 0.867
(0.0006) (0.0008) (0.0023) (0.0175)
KB/sec 800.0 740.7 1,709.4 2,306.8
The 20 KB LOB table was conceptually identical to the first one except that the 20 KB
character column was defined as a CLOB. We created a LOB table space and auxiliary table
and index to support this. For our LOB table spaces, we used a 32 KB page size, so that
comparisons with the non-LOB table were reasonable.
The other two tables were defined with 200 KB and 2 MB LOBs, respectively.
When we retrieved LOB data into the host application, we repeatedly called SUBSTR to
“walk” down the entire length of the column. We used the same technique to process LOB
data with and without the use of LOB locators. Any differences in the performance of
processing LOBs can, therefore, be attributed solely to the use of locators or the processing
of LOBs into host variables.
The diagram above shows the elapsed and CPU time taken to process non-LOB and LOB
data of different lengths and shows the following results:
LOB processing is more efficient for larger LOB columns.
The time taken to process a select of 20 KB worth of LOB data into a host variable is 0.027
seconds. In other words DB2 can process 740.7 KB LOB data per second for a 20 KB
LOB column. To select a 2 MB LOB into a host variable (that is, 100 times more data) does
not take 100 times longer; rather, DB2 can process 2306.8 KB LOB data per second for a
2 MB LOB column.
These measurements lead us to recommend that you use LOB locators when selecting LOB
data.
We now look at the accounting trace output provided by DB2 PM and reported in Figure 7-8.
The values shown for DB2 Class 2 elapsed time clearly indicates which strategy to use for
your small (<32 KB) objects.
We examined the cost of an insert operation using a host variable compared with using a
LOB locator with different sized LOBs. We also measured the cost of a delete and an update.
See Figure 7-8.
NON-LOB 20 KB 20 KB 200 KB 2 MB
LOB insert
It is more expensive to process 20 KB of LOB data, even if a LOB locator is used, than
processing an equivalent volume of non-LOB data. As with select 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 resource. The relative improvement of insert efficiency with
respect to LOB size results, however, are much less dramatic than for select processing. The
reason is that the cost of preformatting disk space to accommodate the newly inserted LOB
increases with the size of the LOB and it accounts for most of the elapsed time.
LOB update
Internally 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.
IFCID 18 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.
IFCID 20 Summary of page, row and LOB locks held and lock escalation.
QW0020PL Maximum number of either page, row or LOB locks held for the
thread
QW0021K6 Row ID
IFCID 44 Records lock suspension. LOB lock type record utility start information
QW0044K6 Row ID
IFCID 58 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.
IFCID 105 Maps the internal 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.
IFCID 107 Open/close information. Also records open and close for LOB table spaces and indexes
on auxiliary tables
QW0150K6 Row ID
QW0172K6 Row ID
QW0185ST For a LOB column, this is the data type of the LOB
QW0185LE For a LOB column, this is the length of the indicator column
IFCID 196 Time-out trace. Lock types are not explicitly specified for this trace
QW0196K6 Row ID
IFCID 306 Records log records. Note that when LOG NO has been specified for a LOB table space,
log records will not be written for the value of the LOB.
COMMIT
DSNT400I SQLCODE = 000, SUCCESSFUL EXECUTION
COMMIT
DSNT400I SQLCODE = 000, SUCCESSFUL EXECUTION
COMMIT
DSNT400I SQLCODE = 000, SUCCESSFUL EXECUTION
PLANNAME: SAMPLE3
AVERAGE APPL(CL.1) DB2 (CL.2) IFI (CL.5) CLASS 3 SUSPENSIONS AVERAGE TIME AV.EVENT HIGHLIGHTS
------------ ---------- ---------- ---------- -------------------- ------------ -------- --------------------------
ELAPSED TIME 24:30.4256 3:29.97658 N/P LOCK/LATCH(DB2+IRLM) 1:28.359418 55.80 #OCCURRENCES : 5
NONNESTED 24:30.4256 3:29.97658 N/A SYNCHRON. I/O 3.145753 71.20 #ALLIEDS : 5
STORED PROC 0.000000 0.000000 N/A DATABASE I/O 3.145753 71.20 #ALLIEDS DISTRIB: 0
UDF 0.000000 0.000000 N/A LOG WRITE I/O 0.000000 0.00 #DBATS : 0
TRIGGER 0.000000 0.000000 N/A OTHER READ I/O 0.000000 0.00 #DBATS DISTRIB. : 0
OTHER WRTE I/O 0.000000 0.00 #NO PROGRAM DATA: 0
CPU TIME 4.398020 1.660921 N/P SER.TASK SWTCH 58.006180 15.20 #NORMAL TERMINAT: 0
AGENT 4.398020 1.660921 N/A UPDATE COMMIT 40.082702 1.00 #ABNORMAL TERMIN: 5
NONNESTED 4.398020 1.660921 N/P OPEN/CLOSE 0.078285 0.20 #CP/X PARALLEL. : 0
STORED PRC 0.000000 0.000000 N/A SYSLGRNG REC 0.021327 0.20 #IO PARALLELISM : 0
UDF 0.000000 0.000000 N/A EXT/DEL/DEF 17.741402 13.20 #INCREMENT. BIND: 0
TRIGGER 0.000000 0.000000 N/A OTHER SERVICE 0.082464 0.60 #COMMITS : 0
PAR.TASKS 0.000000 0.000000 N/A ARC.LOG(QUIES) 0.000000 0.00 #ROLLBACKS : 5
ARC.LOG READ 0.000000 0.00 #SVPT REQUESTS : 0
SUSPEND TIME N/A 2:29.51135 N/A STOR.PRC SCHED 0.000000 0.00 #SVPT RELEASE : 0
AGENT N/A 2:29.51135 N/A UDF SCHEDULE 0.000000 0.00 #SVPT ROLLBACK : 0
PAR.TASKS N/A 0.000000 N/A DRAIN LOCK 0.000000 0.00 MAX SQL CASC LVL: 0
CLAIM RELEASE 0.000000 0.00 UPDATE/COMMIT : 0.20
NOT ACCOUNT. N/A 58.804310 N/A PAGE LATCH 0.000000 0.00 SYNCH I/O AVG. : 0.044182
DB2 ENT/EXIT N/A 101.20 N/A NOTIFY MSGS 0.000000 0.00
EN/EX-STPROC N/A 0.00 N/A GLOBAL CONTENTION 0.000000 0.00
EN/EX-UDF N/A 0.00 N/A COMMIT PH1 WRITE I/O 0.000000 0.00
DCAPT.DESCR. N/A N/A N/P ASYNCH IXL REQUESTS 0.000000 0.00
LOG EXTRACT. N/A N/A N/P TOTAL CLASS 3 2:29.511350 142.20
GLOBAL CONTENTION L-LOCKS AVERAGE TIME AV.EVENT GLOBAL CONTENTION P-LOCKS AVERAGE TIME AV.EVENT
------------------------------------- ------------ -------- ------------------------------------- ------------ --------
L-LOCKS 0.000000 0.00 P-LOCKS 0.000000 0.00
PARENT (DB,TS,TAB,PART) 0.000000 0.00 PAGESET/PARTITION 0.000000 0.00
CHILD (PAGE,ROW) 0.000000 0.00 PAGE 0.000000 0.00
OTHER 0.000000 0.00 OTHER 0.000000 0.00
PLANNAME: SAMPLE3
SQL DML AVERAGE TOTAL SQL DCL TOTAL SQL DDL CREATE DROP ALTER LOCKING AVERAGE
-------- -------- -------- -------------- -------- ---------- ------ ------ ------ ---------------------- -------- ----
SELECT 0.00 0 LOCK TABLE 0 TABLE 0 0 0 TIMEOUTS 0.00
INSERT 0.20 1 GRANT 0 CRT TTABLE 0 N/A N/A DEADLOCKS 0.00
UPDATE 0.00 0 REVOKE 0 DCL TTABLE 0 N/A N/A ESCAL.(SHARED) 0.00
DELETE 0.00 0 SET CURR.SQLID 0 AUX TABLE 0 N/A N/A ESCAL.(EXCLUS) 0.00
SET HOST VAR. 247 INDEX 0 0 0 MAX PG/ROW LOCKS HELD 0.60
DESCRIBE 0.00 0 SET CUR.DEGREE 0 TABLESPACE 0 0 0 LOCK REQUEST 87.60
NORMAL TERM. AVERAGE TOTAL ABNORMAL TERM. TOTAL IN DOUBT TOTAL DRAIN/CLAIM AVERAGE
--------------- -------- -------- ----------------- -------- -------------- -------- -------------- -------- ----
NEW USER 0.00 0 APPL.PROGR. ABEND 5 APPL.PGM ABEND 0 DRAIN REQUESTS 0.00
DEALLOCATION 0.00 0 END OF MEMORY 0 END OF MEMORY 0 DRAIN FAILED 0.00
APPL.PROGR. END 0.00 0 RESOL.IN DOUBT 0 END OF TASK 0 CLAIM REQUESTS 1.60
RESIGNON 0.00 0 CANCEL FORCE 0 CANCEL FORCE 0 CLAIM FAILED 0.00
DBAT INACTIVE 0.00 0
RRS COMMIT 0.00 0
DATA CAPTURE AVERAGE TOTAL DATA SHARING AVERAGE TOTAL QUERY PARALLELISM AVERAGE
----------------- -------- -------- ------------------- -------- -------- ---------------------------- -------- ----
IFI CALLS MADE N/P N/P GLOBAL CONT RATE(%) N/C N/A MAXIMUM MEMBERS USED N/A
RECORDS CAPTURED N/P N/P FALSE CONT RATE(%) N/C N/A MAXIMUM DEGREE N/A
LOG RECORDS READ N/P N/P L-LOCKS XES RATE(%) N/C N/A GROUPS EXECUTED 0.00
ROWS RETURNED N/P N/P LOCK REQ - PLOCKS 0.00 0 RAN AS PLANNED 0.00
RECORDS RETURNED N/P N/P UNLOCK REQ - PLOCKS 0.00 0 RAN REDUCED 0.00
DATA DESC. RETURN N/P N/P CHANGE REQ - PLOCKS 0.00 0 ONE DB2-COORDINATOR = NO 0.00
TABLES RETURNED N/P N/P LOCK REQ - XES 0.00 0 ONE DB2-ISOLATION LEVEL 0.00
DESCRIBES N/P N/P UNLOCK REQ - XES 0.00 0 ONE DB2-DCL TEMPORARY TABLE 0.00
CHANGE REQ - XES 0.00 0 SEQUENTIAL-CURSOR 0.00
SUSPENDS - IRLM 0.00 0 SEQUENTIAL-NO ESA SORT 0.00
SUSPENDS - XES 0.00 0 SEQUENTIAL-NO BUFFER 0.00
SUSPENDS - FALSE 0.00 0 SEQUENTIAL-ENCLAVE SERVICES 0.00
INCOMPATIBLE LOCKS 0.00 0 MEMBER SKIPPED (%) N/C
NOTIFY MSGS SENT 0.00 0 DISABLED BY RLF 0.00
REFORM PARAL-CONFIG 0.00
REFORM PARAL-NO BUF 0.00
PLANNAME: SAMPLE3
STORED PROCEDURES AVERAGE TOTAL UDF AVERAGE TOTAL TRIGGERS AVERAGE TOTAL
----------------- -------- -------- --------- -------- -------- ----------------- -------- --------
CALL STATEMENTS 0.00 0 EXECUTED 0.00 0 STATEMENT TRIGGER 0.00 0
ABENDED 0.00 0 ABENDED 0.00 0 ROW TRIGGER 0.00 0
TIMED OUT 0.00 0 TIMED OUT 0.00 0 SQL ERROR OCCUR 0.00 0
REJECTED 0.00 0 REJECTED 0.00 0
LOGGING AVERAGE TOTAL ROWID AVERAGE TOTAL RID LIST AVERAGE TOTAL
------------------- -------- -------- ------------- -------- -------- ------------------- -------- --------
LOG RECORDS WRITTEN 12.60 63 DIRECT ACCESS 0.00 0 USED 0.00 0
TOT BYTES WRITTEN 7051.60 35258 INDEX USED 0.00 0 FAIL-NO STORAGE 0.00 0
TS SCAN USED 0.00 0 FAIL-LIMIT EXCEEDED 0.00 0
AVERAGE SU CLASS 1 CLASS 2 DYNAMIC SQL STMT AVERAGE TOTAL MISCELLANEOUS AVERAGE TOTAL
------------ -------------- -------------- ------------------ -------- -------- ------------------- -------- -------
CPU 50588.20 19104.60 REOPTIMIZATION 0.00 0 MAX STOR LOB VALUES 102.4K 512021
AGENT 50588.20 19104.60 NOT FOUND IN CACHE 0.00 0
NONNESTED 50588.20 19104.60 FOUND IN CACHE 0.00 0
STORED PRC 0.00 0.00 IMPLICIT PREPARES 0.00 0
UDF 0.00 0.00 PREPARES AVOIDED 0.00 0
TRIGGER 0.00 0.00 STMT INVALID (MAX) 0.00 0
PAR.TASKS 0.00 0.00 STMT INVALID (DDL) 0.00 0
PLANNAME: SAMPLE3
AVERAGE APPL(CL.1) DB2 (CL.2) IFI (CL.5) CLASS 3 SUSPENSIONS AVERAGE TIME AV.EVENT HIGHLIGHTS
------------ ---------- ---------- ---------- -------------------- ------------ -------- --------------------------
ELAPSED TIME 14:54.4918 1:35.51485 N/P LOCK/LATCH(DB2+IRLM) 40.163372 25.36 #OCCURRENCES : 11
NONNESTED 14:54.4918 1:35.51485 N/A SYNCHRON. I/O 1.429888 32.36 #ALLIEDS : 11
STORED PROC 0.000000 0.000000 N/A DATABASE I/O 1.429888 32.36 #ALLIEDS DISTRIB: 0
UDF 0.000000 0.000000 N/A LOG WRITE I/O 0.000000 0.00 #DBATS : 0
TRIGGER 0.000000 0.000000 N/A OTHER READ I/O 0.000000 0.00 #DBATS DISTRIB. : 0
OTHER WRTE I/O 0.000000 0.00 #NO PROGRAM DATA: 4
CPU TIME 2.002305 0.756192 N/P SER.TASK SWTCH 26.434087 12.73 #NORMAL TERMINAT: 6
AGENT 2.002305 0.756192 N/A UPDATE COMMIT 18.286116 1.00 #ABNORMAL TERMIN: 5
NONNESTED 2.002305 0.756192 N/P OPEN/CLOSE 0.035584 0.09 #CP/X PARALLEL. : 0
STORED PRC 0.000000 0.000000 N/A SYSLGRNG REC 0.010161 0.18 #IO PARALLELISM : 0
UDF 0.000000 0.000000 N/A EXT/DEL/DEF 8.064274 6.00 #INCREMENT. BIND: 0
TRIGGER 0.000000 0.000000 N/A OTHER SERVICE 0.037953 5.45 #COMMITS : 7
GLOBAL CONTENTION L-LOCKS AVERAGE TIME AV.EVENT GLOBAL CONTENTION P-LOCKS AVERAGE TIME AV.EVENT
------------------------------------- ------------ -------- ------------------------------------- ------------ --------
L-LOCKS 0.000000 0.00 P-LOCKS 0.000000 0.00
PARENT (DB,TS,TAB,PART) 0.000000 0.00 PAGESET/PARTITION 0.000000 0.00
CHILD (PAGE,ROW) 0.000000 0.00 PAGE 0.000000 0.00
OTHER 0.000000 0.00 OTHER 0.000000 0.00
NORMAL TERM. AVERAGE TOTAL ABNORMAL TERM. TOTAL IN DOUBT TOTAL DRAIN/CLAIM AVERAGE
--------------- -------- -------- ----------------- -------- -------------- -------- -------------- -------- ----
NEW USER 0.00 0 APPL.PROGR. ABEND 5 APPL.PGM ABEND 0 DRAIN REQUESTS 0.09
DEALLOCATION 0.55 6 END OF MEMORY 0 END OF MEMORY 0 DRAIN FAILED 0.00
APPL.PROGR. END 0.00 0 RESOL.IN DOUBT 0 END OF TASK 0 CLAIM REQUESTS 3.18
RESIGNON 0.00 0 CANCEL FORCE 0 CANCEL FORCE 0 CLAIM FAILED 0.00
DBAT INACTIVE 0.00 0
RRS COMMIT 0.00 0
DATA CAPTURE AVERAGE TOTAL DATA SHARING AVERAGE TOTAL QUERY PARALLELISM AVERAGE
----------------- -------- -------- ------------------- -------- -------- ---------------------------- -------- ----
IFI CALLS MADE N/P N/P GLOBAL CONT RATE(%) N/C N/A MAXIMUM MEMBERS USED N/A
RECORDS CAPTURED N/P N/P FALSE CONT RATE(%) N/C N/A MAXIMUM DEGREE N/A
LOG RECORDS READ N/P N/P L-LOCKS XES RATE(%) N/C N/A GROUPS EXECUTED 0.00
ROWS RETURNED N/P N/P LOCK REQ - PLOCKS 0.00 0 RAN AS PLANNED 0.00
RECORDS RETURNED N/P N/P UNLOCK REQ - PLOCKS 0.00 0 RAN REDUCED 0.00
DATA DESC. RETURN N/P N/P CHANGE REQ - PLOCKS 0.00 0 ONE DB2-COORDINATOR = NO 0.00
TABLES RETURNED N/P N/P LOCK REQ - XES 0.00 0 ONE DB2-ISOLATION LEVEL 0.00
DESCRIBES N/P N/P UNLOCK REQ - XES 0.00 0 ONE DB2-DCL TEMPORARY TABLE 0.00
CHANGE REQ - XES 0.00 0 SEQUENTIAL-CURSOR 0.00
SUSPENDS - IRLM 0.00 0 SEQUENTIAL-NO ESA SORT 0.00
SUSPENDS - XES 0.00 0 SEQUENTIAL-NO BUFFER 0.00
SUSPENDS - FALSE 0.00 0 SEQUENTIAL-ENCLAVE SERVICES 0.00
INCOMPATIBLE LOCKS 0.00 0 MEMBER SKIPPED (%) N/C
NOTIFY MSGS SENT 0.00 0 DISABLED BY RLF 0.00
REFORM PARAL-CONFIG 0.00
REFORM PARAL-NO BUF 0.00
LOGGING AVERAGE TOTAL ROWID AVERAGE TOTAL RID LIST AVERAGE TOTAL
------------------- -------- -------- ------------- -------- -------- ------------------- -------- --------
LOG RECORDS WRITTEN 13.73 151 DIRECT ACCESS 0.00 0 USED 0.00 0
TOT BYTES WRITTEN 6169.82 67868 INDEX USED 0.00 0 FAIL-NO STORAGE 0.00 0
TS SCAN USED 0.00 0 FAIL-LIMIT EXCEEDED 0.00 0
AVERAGE SU CLASS 1 CLASS 2 DYNAMIC SQL STMT AVERAGE TOTAL MISCELLANEOUS AVERAGE TOTAL
------------ -------------- -------------- ------------------ -------- -------- ------------------- -------- -------
CPU 23031.36 8697.73 REOPTIMIZATION 0.00 0 MAX STOR LOB VALUES 46547.36 512021
AGENT 23031.36 8697.73 NOT FOUND IN CACHE 0.00 0
NONNESTED 23031.36 8697.73 FOUND IN CACHE 0.00 0
STORED PRC 0.00 0.00 IMPLICIT PREPARES 0.00 0
UDF 0.00 0.00 PREPARES AVOIDED 0.00 0
TRIGGER 0.00 0.00 STMT INVALID (MAX) 0.00 0
PAR.TASKS 0.00 0.00 STMT INVALID (DDL) 0.00 0
ALL PROG VALUE ALL PROG TIMES ALL PROG AVERAGE TIME AVG.EV TIME/E
------------------ ------------------ ------------------ ------------ ------------------ ------------ ------ --------
TYPE PACKAGE ELAP-CL7 TIME-AVG 2:30.091872 LOCK/LATCH 1:03.113870 39.86 1.58
CPU TIME 1.187084 SYNCHRONOUS I/O 2.246966 50.86 0.04
LOCATION 'BLANK' AGENT 1.187084 OTHER READ I/O 0.000000 0.00
COLLECTION ID 'BLANK' PAR.TASKS 0.000000 OTHER WRITE I/O 0.000000 0.00
PROGRAM NAME ALL PROG SUSPENSION-CL8 1:46.842769 SERV.TASK SWITCH 41.481932 11.14 3.72
AGENT 1:46.842769 ARCH.LOG(QUIESCE) 0.000000 0.00
OCCURRENCES 7 PAR.TASKS 0.000000 ARCHIVE LOG READ 0.000000 0.00
SQL STMT - AVERAGE 36.14 NOT ACCOUNTED 42.062020 STORED PROC SCHED 0.000000 0.00
SQL STMT - TOTAL 253 AVG.DB2 ENTRY/EXIT 73.14 UDF SCHEDULE 0.000000 0.00
STOR PROC EXECUTED 0 DB2 ENTRY/EXIT 512 DRAIN LOCK 0.000000 0.00
The table and columns are enabled to handle AVI extenders. This is shown in Example A-1.
We tested the insert using DB2 Connect command center. The results from the connect
statement are:
Database Connection Information
Database server = DB2 OS/390 7.1.1
SQL authorization ID = PAOLOR3
Local database alias = DB2G
We issued an INSERT from a client file to a BLOB column at the host using a relative file
name. Example A-2 shows the command and the results.
-----------------------------------------------------------------------------
DB20000I The SQL command completed successfully
If you specify a relative file name, the extenders will use the directory specifications in various
client and server environment variables as a search path to resolve the file name. In our
example the path to the files stored on the Window NT workstation was setup with the
installation of the AVI extender software.
Here we show as an example only the CCSID 1140 to 367 conversion installation.
/********************************************
* INPUT STATEMENTS FOR THE IMAGE GENERATOR *
********************************************/
/*
The output of the job is shown in Example B-2. Please note that the job creates the
conversion table indirectly, since no direct conversion from 1140 to 367 is currently available.
Verify the UNICODE table activation with command D UNI,ALL. The SYSLOG output is
reported in Example B-5.
MR0322023113 Explain and If an SQL statement visually accesses the base table (when
auxiliary tables selecting a LOB column), the explain output does not show any
access to the auxiliary table nor the auxiliary index. Only the
access path for the base table is shown. This may confuse
those people who do not know that a base table and a LOB
column is accessed by the SQL statement.
MR032605920 Acceptability AUXW state after recovery - only reset by REPAIR utility and
program. Needs to optionally reset at CHECK LOB time, with
LOB values set to null. Also EXCEPTION tables like for RI
would help.
MR0322021925 REORG space REORG to do normal REORG, i.e. release space (remove
reclaim deleted objects physically).
MR0322024927 Usability POSSTR enhancement to support not just the 1st but the nth
occurrence of a string.
PQ54511 DB2 Extenders UQ63855 being prepared. It Enables AVI Extenders with
DB2 V7.
PQ46137 CHECK DATA It fixes several important problems and provides better
with LOBs messages. PTF UQ64673 is available for DB2 V7; UQ64672 for
DB2 V6.
PQ58306 LOB utilities UQ64118. It fixes errors due to inconsistent LOB data after
forward log recovery of a LOB table space defined LOG NO.
PQ59820 LOB support LOAD performance and bad page number. PTF UQ65857is
available for DB2 V7, UQ65856 is available for DB2 V6.
Note:
(1) The APAR is due to a remote possibility of loss of integrity at write time for stripes involving
pages larger than 4 KB. If you want to use striping with LOBs this restriction is not penalizing
performance and is not in contrast with the general recommendation of using 32 KB pages for
large LOBs. Our opinion, supported by the lab measurements, is that the very small penalty in
a little extra CPU time when concatenating 4 KB pages is really negligible, while I/O time re-
mains the same. So it might be worthwhile changing to 4 KB pages if you want to exploit striping,
even for large LOBs. Furthermore, a large majority of LOB users seem to have either small
LOBs or a large variation in size, therefore justifying 4 KB pages in any case.
Select the Additional materials and open the directory that corresponds with the redbook
form number, SG24-6571.
The publications listed in this section are considered particularly suitable for a more detailed
discussion of the topics covered in this redbook.
IBM Redbooks
For information on ordering these publications, see “How to get IBM Redbooks” on page 162.
DB2 for z/OS and OS/390 Version 7 Using the Utilities Suite, SG24-6289
DB2 for z/OS and OS/390 Version 7 Performance Topics, SG24-6129
DB2 UDB Server for OS/390 and z/OS Version 7 Presentation Guide, SG24-6121
DB2 UDB Server for OS/390 Version 6 Technical Update, SG24-6108
DB2 UDB for OS/390 Version 6 Performance Topics, SG24-5351
DB2 for z/OS Application Programming Topics, SG24-6300
Other resources
These publications are also relevant as further information sources:
DB2 UDB for OS/390 and z/OS Version 7 Installation Guide, GC26-9936
DB2 UDB for OS/390 and z/OS Version 7 Command Reference, SC26-9934
DB2 UDB for OS/390 and z/OS Version 7 Messages and Codes, GC26-9940
DB2 UDB for OS/390 and z/OS Version 7 Utility Guide and Reference, SC26-9945
DB2 UDB for OS/390 and z/OS Version 7 Programming Guide and Reference for Java,
SC26-9932
DB2 UDB for OS/390 and z/OS Version 7 Administration Guide, SC26-9931
DB2 UDB for OS/390 and z/OS Version 7 Application Programming and SQL Guide,
SC26-9933
DB2 UDB for OS/390 and z/OS Version 7 Release Planning Guide, SC26-9943
DB2 UDB for OS/390 and z/OS Version 7 SQL Reference, SC26-9944
DB2 UDB for OS/390 and z/OS Version 7 Text Extender Administration and Programming,
SC26-9948
DB2 UDB for OS/390 and z/OS Version 7 Data Sharing: Planning and Administration,
SC26-9935
DB2 UDB for OS/390 and z/OS Version 7 Image, Audio, and Video Extenders, SC26-9947
DB2 UDB for OS/390 and z/OS Version 7 ODBC Guide and Reference, SC26-9941
DB2 UDB for OS/390 and z/OS Version 7 XML Extender Administration and Reference,
SC26-9949
DB2 UDB for OS/390 and z/OS Version 7 Diagnosis Guide and Reference, LY37-3740
DB2 UDB Replication Guide and Reference Version 7, SC26-9920
You can also download additional materials (code samples or diskette/CD-ROM images) from
that site.
L
large objects 6–7 M
LENGTH 92 maintenance 2
LENGTH2 92 map page 61
LIKE 46 mass delete 65–66
list 58 mass delete statements 64
list prefetch 58 materialization 9, 120
LOAD 94 DELETE and UPDATE 122
LOAD utility INSERT 122
loading LOBs 34 SELECT 121
misusing LOBs 3
Index 165
unload parts of LOB using locators 57
unloading a LOB 54
unloading a LOB using a host variable 54
unloading an entire LOB using locators 55
UPDATE 24, 132
updating a specific part of a LOB 53
UQ52836 84
UQ54223 152
UQ63855 76, 152
UQ64118 153
UQ64357 153
UQ64672 152
UQ64673 105, 152
UQ65856 153
UQ65857 153
user defined functions 6
user defined types 6
USS 76
UTF-16 16
UTF-8 16
V
VALUE 45
VARCHAR 6
VARGRAPHIC 6
VDWQT 125
version number 28
vertical deferred write threshold 125
video extender 75
W
WLM Application Environment 83
write performance 132
X
X-LOB 25
X-LOB lock 59, 62
XML 7
UDFs 89
UDTs 89
XML and LOBs 84
XML collection 88
XML COLUMN 84, 86
XML Extender 81
XML EXTENDER UDFs 82
XML security 89
XML Toolkit 83
XML UDFs 81
Large Objects
with DB2 for z/OS and OS/390
Define LOBs, see how The amount of data to be managed by workstations, middleware
systems and mainframes, is growing day by day. The times are INTERNATIONAL
they work, and see
changing, and so the requirements for a database management TECHNICAL
how to store them
system (DBMS) are changing. SUPPORT
Manage LOBs in
ORGANIZATION
With the incorporation of object-orientation into DB2 for OS/390, you
operational can define new data types and functions. Some of the data objects you
environments want to model may well be very large and complex. The foundation of
object-relational extension, introduced with DB2 for OS/390 Version 6
has two major functions. One is based on support for large objects BUILDING TECHNICAL
Use LOBs in (LOB), and the other is support for user defined functions, user defined
applications and DB2 INFORMATION BASED ON
distinct types, and triggers. These large objects can contain text PRACTICAL EXPERIENCE
Extenders documents, images or even movies, and can be stored directly in the
DBMS with sizes up to 2 gigabytes per object and 4.000 terabytes per IBM Redbooks are developed
LOB column. by the IBM International
Technical Support
Normally, large objects are used and manipulated through Graphical Organization. Experts from
User Interfaces from a workstation. So with the implementation of IBM, Customers and Partners
LOBs we can exploit the functionalities of the DB2 family and the from around the world create
capacity that DB2 for z/OS provides today. The introduction of these timely technical information
new data types implies some changes in the administration processes based on realistic scenarios.
and programming techniques. Specific recommendations
are provided to help you
In this IBM Redbook we describe the new data types, and provide implement IT solutions more
some useful information on how to design and implement LOBs. We effectively in your
also offer examples of their use, programming considerations, and the environment.
new processes which are necessary for administration and
maintenance.
For more information:
ibm.com/redbooks