Skip to content

Don't treat transient lock failures as a storage-version mismatch (#977)#983

Merged
erikdarlingdata merged 1 commit into
devfrom
feature/977-storage-version-detection
May 22, 2026
Merged

Don't treat transient lock failures as a storage-version mismatch (#977)#983
erikdarlingdata merged 1 commit into
devfrom
feature/977-storage-version-detection

Conversation

@erikdarlingdata
Copy link
Copy Markdown
Owner

Summary

Fixes the data-loss half of #977. DuckDbInitializer.IsStorageVersionError matched generic DuckDB open failures ("unable to open database", "serialization error") that also occur on transient lock contention and on a WAL recovering from an unclean shutdown. When Lite is killed abruptly — e.g. an idle VM logging the user off — the next launch could match that predicate and run MigrateViaParquetAsync, which moves the live monitor.duckdb aside and starts with empty tables. To the user this looks like "lost all historical data" after an upgrade.

Changes

  • Narrowed IsStorageVersionError to genuine incompatible-format signals only ("failed to deserialize", "trying to read a database file with version", "storage version").
  • Added IsTransientLockError and OpenDatabaseAsync, which retries the open up to 5 times for lock contention (a just-killed prior instance, antivirus) instead of rebuilding.
  • Any other open failure now propagates instead of silently triggering the destructive Parquet rebuild.

Test plan

  • dotnet build Lite/PerformanceMonitorLite.csproj -c Debug — clean (0 warnings, 0 errors)
  • Storage-version mismatch path unchanged: a genuine incompatible file still migrates via Parquet.
  • Transient lock now retries instead of rebuilding; other open failures surface instead of silently emptying the DB.

🤖 Generated with Claude Code

DuckDbInitializer.IsStorageVersionError matched "unable to open database"
and "serialization error" — generic DuckDB open failures that also occur
on transient lock contention or a WAL recovering from an unclean shutdown.
When Lite is killed abruptly (e.g. an idle VM logging the user off), the
next launch could match that predicate and run MigrateViaParquetAsync,
which moves the live monitor.duckdb aside and starts with empty tables —
surfacing as "lost all historical data" after an upgrade.

- Narrow IsStorageVersionError to genuine incompatible-format signals
  ("failed to deserialize", "trying to read a database file with version",
  "storage version") only.
- Add IsTransientLockError and retry the open up to 5 times for lock
  contention (a just-killed prior instance, antivirus) instead of rebuilding.
- Any other open failure now propagates instead of silently triggering the
  destructive Parquet rebuild.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@erikdarlingdata erikdarlingdata merged commit 4697ac8 into dev May 22, 2026
2 checks passed
@erikdarlingdata erikdarlingdata deleted the feature/977-storage-version-detection branch May 22, 2026 12:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant