Introduction to DB2 9 database recovery

Recovery scenarios

A tried and tested backup and recovery strategy is essential in preventing data loss. A database can encounter any number of problems, including power interruptions, storage media failure, and application crashes. Each of these can result in a database failure and each failure requires a different recovery action. This tutorial introduces the backup and recovery capabilities in IBM® DB2® for Linux®, UNIX® and Windows®. In addition, it presents a step-by-step approach showing how to recover data in various failure scenarios.

Amol D. Barsagade (amolbarsagade@in.ibm.com), Database Consultant, IBM

Author Photo: Amol BarsagadeAmol D. Barsagade is a senior database consultant with the IBM Business Partner Technical Enablement team, and is based at the India Software Lab. Amol works with Business Partners and specializes in providing mission critical DB2 solutions for database recovery, performance tuning, migration, and application development. Amol has a bachelor's degree in computer science and has several years of experience working with other relational database systems including Oracle and SQL Server.



16 August 2007

Also available in Vietnamese

Before you start

About this tutorial

Global support organizations are based on customer service and satisfaction. As such, protecting against failures is a huge challenge for the database administrator. In production or 24 X 7 environments, where databases are mission critical, any data loss is unacceptable. Therefore, it is vital to understand the different data recovery options offered by a database management system (DBMS) as well as have a data recovery plan in place that implements them.

Objectives

This tutorial introduces various DB2 9 recovery options and covers the following topics:

  • Database logging
  • How to change the database logging mode
  • Best practices to keep database data safe
  • How to recover an entire database after a failure
  • How to recover when a table space container gets dropped or corrupted
  • How to recover a table that is dropped by accident
  • How to recover to a specific point-in-time

Database logging

DB2 databases support two different logging modes: Circular and Archival. When a new database is created, circular logging is the default. If the business need requires something more advanced, you can change the logging mode from circular to archival.

A summary of transaction logging in DB2

A transaction is a logical unit of work. Every transaction has corresponding log records that are stored in transaction log files. Every transaction has a corresponding entry in what is called the Redo Log. Redo log entries are written to the current active log file. When the active log file becomes full, it is marked as unavailable, at which point DB2 makes the next log file in the sequence the active log file and continues writing log entries into it. This cycling process is repeated as the current active log file becomes full. When transactions are completed (a COMMIT or ROLLBACK statement is issued), the corresponding log entries are released, since they are no longer needed to recover the database.

DB2 always tries to write log entries into the set of primary log files, that is, the log files that are automatically allocated at database activation time. If a situation arises where a transaction has consumed all the primary log files (all primary log files are marked as unavailable), then the database manager allocates a secondary log file. As soon as that file becomes full, the database manager checks the primary log files again to see if their status is unavailable. If so, another secondary log file is allocated and entries are written into it. This process continues until all the secondary log files are allocated and filled. If there is no primary log file available for writing redo entries, and the maximum number of secondary log files have already been allocated, then an application receives the following error message:

SQL0964C The transaction log for the database is full.

Hopefully you ever encounter this error. However, if you do, you should increase the number of primary and secondary log files (or their size) as needed. Ideally, the primary log files should be large or numerous enough to contain the largest transaction. Allocating secondary log files is costly since it is done at runtime, so you should minimize the number of secondary log files that need to be allocated during your peak workload period. To update the number of primary or secondary log files, you can issue the following commands:

  • UPDATE DB CFG FOR db_name USING LOGPRIMARY value
  • UPDATE DB CFG FOR db_name USING LOGSECOND value

Note: If this problem occurs, you should investigate why the entire log space is filled. It might be due to a runaway query or a user mistake, so increasing the number or size of log files may only mask the problem. For example, suppose a user issues a DELETE FROM tab1 statement and TAB1 is a very large table. While this statement looks very innocent, one delete log record is generated per row, which can easily fill the log space if it is not configured to handle it.

Circular logging

When circular logging mode is in effect, transaction data is written to the primary log files in a circular fashion. When all the records stored in an individual log file are no longer needed for recovery, that log file is treated as being reusable and it can become the active log file again in the future. This means that in circular logging, a log file's contents are eventually overwritten by new log entries. Since the contents of log files are overwritten, you can only recover a database up to the last full database backup. You cannot perform point-in-time recovery with circular logging.

