Replication and WAL10 min read

MySQL Orchestrator vs PostgreSQL Patroni: Two Failover Cultures

MySQL grew failover tooling around topology repair; PostgreSQL grew it around consensus and leases. Comparing orchestrator and group replication with Patroni and repmgr, honestly.

Ask a MySQL veteran and a PostgreSQL veteran how automated failover works and you will hear two different philosophies. The MySQL answer centers on topology: discover the replication graph, detect the dead primary, heal the graph around a promoted replica. The PostgreSQL answer centers on consensus: there is a leader lease in an external strongly consistent store, and whoever holds it is the primary, full stop. Neither culture is wrong. But a team migrating from MySQL to PostgreSQL is not just swapping a database; it is joining a different school of thought about what makes failover safe, and it helps to know the curriculum before the first 3 a.m. promotion.

I have operated orchestrator-managed MySQL fleets and Patroni-managed PostgreSQL clusters. This is a field comparison of the tooling, the durability knobs that decide how much data a failover can lose, the split-brain defenses, and the discipline of actually testing any of it.

The MySQL side: orchestrator, group replication, InnoDB Cluster

Orchestrator (from the GitHub lineage, now community-maintained) is the emblematic MySQL tool: it crawls the topology, draws the replication graph, detects failures by cross-checking what replicas see rather than trusting a single ping, and executes recovery by promoting the best-positioned replica and repointing the rest, which GTIDs make mechanical. Its holistic detection is genuinely clever: a primary is judged dead when its replicas also stop hearing from it, which filters out mere monitor-to-primary network blips. Around promotion, hooks integrate with proxies and service discovery to move traffic.

The other MySQL lineage moved consensus into the database itself. Group replication runs a Paxos-derived protocol among the servers; in single-primary mode the group elects a primary, and a network partition leaves the minority side refusing writes. InnoDB Cluster packages this with MySQL Shell for operations and MySQL Router for connection routing, giving an integrated, officially supported stack. The tradeoff profile is familiar from any quorum system: write availability follows the majority, group membership needs care, and large transactions and flaky networks stress the protocol. Classic async replication plus orchestrator remains common precisely because it keeps the data path simple and puts the cleverness in an external manager.

The PostgreSQL side: Patroni, repmgr, and friends

PostgreSQL's community converged on the external-consensus model. Patroni runs an agent beside every PostgreSQL instance; the agents compete for a leader key with a TTL in a distributed configuration store, typically etcd (Consul and ZooKeeper are also supported). Only the lease holder runs as primary. If the primary's agent cannot refresh the lease, the lease expires, the old primary demotes itself, and a standby that can win the key, generally the least-lagged one, promotes. Configuration is managed through the same store, and a REST API on each node serves health checks that load balancers such as HAProxy use for routing. The architecture is honest about its dependency: Patroni is exactly as reliable as your etcd cluster and the network to it, which is why the standard deployment gives the DCS the same care as the database.

repmgr is the older, lighter alternative: replication management plus a failover daemon with witness-node support, no external consensus store required. It is simpler to stand up and correspondingly easier to misconfigure into split-brain, since fencing is largely left to your scripts. pg_auto_failover offers another take, with a monitor node coordinating a primary-secondary pair through explicit state machines. In 2026, for multi-node production clusters, Patroni is the de facto default, and most managed Kubernetes operators for PostgreSQL embed it or reimplement its pattern. A useful cultural note for arriving MySQL teams: PostgreSQL itself ships no failover manager; promotion (pg_ctl promote, pg_promote()) is a primitive, and the orchestration layer is explicitly your choice. The self-hosted PostgreSQL monitoring guide covers the observability that choice obligates you to build.

Durability knobs: semi-sync vs synchronous_commit

Automated failover is only as good as the data the survivor holds, which makes replication durability part of the failover design, not an afterthought. MySQL's tool is semi-synchronous replication: a commit waits until at least one replica acknowledges receiving (not applying) the transaction's events. Its notorious property is the timeout fallback: if no replica acknowledges within rpl_semi_sync_source_timeout, the primary silently degrades to asynchronous and keeps accepting writes. That default favors availability, and it means your zero-loss guarantee can evaporate quietly minutes before the crash that needed it; monitoring the semi-sync status variables is therefore mandatory, not optional.

