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.
Category | Data Type | Constant |
---|---|---|
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.