Archival logging

As with circular logging mode, redo log entries are written to the primary log files. However, unlike circular logging, these log files are never reused. When all records stored in an individual log file are no longer needed for recovery, that log file is marked as being inactive rather than as being reusable. This means that its contents are never overwritten. When the first primary log file becomes full, a new primary log file is allocated so that the configured number of primary log files (the LOGPRIMARY database parameter) are always available.

All log entries related to a single transaction must fit within the active log space. In the case that a long running transaction requires more log space than can be provided in the primary log files, secondary log files may be allocated and used. In archival logging mode, you can recover a database up to a specific point in time by using a combination of database backup images and log files. This process is described in more detail later.

How to change the logging mode

When a new DB2 database is created, circular logging is the default mode. If you want to change the mode from circular to archival, you can perform the following steps:

  1. Create a folder on a disk (such as e:\db_name\archive) where there is sufficient disk space to store archived log files. As a best practice, keep your archived log file destination separate from the active log file destination.
  2. Terminate the connection to the database:

    • TERMINATE
  3. Update the archived log file destination. (Specifying a path for archived log files has the effect of turning the archival logging mode on).

    • UPDATE DB CFG FOR db_name USING LOGARCHMETH1 "Disk:e:\db_name\archive"
  4. Reconnect to the database:

    • CONNECT TO db_name
  5. The connection fails and you get following error message:

    SQL1116N A connection to or activation of database db_name cannot be made because of backup pending: SQLSTATE=57019

    This occurs because the database logging mode was changed from circular to archival and a full database backup must be taken. A backup taken when the database is in circular logging is not sufficient when switching logging modes and a new one must be taken.
  6. Take a full database backup using a command such as the following:

    • BACKUP DATABASE db_name TO d:\db_name\backup
  7. Try to connect to the database again. This time it should succeed.

    • CONNECT TO db_name

Best practices to keep data safe

Here are a few best practices to keep your data safe:

  1. Keep your database in archival logging mode so that in the case of failure you can recover the database up to a particular point-in-time.
  2. Perform full and incremental database backups regularly. Business requirements ultimately dictate the schedule and frequency.
  3. Keep a clone or standby database ready at all times if the database is mission critical.
  4. Keep active log files and archived log files in different locations, with each location having sufficient disk space.
  5. Ensure the database parameter BLK_LOG_DSK_FUL is set to the value YES using the following command:

    • UPDATE DB CFG FOR db_name USING BLK_LOG_DSK_FUL YES
    Setting BLK_LOG_DSK_FUL to YES causes applications to hang when DB2 encounters an error because the file system holding the log files becomes full. This allows you to resolve the error and allows running transactions to complete. You can resolve a log disk full error by moving old log files to another file system or by enlarging the file system.

Recovery scenarios

It is important to understand how failures can occur and how to recover from them. The following sections simulate different types of failures and present a series of steps that can be followed to recover from them.

Scenario 1. An entire database is accidentally dropped or becomes corrupted

This scenario shows how to recover from a complete database failure. This situation may occur if the database is accidentally dropped or becomes damaged or inconsistent due to a manual error or hardware failure. In cases like these, you can recover the database completely by applying the last full database backup taken. This scenario is based on the configuration shown in Table 1.

Table 1. System configuration(s) used in recovery scenario 1
ComponentDescription
Operating systemWindows XP Service Pack 2 / RHEL 4.0
DB2 edition and levelDB2 UDB Enterprise Server Edition (ESE) V8.2.6 fixpak 13 / DB2 V9.1 ESE fixpak 1
Database nameTESTDB1

Step 1. Take a full database backup

To take a full offline database backup, the following commands can be issued:

  • TERMINATE
  • FORCE APPLICATION ALL
  • BACKUP DATABASE testdb1 TO c:\testdb1\backup

Be sure to note the ID that is generated in the backup file name. It looks something like: 20060411154219. This ID is simply the time stamp of the backup image and is needed during the restore process.

Step 2. Simulate a failure

