The Prometheus mysqld_exporter scrapes metrics from MySQL or MariaDB and exposes them in the Prometheus text format on port 9104. Add it as a scrape target to your Prometheus server and you get more than 100 metrics out of the box, covering connection counts, query throughput, InnoDB buffer pool, replication state, slow query count, and table lock wait times. Feeding these into a Grafana dashboard like the official one at grafana.com/dashboards/7362 gives you instant visibility into database health without writing any collectors yourself.
This guide installs the latest mysqld_exporter release on Ubuntu 24.04 LTS pointing at a local MariaDB server, configures a dedicated read-only monitoring user, runs the exporter, and verifies it’s serving metrics.
Tested April 2026 on Ubuntu 24.04.4 LTS with mysqld_exporter 0.19.0 and MariaDB 10.11.14
Step 1: Install MariaDB (if not already present)
If you already have MariaDB or MySQL running, skip to Step 2. For a clean exporter host, install MariaDB from the default Ubuntu or Debian repos:
sudo apt update
sudo apt install -y mariadb-server curl
sudo systemctl enable --now mariadb
The exporter supports MySQL 5.7 and later, and any recent MariaDB. Confirm the server is running:
systemctl is-active mariadb
mariadb --version
Step 2: Create a dedicated monitoring user
Prometheus exporters should never connect as root. Create a dedicated exporter user with the minimum privileges mysqld_exporter needs: PROCESS (to read process list), REPLICATION CLIENT (to query the binary log position and replication state), and SELECT on the information_schema and performance_schema databases. Cap the number of connections too so a stuck exporter can’t exhaust your connection pool:
sudo mariadb -e "CREATE USER 'exporter'@'localhost' IDENTIFIED BY 'exporterpass' WITH MAX_USER_CONNECTIONS 3;
GRANT PROCESS, REPLICATION CLIENT, SELECT ON *.* TO 'exporter'@'localhost';
FLUSH PRIVILEGES;"
Replace exporterpass with a strong random password generated with openssl rand -base64 24. Anyone with filesystem access to the exporter host can read this password, so the user should be scoped to localhost to prevent remote use.
Step 3: Store the credentials in a .my.cnf file
mysqld_exporter reads database credentials from a MySQL-style config file to avoid exposing them in the process list or environment variables. Create the file with restrictive permissions so only root can read it:
sudo tee /etc/.mysqld_exporter.cnf >/dev/null <<'EOF'
[client]
user=exporter
password=exporterpass
EOF
sudo chmod 600 /etc/.mysqld_exporter.cnf
Step 4: Download the latest mysqld_exporter
The exporter is a single statically-linked Go binary distributed as a tarball on GitHub. The version detection command pulls whatever the current release tag is:
cd /tmp
VER=$(curl -sL https://api.github.com/repos/prometheus/mysqld_exporter/releases/latest \
| grep tag_name | head -1 | sed 's/.*"v\([^"]*\)".*/\1/')
echo "Latest: $VER"
curl -sSL -O "https://github.com/prometheus/mysqld_exporter/releases/download/v${VER}/mysqld_exporter-${VER}.linux-amd64.tar.gz"
tar -xzf "mysqld_exporter-${VER}.linux-amd64.tar.gz"
sudo mv "mysqld_exporter-${VER}.linux-amd64/mysqld_exporter" /usr/local/bin/
sudo chown root:root /usr/local/bin/mysqld_exporter
sudo chmod 755 /usr/local/bin/mysqld_exporter
/usr/local/bin/mysqld_exporter --version
The current release reports its version, git revision, build date, and Go compiler version:
mysqld_exporter, version 0.19.0 (branch: HEAD, revision: 464bc5de74325c3ba85b237561e4b6c0bc3ca6d7)
build user: root@add22bd8c9b3
build date: 20260318-15:28:17
go version: go1.26.1
platform: linux/amd64
Step 5: Run the exporter under systemd
Create a dedicated system user and a systemd unit for the exporter:
sudo useradd -r -s /sbin/nologin prometheus
sudo tee /etc/systemd/system/mysqld_exporter.service >/dev/null <<'EOF'
[Unit]
Description=Prometheus MySQL Exporter
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=prometheus
Group=prometheus
ExecStart=/usr/local/bin/mysqld_exporter \
--config.my-cnf=/etc/.mysqld_exporter.cnf \
--web.listen-address=:9104
Restart=on-failure
RestartSec=5s
[Install]
WantedBy=multi-user.target
EOF
# Let the prometheus user read the creds file
sudo chgrp prometheus /etc/.mysqld_exporter.cnf
sudo chmod 640 /etc/.mysqld_exporter.cnf
sudo systemctl daemon-reload
sudo systemctl enable --now mysqld_exporter
Confirm the service is running:
systemctl is-active mysqld_exporter
ss -tlnp | grep 9104
Step 6: Verify metrics are served
The exporter serves Prometheus metrics on http://localhost:9104/metrics. Fetch a couple of key lines to confirm it’s scraping MariaDB successfully:
curl -s http://localhost:9104/metrics | grep -E '^mysql_up|^mysql_global_status_uptime ' | head -5
The mysql_up metric is the binary health check, and mysql_global_status_uptime returns how long the MariaDB server has been running in seconds:
mysql_global_status_uptime 28
mysql_up 1
mysql_up 1 is the answer you want. If it reports 0, the credentials in /etc/.mysqld_exporter.cnf are wrong or the user can’t connect from localhost. Check the service logs with journalctl -u mysqld_exporter -n 30 for the specific error.
Step 7: Add to Prometheus scrape config
On your Prometheus server, add a scrape job. Edit /etc/prometheus/prometheus.yml and append:
scrape_configs:
- job_name: 'mysql'
static_configs:
- targets: ['db01.internal:9104', 'db02.internal:9104']
labels:
environment: 'prod'
Reload Prometheus (or send SIGHUP) and check the target shows up as UP in the Prometheus web UI at /targets. From there, add the official MySQL Grafana dashboard by importing ID 7362.
Step 8: Firewall the exporter port
Port 9104 should only be accessible to the Prometheus server. If you allowed it everywhere, anyone who can reach the host gets a detailed view of your database internals. Lock it down with UFW:
sudo ufw allow from 10.0.1.20 to any port 9104 proto tcp comment 'Prometheus scrape from monitoring host'
Replace the IP with the Prometheus server’s actual address. See our UFW reference for the full syntax including how to delete and reorder rules.
Useful metric queries
A few PromQL starting points once the exporter is feeding metrics:
- Queries per second:
rate(mysql_global_status_queries[5m]) - Slow queries per second:
rate(mysql_global_status_slow_queries[5m]) - InnoDB buffer pool hit ratio:
1 - (rate(mysql_global_status_innodb_buffer_pool_reads[5m]) / rate(mysql_global_status_innodb_buffer_pool_read_requests[5m])) - Active connections:
mysql_global_status_threads_connected - Replication lag:
mysql_slave_status_seconds_behind_master
Wrap up
The Prometheus MySQL exporter is a one-binary install that gives you deep database observability with almost no maintenance burden. Pair it with the MariaDB replication guide to monitor replication lag across a cluster, the MySQL S3 backup guide for durability, and the Prometheus on Rocky Linux 10 install for the other side of the wire. For the broader monitoring picture, the Grafana on Ubuntu/Debian guide gets your dashboards online.
Can’t download json file for dashboard. can you check the link?