Skip to content

3. Analyzing Logs#

This chapter describes XLogs, meta data and the Altibase internal data types, all of which are required in order to analyze XLogs.

XLogs and meta data can be accessed using the Log Analysis API.

XLog#

This section describes the various kinds of XLogs and their constituent elements.

In order to access XLogs, it is necessary to call ALA_GetXLog()

Types of XLog#

typedef enum
{
    XLOG_TYPE_COMMIT            = 2,   /* Transaction Commit */
    XLOG_TYPE_ABORT             = 3,   /* Transaction Rollback */
    XLOG_TYPE_INSERT            = 4,   /* DML: Insert */
    XLOG_TYPE_UPDATE            = 5,   /* DML: Update */
    XLOG_TYPE_DELETE            = 6,   /* DML: Delete */
    XLOG_TYPE_SP_SET            = 8,   /* Savepoint Set */
    XLOG_TYPE_SP_ABORT          = 9,   /* Abort to savepoint */
    XLOG_TYPE_LOB_CURSOR_OPEN   = 14,  /* LOB Cursor open */
    XLOG_TYPE_LOB_CURSOR_CLOSE  = 15,  /* LOB Cursor close */
    XLOG_TYPE_LOB_PREPARE4WRITE = 16,  /* LOB Prepare for write */
    XLOG_TYPE_LOB_PARTIAL_WRITE = 17,  /* LOB Partial write */
    XLOG_TYPE_LOB_FINISH2WRITE  = 18,  /* LOB Finish to write */
    XLOG_TYPE_KEEP_ALIVE        = 19,  /* Keep Alive */
    XLOG_TYPE_REPL_STOP         = 21,  /* Replication Stop */
    XLOG_TYPE_LOB_TRIM          = 35,  /* LOB Trim */
    XLOG_TYPE_CHANGE_META       = 25  /* Meta change by DDL */
} ALA_XLogType;

There are 13 kinds of transaction related XLogs and two kinds of control related XLogs.

The transaction related XLog ends with either XLOG_TYPE_COMMIT or XLOG_TYPE_ABORT.

Because LOB data are typically voluminous, a LOB update task can be associated with more than one XLog. In this case, the LOB XLogs are received in the sequence shown below:

XLOG_TYPE_LOB_CURSOR_OPEN
{
    XLOG_TYPE_LOB_PREPARE4WRITE
    {
        XLOG_TYPE_LOB_PARTIAL_WRITE
        ...
    }
    XLOG_TYPE_LOB_FINISH2WRITE
    ...
     or
     XLOG_TYPE_LOB_TRIM
…
}
XLOG_TYPE_LOB_CURSOR_CLOSE

The control-related XLogs are KEEP_ALIVE and REPL_STOP.

The KEEP_ALIVE XLog is sent by the XLog to check whether the network connection is still valid when it has no XLog to send.

The REPL_STOP Xlog indicates that the XLog Sender is shutting down normally. The connection is terminated after ALA_SendACK() is called.

The CHANGE_META shows modification of meta information by DDL occurrence in the XLog Sender.

The XLog Sender should resend the meta information as a new information to the application program after sending CHANGE_META.Therefore, the XLog Sender sends the REPL_STOP after sending the CHANGE_META which enables the ALA application program to process.

XLog Structure#

typedef UInt   ALA_TID;             /* Transaction ID */
typedef ULong  ALA_SN;              /* Log Record SN */
typedef struct ALA_Value            /* Altibase Internal Data */
{
    UInt         length;            /* Length of value */
    const void * value;
} ALA_Value;
Structure Member Description
length The length of the internal Altibase data value
value The internal data value of Altibase
typedef struct ALA_XLogHeader       /* XLog Header */
{
    ALA_XLogType mType;         /* XLog Type */
    ALA_TID      mTID;              /* Transaction ID */
    ALA_SN       mSN;           /* SN */
    ALA_SN       mSyncSN;       /* Reserved */
    ALA_SN       mRestartSN;        /* Used internally */
    ULong        mTableOID;         /* Table OID */
} ALA_XLogHeader;

typedef struct ALA_XLogPrimaryKey   /* Primary Key */
{
    UInt         mPKColCnt;         /* Primary Key Column Count */
    ALA_Value   *mPKColArray;   /* Primary Key Column Value Array */
} ALA_XLogPrimaryKey;