To simulate a failure scenario, completely drop the database:

  • TERMINATE
  • FORCE APPLICATION ALL
  • DROP DATABASE testdb1

Now, try to connect to the database:

  • CONNECT TO testdb1

The following error is reported, which signifies the database is no longer there:

Error: SQL1013N Database alias name or database name "testdb1" could not found.

Step 3. Create a new database

To begin the recovery process, create a new database with the same name as the dropped database:

  • CREATE DATABASE testdb1

Ensure the database is created and cataloged correctly by viewing the contents of the database directory:

  • LIST DB DIRECTORY

Step 4. Restore database

Restore the database backup image. In this example, you restore a backup image with the timestamp 20060411154219:

  • RESTORE DATABASE testdb1 FROM c:\testdb1\backup TAKEN AT 20060411154219 INTO testdb1

The following warning message is returned:

SQL2523W: Restoring to an existing database that is different from the database on the backup image. The target database will be overwritten by the backup version. The roll-forward recovery logs associated with the target database will be overwritten.

Type Y to proceed. This restores the database backup over the newly created database from the previous step. Once the image is restored, the database is consistent up to the point that the backup was taken.

Step 5. Connect to database

Attempt to connect to the database:

  • CONNECT TO testdb1

The following error message may be returned:

SQL1117N A connection to or activation of database "testdb1" cannot be made because of Roll-Forward Pending SQLSTATE=57019.

This may occur because consistency checking must occur using some of the log files. Issue the following command to bring the database to a consistent state:

  • ROLLFORWARD DATABASE testdb1 COMPLETE

Attempt to connect to the database again:

  • CONNECT TO testdb1

Step 6. Verification of database and objects

Verify that the objects that existed before are still there and available, for example:

  • LIST TABLESPACES SHOW DETAIL
  • LIST TABLES

The previous commands should report that all table spaces are in a normal state and that the containers are accessible. All the tables should also be there with the set of data that was present at the time the backup was taken.

Scenario 2. A table space container is accidentally dropped or is corrupted

This scenario shows how to recover from a situation where one or more table space containers are missing or damaged. This situation may arise because of a human error (such as, a user deletes a directory or file) or because of a data file corruption issue. This scenario is based on the configuration shown in Table 2.

Table 2. System configuration(s) used in recovery scenario 2
ComponentDescription
Operating systemWindows XP Service Pack 2 / RHEL 4.0
DB2 edition and levelDB2 UDB Enterprise Server Edition (ESE) V8.2.6 fixpak 13 / DB2 V9.1 ESE fixpak 1
Database nameTESTDB1
Table space nameTS1
Containers in TS1c1.dat, c2.dat, c3.dat, c4.dat

Step 1. Take an inventory of all the defined table spaces

  • CONNECT TO testdb1
  • LIST TABLESPACES SHOW DETAIL

Step 2. Take an inventory of all table space container information

  • LIST TABLESPACE CONTAINERS FOR 1 SHOW DETAIL Note that the "1" in the command above is the table space ID for table space TS1 in this environment. It was obtained from the output of the previous LIST TABLESPACES SHOW DETAIL command. This command would need to be repeated for each table space ID being used.

Step 3. Backup the table space

  • TERMINATE
  • FORCE APPLICATION ALL
  • BACKUP DATABASE testdb1 TABLESPACE ts1 TO c:\testdb1\backup\ts1

As you can see, this scenario assumes that you have taken backups of the most critical table spaces for recovery purposes.

Step 4. Simulate a table space failure

Manually simulate a situation in which table space container files are accidentally deleted by a user:

  • DEL C:\TESTDB1\TS1\C1.DAT
  • DEL C:\TESTDB1\TS1\C2.DAT
  • DEL C:\TESTDB1\TS1\C3.DAT

Subsequently, when you connect to the database and try to perform operations that are dependent on table space TS1, an error should be returned. For example:

  • CONNECT TO testdb1
  • CREATE TABLE tab1(c1 INTEGER) IN ts1

returns the following error message:

SQL0290N Table space access is not allowed.

You can also check the table space status by issuing the following command:

  • LIST TABLESPACES SHOW DETAIL

