Architecture overview
AxialDB is a database-neutral analytical engine that runs beside an operational database.
MySQL is the first supported host; this page describes that integration. It adds an
analytical path without changing how your application writes. A storage-engine plugin
exposes analytical views as ordinary tables. A separate
process, axialdb-engine, stores them as columnar Parquet and answers the
heavy queries. Views can be static snapshots or follow the binlog. InnoDB stays the system
of record and is never written to by AxialDB.
What each layer does
-
MySQL plugin.
Registers
ENGINE=AXIALDBtables. For aggregate queries it pushes the wholeGROUP BYto the engine and returns only the grouped rows, so MySQL does not pull millions of rows through the handler. Queries it cannot push, such as joins to InnoDB tables, still work; MySQL reads the view's rows and finishes the query itself. -
Analytical engine.
axialdb-engineruns as its own service on the same host, talking to the plugin over loopback. It uses a vectorized columnar executor (Apache DataFusion). Memory and CPU spent on reports are outside the mysqld process. The engine, storage format, and CDC write-ahead log are database-neutral; MySQL-specific code lives in the plugin and the binlog reader. MySQL is the first supported host, and others are planned on the same engine. - Local columnar store. Each view is a set of Parquet files under the engine's data directory. Live views keep a base generation plus a small merge-on-read overlay, so updates apply without rewriting the table. Readers pin a consistent generation; files a query is reading are not removed until it finishes.
How the binlog is read
Live views are fed by ce-stream,
our own open-source change-stream reader. It connects to MySQL the way a replica does,
with its own server_id, and reads ROW-format binlog events. It never writes to
the source database.
- Only the tables you watch. ce-stream subscribes to the source tables behind your live views and ignores the rest of the binlog.
- Whole transactions. Changes are delivered per committed transaction, with full row images, so a view never shows half of a transaction.
- Durable and resumable. The engine appends each transaction to its own write-ahead log before applying it and records the GTID position. After a restart it resumes from that GTID instead of rescanning the source.
- Consistent first load. A new live view takes its initial snapshot and the binlog position together, then replays changes that arrived during the load. Until that catch-up finishes, reads on the view are refused rather than served partially.
-
Fails closed.
A change the view cannot apply safely, such as a
TRUNCATEor a breakingALTERon a source table, marks the view for resync instead of serving quietly wrong numbers.
Requirements on the MySQL side: binlog_format=ROW,
binlog_row_image=FULL, binlog_row_metadata=FULL, GTID mode on, and a
user with REPLICATION SLAVE, REPLICATION CLIENT, and SELECT
for the engine.
Two ways a view stays current
Any SELECT MySQL can run, including aggregates and complex joins. Data is as of creation time until you recreate the view.
COMMENT='cdc' on one table, or a fact table left-joined to its dimensions,
with a primary key and plain source columns. Inserts, updates, and deletes apply
incrementally, usually within seconds.
Performance on one representative query, with hardware and every run, is on the measurements page.