typedef struct ALA_XLogColumn           /* Column */
{
    UInt         mColCnt;       /* Column Count */
    UInt        *mCIDArray;     /* Column ID Array */
    ALA_Value   *mBColArray;    /* Before Image Column Value Array */
    ALA_Value   *mAColArray;    /* After Image Column Value Array */
} ALA_XLogColumn;

typedef struct ALA_XLogSavepoint        /* Savepoint */
{
    UInt         mSPNameLen;            /* Savepoint Name Length */
    SChar       *mSPName;               /* Savepoint Name */
} ALA_XLogSavepoint;

typedef struct ALA_XLogLOB              /* LOB */
{
    ULong        mLobLocator;           /* LOB Locator of Altibase */
    UInt         mLobColumnID;
    UInt         mLobOffset;
    UInt         mLobOldSize;
    UInt         mLobNewSize;
    UInt         mLobPieceLen;
    UChar       *mLobPiece;
} ALA_XLogLOB;

typedef struct ALA_XLog                 /* XLog */
{
    ALA_XLogHeader      mHeader;
    ALA_XLogPrimaryKey  mPrimaryKey;
    ALA_XLogColumn      mColumn;
    ALA_XLogSavepoint   mSavepoint;
    ALA_XLogLOB         mLOB;

    /* Used internally */
    struct ALA_XLog    *mPrev;
    struct ALA_XLog    *mNext;
} ALA_XLog;

An XLog structure consists of a header, a primary key, a column, a savepoint, and LOB-related structures.

Each of these elements can be read either by accessing the ALA_XLog structure directly or via the XLog Log Analysis API.

ALA_XLogPrimaryKey does not actually contain the primary key column ID array values. These values can be accessed as individual mColumnID values in the mPKColumnArray[sIndex] array element in the ALA_Table structure that contains meta data about the table. The meta data, in turn, can be accessed using either ALA_GetTableInfo() or ALA_GetTableInfoByName().

Configuration Based on XLog Type#

The type of XLog can be determined by checking the value of the mType member of the ALA_XLogHeader structure.

COMMIT XLog#

Header (mType, mTID, mSN, mSyncSN)

ABORT XLog#

Header (mType, mTID, mSN, mSyncSN)

INSERT XLog#

Header (mType, mTID, mSN, mSyncSN, mTableOID)
Column (mColCnt, mCIDArray, mAColArray)

UPDATE XLog#

Header (mType, mTID, mSN, mSyncSN, mTableOID)
Primary Key (mPKColCnt, mPKColArray)
Column (mColCnt, mCIDArray, mBColArray, mAColArray)

DELETE XLog#

Header (mType, mTID, mSN, mSyncSN, mTableOID)
Primary Key (mPKColCnt, mPKColArray)

SP_SET XLog#

Header (mType, mTID, mSN, mSyncSN)
Savepoint (mSPNameLen, mSPName)
  • If mSPName begins with "$$IMPLICIT", it is an implicit savepoint.
  • If mSPName is "$$PSM_SVP", it is a PSM Savepoint.

SP_ABORT XLog#

Header (mType, mTID, mSN, mSyncSN)
Savepoint (mSPNameLen, mSPName)
  • If mSPName begins with "$$IMPLICIT", it is an implicit savepoint.

  • If mSPName is "$$PSM_SVP", it is a PSM Savepoint.

LOB_CURSOR_OPEN XLog#

Header (mType, mTID, mSN, mSyncSN, mTableOID)
Primary Key (mPKColCnt, mPKColArray)
LOB (mLobLocator, mLobColumnID)

LOB_CURSOR_CLOSE XLog#

Header (mType, mTID, mSN, mSyncSN)
LOB (mLobLocator)

LOB_PREPARE4WRITE XLog#

Header (mType, mTID, mSN, mSyncSN)
LOB (mLobLocator, mLobOffset, mLobOldSize, mLobNewSize)

LOB_PARTIAL_WRITE XLog#

Header (mType, mTID, mSN, mSyncSN)
LOB (mLobLocator, mLobOffset, mLobPieceLen, mLobPiece)
  • mLobOffset is the position relative to the value of mLobOffset in the LOB_PREPARE4WRITE XLog.