After the containers are deleted, the above command shows the status of TS1 as being 0x400, which means it is in a offline and not accessible state. Since three containers were deleted, the table space no longer remains in a normal state (0x000).

If you reissue the LIST TABLESPACE CONTAINERS command, you can verify which containers are missing or unavailable:

  • LIST TABLESPACE CONTAINERS FOR 1 SHOW DETAIL

In the results, the Accessible status should show as No for containers C1, C2, and C3.

Step 6. Restore the table space backup image

In order to restore the backup image, issue the following commands:

  • TERMINATE
  • RESTORE DATABASE testdb1 TABLESPACE (ts1) FROM C:\TESTDB1\BACKUP\TS1

Step 7. Check the table space status

Make sure the containers are accessible:

  • LIST TABLESPACES SHOW DETAIL
  • LIST TABLESPACE CONTAINERS FOR 1 SHOW DETAIL

If the restore is successful, the state of table space TS1 should be normal (0x000) and all the containers should be accessible.

Step 8. Verify that the restore is successful

  • CREATE TABLE tab1(no INTEGER) IN ts1

Note: You may encounter a situation where after restoring the table space, further recovery action is needed. This may occur if there are any log file changes that were not applied yet to make the database consistent. In this case, simply issue one of the following commands to complete the recovery:

  • ROLLFORWARD DATABASE testdb1 COMPLETE

OR

  • ROLLFORWARD DATABASE testdb1 TO END OF LOGS AND STOP

The above commands apply any remaining log files and bring the database to a consistent state.

Scenario 3. A table is accidentally dropped

In some database environments where there are thousands of tables, sometimes a table is dropped by mistake. In this scenario, you see how to recover a table that was dropped accidentally. To be able to perform this type of recovery, your database must be configured for archival logging mode and must have a full database backup image available. For a dropped table to be recoverable, the table space in which the table resides must have the DROPPED TABLE RECOVERY option turned on. This can be set during table space creation, or by invoking the ALTER TABLESPACE statement. The DROPPED TABLE RECOVERY option is table space-specific and limited to regular table spaces.

This scenario is based on the system configuration shown in Table 3.

Table 3. System configuration(s) used in recovery scenario 3
ComponentDescription
Operating systemWindows XP Service Pack 2 / RHEL 4.0
DB2 edition and levelDB2 UDB Enterprise Server Edition (ESE) 8.2.6 fixpak 13 / DB2 9.1 ESE fixpak 1
Database nameTESTDB1
Table space nameTS1
Table nameTAB1

Step 1. Perform a full database backup

  • TERMINATE
  • FORCE APPLICATION ALL
  • BACKUP DATABASE testdb1 TO c:\testdb1\backup

Be sure to note the time stamp of the backup image.

Step 2. Connect to the database and perform operations that generate log records

  • CONNECT TO testdb1
  • CREATE TABLE tab1(no INTEGER) IN ts1
  • TERMINATE
  • ARCHIVE LOG FOR DATABASE testdb1
  • CONNECT TO testdb1
  • INSERT INTO tab1 VALUES(1)
  • INSERT INTO tab1 VALUES(2)
  • INSERT INTO tab1 VALUES(3)
  • COMMIT
  • TERMINATE
  • ARCHIVE LOG FOR DATABASE testdb1
  • CONNECT TO testdb1
  • INSERT INTO tab1 VALUES(4)
  • INSERT INTO tab1 VALUES(5)
  • COMMIT
  • TERMINATE
  • ARCHIVE LOG FOR DATABASE testdb1
  • CONNECT TO testdb1
  • SELECT * FROM tab1 /* check the 5 committed values from TAB */

Step 3. Simulate the accidental dropping of the table

  • DROP TABLE tab1
  • COMMIT
  • SELECT * FROM tab1

The following error message should be returned:

Error: SQL0204N "Administrator.TAB1" is an undefined name

Step 4. Restore the database

To recover the dropped table, restore the database backup taken, then issue a rollforward operation:

  • TERMINATE
  • FORCE APPLICATION ALL
  • RESTORE DATABASE testdb1 FROM c:\testdb1\backup TAKEN AT 20070314144204 INTO testdb1

