Skip to content

Store Swiftlet (HA)

Overview

The High Availability (HA) Store Swiftlet extends the standard CE Store Swiftlet by adding synchronous replication of all persistent data between an ACTIVE and a STANDBY instance for failover scenarios. All store operations are synchronously mirrored to the STANDBY, ensuring no data loss during failover. For standard store features such as swap files, backup, shrink, and cache management, refer to the CE Store Swiftlet documentation.

Features

Synchronous Store Replication

In HA mode, the Store Swiftlet replicates all persistent data changes (database, transaction log, and durable subscriber files) from the ACTIVE to the STANDBY instance using a dedicated replication protocol. Every store operation (such as page creation, update, deletion, and transaction log writes) is transmitted to the STANDBY and only acknowledged to the application once the STANDBY has successfully received and applied the change. This ensures that the STANDBY is always in a consistent state and ready for immediate takeover in case of failover.

Replication is performed at the protocol level using a set of request types (e.g., PageDBPutRequest, TxLogWriteRequest, DurableDeleteRequest) that mirror all store mutations. The ACTIVE instance acts as a replication source, while the STANDBY acts as a sink and applies all received requests to its local store files.

Transaction Log Replication

All transaction log writes are synchronously sent from the ACTIVE to the STANDBY. The transaction log is kept in memory on the ACTIVE while in HA mode for performance, and is flushed to disk only when switching to standalone mode or during a controlled shutdown. The STANDBY receives transaction log chunks and reconstructs the log file locally, ensuring transactional consistency.

Store Image Transfer

When a STANDBY instance joins or resumes, the ACTIVE sends a full image of the current store files (database, transaction log, and durable subscriber files) to the STANDBY. This is done using file chunk requests to efficiently transfer large files in segments. The STANDBY deletes any old content before applying the new image, and can optionally back up previous files in split-brain scenarios.

Durable Subscriber Replication

All changes to durable subscriber state (creation, update, deletion) are mirrored to the STANDBY. Durable subscriber files are transferred in full when created or updated, and deleted on the STANDBY when removed on the ACTIVE.

HA Store Modes and Store Types

The HA Store Swiftlet supports three persistent store deployment options, each with different trade-offs for performance, reliability, and operational complexity:

  1. Replicated File Store: Each HA node maintains its own local store files. All changes are synchronously replicated over the network. This is the default and recommended mode for most deployments, as it provides full redundancy and no single point of failure.

  2. Shared File Store: Both ACTIVE and STANDBY instances access the same shared filesystem (e.g., NFS or SAN). Replication is not performed; both nodes see the same files. This mode is enabled by setting the shared-store property to true. It reduces network replication overhead but introduces a dependency on the shared storage's availability and performance.

  3. Shared JDBC Store: Both nodes use the same JDBC-accessible database for persistence. This is a variant of shared store mode, and also requires shared-store to be set to true.

When shared-store is enabled, the replication protocol is bypassed and both nodes directly access the same underlying store. In this case, the STANDBY does not receive replicated changes, but instead relies on the shared storage for consistency.

Replicated File Store

Default mode. Each node has its own local files. All modifications are synchronously replicated from ACTIVE to STANDBY. Provides maximum redundancy and no single point of failure.

Shared File Store

Both nodes access the same physical files via a shared filesystem. Set shared-store to true to enable. No network replication occurs. Availability depends on the shared storage.

Shared JDBC Store

Both nodes use the same JDBC database for persistence. Also requires shared-store to be true. No network replication occurs.

Configuration Example:

<swiftlet name="sys$store" shared-store="true"/>

Force Sync in Standalone Mode

The force-sync-in-standalone-mode property (under the transaction-log entity) controls whether the transaction log is forcibly synced to disk when the HA instance operates in STANDALONE mode (i.e., not participating in HA replication). By default, this is enabled (true), ensuring maximum durability when the node is running independently. When operating as ACTIVE in HA, the transaction log is kept in memory for performance, and only flushed to disk when switching to STANDALONE or during shutdown.

Configuration Example:

<swiftlet name="sys$store">
  <transaction-log force-sync-in-standalone-mode="false"/>
</swiftlet>

HA State Transitions and Store Behavior

The Store Swiftlet adapts its behavior based on the HA state (ACTIVE, STANDBY, STANDALONE):

  • In ACTIVE mode, all store operations are performed locally and synchronously replicated to the STANDBY. The transaction log is kept in memory for performance.
  • In STANDBY mode, the instance receives and applies all replicated operations from the ACTIVE, maintaining a hot backup.
  • In STANDALONE mode (when not connected to a partner), the store operates as a standard, non-replicated store, and the transaction log is always flushed to disk if force-sync-in-standalone-mode is enabled.