LOB_FINISH2WRITE XLog#

Header (mType, mTID, mSN, mSyncSN)
LOB (mLobLocator)

KEEP_ALIVE XLog#

Header (mType, mTID, mSN, mSyncSN)

REPL_STOP XLog#

Header (mType, mTID, mSN, mSyncSN)

LOB_TRIM XLog#

Header (mType, mTID, mSN, mSyncSN)
LOB (mLobLocator, mLobOffset)
  • mLobOffset is the position in which the trimmed LOB data byte starts.

CHANGE_META#

Header (mType, mTID, mSN, mSyncSN)
  • mSN is the last sequence number of modified logs which have been processed up to now, mTID and mSyncSN is the value which has no meaning to a user.

Meta Data#

This section describes how to access the meta data that are used to interpret XLogs.

Before the meta data can be accessed, it is necessary to call ALA_Handshake().

Meta Data Structure#

typedef struct ALA_ProtocolVersion
{
    UShort      mMajor;             /* Major Version */
    UShort      mMinor;             /* Minor Version */
    UShort      mFix;               /* Fix Version */
} ALA_ProtocolVersion;

typedef struct ALA_Replication
{
    SChar        mXLogSenderName[ALA_NAME_LEN];   /* XLog Sender Name */
    UInt         mTableCount;       /* Table Count */
    ALA_Table   *mTableArray;     /* Table Array */
    SChar mDBCharSet[ULA_NAME_LEN]; /* DB Charter Set */
    SChar mDBNCharSet[ULA_NAME_LEN]; /* DB National Charter Set */
} ALA_Replication;

typedef struct ALA_Table
{
    ULong      mTableOID;                  /* Table OID */
    SChar      mFromUserName[ALA_NAME_LEN]; /* (From) User Name */
    SChar      mFromTableName[ALA_NAME_LEN]; /* (From) Table Name */
    SChar      mToUserName[ALA_NAME_LEN];  /* (To) User Name */
    SChar      mToTableName[ALA_NAME_LEN]; /* (To) Table Name */
    UInt       mPKIndexID;            /* Index ID of Primary Key */
    UInt       mPKColumnCount;       /* Primary Key Column Count */
    ALA_Column **mPKColumnArray;   /* Primary Key Column Array */
    UInt         mColumnCount;        /* Column Count */
    ALA_Column  *mColumnArray;      /* Column Array */
    UInt         mIndexCount;         /* Index Count */
    ALA_Index   *mIndexArray;        /* Index Array */
} ALA_Table;

typedef struct ALA_Column
{
    UInt            mColumnID;              /* Column ID */
    SChar        mColumnName[ALA_NAME_LEN]; /* Column Name */
    UInt            mDataType;              /* Column Data Type */
    UInt            mLanguageID;            /* Column Language ID */
    UInt            mSize;                  /* Column Size */
    SInt            mPrecision;             /* Column Precision */
    SInt            mScale;                 /* Column Scale */
    ALA_BOOL     mNotNull;                  /* Column Not Null? */
} ALA_Column;

typedef struct ALA_Index
{
    UInt          mIndexID;                 /* Index ID */
    SChar         mIndexName[ALA_NAME_LEN]; /* Index Name */
    ALA_BOOL      mUnique;                  /* Index Unique? */
    UInt          mColumnCount;             /* Index Column Count */
    UInt         *mColumnIDArray;           /* Index Column ID Array */
} ALA_Index;

The meta data include data about the Protocol Version, Replication, tables, columns and indexes.

The mPKColumnArray element of the ALA_Table structure is an array of ALA_Column pointers.

Altibase Data Types and Internal Structure#

This section describes the format in which the data are stored internally for each data type of Altibase.

Information about columns, which is stored in the ALA_Column structure, can be accessed by calling ALA_GetColumnInfo(), whereas actual column values, which are stored in the ALA_Value structure, can be accessed using the XLog Log Analysis API.

The actual column value is stored in the value element of the ALA_Value structure, whereas the length of the column value is stored in the length element of the ALA_Value structure.

Meanwhile, the type of data stored in the column can be determined by checking the value of mDataType in the ALA_Column structure.

