Multi-Tenancy (Fluid Clusters)
multi_tenancy. Flags and environment
variables cannot enable it. To license this feature, contact the
AetheriusDB team at
aetheriusdb.com or
aetheriuslabs.com.
Set on the orchestrator and on every worker.
See Licensing → Premium features.
What it is
Section titled “What it is”A cluster can serve many tenants at once. Each connection executes for exactly one tenant, every statement it sends is routed for that tenant, and on the worker each tenant’s rows live in a directory of their own. A tenant never sees, counts or deletes another tenant’s rows — not through a query, not through an index, not through a backup.
Tenant 0 is the system tenant. It maps to the worker’s root data
directory, so a single-tenant deployment needs no configuration at all.
Turning it on
Section titled “Turning it on”Multi-tenancy is off by default. Set the flag on the orchestrator and on every worker:
AETHERIUS_ENABLE_MULTI_TENANCY=1With the flag off, any statement or request for a tenant other than 0 is
refused before anything is routed or read: the client gets a
TenancyViolation error (SQLSTATE 08P01), and a worker that receives such a
request directly aborts it. Both ends check independently, so a worker never
relies on the orchestrator having done so. Every refusal is counted.
How a connection gets its tenant
Section titled “How a connection gets its tenant”The tenant is an attribute of the connection’s session, set by the application that embeds the orchestrator. It is read once per statement and travels with the statement to the worker. Nothing in the SQL text names the tenant, so a query cannot be rewritten to reach another tenant’s data.
Where a tenant’s data lives
Section titled “Where a tenant’s data lives”On a worker, tenant 7 reads and writes under tenant_7/ inside the data
directory; the system tenant uses the data directory itself. An INSERT for a
tenant lands in that tenant’s directory as a new container, and a SELECT only
ever opens the blocks in the connection’s own directory. Two tenants inserting at
the same time never touch the same file.
Noisy neighbours
Section titled “Noisy neighbours”One tenant cannot occupy the cluster. Each tenant may have a bounded number of statements in flight at the orchestrator:
AETHERIUS_MAX_CONCURRENT_QUERIES_PER_TENANT=50 # the defaultA statement over the limit is refused immediately with a RESOURCE_EXHAUSTED
error and never reaches a worker; other tenants are unaffected. The slot is
released when the statement finishes, fails, or the connection drops, so a
crashed client cannot pin a tenant’s quota.
Per-tenant columns without downtime
Section titled “Per-tenant columns without downtime”A cluster table’s schema can grow without rewriting a single file:
- Add a column with a default — every existing row reads the default until
the column is physically written for that tenant.
SELECTandWHEREuse it like any other column. - Add a nullable column — existing rows read
NULL. - Per-tenant overlays — a column that exists for one tenant only, invisible to every other tenant of the same table.
- Materialise — once a tenant’s new data carries the column physically, mark it materialised for that tenant; other tenants keep the default.
These are declared through the orchestrator’s schema API
(aetherius_orchestrator::catalog::TableSchema, installed with
catalog::install), not through SQL in this release.
Snapshots and constant-time restore
Section titled “Snapshots and constant-time restore”A tenant snapshot is taken on the worker in one request and is complete in the time it takes to link the tenant’s files — it does not copy bytes, so a terabyte tenant snapshots in milliseconds. Every file the tenant owns is included: its containers and all of their sidecars (deleted-row marks, indexes and string data). A snapshot is immutable; asking for the same snapshot id twice is refused.
A restore is a routing change, not a copy: from the next statement on, every
read and write for that tenant is served from the snapshot. Restoring to
snapshot 0 returns the tenant to its live data. Nothing is moved and nothing
waits.
Both are orchestrator API calls in this release
(aetherius_orchestrator::topology::snapshot_tenant and
restore_tenant_snapshot).
What is counted
Section titled “What is counted”Refused statements and refused worker requests (tenancy), admitted and rejected statements per tenant (quota), snapshots requested, and the number of frames shipped for non-system tenants. See Observability.
Limits in this release
Section titled “Limits in this release”- The tenant id is a session attribute set by the embedding application; the wire protocols do not yet carry a client-side “use tenant N” setting.
- Schema changes, snapshots and restores are API calls, not SQL statements.
- A worker discovers each tenant’s directory lazily on first use; a directory created by hand is picked up on the next statement for that tenant.