15 Using Journal Persistence

The Unified Persistence Journal stores partition data in append-only files and can also supply the primary and backup backing maps.

Use journal persistence in Coherence 26.1.0.0.0 or later when you want journal-based recovery and snapshots. Select the persistence engine separately from the cache backing-map type. Berkeley DB (BDB) remains supported and is the default persistence type when no type is selected.

Your application continues to use NamedMap or NamedCache. Storage configuration determines whether writes reach a separate backing map and journal, or whether the journal itself stores the backing-map data. This chapter explains application configuration, behavior, and migration; persistence administration and snapshot operations are described in the Administrator’s Guide.

The Unified Persistence Journal described in this chapter provides the journal persistence engine and optional primary and backup backing maps. The Elastic Data Journal provides RAM and flash journal storage tiers. Use journal-scheme with the journal persistence environment for a Unified Persistence Journal primary backing map; use ramjournal-scheme or flashjournal-scheme for an Elastic Data Journal backing map. See Using the Elastic Data Feature to Store Data for Elastic Data configuration.

This chapter includes the following sections:

Choosing a Journal Persistence Mode

Choose a separate persistence store, a journal primary backing map, or journal backup backing maps to match the service’s storage requirements.

Table 15-1 Journal storage choices

Mode Configuration Application implications
Side-channel persistence Existing backing map and an environment whose persistence-type is journal. Keep the existing map implementation. Writes update that map and the separate journal persistence store.
Journal primary backing map journal-scheme and a journal persistence environment. The journal is the backing store. Coherence bypasses the duplicate persistence side-channel write.
Journal backup backing map backup-storage/type set to journal and a journal environment that persists backups. Backup mutations write directly to the backup journal. Use active-backup for durable backup stores.

Primary and backup choices can be combined. A journal-scheme primary automatically selects journal backup maps when no explicit backup storage is configured. Configure the persistence environment’s backup mode and directory as well; automatic map selection alone does not select active-backup. An explicit backup-storage choice overrides automatic pairing.

In the combined primary and backup configuration, each copy writes its mutation once to its own journal. This describes storage routing, not a promise of one file system call, one device flush, or a change to the selected persistence mode’s acknowledgment semantics.

Configuring a Journal Persistence Environment

Define the journal engine and storage directories in an operational override, then reference that environment from the cache service.

Save the following complete operational override as journal-override.xml. Provide writable, member-specific storage locations with sufficient capacity before starting storage members. The application’s operating-system account owns the directories; cluster members must not share an active or backup store directory concurrently.

<?xml version="1.0"?>
<coherence xmlns="http://xmlns.oracle.com/coherence/coherence-operational-config"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://xmlns.oracle.com/coherence/coherence-operational-config coherence-operational-config.xsd">
  <cluster-config>
    <persistence-environments>
      <persistence-environment id="orders-journal">
        <persistence-mode>active-backup</persistence-mode>
        <persistence-type>journal</persistence-type>
        <active-directory system-property="orders.persistence.active">/var/coherence/orders/active</active-directory>
        <backup-directory system-property="orders.persistence.backup">/var/coherence/orders/backup</backup-directory>
        <snapshot-directory system-property="orders.persistence.snapshot">/var/coherence/orders/snapshot</snapshot-directory>
        <trash-directory system-property="orders.persistence.trash">/var/coherence/orders/trash</trash-directory>
      </persistence-environment>
    </persistence-environments>
  </cluster-config>
</coherence>

Load this file with -Dcoherence.override=journal-override.xml on every storage member. The system-property names in this example are application-defined deployment overrides. Set them before startup when the sample absolute paths are inappropriate for your platform.

Choose active, active-backup, active-async, or on-demand according to the persistence requirements. These names retain their existing persistence meaning. A journal-backed primary requires active persistence: use active or active-backup. On-demand and asynchronous side-channel configurations do not satisfy the journal-scheme primary requirement. Journal backup maps require backup persistence, so select active-backup for the primary/backup example.

Restrict access to journal, snapshot, migration, and trash directories. Recovered bytes still cross deserialization and application-type trust boundaries. See Limiting Resource Use and Protecting Persisted Data in the Security Guide.

