fix: an old primary stays read only until it proves it holds the VIP (keel#104) #111
No reviewers
Labels
No labels
accessibility
bug
documentation
duplicate
enhancement
good first issue
help wanted
invalid
question
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Keel-Linux/keel!111
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "fix/old-primary-read-only-until-proven"
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?
Fixes #104 (bug B2 of the real-node MariaDB pair test, Keel-Linux/handbook#60).
Problem
After a crash and a boot, the old primary read its own claim of the VIP from
/var/lib/keel/vipandkeel database followsetread_only OFF. The other node held the VIP at a newer epoch. The old primary was writable for 31 s, untilkeel vip checklearned the newer epoch. A write in that window makes an errant GTID.Change
keel/system/dbfollow.py: on a node whose newest claim is its own, follow liftsread_onlyonly when the VIP is onwg0. keel adds the VIP towg0only after a proof:keel vip promoteafter its new claim;keel vip checkwhen a peer answered and no peer knows a newer claim; with etcd, the controller after a lease renewal that the majority confirmed (the kernelvalid_lftends it). A boot removes the address. Without the proof, follow setsread_only ONand the root lock, and writes no primary role file. Follow waits up to 15 s (PROOF_WAIT) for the address, because a promote records its claim before it adds the VIP.keel/mesh/vipnode.py(carry_held): when keel adds the VIP towg0, it writes the VIP's state again, sokeel-database-follow.pathruns follow again.keel database watchalso runs follow again within 30 s.keel/system/dbwatch.py(needs_follow): follows a server again when it takes writes with no claim, or while the VIP is not onwg0(itsvalid_lftran out).keel/system/dbfollow.py(follow): one run at a time, under/var/lib/keel/database/follow.lock, so the unit andkeel database watchnever interleave between the proof andSET read_only OFF.docs/replication.mdsays so.docs/replication.md: the follow table and the rule.debian/changelog,pyproject.toml,keel/__init__.py: 0.23.4.Tests
tests/test_system_dbfollow.py,TestTheOldPrimaryAtBoot: crash, the other node promoted at a newer epoch, the old node boots, stays read only, then follows as a replica (cloud simple, as on the real mesh); a server found writable without a proof is made read only; the holder proven again after its boot takes writes; no peer answers; the proof comes while follow waits; etcd does not answer at boot. The old code fails five of these withSET GLOBAL read_only = OFF.TestNoClaimAndNoAddress: the state file removed on a primary with a pair record, follow keeps it read only; watch follows a writable primary whose VIP leftwg0; follow takes its lock.tests/test_mesh_vipmove.py: the state is written again whenkeel vip checkadds the VIP, and not when it is there.tests/mariadb_netns.py: A now takes the VIP (and follow runs) before the application's data is written, because a paired node with no claim is read only.tests/mariadb_netns.py(mariadb / trixie): the primary's server killed, its VIP helper stopped, cut off;keel database promote --old-primary-goneon the replica; the old primary boots with its old claim:@@read_onlyis 1 at boot, after follow, and in every 0.5 s sample until it replicates from the new primary over TLS by GTID.Test plan
CI record
First run (617bfbb's first version):
mariadb / trixiefailed in the new case only: the replica's I/O thread was stillConnectingwhen the status was read (read only held in every sample, replica after 6.4 s). The case now waits for the I/O thread to stream, as case (a) does (amended).vip / trixiefailed atg_promote_b(etcdctl get: context deadline exceeded), the same failure as main's run 37833124848 and run 37843439840. No job was rerun: the amended push ran all checks again, all green.Security review: H1, M2 and L1 are fixed in the amended commit; M1 is #113.
Head
7cbfab1(after the security review): every check green butmesh / trixie. Attempt 1 timed out intest_a_spent_invite_is_refused(the inviter process). I reran the job once (run 37869774880, attempt 2); it failed in another test,test_c_joins_through_the_fallback, the same failure as main's run 37833124848. This PR changes nothing in keel.mesh's join or invite code. #112 holds this commit plus its own, and itsmesh / trixiepassed at132a13a. I did not rerun a second time.