A Galera Cluster can write to any node simultaneously, but it’s not actually doing "multi-master" writes in the way you might think.

Let’s see this in action. Imagine a simple 3-node Galera cluster: galera-node-1, galera-node-2, and galera-node-3.

# On galera-node-1:
mysql -u root -p -h galera-node-1

# Inside the MySQL client:
CREATE DATABASE IF NOT EXISTS testdb;
USE testdb;
CREATE TABLE IF NOT EXISTS messages (
    id INT AUTO_INCREMENT PRIMARY KEY,
    content VARCHAR(255) NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
INSERT INTO messages (content) VALUES ('Hello from node 1!');

Now, switch to galera-node-2 and run the same INSERT statement:

# On galera-node-2:
mysql -u root -p -h galera-node-2

# Inside the MySQL client:
USE testdb;
INSERT INTO messages (content) VALUES ('Greetings from node 2!');

And then to galera-node-3:

# On galera-node-3:
mysql -u root -p -h galera-node-3

# Inside the MySQL client:
USE testdb;
INSERT INTO messages (content) VALUES ('Salutations from node 3!');

If you then query the messages table on any of the nodes (e.g., SELECT * FROM messages;), you’ll see all three messages. This is because Galera’s certification-based replication ensures that all transactions are applied atomically across all nodes.

The core problem Galera Cluster solves is providing High Availability (HA) and read/write scalability for MariaDB. Traditional master-slave replication has a single point of failure (the master) and can only scale reads. Galera allows any node to accept write traffic, synchronizing it to all other nodes before committing the transaction. This ensures data consistency across the cluster.

Internally, Galera works by intercepting SQL statements at the transaction commit stage. Before a transaction is committed on a node, Galera broadcasts the transaction’s changes to all other nodes in the cluster. Each node then performs a "certification" process. This involves checking if the transaction conflicts with any other transactions that have already been committed or are in the process of being committed on that node. If no conflicts are found, the transaction is committed on that node. If a conflict is detected, the transaction is rolled back on that specific node, and the application receives an error. The application is then expected to retry the transaction. This is the "multi-master" aspect – multiple nodes can accept writes concurrently, but the underlying mechanism ensures that only one version of the data ultimately survives, thanks to this conflict resolution.

The key levers you control are in the Galera configuration file (typically galera.cnf or within my.cnf/my.ini).

  • wsrep_cluster_address: This defines the communication endpoint for the cluster. For a new cluster, you might start a node with gcomm:// to form a new cluster. To join an existing cluster, you’d list the addresses of one or more existing nodes, e.g., gcomm://192.168.1.101,192.168.1.102.
  • wsrep_cluster_name: A unique name for your cluster. All nodes must share the same name to form a cluster.
  • wsrep_node_address: The IP address of the current node.
  • wsrep_sst_method: The method used for State Snapshot Transfers (SST) when a new node joins. Common methods are rsync, mariabackup, and xtrabackup-v2. mariabackup is generally recommended for MariaDB.
  • binlog_format: Must be set to ROW. Galera relies on row-based binary logging for its replication.
  • default_storage_engine: Must be InnoDB. Galera only supports transactional storage engines.

The most surprising thing is how Galera handles network partitions. It doesn’t automatically elect a new "master" or split the cluster into separate, independent databases. Instead, when a node becomes isolated, it stops accepting writes that would conflict with the majority partition. If a node can’t communicate with a quorum of the cluster (typically more than half the active nodes), it will enter a read-only state or even stop accepting connections to prevent data divergence. This is a deliberate choice to maintain consistency, even if it means temporary unavailability for writes from the partitioned node’s perspective.

The next concept you’ll grapple with is handling transaction conflicts and ensuring your application is resilient to them.

Want structured learning?

Take the full Mariadb course →