PostgreSQL's knob is more granular and less forgiving. synchronous_standby_names defines which standbys count, with FIRST and ANY quorum forms, and synchronous_commit selects the level per transaction: local, remote_write (standby received it), on (standby flushed it to disk), remote_apply (standby replayed it, so it is visible to standby reads).

-- Quorum sync: any one of two standbys must confirm
ALTER SYSTEM SET synchronous_standby_names = 'ANY 1 (replica_a, replica_b)';
SELECT pg_reload_conf();

-- Relax durability for a low-value bulk write, per transaction
BEGIN;
SET LOCAL synchronous_commit = 'local';
INSERT INTO audit_archive SELECT * FROM audit_staging;
COMMIT;

Crucially, PostgreSQL does not time out and degrade: if the synchronous standby is gone, commits hang until an operator (or automation like Patroni, which can manage synchronous mode and pick a healthy standby) intervenes. MySQL's default lets you lose the guarantee silently; PostgreSQL's default lets you lose availability visibly. Migrating teams should decide deliberately which failure they prefer, per write path, rather than inheriting a default. The per-transaction control is one of my favorite PostgreSQL features: durability becomes a dial the application turns per operation instead of a cluster-wide constant.

Split-brain: how each culture fences the old primary

Split-brain, two nodes accepting writes for the same dataset, is the failure that turns an outage into a data-reconciliation project. Group replication prevents it structurally: the minority partition cannot commit. Orchestrator-managed async topologies prevent it procedurally: anti-flapping windows, pre- and post-failover hooks that fence the old primary via proxy reconfiguration, service discovery updates, or power fencing, and the honest admission that a hook that fails to fence is a hole. Patroni's defense is the lease plus self-demotion: an isolated primary that cannot refresh the leader key demotes itself when the TTL expires, and for the hard cases, a kernel watchdog device can reset a node whose agent hangs rather than exits. repmgr sits closer to orchestrator's procedural model, with witness nodes for quorum-ish decisions and fencing delegated to your scripts.

On both sides, the residual risk concentrates in the seconds between failure and fence, and in clients holding stale connections to a demoted primary. This is why connection routing (Router, ProxySQL, HAProxy checking Patroni's REST API, or client drivers with target_session_attrs=read-write) is part of the failover system, not an accessory: PostgreSQL standbys are read-only, so a stale client fails loudly with read-only errors rather than silently diverging, which is one of physical replication's quiet safety benefits.

Test failovers like you test backups

Whatever stack you choose, an untested failover system is a hypothesis. The teams I trust run drills quarterly at minimum: planned switchovers (orchestrator graceful takeover, patronictl switchover) during business hours to validate the happy path and the client-reconnect story, then genuine failure injection, killing the primary process, partitioning the network, freezing the DCS, to validate detection and fencing. Measure three things every drill: detection time, promotion time, and client recovery time, and check post-failover replication health, including whether your logical replication slots and CDC consumers survived the promotion, a step that PostgreSQL 17's failover slots finally makes routine. Record data loss, if any, against your stated RPO. During every PostgreSQL drill, watch the promotion candidates directly rather than trusting the manager's summary.

-- On the primary during a drill: who is caught up, who is synchronous?
SELECT application_name,
       state,
       sync_state,
       pg_wal_lsn_diff(pg_current_wal_lsn(), flush_lsn)  AS flush_bytes_behind,
       pg_wal_lsn_diff(pg_current_wal_lsn(), replay_lsn) AS replay_bytes_behind
FROM pg_stat_replication
ORDER BY replay_bytes_behind;

If sync_state does not show what your durability design assumes, or a supposed promotion candidate is gigabytes behind on replay, you want to learn that on a Tuesday afternoon drill, not during the real event. A drill that has never surprised you is a drill you are not running hard enough.

How MonPG helps once you are on PostgreSQL

MonPG does not manage failover, and it monitors PostgreSQL only, but it supplies the evidence a Patroni-era operation runs on. Before an incident, it tracks per-standby replay lag and sync state from pg_stat_replication, so you know whether your promotion candidates are actually caught up and whether your quorum-sync guarantee is intact. It watches replication slot retention so a failover-surviving slot cannot quietly fill the new primary's disk, and WAL generation rate so lag spikes have a cause attached. After a drill or a real failover, its history answers the review's questions: when did lag start, which standby was ahead, what did the write workload look like at the moment of promotion. If PostgreSQL is where your failover story is headed, PostgreSQL monitoring shows the replication baseline to put underneath it.