The following warning message is returned:

SQL2539W Warning! Restoring to an existing database that is the same as the Backup image database.
The database files will be deleted.

Do you want to continue? (Y/N)

Type Y to complete the process.

Step 5. Retrieve the dropped table's object ID

Use the following command to retrieve the object ID of the table that was accidentally dropped:

  • LIST HISTORY DROPPED TABLE ALL FOR DATABASE testdb1

The information returned, such as the sample shown in Listing 1, can be copied into a text file for future reference.

Listing 1. Information returned from the LIST HISTORY command
Op Obi Timestamp Sequence Type Dev Earliest Log Current Log  Backup ID
-- --- ------------------ ---- --- ------------ ------------ -----------------------------
 D  T  20070314142913                               	     000000000000892700050108
------------------------------------------------------------------------------------------
 "ADMINISTRATOR"."TAB1" resides in 1 table space(s):
 00001 TS1
----------------------------------------------------------------------------
 Comment: DROP TABLE
 Start Time: 20070314142913
 End Time: 20070314142913
 Status: A
----------------------------------------------------------------------------
 EID: 37
 DDL: CREATE TABLE "ADMINISTRATOR"."TAB1" ( "NO" INTEGER )  IN "TS1" ;

The Backup ID column from Listing 1 shows 000000000000892700050108 as the ID for the dropped table. This is an important piece of information needed to recover the table.

Step 6. Roll the database forward

Now that you have the ID for the dropped table, the next step is to roll forward the database using the backup ID of the dropped table, so that the table's data can be exported. Before rolling forwarding, ensure that there is a directory to store the exported data in, for example: c:\testdb1\exporttab1. Use following command to roll forward the database:

  • ROLLFORWARD DATABASE testdb1 TO END OF LOGS
    AND STOP RECOVER DROPPED TABLE 000000000000892700050108 TO c:\testdb1\exporttab1

The END OF LOGS option is used so that DB2 applies all the logs files that are available after the backup was performed.

Step 7. Check the exported data file

After the roll forward database completes, check the path you specified in the ROLLFORWARD command. You should find a .TXT file that you can open and verify that the data contained in it is the same (committed) data that was present before the table was accidentally dropped.

Step 8. Connect to the database and recreate the dropped table

After verifying the exported file, you will need to recreate the dropped table and repopulate it. The definition of the dropped table is contained in the output of the LIST HISTORY command from Step 5. Connect to the database and execute the CREATE TABLE statement:

  • CONNECT TO testdb1
  • CREATE TABLE "ADMINISTRATOR"."TAB1" ( "NO" INTEGER ) IN "TS1"

Step 9. Import the data

Once you recreate the table, import the data back into it using a command such as:

  • IMPORT FROM c:\testdb1\exporttab1\Node0000\data.txt OF DEL INSERT INTO administrator.tab1

The IMPORT utility imports all the data from the exported file and reports back to you on its success (not shown).

Step 10. Verify the recovered data

Ensure there were no error or warning messages in the IMPORT process and that all the data made it back into the table:

  • SELECT * FROM tab1

If everything went smoothly, all the committed data up until the accidental drop point should be in the table.

Scenario 4. Recover to a point-in-time

If a table space gets dropped or becomes corrupted, the tables defined in it and and their data become inaccessible. To recover from this scenario, you must have a full database backup image available and the database must be configured to for archival logging. This scenario is based on the system configuration shown in Table 4.

Table 4. System configuration(s) used in recovery scenario 4
ComponentDescription
Operating systemWindows XP Service Pack 2 / RHEL 4.0
DB2 edition and levelDB2 UDB Enterprise Server Edition (ESE) 8.2.6 fixpak 13 / DB2 9.1 ESE fixpak 1
Database nameTESTDB1
Table space nameTS1
Table nameTAB1

Step 1. Take a full database backup

  • TERMINATE
  • FORCE APPLICATION ALL
  • BACKUP DATABASE testdb1 TO c:\testdb1\backup

Be sure to jot down the timestamp the backup image file receives as this is required during the restore process.

Step 2. Create a new table space

