Both Halves Thought They Were Primary — JavaScript Bug Hunt
Modelled on the GitHub outage of 21 October 2018: a 43-second network partition let automated failover promote a second primary on the other coast.
- Language: JavaScript
- Layer: Database
- Difficulty: Hard
- Concepts: Consensus, Split Brain
- Modelled on: GitHub · 2018
- Visible tests: a node with a majority commits; the minority side refuses to commit
- Reward: 50 XP for a complete fix
Briefing
Modelled on the GitHub outage of 21 October 2018: a 43-second network partition let automated failover promote a second primary on the other coast. Writes landed on both sides, and reconciling them took over 24 hours of degraded service.
replica.js accepts a write on whichever node receives it, with no quorum check.
Fix commitWrite so a node only commits when it can see a majority of the cluster.
Bug report
BUG-GH1021 · Priority: Critical (data divergence) · Reported by: database SRE
commitWrite(cluster, nodeId, value) must:
- commit only if the node is reachable AND a strict majority of the cluster's nodes are reachable from it
- on commit, append the value to that node's log and return true
- otherwise change nothing and return false
Observed: after a partition, both sides accept writes and the logs diverge.
Logs
[repl] node=us-east committed seq=91002 (visible peers: 2 of 5)
[repl] node=us-west committed seq=91002 (visible peers: 3 of 5)The code as shipped
src/db/replica.js (editable)
// Commits a write on the given node.
exports.commitWrite = function (cluster, nodeId, value) {
var node = cluster.nodes[nodeId];
node.log.push(value);
return true;
};
Read-only context: src/db/QUORUM.js.
Open the hunt to edit the files, run the visible tests and submit against the hidden ones. More JavaScript bug hunts.