Skip to content

Enabling HADR support for DB2

To prevent data loss on DB2, you can modify the JCR schema to support high availability data replication (HADR) on WebEngine.

Before you enable HADR, use the Database Transfer option in your configuration values templates to transfer your data from Apache Derby to DB2.

Setting up the database tier and provisioning HADR

To ensure database instances communicate directly across network interfaces without address translation conflicts, prepare your primary and standby host environments using one of the following deployment options:

Deploying DB2 in Docker

If you run the DB2 instance inside a Docker container, perform the following steps on both host machines:

  1. Create the persistent database storage directory structures on the host system:

        sudo mkdir -p /opt/Docker/archive
        sudo mkdir -p /opt/Docker/backup
    
  2. Launch the DB2 container engine on both machines. Include the --network=host flag to ensure that high-availability log shipping bypasses container bridge Network Address Translation (NAT) limitations:

    docker run \
        -h db2server \
        --name db2server \
        --restart=always \
        --detach \
        --privileged \
        --network=host \
        -e DB2INST1_PASSWORD="your_db2inst1_password" \
        -v /opt/Docker:/database \
        <your-authorized-registry>/dx-db2:<version>
    

    Ensure you replace the image reference (<your-authorized-registry>/dx-db2:<version>) with your authorized registry tag path.

Deploying DB2 natively

If you run the DB2 instance as a native operating system installation, perform the following steps on both host machines:

  1. Create the database storage directory structures on the host system where the instance owner account (such as db2inst1) has read and write privileges:

    mkdir -p /database/archive
    mkdir -p /database/backup
    
  2. Configure firewalls to allow bidirectional TCP communication across the log-shipping replication ports (starting at port 3700) between the primary and standby network interfaces.

Configuring archive logging and base backups on the primary node

HADR requires archive logging to replicate data. Switch each standalone Portal database sequentially.

  1. Log into the primary node container shell environment as the database instance owner:

    docker exec -it db2server su - db2inst1
    
  2. Run the following commands for each target database instance (such as WPREL, WPCOMM, WPCUST, WPFDBK, WPLM, and WPJCR) to provision local log mounts, activate archive logging, and build the baseline images:

    # Create matching archive and backup subdirectories
    mkdir -p /database/archive/WPREL /database/backup/WPREL
    
    # Deactivate the instance to change modes offline
    db2 deactivate db WPREL
    
    # Direct transaction log archiving to your persistent mount
    db2 "UPDATE DB CFG FOR WPREL USING LOGARCHMETH1 'DISK:/database/archive/WPREL/'"
    
    # Enforce high-availability log tracking constraints
    db2 "UPDATE DB CFG FOR WPREL USING LOGINDEXBUILD ON BLOCKNONLOGGED YES"
    
    # Take the full offline backup
    db2 "backup db WPREL to /database/backup/WPREL/"
    
  3. Note the 14-digit backup timestamp generated by the success output string (such as 20260423150000).

Transferring backup and archive files to the standby node

