Home | Previous Page | Next Page   Distributed Data > Recovering Manually from Failed Two-Phase Commit > Determining If Manual Recovery Is Required >

Determining If the Distributed Database Contains Inconsistent Data

If you determine that a transaction was inconsistently implemented, you must determine what this situation means for your distributed database system. Specifically, you must determine if data integrity has been affected.

A transaction that is inconsistently implemented causes problems whenever the piece of work rolled back by one participant is dependent on a piece of work that was updated by another participant. It is impossible to define these dependencies with SQL because distributed transactions do not support constraints that reference data at multiple database servers. The pieces of work are independent (no dependencies exist) only if the data could have been updated in two independent transactions. Otherwise, the pieces of work are considered to be dependent.

Before you proceed, consider the transaction that caused the error. Are the pieces of data that were updated and rolled back dependent on one another? Multiple updates might be included in a single transaction for reasons other than maintaining data integrity. For example, three possible reasons are as follows:

Verify also that every participant database server that is assumed to have committed the transaction actually modified data. A read-only database server might be listed as a participant that committed a transaction.

If an inconsistent transaction does not lead to a violation of data integrity, you can quit the procedure at this point.

Obtaining Information from the Logical Log

To determine if data integrity has been affected by an inconsistently implemented global transaction, you need to reconstruct the global transaction and determine which parts of the transaction were committed and which were rolled back. Use the onlog utility to obtain the necessary information. The procedure is as follows:

  1. Reconstruct the transaction at the participant that contains the HEURTX record.
    1. A participant database server logical log is the starting point for your information search. Each record in the log has a local transaction identification number (xid). Obtain the xid of the HEURTX record.
    2. Use the local xid to locate all associated log records that rolled back as part of this piece of work.
  2. Determine which database server acted as coordinator for the global transaction.
    1. Look for the PREPARE record on the participant that contains the same local xid. The PREPARE record marks the start of the two-phase commit protocol for the participant.
    2. Use the onlog -l option to obtain the long output of the PREPARE record. This record contains the global transaction identifier (GTRID) and the name of the coordinating database server. For information about GTRID, see Obtaining the Global Transaction Identifier.
  3. Obtain a list of the other participants from the coordinator log.
    1. Examine the log records on the coordinator database server. Find the BEGPREP record.
    2. Examine the long output for the BEGPREP record. If the first 32 bytes of the GTRID in this record match the GTRID of the participant, the BEGPREP record is part of the same global transaction. Note the participants displayed in the ASCII part of the BEGPREP long output.
  4. Reconstruct the transaction at each participant.
    1. At each participant database server, read the logical log to find the PREPARE record that contains the GTRID associated with this transaction and obtain the local xid for the piece of work performed by this participant.
    2. At each participant database server, use the local xid to locate all logical-log records associated with this transaction (committed or rolled back).

After you follow this procedure, you know what all the participants for the transaction were, which pieces of work were assigned to each participant, and whether each piece of work was rolled back or committed. From this information, you can determine if the independent action affected data integrity.

Obtaining the Global Transaction Identifier

When a global transaction starts, it receives a unique identification number called a global transaction identifier (GTRID). The GTRID includes the name of the coordinator. The GTRID is written to the BEGPREP logical-log record of the coordinator and the PREPARE logical-log record of each participant.

To see the GTRID, use the onlog -l option. The GTRID is offset 20 bytes into the data portion of the record and is 144 bytes long. Figure 90 shows the onlog -l output for a BEGPREP record. The coordinator is chrisw.

Figure 90. Output of the onlog -l Option for a BEGPREP Record
4a064    188  BEGPREP  4        0  4a038       0    1
         000000bc 00000043 00000004 0004a038 .......C .......8
         00087ef0 00000002 63687269 73770000 ..~..... chrisw..
         00000000 00000000 00000000 00087eeb ........ ......~.
         00006b16 00000000 00000000 00000000 ..k..... ........
         00000000 00000000 00000000 00000000 
         00000000 00000000 00000000 00000000 
         00000000 00000000 00000000 00000000 
         00000000 00000000 00000000 00000000 
         00000000 00000000 00000000 00000000 
         00000000 00000000 00000000 00000000 
         00000000 00000001 6a756469 74685f73 ........ judith_s
         6f630000 736f6374 63700000          oc..soct cp..

The first 32 bytes of the GTRID are identical for the BEGPREP record on the coordinator and the PREPARE records on participants, which are part of the same global transaction. For example, compare the GTRID for the PREPARE record in Figure 91 with that of the BEGPREP record in Figure 90.

Figure 91. Output of the onlog -l Option for a PREPARE Record
c7064    184  PREPARE  4        0  c7038    chrisw
         000000b8 00000044 00000004 000c7038 .......D ......p8
         00005cd6 00000002 63687269 73770000 ...... chrisw..
         00000000 00000000 00000069 00087eeb ........ ...i..~.
         00006b16 00000000 00000010 00ba5a10 ..k..... ......Z.
         00000002 00ba3a0c 00000006 00000000 ......:. ........
         00ba5a10 00ba5a1c 00000000 00000000 ..Z...Z. ........
         00ba3a0e 00254554 00ba2090 00000001 ..:..%ET .. .....
         00000000 00ab8148 0005fd70 00ab8148 .......H ...p...H
         0005fe34 0000003c 00000000 00000000 ...4...< ........
         00000000 00ab80cc 00000000 00ab80c4 ........ ........
         00ba002f 63687269 73770000 00120018 .../chrisw......
         00120018 00ba0000                   ........
Home | [ Top of Page | Previous Page | Next Page | Contents | Index ]