(iSeries)
(Dist) Storing and restoring transaction and compensation logs for high availability
We can, optionally, choose to store the WebSphere Application Server transaction and compensation logs in a relational database rather than as operating system files. This feature provides high availability (HA) support without having to use a shared file system. We can also restore your transaction and compensation logs from the relational database to the operating system files.
The WAS transaction service writes information to a transaction log for every global transaction that involves two or more resources, or that is distributed across multiple servers. These transactions are started or stopped either by applications or by the container in which they are deployed. The transaction service maintains transaction logs to ensure the integrity of transactions. Information is written to the transaction logs in the prepare phase of a distributed transaction. If a WAS with active transactions restarts after a failure, the transaction service is able to use the logs to replay any in-doubt transactions. This level of integrity allows the overall system to be brought back to a consistent state.
In previous releases of WAS, the transaction logs were stored as operating system files. In WAS v8.5.5 and later, this setup remains the default configuration. We can also choose to store the transaction logs in a relational database. This configuration option is primarily used for a high availability (HA) environment. Also, in previous releases of WAS, HA transaction support required the use of a shared file system to host the transaction logs, such as an NFSv4-mounted network-attached storage (NAS) or a storage area network (SAN). This new feature enables you, particularly if we have an investment in HA database technology, to use your HA database as a shared repository for the transaction logs as an alternative to using a shared file system.
The current implementation for storing the transaction and compensation logs in a relational database supports High Availability capabilities in DB2 and Oracle. For example, client-specific features such as DB2 HADR or Oracle RAC DataGuard, which enable reconnection to another database instance if a failure occurs, are supported. High availability capabilities in relational databases from other vendors are not currently supported.
In the current implementation, if unexpected JDBC exceptions are encountered by the core recovery log function, transaction logging is disabled and the server must be shut down so that in-flight transactions can be recovered. No attempt is made to reconnect until the server is restarted, and no attempt is made by the current implementation to determine whether the condition is transient.
In WAS v8.5.5 and later, we can use a similar facility, also aimed at customers that are working in a HA environment, to store the compensation recovery logs in a relational database. The WAS compensation service enables applications on disparate systems to coordinate activities that are more loosely coupled than atomic transactions. It stores information necessary to complete compensation after a system failure in its own dedicated recovery logs.
The datasource of the SQL Recovery Log needs a max pool size value of:
(2 * the number of potential servers being peer recovered) + 2This max pool size allows for sufficient connections to the database to close all the related transaction logs. Not having a max pool size set to this value can lead to the error message, J2CA0045E, because there are not sufficient connections available.
For the procedure to restore transaction and compensation logs from the relational database to operating system files, see step 5.
Tasks
Configure the transaction log location and the compensation log location for each server in the cluster before we can enable high availability, by setting the TransactionLogDirectory and CompensationLogDirectory attributes for each server. Each server in a cluster must reference unique transaction log and compensation log locations by specifying a distinct tablesuffix property, so that multiple servers do not contend for relational database management system (RDBMS) resources. For example, if we have a cluster that is named AppCluster with the following four member servers:
- AppClusterMember1
- AppClusterMember2
- AppClusterMember3
- AppClusterMember4
We can define the following table suffixes for AppCluster:
- App1 for AppClusterMember1
- App2 for AppClusterMember2
- App3 for AppClusterMember3
- App4 for AppClusterMember4
Complete the following steps:
- Configure a non-transactional data source for transaction and compensation recovery log storage:
- Create a JDBC provider for our specific RDBMS implementation. Specify an implementation type of non-XA.
- Create a JAAS J2C authentication data alias. This data alias defines the security credentials used to connect to the RDBMS. The credentials defined in the RDBMS must have sufficient authority to create tables in the database.
- Create a data source using the JDBC provider created in step a. Its component managed authentication alias must be set to the JAAS alias created in step b. Define the URL for your data source to specify a connection to the RDBMS.
- Configure the new data source to be non-transactional by completing the following steps:
- Open the newly created data source.
- Under Additional Properties, click WAS data source properties.
- Select the Non-transactional data source check box.
- Save changes.
- Configure the transaction service to store transactions in a relational database:
- In the WAS administrative console, click...
Servers > Server Types > WebSphere application servers > server. The properties of the specified application server are displayed.
- In the Container Settings section, click Container Services > Transaction service. The transaction service settings page is displayed.
- Select the Configuration tab if it is not already displayed.
- In the Transaction log directory field, enter a custom string to indicate that we want the logs to be stored in a database. The string must have the following format:
custom://com.ibm.rls.jdbc.SQLRecoveryLog?datasource=data_source_jndi_name,tablesuffix=suffixwhere data_source_jndi_name is the JNDI name of the non-transactional data source created previously, and suffix is a string that we must set to uniquely label each member of our HA cluster.Restriction: If we are using an Oracle database, the length of the suffix string must not exceed 15 characters.
- Optional: Configure the compensation service to store transactions in a relational database if we plan to use Compensation or Activity services in WAS:
- In the WAS administrative console, click...
Servers > Server Types > WebSphere application servers > server. The properties of the specified application server are displayed.
- In the Container Settings section, click Container Services > Compensation service. The compensation service settings page is displayed.
- Select the Configuration tab if it is not already displayed.
- In the Recovery log directory field, enter a custom string to indicate that we want the logs to be stored in a database. The string must have the following format:
custom://com.ibm.rls.jdbc.SQLRecoveryLog?datasource=data_source_jndi_name,tablesuffix=suffixwhere data_source_jndi_name is the JNDI name of the non-transactional data source created previously, and suffix is a string that we must set to uniquely label each member of our HA cluster.Restriction: If we are using an Oracle database, the length of the suffix string must not exceed 15 characters.
- Optional: Create the database tables.
WAS attempts to create the necessary database tables when it first starts. When this creation is not possible, due to insufficient permission for example, the server fails to start. Under these circumstances, create the three database tables manually.
The following DDL is representative and appropriate to a stand-alone server environment. In a stand-alone environment, two database tables, a transaction log and a partner log table are needed to support the transaction service. If we plan to use Compensation or Activity Services, then a third compensation log table is also needed.
The table names can be tailored for the environment. For example, create four transaction log tables, four partner log tables and optionally, four compensation log tables if we have a cluster that is named AppCluster with the following four member servers:
- AppClusterMember1
- AppClusterMember2
- AppClusterMember3
- AppClusterMember4
So we can define the following tables for AppCluster:
The following DDL shows how to create the database tables with the App1 table suffix on DB2:
Cluster Name Server Name Transaction Log Table Partner Log Table Compensation Log Table AppCluster AppClusterMember1 WAS_TRAN_LOGApp1 WAS_PARTNER_LOGApp1 WAS_COMP_LOGApp1
AppClusterMember2 WAS_TRAN_LOGApp2 WAS_PARTNER_LOGApp2 WAS_COMP_LOGApp2
AppClusterMember3 WAS_TRAN_LOGApp3 WAS_PARTNER_LOGApp3 WAS_COMP_LOGApp3
AppClusterMember4 WAS_TRAN_LOGApp4 WAS_PARTNER_LOGApp4 WAS_COMP_LOGApp4
CREATE TABLE WAS_TRAN_LOG( SERVER_NAME VARCHAR(128), SERVICE_ID SMALLINT, RU_ID BIGINT, RUSECTION_ID BIGINT, RUSECTION_DATA_INDEX SMALLINT, DATA BLOB)CREATE TABLE WAS_PARTNER_LOG( SERVER_NAME VARCHAR(128), SERVICE_ID SMALLINT, RU_ID BIGINT, RUSECTION_ID BIGINT, RUSECTION_DATA_INDEX SMALLINT, DATA BLOB)CREATE TABLE WAS_COMP_LOG( SERVER_NAME VARCHAR(128), SERVICE_ID SMALLINT, RU_ID BIGINT, RUSECTION_ID BIGINT, RUSECTION_DATA_INDEX SMALLINT, DATA BLOB)The following DDL structures show how to create the database table on Oracle:
CREATE TABLE WAS_TRAN_LOGApp1( SERVER_NAME VARCHAR(128), SERVICE_ID SMALLINT, RU_ID NUMBER(19), RUSECTION_ID NUMBER(19), RUSECTION_DATA_INDEX SMALLINT, DATA BLOB)CREATE TABLE WAS_PARTNER_LOGApp1( SERVER_NAME VARCHAR(128), SERVICE_ID SMALLINT, RU_ID NUMBER(19), RUSECTION_ID NUMBER(19), RUSECTION_DATA_INDEX SMALLINT, DATA BLOB)CREATE TABLE WAS_COMP_LOGApp1( SERVER_NAME VARCHAR(128), SERVICE_ID SMALLINT, RU_ID NUMBER(19), RUSECTION_ID NUMBER(19), RUSECTION_DATA_INDEX SMALLINT, DATA BLOB)- Optional:
Restore the transaction and compensation logs from the relational database to the operating system files.
On a multiple-server product:
- Stop the application server normally.
- Verify that all transactions are complete by checking the system output log for the WTRN0105I message:
WTRN0105I: The transaction service has shutdown successfully with no transactions requiring recovery.If WTRN0105I is not in the log, then restart the application server in recovery-only mode. This mode requires a non-HA environment.
- Modify the transaction log directory setting for the application server and synchronize the nodes.
- Restart the application server.
On a single-server product:
- Modify the transaction log directory only when ready to stop the application server. Then, stop the application server normally.
- Verify that all transactions are complete by checking the system output log for the WTRN0105I message:
WTRN0105I: The transaction service has shutdown successfully with no transactions requiring recovery.If WTRN0105I is not in the log, transactions might not have completed. We might need to recover incomplete transactions. The simplest fix to this problem might be to send the log to IBM Support.
- Restart the application server.
Example
If we have a cluster that is named AppCluster, with four member servers AppClusterMember1, AppClusterMember2, AppClusterMember3, and AppClusterMember4, then configure the log locations like this:
In this example, the table suffix is set to as follows:
Cluster Name Server Name Transaction Log Table Compensation Log Table AppCluster AppClusterMember1 custom://com.ibm.rls.jdbc.SQLRecoveryLog?datasource=jdbc/tranlog,tablesuffix=App1 custom://com.ibm.rls.jdbc.SQLRecoveryLog?datasource=jdbc/tranlog,tablesuffix=App1 AppClusterMember2 custom://com.ibm.rls.jdbc.SQLRecoveryLog?datasource=jdbc/tranlog,tablesuffix=App2 custom://com.ibm.rls.jdbc.SQLRecoveryLog?datasource=jdbc/tranlog,tablesuffix=App2 AppClusterMember3 custom://com.ibm.rls.jdbc.SQLRecoveryLog?datasource=jdbc/tranlog,tablesuffix=App3 custom://com.ibm.rls.jdbc.SQLRecoveryLog?datasource=jdbc/tranlog,tablesuffix=App3 AppClusterMember4 custom://com.ibm.rls.jdbc.SQLRecoveryLog?datasource=jdbc/tranlog,tablesuffix=App4 custom://com.ibm.rls.jdbc.SQLRecoveryLog?datasource=jdbc/tranlog,tablesuffix=App4
- AppClusterMember1
- AppClusterMember2
- AppClusterMember3
- AppClusterMember4
The database tables with the following names are created:
- WAS_TRAN_LOGApp1
- WAS_TRAN_LOGApp2
- WAS_TRAN_LOGApp3
- WAS_TRAN_LOGApp4
- WAS_PARTNER_LOGApp1
- WAS_PARTNER_LOGApp2
- WAS_PARTNER_LOGApp3
- WAS_PARTNER_LOGApp4
- WAS_COMP_LOGApp1
- WAS_COMP_LOGApp2
- WAS_COMP_LOGApp3
- WAS_COMP_LOGApp4