Configuring Side-Channel Journal Persistence

Keep the existing primary backing map while selecting the journal persistence engine.

Use the environment from the preceding topic and save the following as orders-cache-config.xml. Start storage members with -Dcoherence.cacheconfig=orders-cache-config.xml. This complete example uses an on-heap primary map; replace it with another supported backing map when required by the application.

<?xml version="1.0"?>
<cache-config xmlns="http://xmlns.oracle.com/coherence/coherence-cache-config"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://xmlns.oracle.com/coherence/coherence-cache-config coherence-cache-config.xsd">
  <caching-scheme-mapping>
    <cache-mapping><cache-name>orders</cache-name><scheme-name>orders</scheme-name></cache-mapping>
  </caching-scheme-mapping>
  <caching-schemes>
    <distributed-scheme>
      <scheme-name>orders</scheme-name>
      <service-name>OrdersService</service-name>
      <backup-count>1</backup-count>
      
      <backing-map-scheme><local-scheme/></backing-map-scheme>
      <persistence><environment>orders-journal</environment></persistence>
      <autostart>true</autostart>
    </distributed-scheme>
  </caching-schemes>
</cache-config>

Writes update the primary backing map and the separate journal persistence store. Recovery reads the persisted partition data back into the backing map. Keep the existing cache and service identities during a planned storage-engine migration.

Configuring Journal Primary and Backup Maps

Use journal-backed maps to avoid a separate backing-map copy and its duplicate persistence write.

Use the journal environment from this chapter with the following complete cache configuration. It explicitly selects journal backup storage so the primary, backup, and persistence choices are visible together. Save it as orders-cache-config.xml.

<?xml version="1.0"?>
<cache-config xmlns="http://xmlns.oracle.com/coherence/coherence-cache-config"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://xmlns.oracle.com/coherence/coherence-cache-config coherence-cache-config.xsd">
  <caching-scheme-mapping>
    <cache-mapping><cache-name>orders</cache-name><scheme-name>orders</scheme-name></cache-mapping>
  </caching-scheme-mapping>
  <caching-schemes>
    <distributed-scheme>
      <scheme-name>orders</scheme-name>
      <service-name>OrdersService</service-name>
      <backup-count>1</backup-count>
      <backup-storage><type>journal</type></backup-storage>
      <backing-map-scheme><journal-scheme/></backing-map-scheme>
      <persistence><environment>orders-journal</environment></persistence>
      <autostart>true</autostart>
    </distributed-scheme>
  </caching-schemes>
</cache-config>

The standard extensible cache factory supports these schemes. The legacy DefaultConfigurableCacheFactory does not support journal backup storage. A missing journal environment, or one selecting BDB, is a startup configuration error. In the 26.1 cache schema, backup-storage precedes backing-map-scheme and persistence.

Removing the explicit backup-storage element produces automatic journal pairing for this primary map. To retain a different supported backup-map type, configure it explicitly. Keep a positive backup count and enough storage members for the required redundancy.

Understanding Journal Cache Behavior

Journal-backed caches preserve map operations and event contracts while changing the storage path.

  • Map insert, update, and delete events retain their usual meaning. Register application listeners through the cache API.
  • Caches sharing a service have separate extents inside each partition. Clearing one cache does not clear another cache’s extent.
  • Do not assume that a disk-backed map has the heap capacity or eviction behavior of a local on-heap cache. Size disk capacity, indexes, metadata, and any configured memory tiers separately.
  • Expiry and removal are data mutations. Expired or deleted data may remain physically present until old files are reclaimed; application removal is not a secure erase operation.
  • A checkpoint speeds recovery; it is not the durability boundary. Graceful shutdown and recovery can create checkpoints, and background checkpointing and compaction consume I/O.

Configure application-level expiry and eviction only where the selected map supports them; retain the service and backing-map configuration required by those features. Do not attach local-map-only eviction settings to the empty journal-scheme element.

Recovering and Observing Journal Data

Use the standard persistence lifecycle and account for journal replay, compaction, and snapshot storage.

