Migrate vega Attic metadata from SQLite to PostgreSQL #6
Labels
No labels
host:electra
host:fleet
host:lyra
host:vega
host:vega
phase:cutover
phase:deploy
phase:mcp
phase:module
phase:packaging
phase:prep
phase:validation
project:attic-postgres-lyra-rollout
project:auto-update-reliability
project:declarative-purity-cleanup
project:external-review
project:host-facts-refactor
project:lyra-nixos-deploy
project:lyra-service-stack-migration
project:nebula-mesh-network
project:security-hardening
project:service-stack-migration
project:vega-sillytavern-cutover
service:auto-update
service:mem0
service:sillytavern
No milestone
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
nimmo/nixos-config#6
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Goal
Move the production Attic instance on
vegafrom local SQLite metadata to PostgreSQL before introducing dual-node serving.Scope
This issue covers the work from
projects/attic-postgres-lyra-rollout.mdPhase 2.Acceptance Checklist
atticdonvegacleanly./var/lib/atticd/server.dbbefore changing anything.vegato PostgreSQL-backed Attic and start it successfully.Procedure Outline
atticdonvega.vegato use PostgreSQL.atticdand validate both HTTP responses andnix copyreads.Verification
Known-good paths called out in the note:
6nli808zpb1k9vk7cz175m2ri78455rl-ollama-0.30.74da5p6rwzj366cfsq0xslgqi1q7j5nbr-cuda12.9-libcublas-12.9.1.4-libdwpxiy6qmw74y2fchx4jfzvpsh3q7p9a-paseo-desktop-0.1.102-beta.1Rollback
If migration fails:
atticd.atticdonvega.Initial migration-path research is done.
Findings so far:
secrets/attic.yaml, and a stagedvegaactivation succeeded with the renderedatticd-envcarryingATTIC_SERVER_DATABASE_URL.vegausing the real Attic credentials was tested successfully; the target database is reachable and currently empty (Did not find any relations.).atticd db-migrations/ the server startup path can apply schema migrations to the configured database.Next step is to treat the migration itself as an explicit cutover exercise:
Live-state check on
vegasuggests the actual SQLite -> PostgreSQL cutover has not happened yet.Observed today:
atticd.servicehas been continuously running since2026-07-05 19:35:52 BST./var/lib/atticd/server.dbis995897344bytes, owned byatticd:atticd, and its mtime is2026-07-06 14:10.vegaand is still empty (Did not find any relations.).Inference:
vegais almost certainly still writing to / serving from SQLite.That means issue #6 remains the first real metadata migration step, not just a post-migration cleanup.
Proposed cutover shape for this issue, based on the live-state check:
Recommended migration approach
pgloaderfor the one-off SQLite -> PostgreSQL metadata copy rather than expecting Attic itself to convert between engines.Suggested execution order on
vegaatticdcleanly./var/lib/atticd/server.db..tables, row counts) so we know what was copied.pgloaderfrom the SQLite file into the target PostgreSQL DB.atticdwith the PostgreSQL-backed configuration and let Attic apply normal schema migrations there if needed.nix-cache-info, known-good.narinfolookups, and anix copy --fromread.Why this is the current recommendation
Migration attempt found the next operational blocker:
pgloaderfailed withCANTOPENon/var/lib/atticd/server.db.0600and owned byatticd:atticd, so runningpgloaderas the regularnimmouser cannot read it directly.Implication:
pgloadercan open the SQLite source file.Follow-up on the migration attempt:
vega, usernimmohas primary groupusers, not a matchingnimmogroup./tmpstayed root-owned because it was created viasudo, so the subsequentchown nimmo:nimmofailed andchmodas the unprivileged user also failed.Practical fix:
install -o nimmo -g users -m 600 ...) before runningpgloader.Another concrete migration finding:
pgloaderfailed when creating PostgreSQL tables from the SQLite schema because it generated invalid types such astimestamp_with_timezone_text.pgloaderschema inference is not compatible with Attic's SQLite schema as-is.Revised migration approach:
pgloadercreate the PostgreSQL schema.pgloaderin data-only mode into the already-created Attic schema.This keeps schema authority with Attic and limits
pgloaderto row-copying, which should avoid the invalid type generation seen here.Latest migration checkpoint:
atticdinstance did not actually connect to the PostgreSQL URL during startup.Most likely causes now:
atticdenvironment file still contains the old SQLite URL,Next step is to inspect the active systemd unit environment and rendered Attic config on
vegabefore attempting any more data-copy work.Current diagnosis after inspecting the live
vegaunit:atticd.serviceis definitely reading/run/secrets/rendered/atticd-env.ATTIC_SERVER_DATABASE_URL=postgresql://...@nova.mesh:5432/atticd.Most likely remaining explanation:
checked-attic-server.tomlstill contains adatabase.urlentry pointing at SQLite, and Attic is using that explicit config value instead of the env-backed default.Next diagnostic step:
/nix/store/...-checked-attic-server.tomldirectly fordatabase,sqlite,postgres, orserver.dbbefore attempting further migration work.Root cause of the failed PostgreSQL cutover is now confirmed and patched in the repo.
What was happening
atticdunit correctly loaded/run/secrets/rendered/atticd-envwithATTIC_SERVER_DATABASE_URL=postgresql://....[database]url = "sqlite:///var/lib/atticd/server.db?mode=rwc"services.atticdmodule, which sets a default SQLitedatabase.urlinsettings.database.urlis absent from config, the explicit SQLite value always won.Repo fix
modules/services/atticd.nixto forceservices.atticd.settings.database = {}so the generated TOML no longer bakes in the nixpkgs SQLite default.nix flake checkpasses with this change.Next step
vega.sqlite:///var/lib/atticd/server.db?mode=rwc.Post-fix redeploy result:
checked-attic-server.tomlfiles in/nix/storeis expected; they are previous generations and not evidence that the current generation is still on SQLite.This moves issue #6 from configuration/debugging into the actual metadata-copy phase: next step is to stop
atticd, run a data-only migration from the SQLite copy into the now-initialized PostgreSQL schema, then restart and verify cache reads.The next blocker was only
pgloaderinvocation syntax:pgloader --with "data only, reset sequences, disable triggers" ...failed at argument parsing before any database work began.Practical adjustment:
WITH data only, reset sequences, disable triggersclause instead of relying on the CLI--withparser.The data-copy phase is effectively successful.
Observed from the
pgloaderrun:cache,chunk,object,chunkref, andnarrows copied into PostgreSQL.seaql_migrationswithduplicate key value violates unique constraint "seaql_migrations_pkey".Interpretation:
seaql_migrationswas already populated by Attic's own migration runner.seaql_migrationscopy is not required for correctness once the schema already exists.Next step:
atticd, and verify public cache reads plus anix copy --fromread.Verification after the PostgreSQL cutover is mixed, so issue #6 is not ready to close yet.
Observed after starting
atticdon PostgreSQL:.narinfo(example:4da5p6rwzj366cfsq0xslgqi1q7j5nbr-cuda12.9-libcublas-12.9.1.4-lib).NoSuchObject/ missingnar/...from the cache (example:6nli808zpb1k9vk7cz175m2ri78455rl-ollama-0.30.7).Interpretation:
Next step:
Follow-up integrity check on the missing
6nli808zpb1k9vk7cz175m2ri78455rlsample:store_path_hashreturned noobjectrow and therefore no linkednarrow in the checked database.Implication:
6nli...sample was stale and its absence is not evidence of migration loss.Next step remains to compare the same
store_path_hashlookup in both SQLite and PostgreSQL so the verification set can be corrected or the missing-row path can be debugged precisely.Table-count comparison shows the PostgreSQL cutover is still incomplete.
Current counts:
object: 6533nar: 6427chunk: 1772151chunkref: 284215cache: 1object: 6477nar: 6382chunk: 1707116chunkref: 276611cache: 1Interpretation:
Consequence:
pgloaderproduced lower final row counts in PostgreSQL than exist in the SQLite source before deciding whether to retry with a different import strategy or roll back to SQLite pending a safer migration path.Operational decision for this migration:
Practical implication:
Recommended follow-up after the cutover:
Resolution path changed after validating the partial PostgreSQL migration:
Why this is preferable now:
Next action is a coordinated wipe of:
Fresh-cache bootstrap after the full reset succeeded.
Completed on
vega:nixoscache in the empty PostgreSQL-backed Attic instance,nixoscache as public.This was the missing post-reset step after wiping metadata and storage: an empty Attic DB has schema but no cache definitions, so
/nixos/nix-cache-infocannot work until thenixoscache row is recreated.At this point the remaining verification is straightforward:
/nixos/nix-cache-infonow responds through Attic/proxy,.narinfoentries miss cleanly,Final verification after the reset-based resolution passed.
Current state:
http://127.0.0.1:8081/nixos/nix-cache-inforeturns200 OK,https://attic.nimmog.uk/nixos/nix-cache-inforeturns200 OK,.narinforequests now miss cleanly with404 NoSuchObject, which is the expected behavior for an empty fresh cache.Issue outcome:
nixoscache on PostgreSQL, and let future pushes/builds repopulate it.Follow-up operational note:
nimmo referenced this issue2026-07-20 15:34:36 +01:00