CategoryData TypeConstant

Number

FLOAT

6

NUMERIC

2

DOUBLE

8

REAL

7

BIGINT

(UInt)-5

INTEGER

4

SMALLINT

5

Date/Time

DATE

9

Character/Binary

CHAR

1

VARCHAR

12

NCHAR

(UInt)-8

NVARCHAR

(UInt)-9

BYTE

20001

NIBBLE

20002

BIT

(UInt)-7

VARBIT

(UInt)-100

BLOB

30

CLOB

40

Spacial

GEOMETRY

10003

[Table 3-2] Altibase Data Types

FLOAT, NUMERIC#

Internal Structure#

The internal data structures of the FLOAT and NUMERIC types are the same.

typedef struct mtdNumericType
{
    UChar   length;        /* Length of (signExponent + mantissa) */
    UChar   signExponent;  /* Sign and Exponent */
    UChar   mantissa[1];   /* UChar Array (Base 100) */
} mtdNumericType;

To determine the sign and exponent of a FLOAT or NUMERIC value, call ALA_GetInternalNumericInfo(), or check the values of the mtdNumericType structural elements as shown below.

Obtaining the sign from mtdNumericType#

if(signExponent is 128 ~ 255)
{
  Sign = '+';
}
else /* if(signExponent is 0 ~ 127) */
{
  Sign = '-';
}

Obtaining the exponent from mtdNumericType#

This is the exponent of a decimal number.

if(signExponent is 128 ~ 255)
{
  Exponent = ((SInt)(signExponent & 0x7F) - 64) * 2
             + ((mantissa[0] < 10) ? -1 : 0);
}
else /* if(signExponent is 0 ~ 127) */
{
  Exponent = (64 - (SInt)(signExponent & 0x7F)) * 2
             + ((mantissa[0] >= 90) ? -1 : 0);
}

Obtaining the mantissa from mtdNumericType#

The value of each UChar ranges from 0 and 99 inclusive, that is, each UChar is a base 100 number.

The result is a number between 0 and 1.

if(Sign is '+')
{
/* Example : 01 23 45 67 89 -> 0.123456789
/*           12 34 56 78 99 -> 0.1234567899
     */

/* mantissa[0] */
    if(mantissa[0] < 10)
    {
        MantissaStr = mantissa[0];
    }
    else
    {
        MantissaStr = mantissa[0] / 10;
        MantissaStr = MantissaStr + mantissa[0] % 10;
    }

    /* mantissa[1] ~ mantissa[mLength - 1] */
    for(Index = 1; Index < mLength - 1; Index++)
    {
        MantissaStr = MantissaStr + mantissa[Index] / 10;
        MantissaStr = MantissaStr + mantissa[Index] % 10;
    }
}
else /* if(Sign is '-') */
{
    /* Example : 98 76 54 32 10 -> 0.123456789
    /*           09 87 65 43 21 -> 0.9012345678
     */

/* mantissa[0] */
    if(mantissa[0] >= 90)
    {
        MantissaStr = MantissaStr + (99 - mantissa[0]);
    }
    else
    {
        MantissaStr = MantissaStr + (99 - mantissa[0]) / 10;
        MantissaStr = MantissaStr + (99 - mantissa[0]) % 10;
    }

    /* mantissa[1] ~ mantissa[mLength - 1] */
    for(Index = 1; Index < mLength - 1; Index++)
    {
        MantissaStr = MantissaStr + (99 - mantissa[Index]) / 10;
        MantissaStr = MantissaStr + (99 - mantissa[Index]) % 10;
    }
}

DOUBLE, REAL, BIGINT, INTEGER, SMALLINT#

Internal Structure#

Each type is mapped to a primitive data type.

typedef SDouble mtdDoubleType;      /* DOUBLE */
typedef SFloat  mtdRealType;        /* REAL */
typedef SLong   mtdBigintType;      /* BIGINT */
typedef SInt    mtdIntegerType;     /* INTEGER */
typedef SShort  mtdSmallintType;    /* SMALLINT */

DATE#

Internal Structure#

There is only one internal data type available for handling dates and times.