On recovery, the engine loads a usable checkpoint and replays subsequent journal entries. Without a usable checkpoint, it scans the journal. Entry checksums help detect corrupt or incomplete data; they do not authenticate the writer or replace protected storage and backups.

Standard persistence snapshot, recovery, and archival operations apply. A snapshot rotates appending files and captures checkpoint and metadata files. Immutable journal files can be hard-linked when the file system supports it, with copying as a fallback. Capacity planning must include retained snapshots, compaction overlap, and temporary migration data; a hard link does not eliminate the lifetime of the referenced blocks.

Observe service recovery status, ownership, and persistence failures together with file system capacity, latency, and journal compaction activity. A service that has not completed recovery is not ready merely because its JVM is running. Follow the Administrator’s Guide for coordinated snapshot creation, archive operations, recovery quorum, and repair.

If startup rejects the configuration, verify the environment name, persistence-type, directory ownership and the primary/backup scheme pairing before changing application code.

Migrating BDB Data to Journal Persistence

Choose a controlled snapshot import or a qualified rolling transition and preserve a separate rollback point.

Changing the persistence type does not make BDB files journal files. For a controlled cutover, create and verify a BDB snapshot, stop the service or cluster as required by the operational procedure, and configure a journal environment with a separate destination. Set migration-source-directory to the BDB snapshot directory before its first startup.

<persistence-environment id="orders-journal-import">
  <persistence-mode>active</persistence-mode>
  <persistence-type>journal</persistence-type>
  <active-directory>/var/coherence/orders-journal/active</active-directory>
  <snapshot-directory>/var/coherence/orders-journal/snapshot</snapshot-directory>
  <trash-directory>/var/coherence/orders-journal/trash</trash-directory>
  <migration-source-directory>/var/coherence/bdb/snapshot/orders-cutover</migration-source-directory>
</persistence-environment>

This fragment belongs under cluster-config/persistence-environments. Reference its ID from the cache service. The journal environment opens the BDB snapshot as a read-only source and records migration completion. An interrupted import is retried at the next startup. Keep the source snapshot intact and verify recovered cache contents and application behavior before removing the initial-import setting.

A rolling engine transition persists transferred partitions into the engine configured on each restarted member. Qualify the exact source and target release combination, redundancy, recovery quorum, and available capacity first, and restart one member at a time only after the service is healthy. Do not use a full-cluster outage midway through the transition as a migration technique.

Legacy active BDB files found at a journal destination can be quarantined to the configured trash directory. Preserve and inspect them rather than treating quarantine as a verified import. A rollback requires a supported release/configuration and compatible persisted data, or restoration of the retained BDB snapshot; journal files cannot be opened by selecting BDB again.

Tuning Journal Persistence

Start with the journal defaults and tune checkpoint and compaction work using measured storage behavior.

Table 15-2 Journal tuning properties

System property Default Meaning
coherence.persistence.journal.max.file.size 128MB Maximum journal file size per extent; affects rotation and compaction granularity.
coherence.persistence.journal.compaction.min.load.factor 0.5 Files with a lower live-byte fraction become compaction candidates.
coherence.persistence.journal.checkpoint.threshold 64MB Bytes written before a periodic checkpoint; zero disables this trigger.
coherence.persistence.journal.checkpoint.adaptive.initial.writes 1000 Initial adaptive write-count threshold; zero disables the adaptive trigger.
coherence.persistence.journal.checkpoint.adaptive.min.writes 1000 Lower adaptive write-count threshold.
coherence.persistence.journal.checkpoint.adaptive.max.writes 1000000 Upper adaptive write-count threshold.
coherence.persistence.journal.checkpoint.adaptive.target.millis 2.0 Per-extent checkpoint-duration budget used to back off checkpoint frequency.
coherence.persistence.journal.checkpoint.adaptive.warmup.count 4 Initial checkpoint observations excluded from adaptation.

Set deployment properties before the persistence environment starts. Disabling one checkpoint trigger leaves the other trigger available. Account for the number of partitions and caches: a per-extent threshold does not describe a service-wide I/O budget. Measure restart time, steady-state mutation latency, and free space together.