Writer-pointing READ_DATABASE_URL accepted silently; route telemetry reports replica/fresh from the writer
- Dominant language
- Rust
- Stars
- 32.7k
- Forks
- 4.3k
- Avg merge
- 1d 13h
- Merged PRs (30d)
- 253
Description
## Summary
Max's live redteam of #3268 (finding 5, thread cf5deba4 in #buzz-read-only-replica-usage; evidence `RESEARCH/PR3268_LIVE_REPLICA_REDTEAM.md`): pointing `READ_DATABASE_URL` at the **writer** is accepted silently, and route telemetry then reports `replica / fresh` while debug backend identity shows the writer pod. The freshness fence is trivially satisfied (the "replica" has zero lag because it IS the writer), so nothing is unsafe — but `buzz_db_route_decision` becomes semantically misleading: operators watching the rollout dashboards would believe replica offload is working when every byte still comes from the writer.
## Suggested fix
At boot (or on first routed read), compare backend identity between the writer and reader pools — e.g. `pg_control_system().system_identifier` + `pg_is_in_recovery()`, or the existing Aurora identity probe. If the reader connection reports `pg_is_in_recovery() = false` and matches the writer's identity, either:
- log a loud warning and label routes `replica_is_writer` instead of `replica/fresh`, or
- treat it as a misconfiguration and refuse the reader pool (log + serve all-writer), matching the fail-closed posture everywhere else.
Aurora caveat: `cluster-ro` legitimately resolves to the writer when the cluster has no readers, so a hard refusal must not crash — degrade to all-writer with a clear log line.
Low priority relative to #3643; nothing serves wrong data. Refs: #3268, #3643.
Contributor guide
Research direction
Start with RESEARCH/PR3268_LIVE_REPLICA_REDTEAM.md and the existing Aurora identity probe, then trace the boot or first routed-read path that produces buzz_db_route_decision. Verify how writer and reader backend identities and pg_is_in_recovery() are available. Done means writer-targeted readers are clearly labeled or degraded to all-writer without breaking the Aurora no-reader case.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- postgresql, rust
- Domain
- backend, databases, observability
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100