Skill
MariaDB
mariadb · current version v1
Troubleshoot and support a MariaDB server — connect, diagnose, and resolve problems across 10.6/10.11/11.x, on Docker, bare metal, systemd, a managed service, or Kubernetes. Covers the mariadb client (the mysql name is gone in 11.x), config paths, connections, InnoDB locks, slow queries, replication and Galera, and disk. Use when someone reports MariaDB is down, slow, refusing connections, a mysql command "not found", deadlocking, a Galera node not joining, or lagging a replica.
11 downloads · published 2026-09-02
What this grants
- skill mariadb
Skill Card
- License or terms: check the skill's own repository for license details (mariadb on GitHub).
Security Audits
- NanoInfra Scanner PASS no issues found
- VirusTotal PASS no engines flagged this file (full report)
Version history
| Version | Published | Status |
|---|---|---|
| v1 | 2026-09-02 | published |
Files
SKILL.md(7450 bytes)
SKILL.md
raw | preview
MariaDB — Troubleshooting & Support
A support runbook, not a tutorial. Establish the host with the detect-platform skill first, then work top to bottom: read before you write. Commands and output below were run against MariaDB 11.8.9. MariaDB is a separate product from MySQL — the SQL and InnoDB overlap, but the tooling, versions, replication (GTID differs), and clustering (Galera) do not. Confirm which you are on before applying a MySQL runbook here.
Lines: 10.6 and 10.11 are long-term; 11.x is current. Diagnose against SELECT VERSION();
(it prints e.g. 11.8.9-MariaDB).
0. Identify what you are on — and the client-name trap
mariadb --version # mariadb … 11.8.9-MariaDB … — the client is `mariadb`
mariadb -uroot -p -N -e 'SELECT VERSION();'
mariadbd --version # the server binary is `mariadbd`
The trap: in current MariaDB the historical mysql/mysqld names are gone — verified in the
11.8 image, only mariadb and mariadbd exist, no mysql symlink. A runbook (or a monitoring
check) that calls mysql/mysqld fails with "command not found" on a modern MariaDB. Use
mariadb/mariadbd. Older packages still ship mysql as a compatibility symlink, so its
presence does not prove the server is MySQL — the version string does.
Config and data:
mariadb -uroot -p -e "SHOW VARIABLES WHERE Variable_name IN ('datadir','log_error','socket','port','bind_address');"
# Debian/Ubuntu: /etc/mysql/ (mariadb.conf.d/) ; RHEL: /etc/my.cnf.d/ ; upstream image: /etc/mysql/
1. Connect, per deployment
Docker — error log to stderr → docker logs:
docker exec -it <c> mariadb -uroot -p
docker logs --tail 200 -f <c>
systemd (bare metal or VM):
systemctl status mariadb
journalctl -u mariadb -n 200 --no-pager
tail -f /var/log/mysql/error.log 2>/dev/null || tail -f /var/lib/mysql/*.err
Bare metal — the settings that bite (detect-platform gave RAM and any cgroup cap):
# innodb_buffer_pool_size ~50-70% of RAM on a dedicated host, but it MUST fit under a
# container/cgroup limit or mariadbd is OOM-killed.
mariadb -uroot -p -e "SELECT @@innodb_buffer_pool_size/1024/1024/1024 AS gb, @@max_connections;"
cat /proc/$(pgrep -o mariadbd)/limits | grep 'open files'
Managed — no host shell; client connects, config is the parameter group, restarts/failover via
the console. SHOW, the slow log, and status views still work.
Kubernetes (operator) — kubectl exec -it <pod> -- mariadb -uroot -p; config is the CR; the
root password is in a Secret.
2. Tools and arguments
mariadb -h <host> -P 3306 -u <user> -p -D <db> # -N no header, -B tab-separated, -e "SQL" one-shot
mariadb-admin -uroot -p status # uptime/threads/questions (was mysqladmin)
mariadb-dump -uroot -p --single-transaction --routines --triggers <db> > db.sql # was mysqldump
mariadb-binlog <binlog> # inspect/replay binlogs
The mariadb-* names replace the old mysql* tool names; on older installs the mysqldump etc.
names may still exist as symlinks.
3. Diagnostics — read-only first
SHOW GLOBAL STATUS LIKE 'Threads_connected'; SHOW VARIABLES LIKE 'max_connections';
SHOW FULL PROCESSLIST; -- connections, their Time and State
SHOW ENGINE INNODB STATUS\G -- LATEST DETECTED DEADLOCK, lock waits, buffer pool
SELECT * FROM information_schema.INNODB_LOCK_WAITS; -- current blocking
Slow queries: SET GLOBAL slow_query_log=ON; SET GLOBAL long_query_time=0.2; then read the slow
log. MariaDB also has the slow-log analyzer mariadb-dumpslow. Plans: EXPLAIN <query>; and
ANALYZE <query>; (MariaDB's ANALYZE runs it and shows real vs estimated rows).
4. Common problems → resolution
mysql: command not found — you are on modern MariaDB; use mariadb (see §0). This is the
single most common "the runbook is wrong" ticket after a MySQL→MariaDB migration.
Cannot connect
- Socket path or down server:
Can't connect … socket '/run/mysqld/mysqld.sock'— check the server is up and thesocketvariable, or force TCP with-h 127.0.0.1. - Auth: MariaDB defaults to
mysql_native_password/ed25519, not MySQL 8'scaching_sha2_password— a driver configured for one against the other fails.SELECT user, host, plugin FROM mysql.user;shows what each account uses. Too many connections—max_connectionsreached; a pooler beats raising it.
InnoDB locks / deadlocks — same shape as MySQL: SHOW ENGINE INNODB STATUS\G for the latest
deadlock; find a stuck holder in SHOW PROCESSLIST and KILL <id> (§6); Lock wait timeout exceeded points at a long/abandoned transaction.
Galera cluster (if this is a Galera node)
SHOW STATUS LIKE 'wsrep_cluster_size'; -- how many nodes are in the primary component
SHOW STATUS LIKE 'wsrep_local_state_comment'; -- Synced | Donor/Desynced | Joining | Initialized
SHOW STATUS LIKE 'wsrep_cluster_status'; -- Primary vs non-Primary (a partitioned node)
- A node stuck
Joiningis doing an SST (full state transfer) — watch the error log for the transfer method and disk/network. Anon-Primarynode lost quorum; do not force it Primary unless you are certain it holds the newest data (wsrep_last_committed), or you resurrect stale writes. Bootstrapping the cluster from the wrong node is the classic Galera data-loss event.
Replication lag / broken
SHOW REPLICA STATUS\G -- Seconds_Behind_Source, Slave_IO/SQL_Running, Last_Error (SHOW SLAVE STATUS on old versions)
MariaDB GTID (0-1-1234) differs from MySQL GTID — do not mix the two servers in one topology
expecting compatible GTIDs.
Disk filling / won't start — same as MySQL: binlogs piling up (SHOW BINARY LOGS;,
PURGE BINARY LOGS BEFORE … once replicas consumed them, §6); per-table reclaim via
OPTIMIZE TABLE (locks); on a crash InnoDB recovers on start, and innodb_force_recovery is a
last resort that can lose data (§6).
5. Before you run anything that writes
KILL, PURGE BINARY LOGS, OPTIMIZE TABLE, SET GLOBAL, Galera bootstrap, and restarts change
data, availability, or config — on a nanoinfra deployment a mutate.remote capability (approval
interactively, a standing grant unattended). Name the node and the change.
SET GLOBALis runtime-only; persist in the config or a restart loses it.KILL <id>rolls back an in-flight write.- On Galera, bootstrapping (
galera_new_cluster/--wsrep-new-cluster) declares a node the source of truth for the whole cluster — pick the node with the latest committed state, never blindly. PURGE BINARY LOGS: confirm replicas consumed them first.innodb_force_recovery > 0: copydatadirfirst; use the lowest level that lets you dump and rebuild.