Transfer the backup images and any accumulated transaction logs from the primary host filesystem to the standby host destination:

  • For Docker deployments, copy the local Docker volume contents from the primary host operating system to the standby host.

    scp -r /opt/Docker/backup/* user@<STANDBY_HOST_IP>:/opt/Docker/backup/
    scp -r /opt/Docker/archive/* user@<STANDBY_HOST_IP>:/opt/Docker/archive/
    
  • For native deployments, transfer the directories from the native paths on the primary operating system to the standby host.

    scp -r /database/backup/* user@<STANDBY_HOST_IP>:/database/backup/
    scp -r /database/archive/* user@<STANDBY_HOST_IP>:/database/archive/
    

Synchronizing and initializing the standby node

  1. Log into the standby node container shell environment as the database instance owner:

    docker exec -it db2server su - db2inst1
    
  2. Drop any automatically generated local databases, and restore the primary backup files:

    # Drop conflicting target database if present
    db2 drop db WPREL
    
    # Execute plain restore using the exact 14-digit timestamp from the Primary backup
    db2 "RESTORE DB WPREL FROM /database/backup/WPREL/ TAKEN AT 20260423150000"
    

    Important

    Do not append INTO, REDIRECT, or WITHOUT ROLLING FORWARD options to the restore command. A plain restore leaves the standby database in the roll-forward pending state required for HADR log synchronization.

Mapping HADR configuration parameters

Each database requires a unique replication port sequence so that separate internal DB2 listeners can bind without conflicts. Increment the base port parameter (such as 3700) sequentially for each subsequent database.

  1. On the primary node, run the following commands as the db2inst1 user to configure the network topology:

    db2 "UPDATE DB CFG FOR WPREL USING \
    HADR_LOCAL_HOST  <PRIMARY_PRIVATE_IP> \
    HADR_LOCAL_SVC   3700 \
    HADR_REMOTE_HOST <STANDBY_PRIVATE_IP> \
    HADR_REMOTE_SVC  3700 \
    HADR_REMOTE_INST db2inst1 \
    HADR_SYNCMODE    NEARSYNC"
    
  2. On the standby node, run the following commands as the db2inst1 user with the network connection values reversed:

    db2 "UPDATE DB CFG FOR WPREL USING \
    HADR_LOCAL_HOST  <STANDBY_PRIVATE_IP> \
    HADR_LOCAL_SVC   3700 \
    HADR_REMOTE_HOST <PRIMARY_PRIVATE_IP> \
    HADR_REMOTE_SVC  3700 \
    HADR_REMOTE_INST db2inst1 \
    HADR_SYNCMODE    NEARSYNC"
    

Replicating data between the primary and standby nodes

  1. Start HADR on the standby node container shell to initialize the replication listener:

    db2 "START HADR ON DB WPREL AS STANDBY"
    
  2. Start HADR on the primary node container shell to establish the data link:

    db2 "START HADR ON DB WPREL AS PRIMARY"
    
  3. Verify the replication state by running the following command on the primary node:

    db2pd -db WPREL -hadr
    

    Ensure the output displays HADR_STATE = PEER before you connect the application layer.

Configuring WebEngine container deployments

To connect your containerized Open Liberty application nodes to the database cluster, pass high-availability parameters into your chart attributes.

  1. In your values.yaml file, locate the configuration.webEngine block and update the attributes to enable dynamic client-side failover tracking:

    configuration:
      webEngine:
        # Enable external database configurations
        useExternalDatabase: true
    
        # Activate HADR support
        db2HadrEnabled: true
    
        # Specify the standby host name and port
        db2HadrStandbyHost: "<standby_host>"
        db2HadrStandbyPort: "50000"
    
        # Configure client reroute parameters
        db2HadrMaxRetries: "20"
        db2HadrRetryInterval: "5"
    
  2. Upgrade the Helm release to apply the configuration to the Kubernetes cluster:

    helm upgrade <release-name> hcl-dx/dx-deployment -f values.yaml
    

Automatic client reroute attributes in the Liberty configuration

When you set db2HadrEnabled: true, the WebEngine startup routine injects DB2 Automatic Client Reroute (ACR) attributes into every DB2 data source element in server.xml before Liberty starts. This injection applies to the following domains where DbType is db2:

  • release
  • jcr
  • community
  • customization
  • feedback
  • likeminds

For each domain, the generated <properties.db2.jcc> element receives the following parameters:

<dataSource id="jcr" isolationLevel="TRANSACTION_READ_COMMITTED" jndiName="jdbc/jcrdbDS"
            statementCacheSize="10" type="javax.sql.XADataSource">
  <jdbcDriver javax.sql.XADataSource="com.ibm.db2.jcc.DB2XADataSource" libraryRef="global"/>
  <properties.db2.jcc
    serverName="<primary_host>"
    portNumber="50000"
    databaseName="WPJCR"
    driverType="4"
    clientRerouteAlternateServerName="<standby_host>"
    clientRerouteAlternatePortNumber="50000"
    maxRetriesForClientReroute="20"
    retryIntervalForClientReroute="5"
    user="db2inst1"
    password="{xor}..."/>
  <connectionManager agedTimeout="7200" connectionTimeout="180" maxIdleTime="1800"
                     maxPoolSize="100" minPoolSize="10" purgePolicy="EntirePool" reapTime="180"/>
</dataSource>

The configuration maps the Helm values to the XML attributes at container startup:

  • db2HadrStandbyHost maps to clientRerouteAlternateServerName
  • db2HadrStandbyPort maps to clientRerouteAlternatePortNumber
  • db2HadrMaxRetries maps to maxRetriesForClientReroute
  • db2HadrRetryInterval maps to retryIntervalForClientReroute

Important

Do not set enableClientAffinitiesList and enableSeamlessFailover. Liberty uses DB2XADataSource (XA global transactions) for all DB2 data sources. Setting those properties triggers standby role probing during XA connection creation, which causes SQL1776N errors on the standby node. Plain ACR with retry counts allows the DB2 JCC driver to retry the alternate host after a primary node failure, providing the time required for the standby node to complete the HADR takeover and accept connections as the new primary node.

Failover execution flow

During a DB2 HADR takeover, the application tier automatically manages failover and recovery without manual configuration updates or pod deletions.

  1. Active DB2 XA transactions on the original primary node drop and return a SQL1776N error, which Open Liberty records in SystemOut.log as -1776 or -1,776.
  2. For new connection requests, the DB2 JCC driver reads the following configuration attributes from server.xml and retries the connection against the standby node address:
    • clientRerouteAlternateServerName and clientRerouteAlternatePortNumber specify the standby target address and port.
    • maxRetriesForClientReroute specifies the connection retry limit.
    • retryIntervalForClientReroute specifies the wait time in seconds between attempts to allow takeover completion.
  3. A background supervisor process monitors SystemOut.log for specific error patterns to trigger a graceful Liberty shutdown and exit the container with code 0:

    Error classification Error code Description
    Hard error -1776 or SQL1776N Command rejected on standby database
    Hard error -30108 or SQL30108N Connection failure due to takeover in progress
    Soft error -4470 Closed statement or dead pool connection handle
    Soft error -30081 or SQL30081N TCP/IP communication error
    Soft error -4498 or SQL4498N Lost connection to DB2 server
    Soft error -4499 or SQL4499N Non-transient connection failure

    Note

    • Hard errors trigger an immediate automated container restart.
    • Soft errors trigger an automated container restart when three occurrences are detected within a 60-second window.
  4. Kubernetes detects the container termination and automatically replaces the pod.

  5. On pod startup, server.xml is rebuilt with the original configuration attributes. The DB2 JCC driver attempts to connect to the old primary address, then reroutes initialization traffic to the alternate address (the new primary) to establish clean connection pools without requiring configuration changes or a Helm upgrade. During this startup initialization window, incoming client requests receive 503 Service Unavailable responses until health checks pass and the server fully initializes.

Recovering user sessions

After a database switchover, stale connection contexts or invalidated state handles can cause missing portlets and broken UI elements in active user sessions. Notify users to log out and log back in to clear stale session states.

Related information