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:
-
Create the persistent database storage directory structures on the host system:
sudo mkdir -p /opt/Docker/archive sudo mkdir -p /opt/Docker/backup -
Launch the DB2 container engine on both machines. Include the
--network=hostflag 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:
-
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 -
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.
-
Log into the primary node container shell environment as the database instance owner:
docker exec -it db2server su - db2inst1 -
Run the following commands for each target database instance (such as
WPREL,WPCOMM,WPCUST,WPFDBK,WPLM, andWPJCR) 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/" -
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
-
Log into the standby node container shell environment as the database instance owner:
docker exec -it db2server su - db2inst1 -
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, orWITHOUT ROLLING FORWARDoptions 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.
-
On the primary node, run the following commands as the
db2inst1user 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" -
On the standby node, run the following commands as the
db2inst1user 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
-
Start HADR on the standby node container shell to initialize the replication listener:
db2 "START HADR ON DB WPREL AS STANDBY" -
Start HADR on the primary node container shell to establish the data link:
db2 "START HADR ON DB WPREL AS PRIMARY" -
Verify the replication state by running the following command on the primary node:
db2pd -db WPREL -hadrEnsure the output displays
HADR_STATE = PEERbefore 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.
-
In your
values.yamlfile, locate theconfiguration.webEngineblock 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" -
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:
releasejcrcommunitycustomizationfeedbacklikeminds
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:
db2HadrStandbyHostmaps toclientRerouteAlternateServerNamedb2HadrStandbyPortmaps toclientRerouteAlternatePortNumberdb2HadrMaxRetriesmaps tomaxRetriesForClientReroutedb2HadrRetryIntervalmaps toretryIntervalForClientReroute
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.
- Active DB2 XA transactions on the original primary node drop and return a
SQL1776Nerror, which Open Liberty records inSystemOut.logas-1776or-1,776. - For new connection requests, the DB2 JCC driver reads the following configuration attributes from
server.xmland retries the connection against the standby node address:clientRerouteAlternateServerNameandclientRerouteAlternatePortNumberspecify the standby target address and port.maxRetriesForClientReroutespecifies the connection retry limit.retryIntervalForClientReroutespecifies the wait time in seconds between attempts to allow takeover completion.
-
A background supervisor process monitors
SystemOut.logfor specific error patterns to trigger a graceful Liberty shutdown and exit the container with code0:Error classification Error code Description Hard error -1776orSQL1776NCommand rejected on standby database Hard error -30108orSQL30108NConnection failure due to takeover in progress Soft error -4470Closed statement or dead pool connection handle Soft error -30081orSQL30081NTCP/IP communication error Soft error -4498orSQL4498NLost connection to DB2 server Soft error -4499orSQL4499NNon-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.
-
Kubernetes detects the container termination and automatically replaces the pod.
- On pod startup,
server.xmlis 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.