MariaDB’s Global Transaction IDs (GTIDs) are actually a backward compatibility layer designed to make replication easier, not a fundamental shift in how transactions are tracked.
Let’s see it in action. Imagine you have two MariaDB servers, master and replica.
On the master:
-- Enable GTID and set a unique server ID
SET GLOBAL gtid_domain_id = 1;
SET GLOBAL server_id = 100;
SET GLOBAL gtid_enforce_consistency = ON;
SET GLOBAL binlog_format = ROW;
SET GLOBAL log_bin = ON;
SET GLOBAL log_slave_updates = ON;
-- Create a simple table and insert data
CREATE TABLE test_db.replication_test (
id INT AUTO_INCREMENT PRIMARY KEY,
data VARCHAR(255)
);
INSERT INTO test_db.replication_test (data) VALUES ('Hello GTID!');
On the replica:
-- Set a unique server ID and enable GTID
SET GLOBAL gtid_domain_id = 1; -- Must match master's domain ID
SET GLOBAL server_id = 200;
SET GLOBAL gtid_enforce_consistency = ON;
SET GLOBAL binlog_format = ROW;
SET GLOBAL log_bin = ON;
SET GLOBAL log_slave_updates = ON;
-- Configure replication to use GTID
CHANGE MASTER TO
MASTER_HOST='master_ip_address',
MASTER_PORT=3306,
MASTER_USER='repl_user',
MASTER_PASSWORD='repl_password',
MASTER_AUTO_POSITION = 1; -- This is the key for GTID
-- Start the replica
START SLAVE;
-- Verify replication status
SHOW SLAVE STATUS\G
Now, if you check SHOW SLAVE STATUS\G on the replica, you’ll see Auto_position: 1 and Seconds_Behind_Master should be low. Any changes made on the master will appear on the replica.
The problem GTIDs solve is managing replication when the master server fails and you need to promote a replica. Without GTIDs, you’d have to manually track binary log file names and positions, which is error-prone. With GTIDs, the replica simply asks the new master for all transactions it hasn’t seen yet, identified by their unique global transaction IDs.
Internally, when binlog_format=ROW and gtid_enforce_consistency=ON, MariaDB assigns a unique, sequential, and non-repeating Global Transaction ID to every committed transaction. This ID is composed of two parts: a gtid_domain_id (identifying the origin server cluster) and a gtid_sequence_number (a monotonically increasing number within that domain). When a replica connects to a master and MASTER_AUTO_POSITION=1, it doesn’t ask for master.000001 at position 1234. Instead, it sends its current set of GTIDs to the master, and the master replies with all transactions it has that the replica doesn’t. This makes failover and re-pointing replicas incredibly robust.
The gtid_domain_id is crucial. All servers participating in the same replication topology must share the same gtid_domain_id. If you have multiple independent replication setups, each should have its own unique gtid_domain_id. This prevents conflicts and ensures that GTIDs are truly global within their intended domain.
What most people don’t realize is that gtid_enforce_consistency=ON is essential for preventing data divergence, especially in complex topologies with multiple masters or circular replication. When this is off, MariaDB might allow transactions to be written to the binary log without a corresponding GTID being generated for them, leading to situations where a replica might skip a transaction that a master has already executed, but without a GTID to track it. This can lead to silent data inconsistencies that are very hard to debug.
The next concept you’ll likely encounter is managing GTID sets during complex failover scenarios or when integrating with tools that expect specific GTID information.