Create a new table space called TS1 that is used in this recovery scenario:

  • CREATE TABLESPACE TS1 MANAGED BY DATABASE USING (FILE 'c:\testdb1\s4\C1.dat' 1000 )
    EXTENTSIZE 8 PREFETCHSIZE 24

Confirm the table space and associated containers are created:

  • LIST TABLESPACES
  • LIST TABLESPACE CONTAINERS FOR n SHOW DETAIL

where n is the table space ID shown in the LIST TABLESPACES output.

Step 3. Create a table and perform some operations on it

After creating the table space, create a table called TAB1 and place it in the table space. Insert some data into the table. To make the scenario more realistic, issue some commands that force DB2 to switch active log files:

  • CREATE TABLE tab1 (no INTEGER) IN TS1
  • INSERT INTO tab1 VALUES(1)
  • INSERT INTO tab1 VALUES(2)
  • COMMIT
  • TERMINATE
  • ARCHIVE LOG FOR DATABASE testdb1
  • CONNECT TO testdb1
  • INSERT INTO tab1 VALUES(3)
  • INSERT INTO tab1 VALUES(4)
  • INSERT INTO tab1 VALUES(5)
  • COMMIT
  • SELECT * FROM tab1
  • TERMINATE
  • ARCHIVE LOG FOR DATABASE testdb1
  • CONNECT TO testdb1

Step 4. Simulate a table space failure

To simulate a failure for this scenario, drop the table space:

  • DROP TABLESPACE ts1
  • SELECT * FROM tab1

The following error message should be returned:

SQL0204N Error table does not exist "Administrator.Tab1" is an Undefined Name.

Step 5. Restore the database

Once the table space is dropped, all the tables within that table space are also dropped. To recover the table space, restore the last backup image available:

  • TERMINATE
  • RESTORE DATABASE testdb1 FROM c:\testdb1\backup
    TAKEN AT 20070315150901
    INTO testdb1

When issuing the RESTORE command, use the backup timestamp you jotted down from Step 1. You receive following warning message:

SQL 2539W Warning! Restoring to an existing database that is same as the backup image database.
The database files will be deleted.

Do you want to continue? (Y/N)

Type Y to continue the process.

Step 6. Roll the database forward

After the restoring the database, try to connect to the database:

  • CONNECT TO testdb1

The following message is returned:

SQL 111N A connection to or activation of database cannot be made because of Roll-forward Pending. SQLSTATE=57019

Before you can roll the database forward, you need to figure out the timestamp at which the table space was dropped. To do this, use the LIST HISTORY command:

  • LIST HISTORY CREATE TABLESPACE ALL FOR DATABASE testdb1

You can see the exact dropped table space timestamp. However, this timestamp should not be used because a timestamp value just before it is needed in order to recover up to the last committed value.

This example uses 20070315151500 as the timestamp for recovery. This needs to be formatted to the form recognized by the ROLLFORWARD utility, namely: 2007-03-15.15.15.00

  • ROLLFORWARD DATABASE testdb1 TO 2007-03-15.15.15.00 USING LOCAL TIME AND STOP

DB2 applies all the logs until the timestamp specified and recovers the database along with the table space.

Step 7. Verify the recovered table space and table

  • CONNECT TO testdb1
  • LIST TABLESPACES SHOW DETAIL
  • SELECT * FROM tab1

The results of the above commands allow you to confirm that the table space and table were recovered to the point-in-time specified.


Summary

This article introduced the different types of logging that can be performed in DB2. It also presented critical recovery scenarios containing step-by-step instructions for recovering from various types of failures.

For mission critical databases, it is crucial to understand the backup and recovery processes and plan for contingencies. It is also imperative to have a tried and tested backup and recovery plan in place.

Resources

Learn

Get products and technologies

  • Build your next development project with IBM trial software, available for download directly from developerWorks.
  • A trial version of DB2 9 is available for free download.
  • Download DB2 Express-C, a no-charge version of DB2 Express Edition for the community that offers the same core data features as DB2 Express Edition and provides a solid base to build and deploy applications.

Discuss

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into Information management on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Information Management
ArticleID=248423
ArticleTitle=Introduction to DB2 9 database recovery
publish-date=08162007