Data Lifecycle Diagrams
Hydrolix stores table data as individual partitions in object storage, each with a corresponding metadata row in a catalog database.
These diagrams show the lifecycles for data in both the catalog and the object store. They show which services create partitions, mark them inactive, remove storage objects, and manage the corresponding metadata entries.
To configure, see Set Data Retention Policies and the operational description of the Decay and Reaper services.
Catalog lifecycle⚓︎
Every partition in object storage gets a corresponding row in the catalog, and the services in this diagram are the ones that create, deactivate, and remove those rows. Intake, the merge controller, and the alter service add rows, the merge controller and decay mark rows inactive, and reap collection collects inactive rows for the reaper to delete.
---
config:
themeVariables:
fontSize: 18px
flowchart:
padding: 20
---
flowchart TB
classDef default stroke:#00A99D,stroke-width:2px
catalog[(Catalog)]
subgraph lifecycle-begin[Partition Creation]
intake[Intake
Services]
merge-controller[Merge
Services]
insert[Manual
Ingest]
alter[Alter
Service]
end
subgraph lifecycle-end[Partition Removal and Metadata Maintenance]
decay[Decay
Job]
reapsweep[Reap
Collection Job]
mergecleanup[Merge
Cleanup Job]
reaper[Reaper
Service]
end
catalog ~~~ decay
catalog ~~~ mergecleanup
catalog ~~~ reapsweep
catalog ~~~ reaper
intake --creates catalog entries
for new partitions--> catalog
merge-controller --marks original entries
inactive and inserts
new, merged entries--> catalog
insert --creates catalog entries
for new partitions--> catalog
alter --marks original entries
inactive and inserts
new, altered entries--> catalog
decay --marks old
partitions
inactive--> catalog
mergecleanup --collects
merged
inactive--> catalog
reapsweep --collects
old
inactive--> catalog
reaper --deletes inactive entries --> catalog
classDef dashed font-style:italic,stroke-dasharray: 3 3
Catalog and partition deletion⚓︎
Deleting a partition means removing both its catalog row and its files in object storage.
The merge cleanup and reap collection cron jobs find inactive rows and publish reap events into a RabbitMQ queue. The reaper consumes those events from the queue, deletes the files from object storage, and deletes the catalog rows.
The partition cleaner is an optional, scheduled service that removes files in object storage with no metadata entry in a catalog row. This catches partitions the reaper missed.
---
config:
themeVariables:
fontSize: 18px
flowchart:
padding: 20
nodeSpacing: 80
rankSpacing: 130
---
flowchart TB
classDef default stroke:#00A99D,stroke-width:2px
catalog[("Catalog<br/>(PostgreSQL)")]
rabbitmq@{ shape: das, label: "Persistent Queue\nRabbitMQ\n(stateful set)" }
storage@{ shape: lin-cyl, label: "Object\nStorage" }
reapsweep["Reap Collection<br/>(cron job)"]
mergecleanup["Merge Cleanup<br/>(cron job)"]
reaper["Reaper<br/>(deployment)"]
cleaner["Partition Cleaner<br/>(deployment)"]
%% Invisible edges keep the catalog in the top rank. The reaper edge comes
%% first so the layout engine keeps the reaper in the row when it breaks the
%% RabbitMQ read/write cycle. The repeated cleaner edges pull the catalog to
%% the right so its edge labels don't overlap.
catalog ~~~ reaper
catalog ~~~ reapsweep
catalog ~~~ mergecleanup
catalog ~~~ cleaner
catalog ~~~ cleaner
catalog ~~~ cleaner
catalog ~~~ cleaner
%% Edge order sets the left-to-right order of the row: cron jobs, then
%% reaper, then cleaner. The reaper's RabbitMQ edges come before its object
%% storage edge so RabbitMQ lands on the left.
reapsweep --collects<br/>old<br/>inactive<br/>(read)--> catalog
mergecleanup --collects<br/>merged<br/>inactive,<br/>unlocks<br/>(read/write)--> catalog
reapsweep --publishes<br/>reap events<br/>(write)--> rabbitmq
mergecleanup --publishes<br/>reap events<br/>(write)--> rabbitmq
reaper --deletes catalog entries corresponding to deleted object store files<br/>(write)--> catalog
rabbitmq --consumes
reap
events<br/>(read)--> reaper
reaper --writes to
retry
queue<br/>(write)--> rabbitmq
reaper --deletes partitions<br/>(write)--> storage
cleaner --verifies partition entries<br/>(read)--> catalog
cleaner --deletes partitions the catalog no longer references<br/>(read/write)--> storage
Partition states⚓︎
Partitions are written by intake, merge, alter services, or a client manually inserting data with INSERT INTO. Every partition is in one of the following states:
| Active? | Locked | Data age relative to age.max_age_days |
Description |
|---|---|---|---|
True |
No | under age.max_age_days |
Written by intake, merge, ALTER, or INSERT INTO. Queryable and eligible for merge. |
True |
No | over age.max_age_days |
Past retention but not yet identified by Decay, or the table has age.max_age_days set to 0. Still queryable. |
True |
Yes | any | Owned by the lock holder: a merge reservation, an ALTER job, or a manual lock on a problem partition. Queryable. Decay skips it. |
False |
No | any | This partition has been deactivated by decay or replaced with a new partition by merge or alter. Reaper deletes it once it has been inactive for reaper.max_age_days. |
False |
Yes | any | Locked in preparation either for removal (partitions replaced by a merge and waiting for Merge Cleanup, or problem partitions parked for inspection) or activation (new partitions from an ALTER job that hasn't committed yet). |
Problematic partitions can be removed from the system by locking the partition and setting the active flag to False. The data remain in the partition for inspection, but the query system doesn't consult the partition, since it's inactive.
Partition state diagram⚓︎
The query system uses partitions that are active whether locked or not. This diagram shows how a partition moves between the states in the table, and which service or job drives each transition. States with a bold outline are queryable.
---
title: Partition Lifecycle State Diagram
config:
themeVariables:
fontSize: 18px
---
stateDiagram-v2
classDef onbrand stroke:#00A99D,stroke-width:2px
old: active (old)
[*]:::onbrand --> active:::usable
active --> old:::usable : older than max age
alter:::onbrand: locked (altering)
active --> alter:::usable : ALTER job
alter --> inactive:::onbrand : ALTER job committed
merged : inactive (merged)
merging: locked (merging)
active --> merging:::usable : eligible for compaction
merging --> merged:::onbrand : marked by merge-controller
merged --> inactive : found by merge-cleanup
old --> inactive : marked by decay
inactive --> [*]:::onbrand : deleted by reaper
classDef usable stroke:#00A99D,stroke-width:4px