feat(server): add --flush_on_promotion to flush data when promoted with REPLICAOF NO ONE - #8051
feat(server): add --flush_on_promotion to flush data when promoted with REPLICAOF NO ONE#8051nmass-betpawa wants to merge 5 commits into
Conversation
Qodo reviews are paused for this user.Troubleshooting steps vary by plan Learn more → On a Teams plan? Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center? |
PR Summary by QodoFlush dataset on replica promotion via REPLICAOF NO ONE (opt-in flag)
AI Description
Diagram
High-Level Assessment
Files changed (2)
|
Code Review by Qodo
🟡 Remediation Recommended 1. Stale reads after promotion
|
Qodo reviews are paused for this user.Troubleshooting steps vary by plan Learn more → On a Teams plan? Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center? |
1 similar comment
Qodo reviews are paused for this user.Troubleshooting steps vary by plan Learn more → On a Teams plan? Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center? |
|
Hi @nmass-betpawa, thank you for this but before I follow up I have a question:
I am not sure how the operator works but it seems this should Why not add the functionality to the operator ? In other words, the operator could also do I guess: All in all based on my understanding this should not be the responsibility of dragonfly |
Summary
Adds an opt-in
--flush_on_promotionflag that makes an instance drop its whole dataset themoment it is promoted to master with
REPLICAOF NO ONE. This is for cache deployments that mustnever serve stale data after an unplanned failover: the promoted replica can be behind the master
that just died, and today there is no way to have the new master start empty without racing the
promotion from the outside.
Concretely, on Kubernetes the operator reacts to a dead master by sending
REPLICAOF NO ONEto areplica and only afterwards flipping the
role: masterpod label that the Service selects on.Flushing from a sidecar or an external controller therefore always lands somewhere in that window
and can wipe writes that the new master has already accepted. Doing it inside
ReplicaOfNoOneremoves the race entirely: the dataset is gone before anything outside the process learns about the
new role.
Changes
--flush_on_promotion(defaultfalse) insrc/server/server_family.cc.ServerFamily::ReplicaOfNoOnetracks whether it actually promoted the instance and, when theflag is set, calls the existing
ServerFamily::FlushAll()helper on the default namespace.test_flush_on_promotionintests/dragonfly/replication_test.py.Behavior
false, so there is no change for existing deployments.REPLICAOF NO ONEpath is affected.REPLTAKEOVERpromotions are deliberately leftalone: a takeover is coordinated and loses no data, and it is what the operator uses for rolling
updates -- flushing there would give a cold cache and a backend load spike on every upgrade.
REPLICAOF NO ONEstays idempotent. Thepromotedguard means that issuing it against aninstance that is already a master is still a no-op, so operator reconciliation re-sending the
command cannot wipe a live dataset.
SwitchState(LOADING, ACTIVE)so the FLUSHALL transaction does not runwhile the instance is still in
LOADING.Testing
The test covers both directions: a replica with the flag set has
dbsize == 0right afterREPLICAOF NO ONE, and a secondREPLICAOF NO ONEagainst the now-master keeps its data.