typedef struct mtdDateType
{
  SShort  year;           /* Year(16bit) */
  UShort  mon_day_hour;   /* Not Used(2bit), Month(4bit), */
  /* Day(5bit), Hour(5bit) */
  UInt    min_sec_mic;    /* Minute(6bit), Second(6bit), */
  /* MicroSec(20bit) */
} mtdDateType;

CHAR, VARCHAR, NCHAR, NVARCHAR, BYTE, NIBBLE, BIT, VARBIT, BLOB, CLOB#

Internal Structure#

These data types have similar structures.

typedef struct mtdCharType      /* CHAR, VARCHAR */
{
UShort  length;             /* Length of value */
UChar   value[1];           /* UChar Array */
} mtdCharType;

typedef struct mtdNcharType 
{ /*NCHAR, NVARCHAR */
    UShort length;      /* Length of value */
    UChar  value[1];    /* UChar Array */
} mtdNcharType;

typedef struct mtdByteType      /* BYTE */
{
UShort  length;         /* Length of value */
UChar   value[1];           /* UChar Array */
} mtdByteType;

typedef struct mtdNibbleType    /* NIBBLE */
{
UChar   length;             /* Length of Nibbles */
UChar   value[1];       /* UChar Array */
} mtdNibbleType;

typedef struct mtdBitType       /* BIT, VARBIT */
{
UInt    length;         /* Length of Bits */
UChar   value[1];       /* UChar Array */
} mtdBitType;

typedef struct mtdLobType
{
UInt    length;             /* Length of value */
UChar   value[1];           /* UChar Array */
} mtdLobType;

typedef mtdLobType mtdBlobType;     /* BLOB */
typedef mtdLobType mtdClobType;     /* CLOB */

The ALA_GetAltibaseText(), ALA_GetAltibaseSQL() and ALA_GetODBCCValue() functions cannot be used with BLOB or CLOB type values.

Valid values for the length element of the NIBBLE type are between 0 and 254 inclusive. A length value of 255 indicates a NULL value.

GEOMETRY#

Internal Structure#

For information on the GEOMETRY data structure and how to handle GEOMETRY type data, please refer to the Altibase Spatial SQL Reference.

The ALA_GetAltibaseText(), ALA_GetAltibaseSQL() and ALA_GetODBCCValue() functions cannot be used with GEOMETRY type values.

SAVEPOINT#

Savepoints are declared to temporarily save the interim results of partially processed transactions.

In Altibase, the following three types of savepoints are available for use:

  • Implicit Savepoint

  • Explicit Savepoint

  • PSM Savepoint

Implicit savepoints are used internally and managed in lists. One such list is maintained for each transaction. Implicit savepoints are used for partial rollback, which is performed automatically if the execution of a particular statement fails, so that only that statement, and not the entire transaction, needs to be rolled back.

It is also possible for users to expressly define explicit savepoints, which are also managed in lists that are maintained for individual transactions. (These lists are managed separately from the lists of implicit savepoints noted above.) Please refer to the SQL Reference for more details about explicit savepoints.

PSM savepoints are used internally when stored procedures are executed. These savepoints are only maintained during the execution of stored procedures. For more detailed information about stored procedures, please refer to the Stored Procedures Manual.

Each kind of savepoint is managed separately, and savepoint xlogs can be processed in applications depending on the circumstances.

Example

    iSQL> CREATE TABLE T1 (I1 INTEGER PRIMARY KEY);
    Create success.
    iSQL> INSERT INTO T1 VALUES (2);
    1 row inserted.
    iSQL> CREATE OR REPLACE PROCEDURE PROC1
        2 AS
        3 BEGIN
        4     INSERT INTO T1 VALUES(1);
        5     SAVEPOINT EXPLICIT_SP;
        6     INSERT INTO T1 VALUES(2);
        7     INSERT INTO T1 VALUES(3);
        8 END;
        9 /
    Create success.
    iSQL> AUTOCOMMIT OFF;
    Set autocommit off success.
    iSQL> EXEC PROC1;
    [ERR-11058 : The row already exists in a unique index.
    0006 :     INSERT INTO T1 VALUES(2);
            ^                        ^
    ]
    iSQL> ROLLBACK TO SAVEPOINT EXPLICIT_SP;
    Rollback success.