Prometheus is a popular open-source monitoring system that collects metrics by scraping HTTP endpoints called exporters. The mysqld_exporter binary exposes MySQL server metrics in Prometheus format so you can build dashboards, set alerts, and track database health over time. In this tutorial you will create a dedicated MySQL monitoring user with least-privilege grants, deploy mysqld_exporter as a systemd service on port 9104, and wire it into an existing Prometheus instance on RHEL 8.

Prerequisites

  • RHEL 8 server with MySQL 8.0 running (see the MySQL 8.0 on RHEL 8 tutorial if needed)
  • Prometheus server (same host or a separate host that can reach port 9104)
  • Root or sudo access on the RHEL 8 host
  • firewalld active and configured

Step 1 — Create a Least-Privilege MySQL Monitoring User

Log in to MySQL as root and create a dedicated user. Never use the root account for monitoring:

mysql -u root -p
CREATE USER 'exporter'@'localhost' IDENTIFIED BY 'StrongMonitorPass1!' WITH MAX_USER_CONNECTIONS 3;
GRANT PROCESS, REPLICATION CLIENT, SELECT ON *.* TO 'exporter'@'localhost';
GRANT SELECT ON performance_schema.* TO 'exporter'@'localhost';
FLUSH PRIVILEGES;
EXIT;

The MAX_USER_CONNECTIONS 3 limit prevents the monitoring account from consuming connection slots under load.

Step 2 — Download and Install mysqld_exporter

Fetch the latest release from the Prometheus GitHub releases page. Adjust the version number as needed:

cd /tmp
curl -LO https://github.com/prometheus/mysqld_exporter/releases/download/v0.15.1/mysqld_exporter-0.15.1.linux-amd64.tar.gz
tar xzf mysqld_exporter-0.15.1.linux-amd64.tar.gz
sudo mv mysqld_exporter-0.15.1.linux-amd64/mysqld_exporter /usr/local/bin/
sudo chmod +x /usr/local/bin/mysqld_exporter

Create a dedicated system user to run the exporter:

sudo useradd --no-create-home --shell /bin/false mysqld_exporter

Step 3 — Store MySQL Credentials Securely

Create a credentials file readable only by the exporter user. Hard-coding credentials in systemd unit files or environment variables is less secure:

sudo vi /etc/.mysqld_exporter.cnf
[client]
user=exporter
password=StrongMonitorPass1!
sudo chown mysqld_exporter:mysqld_exporter /etc/.mysqld_exporter.cnf
sudo chmod 400 /etc/.mysqld_exporter.cnf

Step 4 — Create a systemd Service

sudo vi /etc/systemd/system/mysqld_exporter.service
[Unit]
Description=Prometheus MySQL Exporter
After=network.target mysql.service

[Service]
User=mysqld_exporter
Group=mysqld_exporter
ExecStart=/usr/local/bin/mysqld_exporter 
  --config.my-cnf=/etc/.mysqld_exporter.cnf 
  --web.listen-address=:9104 
  --collect.info_schema.innodb_metrics 
  --collect.info_schema.processlist 
  --collect.perf_schema.eventsstatements 
  --collect.perf_schema.indexiowaits 
  --collect.perf_schema.tableiowaits 
  --collect.slave_status
Restart=on-failure
RestartSec=5s

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now mysqld_exporter
sudo systemctl status mysqld_exporter

Confirm metrics are being exposed:

curl -s http://localhost:9104/metrics | grep mysql_up

You should see mysql_up 1.

Step 5 — Open the Firewall for Prometheus

Allow only the Prometheus server IP to scrape port 9104:

sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.100/32" port port="9104" protocol="tcp" accept'
sudo firewall-cmd --reload

Step 6 — Add a Prometheus Scrape Target

On your Prometheus server, edit prometheus.yml and add the following job under scrape_configs:

scrape_configs:
  - job_name: 'mysql'
    static_configs:
      - targets: ['192.168.1.50:9104']
        labels:
          instance: 'rhel8-db01'
          environment: 'production'
sudo systemctl reload prometheus

Key metrics to watch in Prometheus or Grafana dashboards:

  • mysql_up — 1 if the exporter can reach MySQL, 0 if not
  • mysql_global_status_threads_connected — current client connections
  • mysql_global_status_slow_queries — cumulative slow query count
  • mysql_global_status_innodb_buffer_pool_reads — disk reads vs buffer pool hits
  • mysql_global_status_questions — total statements executed per second (use rate())

Conclusion

You have created a restricted MySQL monitoring user, deployed mysqld_exporter as a hardened systemd service with secure credential storage, exposed port 9104 only to your Prometheus server, and configured a scrape job. You can now build Grafana dashboards and alert rules to catch slow queries, connection exhaustion, and InnoDB buffer pool pressure before they affect users.

Next steps: Building a MySQL Grafana Dashboard on RHEL 8, Setting Prometheus Alertmanager Rules for MySQL, and Enabling MySQL Slow Query Log Analysis.