Compare
Bloodraven and the other Kubernetes MySQL operators
Ten other operators, compared on what you would check before trusting one with a production database: licence and cost, how failover decides and fences, what happens across sites, backups you can prove restore, and how much failure testing stands behind the claims.
Checked on 4 November 2026 against each project's repository, release notes, documentation, CI configuration and issue tracker. Where a cell rests on an open issue report rather than the maintainers' own documentation, it links the report. Projects change; if a cell is wrong or out of date, open an issue and we will fix it.
The short version
Pick the replication model first. Group Replication, Galera and loss-less semi-sync lose no committed data when a node fails, but they need three members and slow down over long links. Asynchronous replication works over a WAN with two sites, at the cost of possible data loss on an unplanned failover.
No operator, Bloodraven included, fails over automatically between separate Kubernetes clusters. Every cross-cluster path in this table is a manual promotion. Bloodraven automates failover between sites of one Kubernetes cluster that spans zones or regions; recovering in a different cluster is a restore from S3.
Where Bloodraven is ahead: automatic failover with only two sites, layered fencing that includes evicting application pods from the old site, DNS steering, an interlock before discarding divergent transactions, automated restore testing, and the most failure testing of any project here.
Where Bloodraven is behind: it is new, with one primary maintainer and a v1alpha1 API. It runs MySQL 9.7 only, takes logical backups only, has no proxy, and cannot promote while the operator itself is down. Companies over $1M revenue pay for production use. Two failure scenarios are open known failures; see Known limitations.
Which one fits
- No data loss inside one cluster, mature and fully open sourcePercona PXC
- Upstream Group Replication with support from OracleOracle MySQL Operator, with an Enterprise subscription
- Plain semi-sync replication, no proxy, small codebaseMOCO
- Sharding, or more write volume than one primary can takeVitess
- MariaDBmariadb-operator
- One platform for several database enginesKubeBlocks or KubeDB
- Two sites, async, automatic site failover with DNS, and you can accept bounded data loss on a sudden failureBloodraven
Feature by feature
Strong or presentPartial, preview, paid or caveatedMissing, weak or reported brokenNeutral
| Capability | BloodravenShipStream · v1.6.0 | Oracle MySQL OperatorInnoDBCluster · 26.10.0-2.3.1 | Percona PXCXtraDB Cluster · v1.20.0 | Percona PSPercona Server · v1.3.0 | MOCOCybozu · v0.38.0 | Vitess OperatorPlanetScale · v2.17.1 | mariadb-operatorCommunity · 26.10.2 | KubeBlocks MySQLApeCloud · v1.0.2 | KubeDB MySQLAppsCode · v2026.10.12 | Charmed MySQL K8sCanonical · rev457 | Tungsten OperatorContinuent · commercial |
|---|---|---|---|---|---|---|---|---|---|---|---|
| Licensing and cost | |||||||||||
| Operator licence | BSL 1.1, source-available. Each version becomes Apache-2.0 two years after release | UPL-1.0 | Apache-2.0 | Apache-2.0 | Apache-2.0 | Apache-2.0 | MIT | AGPL-3.0 since 2023; addons Apache-2.0 | AppsCode Community License (source-available, non-compete); source private | Apache-2.0 | Proprietary |
| Free in production? | For individuals, non-profits, non-commercial use and companies under $1M revenue. All non-production use is free | Community edition yes; key features need Enterprise | Yes, every feature | Yes, every feature | Yes | Yes; turnkey multi-cluster is commercial | Yes; MaxScale 25.x and the Enterprise operator are commercial | Yes, under AGPL; an Enterprise edition exists | No. The free community licence ended in 2024; trials are 30 days | Yes | No |
| Features behind a paid tier | None. No licence server, no phone-home | Physical and incremental backup (MEB), PITR, ClusterSet, Vault/KMIP/OCI keyrings, audit log | None | None | None | Turnkey cross-cluster deployment (PlanetScale) | FIPS, drain-triggered switchover, MaxScale 25.x | GUI | Production use; GUI | None | Everything |
| Published price | $990 one-time per failover group or $4,900 per organization; optional update renewals. Pricing | MySQL Enterprise Edition, about $5,350 per server per year | Support subscription, not published | Support subscription, not published | No commercial support offered | PlanetScale, not published | MariaDB Enterprise, not published | Enterprise, not published | Per GB of database memory, 100 GB minimum | Ubuntu Pro support from $500 per node per year | Up to $8,400 per node per year, plus support |
| Project health | |||||||||||
| First release | April 2026 | 2022 | 2019 | GA November 2025 | 2020 | 2020 (Vitess itself 2011, CNCF graduated) | 2022 | 2022; the project still labels itself alpha | 2018 | 2021 | GA May 2025 |
| Releases in the last 12 months | 27 | About 8, quarterly | 3 | 4 | 8 | 3 | 7 | 1 GA, 70 alpha and beta | Frequent | About 4 | Not published |
| GitHub stars / contributors | New project; one primary maintainer | 947 / 16 | 625 / about 88 | 234 / about 34 | 385 / about 47 | 374 / about 71 (Vitess: 21k stars) | 1,033 / about 96 | 3,162 / about 108 | Source is private | New monorepo / 31 | Closed source |
| API version | v1alpha1, no conversion webhook yet | v2 | v1 | v1; async mode in tech preview | v1beta2 | v2 | Stable | v1 with addon churn | v1 | Juju charm | Not published |
| Database and platform | |||||||||||
| Database versions | MySQL Community 9.7 LTS only | MySQL 8.4, 9.7, 26.x (Community or Enterprise) | PXC 8.4, 8.0, 5.7 | Percona Server 9.7, 8.4, 8.0 | MySQL 8.0.28 to 8.4 | MySQL or Percona 8.0, 8.4 | MariaDB 10.6 and later only | MySQL 5.7, 8.0, 8.4 | MySQL 5.7 to 9.7 | 8.0 stable; 8.4 in candidate | MySQL, Percona, MariaDB |
| Platforms in CI | kind (Kubernetes 1.35) in public CI; managed clouds not tested | minikube, k3d, kind, OKE, OpenShift in internal CI | GKE, EKS, AKS, OpenShift, DOKS, Minikube | GKE, EKS, DOKS, OpenShift, Rancher, Minikube | kind, Kubernetes 1.34 to 1.36 | kind | kind | EKS, AKS | Not published | Canonical Kubernetes | Not published |
| arm64 | Multi-arch images; not tested in end-to-end CI | Multi-arch images | Yes | Not documented | Yes | Vitess images | Yes | Yes | Not documented | Yes, tested | Yes |
| Topology | |||||||||||
| Replication model | Asynchronous GTID replication, every replica directly from the primary | Group Replication (InnoDB Cluster), single primary | Galera, virtually synchronous | Group Replication (GA); async with Orchestrator (tech preview) | Loss-less semi-sync that never falls back to async | Async or semi-sync per shard, with sharding | Async, semi-sync or Galera | Semi-sync (default), Group Replication or Orchestrator | Group Replication, InnoDB Cluster, semi-sync | Group Replication with ClusterSet | Async, through the Tungsten replicator |
| Members needed for HA | 2 sites | 3 | 3 | 3 (Group Replication), 2 (async) | 3 | 2 or more per shard | 2 (async), 3 (Galera) | 2 (semi-sync) | 3 | 3 | 3 |
| Read replicas | Read-only sites that are never promoted and are fenced if they turn writable; DR-only sites | Async read replicas | Every node is readable | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes |
| Sharding | No | No | No | No | No | Yes, the core feature | No | No | No | No | No |
| Replicate from an outside MySQL | No; import with a MySQL Shell dump | No; seed by clone or dump | Yes | Through ClusterSet | Yes | Through import workflows | Yes | Not documented | Yes | Through ClusterSet | Yes, including other databases |
| High availability and failover | |||||||||||
| What decides a failover | The operator, polling every 2 s | Group Replication consensus; the operator repairs membership | Galera quorum and proxy health checks | Group Replication; async: Orchestrator | The operator | VTOrc | The operator, or MaxScale | A sidecar holding a ConfigMap lock | A coordinator sidecar | Group Replication and Juju hooks | Tungsten Manager, by quorum |
| Documented failover time | About 6 s to detect plus up to 30 s relay-log drain. Failure-mode matrix | Not documented. Open reports describe a 2-minute failover and a 22-minute write outage (#69) | About 5 s for Galera, then 10 to 30 s for HAProxy | Group Replication: seconds. Async: waits to recover the old primary's binlogs, up to a 1 h default timeout | Not documented | Seconds; no figure published | Not documented. An open report describes no failover at all on node power loss (#1960) | "Generally under 30 s" (vendor) | About 10 s, rarely 45 s | Not documented | Not published |
| Data loss on unplanned failover | Possible, bounded by replica lag. The lost transactions are recorded in status. Durability and RPO | None inside one cluster; possible on a forced cross-cluster failover | None inside one cluster; possible across sites | None with Group Replication. Async: none if the old pod is still reachable, otherwise wait or force with loss | None by design; writes block instead | None for acknowledged writes with semi-sync durability | Possible with async | Possible once semi-sync times out | None with Group Replication | None inside one cluster | Possible (async) |
| Planned switchover without data loss | One annotation or kubectl bloodraven promote; waits for the target to catch up and rolls back on timeout | MySQL Shell command; ClusterSet by custom resource | No command | Yes | kubectl moco switchover | PlannedReparentShard | Yes; an open report describes the primary stuck read-only (#1852) | Yes | Yes | Juju action | Yes |
| Split-brain protection | super_read_only, read-only boot, a sidecar that fences an isolated primary on its own, and node taints that evict application pods from the old site | Quorum and self-abort on expulsion; across clusters the old primary must be fenced by hand | Quorum: a minority refuses queries | Quorum with Group Replication; async relies on read_only and refuses a forced promotion while the old primary is writable | Stops replication on every replica so the old primary cannot get acknowledgements | Semi-sync acknowledgements; no STONITH | read_only on demotion only | Open report: pods start writable (#3103) | Quorum with Group Replication | Quorum; docs acknowledge split-brain after a partition | Quorum |
| Divergent (errant) transactions | Detected and reported with an event and metric; the site stays fenced, ranks last as a candidate, and needs the divergent GTID confirmed before a reclone | Group Replication rejects the member; ClusterSet needs manual steps | Not applicable (Galera) | Not documented | Detected and excluded; recloning is manual | Excluded from promotion; no automatic reclone | Optional reseed on one error code; open report of forked GTID history (#2013) | Not documented | Repaired by pseudo-transaction or clone | Handled by Group Replication | Not documented |
| Anti-flap cooldown | Yes, 5 min by default, survives an operator restart | Not documented | Not applicable | Through Orchestrator | Not documented | Through VTOrc | Not documented | Not documented | Not documented | Not documented | Not documented |
| While the operator is down | No promotion; sidecars keep it safe, but writes stop if the primary also dies. Operator availability | Failover continues; restarted members stay offline | Failover continues | Failover continues | No failover | Failover continues | No failover unless MaxScale is used | Sidecar-driven | Not documented | Failover continues; recovery waits | Failover continues |
| Multi-site, disaster recovery and routing | |||||||||||
| Automatic failover across zones or regions of one Kubernetes cluster | Yes, the design goal: two or more sites, async so it tolerates WAN latency, with site roles and priorities. Multi-site | If the group spans 3 zones; latency-sensitive | If the cluster spans 3 zones; latency-sensitive | If the group spans 3 zones | Across zones; writes block on a lagging link | Yes, aware of cells | Yes | Not documented | Across zones | Across zones | Within one region only |
| Across separate Kubernetes clusters | Manual: restore from S3 with PITR in the other cluster. Multi-cluster DR | ClusterSet (Enterprise); manual failover; needs cross-cluster pod networking | Async replication; manual promotion | ClusterSet; manual, or a forced failover flagged unsafe (#1658) | Replicate from an outside source; manual promotion | Do-it-yourself federation, or commercial | Manual switchover; an open report describes both clusters left writable (#1965) | Not documented | Remote replica; manual promotion | ClusterSet; manual; a forced promotion can split-brain | No |
| DNS or global traffic steering | Writes DNSEndpoint records for external-dns, only after the promotion is confirmed | No | No | No | No | Not needed; VTGate routes | No; the load balancer is repointed by hand | No | No | No | No |
| Client routing | No proxy: primary, replica and per-site Services, plus DNS | MySQL Router | HAProxy or ProxySQL | HAProxy or MySQL Router | Services only | VTGate | Optional MaxScale (licence caveats) | Services; optional ProxySQL | Services; Router for InnoDB Cluster | MySQL Router | Tungsten Connector |
| Cache or session failover | Optional Dragonfly that follows the active site | — | — | — | — | — | — | Separate Redis addon | Separate Redis operator | — | — |
| Backup and restore | |||||||||||
| Backup method | Logical only, with MySQL Shell | MySQL Shell dump; physical only with Enterprise | XtraBackup, physical | XtraBackup, physical | MySQL Shell dump, logical | Built-in, XtraBackup or MySQL Shell | mariadb-backup, VolumeSnapshot or dump | XtraBackup, VolumeSnapshot or mydumper | XtraBackup, logical or VolumeSnapshot | XtraBackup | Vendor tool |
| Storage targets | S3 and S3-compatible, PVC | PVC, OCI, S3, Azure | S3, GCS, Azure, PVC | S3, GCS, Azure | S3, GCS, Azure | S3, GCS, Azure, Ceph, volume | S3, Azure, PVC, NFS | S3, GCS, OSS, MinIO, PVC | S3, GCS, Azure and more | S3 only | S3, folder |
| Point-in-time recovery | Yes, into a new group; refuses to replay across sites after a failover (#206) | Enterprise only | Yes | Tech preview | Yes, into a new cluster | Yes | Replication topology only, with open bug reports | Yes | Yes | Disabled on 8.4 | Not documented |
| Automated restore testing | Yes: scheduled restores into a throwaway MySQL with PITR replay and a sanity query. Backup verification | No | No | No | No | Each scheduled backup restores the previous one first | No | No | No | No | No |
| Backup encryption | Client-side AES-256-GCM for dumps, binlogs and manifests | Depends on storage | Storage-side | Yes | No (#845) | Storage-side | SSE-C | Yes | Yes | Storage-side only | Not documented |
| Incremental backup | No; archived binlogs cover the gap | Enterprise only | No | Tech preview | No | Yes | No | Yes | Through binlog archiving | No | Not documented |
| Restore options | New group, in place for the whole instance, or one schema in place | New cluster only | New or same cluster | New or same cluster | New cluster; single schema | New tablets | New or in place; single database | New cluster only | Same or different database | In place | In place, with manual steps |
| Day-2 operations | |||||||||||
| Rolling MySQL upgrade | Standby first, then a no-loss handoff; writes pause for up to about 30 s | Yes | Yes, with automatic minor upgrades | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes |
| Configuration changes on a live cluster | Reconciled | Open reports: ignored (#63, #56) | Yes | Yes, without restart where possible | Yes | Yes | Yes | Yes | Yes | Yes | Yes |
| Command-line tool | kubectl bloodraven for status, promote, reclone, backup and verify. kubectl plugin | MySQL Shell only | None; GUI through OpenEverest | None | kubectl moco | vtctldclient, VTAdmin | None | kbcli | kubectl dba | Juju | kubectl tungsten |
| Databases and users as resources | MysqlDatabase: database, owner, users, grants, limits | No | Users in the cluster resource | Users in the cluster resource | No | Keyspaces | Database, User and Grant resources | Yes | Yes | Through relations | Not documented |
| Coordination with app deploys | Deployment API: migration lock and failover holds, revoked on emergency. Deployment API | No | No | No | No | Online DDL | No | No | No | No | Schema-change tooling |
| Security | |||||||||||
| TLS | cert-manager; encrypted transport required | From Secrets you supply | cert-manager, automatic rotation | cert-manager, rotation without restart | cert-manager for the agent; operator-to-MySQL traffic is not encrypted | No mTLS (#718) | Built-in CA or cert-manager | Yes | cert-manager | Through TLS charms | cert-manager |
| Encryption at rest | Keyring file with escrow and safe rotation; not compliance-grade TDE. Encryption at rest | Keyring file; Vault, OCI and KMIP with Enterprise | Vault keyring | Vault keyring | No | Not managed | Not documented | Not documented | Not documented | Not supported | Not documented |
| Signed images | cosign; daily vulnerability scans | Not documented | Not documented | Not documented | Not documented | Not documented | Not documented | Not documented | Not documented | Not documented | Not documented |
| Observability and documentation | |||||||||||
| Metrics | About 57 operator metrics with a ServiceMonitor | Bring your own exporter, with an open report it breaks on recent versions (#61); no operator metrics | PMM | PMM | Operator and backup metrics | Every component | Exporters and operator metrics | Exporter | Exporter | Prometheus, Loki, Tempo | Not documented |
| Dashboards and alerts shipped | 5 Grafana dashboards; alert rules as an example file. Alert runbook map | None | Through PMM | Through PMM | None | None | None | Dashboard and alert rules | Dashboards, no alerts | Dashboards and tested alert rules | Vendor dashboard |
| Failure-mode documentation | Failure-mode matrix with timings, runbooks, RPO matrix, partition guide, published known failures | No failover chapter | Detailed, with timings | Good | Precise state documentation | Upstream Vitess docs | Moderate | Moderate | Moderate | Moderate | Vendor manual |
| Failure testing | |||||||||||
| Real-cluster test scenarios | 62 chaos scenarios. Chaos suite | 51 suites | 70 suites | 65 suites | 16 suites | 8 for the operator; Vitess itself has about 80 failover tests outside Kubernetes | About 117 specs | Test code is private | Test code is private | 126 tests | Test code is private |
| …that inject a failure | About 51: kills, sustained outages, network partitions, frozen processes, wiped volumes, RBAC, DNS and storage outages, rogue writes, lag | About 13: process kills and pod deletes | About 9 | About 9 | 4 | 1 | About 8: pod and volume deletes | 15 fault types, from public CI logs | Not verifiable | About 10 | Not verifiable |
| Network-partition tests | Several partition shapes, including partitioning only the operator | No | One pod | Yes | No | Upstream only | No | Yes | Not verifiable | Yes | Not verifiable |
| Deterministic simulation | Seeded fault schedules run against the real control loop on every CI run | No | No | No | No | No | No | No | No | No | No |
| Where the tests run | Public GitHub Actions on kind: a smoke set gates every release, 28 scenarios nightly, the full set on demand | Internal CI, results not public | GKE on every PR; failure tests at release on six platforms | GKE on every PR, failure tests included; six platforms at release | Public CI across Kubernetes and MySQL versions | kind | Public CI on kind | Manually triggered on EKS and AKS | Private | Nightly | Private |
How the failure tests were counted
Counts come from each repository's test tree and CI configuration, not from marketing pages. "Injects a failure" means the test kills, freezes, partitions, deletes or denies something and then checks the outcome; a test that only exercises a planned switchover or an upgrade does not count.
- Bloodraven: 62 registered scenarios. Four need the encryption setup and run in their own CI jobs; two are open known failures, kept quarantined. Every PR runs 190 component tests, 57 envtest tests and a 400-seed deterministic simulation sweep.
- Oracle: 51 end-to-end files, of which about 13 tests crash a process or delete a pod. No partition or node-loss tests. CI is internal.
- Percona PXC: 70 end-to-end tests; 3 chaos-mesh suites plus 6 with kill or delete steps. Chaos suites run at release time.
- Percona PS: 65 kuttl suites, including Group Replication self-healing and async failover with a killed primary; these run on every PR.
- MOCO: 16 suites with 74 specs; 4 kill or delete during writes.
- Vitess: the operator has 8 end-to-end scripts. Vitess itself has 49 reparent and 33 VTOrc end-to-end tests that run as local processes.
- mariadb-operator: about 117 specs on kind; about 8 delete a pod or volume. Multi-cluster specs cover the success path.
- Charmed MySQL: 126 integration tests; about 10 inject faults with chaos-mesh, drains, freezes and kills.
- KubeBlocks, KubeDB and Tungsten keep their test code private. KubeBlocks publishes CI logs showing 15 fault types.
Not in the table
Bitpoke (Presslabs) mysql-operator has had no release since May 2023 and depends on Orchestrator, whose upstream is archived. RadonDB has been inactive since early 2025. Oracle's NDB Operator runs NDB Cluster rather than InnoDB replication. OpenEverest is a management platform over the Percona operators, so its MySQL behaviour is Percona PXC's. TiDB, OceanBase and PolarDB-X are MySQL-compatible distributed databases rather than MySQL.

