Migrate heartbeat storage to ClickHouse - #1562
Open
skyfallwastaken wants to merge 17 commits into
Open
Conversation
Contributor
Greptile SummaryThe PR migrates canonical heartbeat storage and querying from PostgreSQL to ClickHouse while retaining PostgreSQL-backed allocation, lifecycle controls, and a fenced cutover process.
Confidence Score: 5/5The PR appears safe to merge because no eligible blocking failure remains in this follow-up review. No blocking failure remains. Important Files Changed
Sequence DiagramsequenceDiagram
participant Client
participant Rails as Rails / HeartbeatIngest
participant PG as PostgreSQL controls
participant Store as ClickHouse canonical store
participant Alias as ClickHouse aliases
participant Layouts as Query layouts
participant Repair as Delivery / repair jobs
Client->>Rails: Submit heartbeat
Rails->>PG: Acquire admission lock and allocate ID/version
Rails->>Alias: Reserve canonical and legacy hashes
Rails->>Store: Insert canonical payload
Rails->>Layouts: Publish user-first and time-first rows
Rails-->>Client: Return persisted heartbeat
alt Partial write or ambiguous timeout
Rails->>Repair: Enqueue reconciliation
Repair->>Alias: Resolve reserved identity
Repair->>Store: Restore canonical payload if missing
Repair->>Layouts: Repair layout acknowledgements
end
Reviews (17): Last reviewed commit: "Fix ClickHouse admin queue profile" | Re-trigger Greptile |
…-clickhouse Amp-Thread-ID: https://ampcode.com/threads/T-019ff1c9-6d91-755e-a097-b3c6a0654232 # Conflicts: # ARCHITECTURE.md
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.
Summary of the problem
Heartbeat volume makes PostgreSQL scans increasingly expensive across dashboards, projects, leaderboards and administrative tools. Existing caches and rollups also duplicate state and make heartbeat lifecycle operations harder to recover safely.
Describe your changes
CLICKHOUSE_REQUIRED=1makes gated suites fail rather than skip.Deployment contract
HEARTBEAT_STOREdefaults topostgresqland accepts onlypostgresqlorclickhouse. Production web and worker processes remain on PostgreSQL while ClickHouse is provisioned, migrated and backfilled. Mutations are fenced during online backfill, then all writes are fenced for the final pass and verification. Web and worker switch toclickhousetogether while both fences remain closed.Before PostgreSQL purge, rollback means switching reads back while writes remain fenced. Purge is the irreversible boundary because new ClickHouse heartbeats are not dual-written to PostgreSQL. Its final transaction locks the cutover row, rechecks the verified source boundary, records
purged_at, truncates payloads and rollups and resets user rollup generations atomically. An interruption rolls every change back. The empty PostgreSQL tables remain in schema history until a later explicit Rails migration after the rollback period.Account deletion applies ClickHouse tombstones before relational anonymisation completes. Account merge first commits a durable transfer control, then moves heartbeats asynchronously. Both source and surviving target reject writes while the transfer is pending. Source activity can remain globally visible and the surviving account can omit that activity until the retryable job completes.
heartbeat_storeis the recovery source of truth. Delivery reconciliation repairs aliases and incomplete layout acknowledgements. Query-layout repair rebuilds both layouts from the canonical store but cannot recreate canonical payload absent from a backup. After a stale ClickHouse restore, recovery reseeds PostgreSQL allocators, replays retained account transfer, account deletion and JA4 controls, repairs layouts and verifies state before traffic reopens. Ordinary heartbeats plus individual heartbeat delete/restore actions newer than the restored backup remain subject to the documented RPO because those actions have no durable PostgreSQL lifecycle controls.The supported server is exactly
26.7.3.19. Upgrades require an isolated backup restore, version-guard update, real ClickHouse coverage, production-sized load validation and a restore/rollback drill. The runbook also requires per-query and per-user limits, spill thresholds, disk and part alerts, off-node backups and recorded RPO/RTO before cutover.The deploy job depends on
test_clickhouse; repository branch protection must separately configure it as a required merge check. The retained MD5 fields hash is historical deduplication compatibility only, not cryptographic security or sensitive-data hashing.Screenshots / Media
No public production-derived data is attached. The only visual change restores deferred dashboard loading skeletons.