Switching between modes triggers appropriate initialization, replication, and file synchronization to ensure consistency.

Configuration Guide

Enable Shared Store Mode (Shared Filesystem or JDBC)

Use this scenario when both HA nodes should access the same physical store files (either via NFS/SAN or a shared JDBC database). This disables network replication and relies on the shared storage for persistence.

  1. Set the shared-store attribute to true on the sys$store swiftlet.
  2. Restart both HA nodes to apply the change.
<swiftlet name="sys$store" shared-store="true"/>

Disable Force Sync in Standalone Mode

Use this scenario if you want to improve performance when running in STANDALONE mode and are willing to accept the risk of data loss in case of a crash.

  1. Set the force-sync-in-standalone-mode attribute to false under the transaction-log entity.
  2. Restart the router for the change to take effect.
<swiftlet name="sys$store">
  <transaction-log force-sync-in-standalone-mode="false"/>
</swiftlet>

Configuration Reference

The top-level entity in routerconfig.xml is <swiftlet name="sys$store">.

<swiftlet name="sys$store"> Properties

These properties are attributes of the <swiftlet name="sys$store"> entity.

Parameter Type Default Mandatory Reboot Required Description
shared-store Boolean false No Yes Use a shared Store
<swiftlet name="sys$store" shared-store="false"/>

<backup> Entity

Backup Settings

This is a fixed child entity of <swiftlet name="sys$store">.

Parameter Type Default Mandatory Reboot Required Description
path String ./ No No Root Path for Backup Save Sets
keep-generations Integer 3 No No Number of Generations to keep (min: 1)
<swiftlet name="sys$store">
  <backup path="..." keep-generations="..."/>
</swiftlet>

<database> Entity

Database Settings

This is a fixed child entity of <swiftlet name="sys$store">.

Parameter Type Default Mandatory Reboot Required Description
path String ./ No Yes Path of the Database (page.db)
initial-db-size-pages Integer 25600 No Yes Initial Size of the Database in Pages (min: 10)
size-collect-interval Long 1000 No No Interval to collect the Usage
page-size-current Integer 2048 No No Current Size of the Database Pages
page-size-recommended Integer 2048 No No Recommended Size of the Database Pages
page-size-max Integer 32768 No No Maximum Page Size (min: 2048)
perform-compact-on-startup Boolean false No No Perform a compact of the page.db on startup if current page size is equal to recommended page size
perform-resize-on-startup Boolean false No No Perform a page resize on startup if the recommended size is greater than the current page size
<swiftlet name="sys$store">
  <database path="..." initial-db-size-pages="..." size-collect-interval="..." page-size-current="..." page-size-recommended="..." page-size-max="..." perform-compact-on-startup="..." perform-resize-on-startup="..."/>
</swiftlet>

<cache> Entity

Cache Settings

This is a fixed child entity of <swiftlet name="sys$store">.

Parameter Type Default Mandatory Reboot Required Description
min-size Integer 1024 No Yes Min. Size (Pages) (min: 512)
max-size Integer 2048 No Yes Max. Size (Pages) (min: 512)
<swiftlet name="sys$store">
  <cache min-size="..." max-size="..."/>
</swiftlet>

<transaction-log> Entity

Transaction Log Settings

This is a fixed child entity of <swiftlet name="sys$store">.

Parameter Type Default Mandatory Reboot Required Description
path String ./ No Yes Path of the Transaction Log (transaction.log)
checkpoint-size Long 104857600 No Yes Size at which a Checkpoint is performed (min: 1048576)
force-sync Boolean false No Yes Force a sync with the disk
force-sync-in-standalone-mode Boolean true No No Force a sync with the disk while the HA instance is in STANDALONE mode
<swiftlet name="sys$store">
  <transaction-log path="..." checkpoint-size="..." force-sync="..." force-sync-in-standalone-mode="..."/>
</swiftlet>

<swap> Entity

Swap Settings

This is a fixed child entity of <swiftlet name="sys$store">.

Parameter Type Default Mandatory Reboot Required Description
path String ./ No Yes Path of Swap Files
roll-over-size Long 10485760 No Yes Roll Over Size (min: 1048576)
<swiftlet name="sys$store">
  <swap path="..." roll-over-size="..."/>
</swiftlet>

<durable-subscriber> Entity

Durable Subscriber Settings

This is a fixed child entity of <swiftlet name="sys$store">.

Parameter Type Default Mandatory Reboot Required Description
path String ./ No Yes Path of Durable Subscriber Files
<swiftlet name="sys$store">
  <durable-subscriber path="..."/>
</swiftlet>