Install
$ agentstack add skill-mariadb-skills-mariadb-replication-and-ha Open-source listing — not yet scanned by AgentStack. Follow the source repository for install instructions.
Security review
⚠ Flagged1 finding(s); flagged for manual review. · v0.1.0 How review works →
- • Prompt-injection patterns
- • Secret / credential exfiltration
- • Dangerous shell & filesystem operations
- • Untrusted network calls
- • Known-malicious package signatures
- high Destructive filesystem operation.
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
MariaDB Replication and High Availability
Last updated: 2026-06-24
MariaDB offers three tiers of replication depending on your consistency and availability requirements:
| Approach | Consistency | Failover | Best for | |---|---|---|---| | Standard async replication | Eventual | Manual or tool-assisted | Read scaling, backups, low-latency writes | | Semi-synchronous replication | Eventual (same as async) | Manual or tool-assisted | Ensuring a replica received each commit before the client is acknowledged — bounds failover loss (lossless only with AFTER_SYNC) | | Galera Cluster | Synchronous (multi-primary) | Automatic | Zero-data-loss HA, multi-datacenter writes |
> Requires: GTID replication, semi-synchronous replication, and parallel replication (including optimistic mode) are all built in and have been available since well before any currently-supported release — assume they are present on the 11.8 LTS baseline. Current LTS is 11.8 (GA May 2025). > > Default context: Assume MariaDB 11.8 LTS unless the user states another version. Features marked 12.x or 13.0 may be suggested when relevant (including as upgrade options), but always state the minimum version — do not present them as available on 11.8.
What LLMs Get Wrong
| What you might see | What's correct | |---|---| | CHANGE REPLICATION SOURCE TO, SOURCE_* connection options | MariaDB has no CHANGE REPLICATION SOURCE TO — use CHANGE MASTER TO with MASTER_* options. Since 10.5.1, START REPLICA / SHOW REPLICA STATUS are canonical; START SLAVE / SHOW SLAVE STATUS are legacy aliases | | replica_parallel_type with values DATABASE or LOGICAL_CLOCK | MariaDB uses slave_parallel_mode (optimistic / conservative / aggressive / minimal / none) — a different implementation; MySQL's mode settings do not port over. Pool size: slave_parallel_threads | | MySQL GTID format or gtid_mode=ON syntax | MariaDB GTID uses a different format (domain-server-seq) and different commands — MySQL and MariaDB GTIDs are incompatible | | MySQL Group Replication or InnoDB Cluster — START GROUP_REPLICATION, group_replication_* variables, MySQL Shell dba.createCluster() | MariaDB has no Group Replication and no InnoDB Cluster — Group Replication is incompatible with MariaDB. The synchronous multi-primary equivalent is Galera Cluster (built in) | | "Install the Galera plugin" | There is no Galera plugin to load — wsrep support is built into the MariaDB server. But a cluster still requires the separate Galera wsrep provider library (galera-4 / libgalera_smm.so, set via wsrep_provider); on 12.3+ you must install it yourself (see the Galera Cluster section) | | Assuming sequential AUTO_INCREMENT in Galera | Galera produces gaps in auto-increment sequences across nodes by design — never rely on sequential values | | LOCK TABLES or GET_LOCK() in a Galera environment | Not supported in Galera — use transactions instead | | Treating a replica as a backup | Replication is not a backup — a DROP TABLE on the primary replicates immediately to all replicas | | Tables without primary keys in a Galera cluster | All tables in Galera must have a primary key — DELETE fails on keyless tables |
Standard Async Replication
The foundation: one primary, one or more replicas. The primary writes to the binary log; replicas apply changes asynchronously.
GTID-based replication is the default since MariaDB 10.10 (MDEV-19801) and remains so on 10.11 LTS, 11.4 LTS, and 11.8 LTS. On a fresh replica start, a RESET SLAVE, or a CHANGE MASTER TO that omits MASTER_USE_GTID, the replica defaults to slave_pos instead of legacy file/position. If you have configs that rely on the old behavior, set MASTER_USE_GTID=no explicitly.
-- On replica (10.10+ — MASTER_USE_GTID is optional, slave_pos is the default):
CHANGE MASTER TO
MASTER_HOST='primary.host',
MASTER_USER='repl_user',
MASTER_PASSWORD='password',
MASTER_USE_GTID = slave_pos;
START SLAVE;
Promoting a replica to primary — historically MASTER_USE_GTID=current_pos was used to include locally-written GTIDs. current_pos is deprecated since 10.10 (MDEV-20122). Use MASTER_DEMOTE_TO_SLAVE=1 instead: it converts the old primary's gtid_binlog_pos into gtid_slave_pos so the demoted server can attach to the new primary cleanly without race conditions.
-- On the former primary, being demoted to a replica (10.10+):
CHANGE MASTER TO
MASTER_HOST='new_primary.host',
...,
MASTER_DEMOTE_TO_SLAVE=1;
START SLAVE;
Since MariaDB 13.0, CHANGE MASTER also resets Master_Server_Id in SHOW SLAVES STATUS. On older versions this field could carry stale values across primary changes — check it explicitly when reconfiguring replication on pre-13.0 servers.
MariaDB GTID Format
MariaDB GTIDs have three components: domain_id-server_id-sequence (e.g., 0-1-247).
This is different from MySQL's server_uuid:sequence format. They are not compatible — a MariaDB primary cannot replicate to a MySQL replica using GTIDs, and vice versa.
Domain IDs (gtid_domain_id) identify independent replication streams. The rule is about concurrency of writes, not server count — a common and damaging mistake is to give every server its own domain ID:
- Single active primary, including simple failover: leave
gtid_domain_id = 0on all servers. In anA → Bpair whereBis later promoted (so it becomesB → A),AandBshare the same domain ID — do not give them different ones. - Multiple primaries updated concurrently (multi-source, or multi-primary within one topology): give each concurrently-updated primary its own distinct
gtid_domain_id, so each stream stays independently ordered and automatic GTID replica-switchover works correctly.
-- Multi-source / multi-primary ONLY — each concurrently-written primary gets its own domain:
SET GLOBAL gtid_domain_id = 1; -- on primary A
SET GLOBAL gtid_domain_id = 2; -- on primary B
Assigning a distinct domain ID per server otherwise complicates the GTID position and loses the single ordered binlog stream. See Global Transaction ID.
Enable gtid_strict_mode alongside domain ID configuration — it catches out-of-order or mixed-domain GTID mistakes before they corrupt a replica's position:
# my.cnf on all servers:
gtid_strict_mode = ON
With strict mode ON, a replica stops with an error on a GTID ordering violation rather than silently applying out-of-order transactions. Without it, a domain ID misconfiguration can go undetected until the only fix is a full resync.
In multi-source replication, replication commands and variables (START SLAVE, SHOW SLAVE STATUS, …) act on the connection named by default_master_connection. It was session-only — you had to SET SESSION default_master_connection='name' in each session before issuing commands for that source. Since MariaDB 13.0 (MDEV-9247) it can also be set globally, making a chosen named connection the default for all sessions.
Parallel Replication
By default, replicas apply events serially — slave_parallel_threads defaults to 0, meaning parallel replication is off out of the box regardless of the mode setting. To enable it:
# my.cnf on replica:
slave_parallel_threads = 4 # must be > 0 to enable parallel apply
slave_parallel_mode = optimistic # default since 10.5.1 — tries parallel, retries on conflict
optimistic mode applies transactions in parallel and retries on conflict. Use conservative for stricter workloads where conflict retries are unacceptable.
> Different from MySQL: MariaDB's slave_parallel_mode (optimistic, conservative, etc.) is its own implementation — not equivalent to MySQL's replica_parallel_type (DATABASE / LOGICAL_CLOCK). Copy-pasting a MySQL parallel-replication mode config will not work. Pool size is slave_parallel_threads (alias slave_parallel_workers).
Since MariaDB 12.1, parallel replication also works when asynchronously replicating between two Galera clusters (MDEV-20065) — useful for cross-datacenter or DR setups where one Galera cluster is an async replica of another.
Replication Improvements in 10.7–10.11 LTS
- Two-phase
ALTER TABLEreplication (10.8+, MDEV-11675,binlog_alter_two_phase) — opt-in: when enabled, a largeALTER TABLEcan start on the replica while the primary is still executing it, rather than only after, which can reduce replication lag during schema changes. Off by default. Treat as advanced/experimental — validate thoroughly before relying on it in production rather than enabling it by default. - GTID-aware
mariadb-binlog(10.8+, MDEV-4989) —--start-positionand--stop-positionaccept GTID lists, so point-in-time replay tools can target GTIDs directly without needing binlog file/offset pairs. (Separately,--gtid-strict-mode— on by default — is only a safeguard: it checks that GTID sequence numbers are monotonic per domain and aborts on out-of-order events; it does not enable GTID targeting.) See mariadb-binlog. slave_max_statement_time(10.10+, MDEV-27161) — caps how long a single statement may run on the replica SQL thread. If a replicated statement exceeds it, the SQL thread stops with an error (error 3024) so a slow or runaway query surfaces instead of lag growing unnoticed. It does not skip the statement and continue — replication halts until you investigate and restart it.mariadb-binlog --do-domain-ids/--ignore-domain-ids/--ignore-server-ids(10.9+, MDEV-20119) — domain/server filtering when extracting binlog events.- Multi-source replication CHANNEL syntax (10.7+, MDEV-26307) — MySQL-style
FOR CHANNEL 'name'clauses now work inCHANGE MASTER TO,START SLAVE, etc.
Replication Improvements in 11.4 LTS
- Global limit on binary log disk space (11.4+, MDEV-31404) —
max_binlog_total_size(aliasbinlog_space_limit, default0= no limit) triggers binlog purging when the total size of all binlogs exceeds the threshold. Combine with--slave-connections-needed-for-purge(default1) so purging won't run if a configured replica is disconnected. New status variablebinlog_disk_usereports current disk usage. - GTID index for the binary log (11.4+, MDEV-4991) — a new GTID-to-position index lets reconnecting replicas seek straight to their start position without scanning whole binlog files. Controlled by
binlog_gtid_index(defaultON),binlog_gtid_index_page_size, andbinlog_gtid_index_span_min. Status variablesbinlog_gtid_index_hit/binlog_gtid_index_misslet you confirm it's being used. SQL_BEFORE_GTIDS/SQL_AFTER_GTIDSforSTART SLAVE UNTIL(11.4+, MDEV-27247) — finer-grained stopping for staged failover or PITR replay.- Detailed replication-lag fields (11.4+, MDEV-29639) —
SHOW REPLICA STATUSaddsMaster_last_event_time,Slave_last_event_time,Master_Slave_time_difffor clearer lag interpretation thanSeconds_Behind_Masteralone (the 11.6 update built on this — see below).
Binlog Performance Improvements in 11.7
- Large-transaction commit no longer freezes other transactions (11.7+, MDEV-32014) — previously, committing a very large transaction while
log_binwas on would stall all other transactions until the binlog write completed. This bottleneck is gone. - Async rollback of prepared transactions during binlog crash recovery (11.7+, MDEV-33853) — faster startup after a crash with many prepared transactions.
slave_abort_blocking_timeout(11.7+, MDEV-34857) — kill long-running queries on a replica when they block replication progress past a threshold. Useful on read replicas that occasionally run long analytical queries.
Monitoring Replication Lag
SHOW SLAVE STATUS\G
-- Key fields:
-- Seconds_Behind_Master: estimated lag in seconds
-- Last_SQL_Error: last error stopping the SQL thread
-- Relay_Log_Pos vs Read_Master_Log_Pos: how far behind the relay log is
Alert when Seconds_Behind_Master > 5 for latency-sensitive applications. A value of NULL means replication is not running. Note: Seconds_Behind_Master can be misleading on idle primaries — use heartbeat tools (e.g., pt-heartbeat) for accurate measurement.
Since MariaDB 11.6 (MDEV-33856), the definition of Seconds_Behind_Master was refined and three new columns were added to SHOW ALL REPLICAS STATUS plus a new Information Schema SLAVE_STATUS table, providing more nuanced lag visibility (e.g., separate measurements for IO vs SQL thread lag).
Semi-Synchronous Replication
The primary writes and fsyncs each transaction to its own binary log first — making it durable locally — and only then waits for at least one replica to acknowledge that it has received the transaction before reporting the commit complete to the client. The rpl_semi_sync_master_wait_point setting controls when that wait happens: with AFTER_SYNC the primary waits before the changes become visible, so failover to an acknowledged replica is lossless; with AFTER_COMMIT (the MariaDB default) the transaction is already committed and visible before the wait, so a crash in that window can still lose it on failover. See Semisynchronous Replication.
-- Enable on primary:
SET GLOBAL rpl_semi_sync_master_enabled = 1;
-- Enable on replica:
SET GLOBAL rpl_semi_sync_slave_enabled = 1;
If no replica acknowledges within rpl_semi_sync_master_timeout (default 10 seconds), the primary falls back to async. Built-in since MariaDB 10.3 — no plugin needed.
Use when: you want at least one replica to have received each transaction before the client's commit returns — e.g. to bound failover data loss (use AFTER_SYNC). Note that semi-sync only delays commit completion as seen by the client; it does not add durability to the primary's own copy, and a transaction lost before any replica receives it is gone regardless of semi-sync.
Galera Cluster
Multi-primary synchronous replication — all nodes accept reads and writes, changes are certified across the cluster before committing. No single point of failure. Built into MariaDB.
> Packaging change (12.3+): The Galera library is no longer included as a server-package dependency or in the MariaDB repositories by default (MDEV-38744). On 12.3+ you must install galera-4 (or your distro's equivalent) separately when setting up a Galera node. The MariaDB server still understands Galera natively — only the library distribution changed.
Developer Constraints
These will break in Galera if you're not aware of them:
All tables must have a primary key:
-- ✗ DELETE fails in Galera on keyless tables:
CREATE TABLE logs (message TEXT);
-- ✅ Always define a PK:
CREATE TABLE logs (id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, message TEXT);
AUTO_INCREMENT values have gaps — Galera uses auto_increment_increment and auto_increment_offset per node to avoid conflicts, resulting in non-sequential IDs. Never rely on sequential auto-increment in Galera.
LOCK TABLES, GET_LOCK(), and FLUSH TABLES {table list} WITH READ LOCK are not supported — use transactions. Note: global FLUSH TABLES WITH READ LOCK (no table list) IS suppor
…
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: MariaDB
- Source: MariaDB/skills
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.