Repository navigation
ARTEMIS-6333 Relational Database Persistence Storage - #6838
Draft
clebertsuconic wants to merge 3 commits into
Draft
clebertsuconic wants to merge 3 commits into
clebertsuconic wants to merge 3 commits into
Conversation
clebertsuconic
force-pushed
the
new-storage
branch
7 times, most recently
from
October 29, 2026 01:12
fc29f44 to
1470bb6
Compare
Motivation: Artemis's append-only journal delivers outstanding throughput and is the ideal choice when fast local storage is available. However, many cloud and containerised deployments already operate managed relational databases and would benefit from an alternative persistence path that leverages that existing infrastructure — simplifying operations, backup, and disaster recovery without giving up the broker's asynchronous, non-blocking persistence contract. Modifications: Introduce a new `artemis-database-storage` module that implements the full broker persistence layer on top of JDBC, wired through the existing `StorageManager` / `PagingManager` SPIs so no protocol or core-broker code needs to change. Key design choices: - Group-commit / write-coalescing: `DataManager` buffers incoming writes and a scheduled timer flushes them in a single JDBC transaction, amortising the most expensive part (network round-trip + fsync) across many operations — the same technique database engines use internally (e.g. InnoDB group commit). - Command pattern with heterogeneous batching: each `DBData` subclass (messages, references, addresses, queues, prepared-TX, generic KV) dispatches itself to the correct `BatchableStatement`; a single transaction can therefore mix inserts and deletes across different tables atomically. - Worker pool with dedicated connections: multiple `DataWorker` instances, each owning its own JDBC `Connection` and full set of `PreparedStatement`s, cycle through a pool. `BorrowedWorker` adds a lease-based model for callers that need a connection for an extended sequence of operations. - Credit-based flow control: producers are throttled via a credit window so the broker cannot out-run the database. - Async write-behind with `IOCompletion` callbacks: callers never block on commit; each data item carries `storeLineUp()` / `done()` / `onError()` callbacks, preserving the same contract the journal already exposes. - Retry with reconnect: transient `SQLException`s are retried up to five times with connection re-establishment between attempts. - Database paging: `DatabasePagingManager` and `DatabasePagingStoreImpl` replace file-based paging when this store type is selected. `AddressSizeLimiter` is extracted from `PagingStoreImpl` so both the file and database paths share address-level flow control (max size, max messages, blocking, page-full rejection). - `DatabaseStorageMessageReader` provides cursor-based message reading from the database with configurable prefetch for queue consumption. - Six database dialects are supported out of the box: PostgreSQL, MySQL, Oracle, DB2, MS SQL Server, and HSQLDB, each with a dedicated `SQLProvider` handling type mappings and DDL differences. - `AbstractStorageManager` is extracted from `AbstractJournalStorageManager` so both the journal-backed and database-backed managers share common bookkeeping without duplication. Tests cover every layer: statement-level (insert/delete/update per entity), worker-level (retry, flow control, borrowed-worker lifecycle), full integration (StorageManager round-trips, real broker boot, cross-protocol, XA / prepared transactions), and stress (concurrent producers under sustained load). Result: Operators now have a choice between the journal — which remains the highest-throughput option for local storage — and a relational database backend that integrates naturally with managed database services, broadening the set of environments where Artemis can be deployed with minimal operational overhead. Assisted-By: Claude Opus 4.6 <noreply@anthropic.com>
clebertsuconic
force-pushed
the
new-storage
branch
from
October 29, 2026 12:24
1470bb6 to
5c9ce8f
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation:
Artemis's append-only journal delivers outstanding throughput and
is the ideal choice when fast local storage is available. However,
many cloud and containerised deployments already operate managed
relational databases and would benefit from an alternative
persistence path that leverages that existing infrastructure —
simplifying operations, backup, and disaster recovery without
giving up the broker's asynchronous, non-blocking persistence
contract.
Modifications:
Introduce a new
artemis-database-storagemodule that implementsthe full broker persistence layer on top of JDBC, wired through
the existing
StorageManager/PagingManagerSPIs so noprotocol or core-broker code needs to change.
Key design choices:
Group-commit / write-coalescing:
DataManagerbuffers incomingwrites and a scheduled timer flushes them in a single JDBC
transaction, amortising the most expensive part (network
round-trip + fsync) across many operations — the same technique
database engines use internally (e.g. InnoDB group commit).
Command pattern with heterogeneous batching: each
DBDatasubclass (messages, references, addresses, queues, prepared-TX,
generic KV) dispatches itself to the correct
BatchableStatement; a single transaction can therefore mixinserts and deletes across different tables atomically.
Worker pool with dedicated connections: multiple
DataWorkerinstances, each owning its own JDBC
Connectionand full set ofPreparedStatements, cycle through a pool.BorrowedWorkeradds a lease-based model for callers that need a connection for
an extended sequence of operations.
Credit-based flow control: producers are throttled via a credit
window so the broker cannot out-run the database.
Async write-behind with
IOCompletioncallbacks: callers neverblock on commit; each data item carries
storeLineUp()/done()/onError()callbacks, preserving the same contractthe journal already exposes.
Retry with reconnect: transient
SQLExceptions are retried upto five times with connection re-establishment between attempts.
Database paging:
DatabasePagingManagerandDatabasePagingStoreImplreplace file-based paging when thisstore type is selected.
AddressSizeLimiteris extracted fromPagingStoreImplso both the file and database paths shareaddress-level flow control (max size, max messages, blocking,
page-full rejection).
DatabaseStorageMessageReaderprovides cursor-based messagereading from the database with configurable prefetch for queue
consumption.
Six database dialects are supported out of the box: PostgreSQL,
MySQL, Oracle, DB2, MS SQL Server, and HSQLDB, each with a
dedicated
SQLProviderhandling type mappings and DDLdifferences.
AbstractStorageManageris extracted fromAbstractJournalStorageManagerso both the journal-backed anddatabase-backed managers share common bookkeeping without
duplication.
Tests cover every layer: statement-level (insert/delete/update per
entity), worker-level (retry, flow control, borrowed-worker
lifecycle), full integration (StorageManager round-trips, real
broker boot, cross-protocol, XA / prepared transactions), and
stress (concurrent producers under sustained load).
Result:
Operators now have a choice between the journal — which remains
the highest-throughput option for local storage — and a relational
database backend that integrates naturally with managed database
services, broadening the set of environments where Artemis can be
deployed with minimal operational overhead.
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com