This post explains how you can quickly start using such trending tools as Prometheus and Grafana for monitoring and graphing of MySQL and system performance.
Update, February 20, 2017: Since this blog post was published, we have released Percona Monitoring and Management (PMM), which is the easiest way to monitor MySQL and MongoDB using Grafana and Prometheus. You can check the PMM documentation for more detail. If you need help, PMM is fully supported under Percona Support. Alternatively, community support is available through the Percona Montoring and Management Forums.
I will try to keep this blog as short as possible, so you can quickly set things up before getting bored. I plan to cover the details in the next few posts. I am going to go through the installation process here in order to get some really useful and good-looking graphs in the end.
Prometheus is an open-source service monitoring system and time series database. In short, the quite efficient daemon scrapes metrics from remote machines using HTTP protocol and stores data in the local time-series database. Prometheus provides a simple web interface, a very powerful query language, HTTP API, etc. However, the storage is not designed to be durable for the time being.
The remote machines need to run exporters to expose metrics to Prometheus. We will be using the following two:
Grafana is an open source, feature-rich metrics dashboard and graph editor for Graphite, Elasticsearch, OpenTSDB, Prometheus, and InfluxDB. It is a powerful tool for visualizing large-scale measurement data and designed to work with time-series. Grafana supports different types of graphs, allows for a custom representation of individual metrics on the graph and various methods of authentication including LDAP.
Here is a diagram of the setup we are going to use:
To install on the monitor host.
Get the latest tarball from Github.
|
1 |
wget https://github.com/prometheus/prometheus/releases/download/0.17.0rc2/prometheus-0.17.0rc2.linux-amd64.tar.gz<br>mkdir /opt/prometheus<br>tar zxf prometheus-0.17.0rc2.linux-amd64.tar.gz -C /opt/prometheus --strip-components=1<br> |
Create a simple config:
|
1 |
cat << EOF > /opt/prometheus/prometheus.yml<br>global:<br> scrape_interval: 5s<br> evaluation_interval: 5s<br> <br>scrape_configs:<br> - job_name: linux<br> target_groups:<br> - targets: ['192.168.56.107:9100']<br> labels:<br> alias: db1<br> - job_name: mysql<br> target_groups:<br> - targets: ['192.168.56.107:9104']<br> labels:<br> alias: db1<br>EOF<br> |
where 192.168.56.107 is the IP address of the db host we are going to monitor and db1 is its short name. Note, the “alias” label is important here because we rely on it in the predefined dashboards below to get per host graphs.
Start Prometheus in the foreground:
|
1 |
[root@centos7 ~]# cd /opt/prometheus<br>[root@centos7 prometheus]# ./prometheus <br>prometheus, version 0.17.0rc2 (branch: release-0.17, revision: 667c221)<br> build user: fabianreinartz@macpro<br> build date: 20160205-13:35:53<br> go version: 1.5.3<br>INFO[0000] Loading configuration file prometheus.yml source=main.go:201<br>INFO[0000] Loading series map and head chunks... source=storage.go:297<br>INFO[0000] 0 series loaded. source=storage.go:302<br>WARN[0000] No AlertManager configured, not dispatching any alerts source=notification.go:165<br>INFO[0000] Starting target manager... source=targetmanager.go:114<br>INFO[0000] Target manager started. source=targetmanager.go:168<br>INFO[0000] Listening on :9090 source=web.go:239<br> |
Now we can access Prometheus’ built-in web interface by http://monitor_host:9090

If you look at the Status page from the top menu, you will see that our monitoring targets are down so far. Now let’s setup them – prometheus exporters.
Install on the db host. Of course, you can use the same monitor host for the experiment. Obviously, this node must run MySQL.
Download exporters from here and there.
|
1 |
wget https://github.com/prometheus/node_exporter/releases/download/0.12.0rc3/node_exporter-0.12.0rc3.linux-amd64.tar.gz<br>wget https://github.com/prometheus/mysqld_exporter/releases/download/0.7.1/mysqld_exporter-0.7.1.linux-amd64.tar.gz<br>mkdir /opt/prometheus_exporters<br>tar zxf node_exporter-0.12.0rc3.linux-amd64.tar.gz -C /opt/prometheus_exporters<br>tar zxf mysqld_exporter-0.7.1.linux-amd64.tar.gz -C /opt/prometheus_exporters<br> |
Start node_exporter in foreground:
|
1 |
[root@centos7 ~]# cd /opt/prometheus_exporters<br>[root@centos7 prometheus_exporters]# ./node_exporter <br>INFO[0000] No directory specified, see --collector.textfile.directory source=textfile.go:57<br>INFO[0000] Enabled collectors: source=node_exporter.go:146<br>INFO[0000] - filesystem source=node_exporter.go:148<br>INFO[0000] - loadavg source=node_exporter.go:148<br>INFO[0000] - time source=node_exporter.go:148<br>INFO[0000] - vmstat source=node_exporter.go:148<br>INFO[0000] - diskstats source=node_exporter.go:148<br>INFO[0000] - filefd source=node_exporter.go:148<br>INFO[0000] - mdadm source=node_exporter.go:148<br>INFO[0000] - meminfo source=node_exporter.go:148<br>INFO[0000] - netdev source=node_exporter.go:148<br>INFO[0000] - textfile source=node_exporter.go:148<br>INFO[0000] - entropy source=node_exporter.go:148<br>INFO[0000] - stat source=node_exporter.go:148<br>INFO[0000] - uname source=node_exporter.go:148<br>INFO[0000] - conntrack source=node_exporter.go:148<br>INFO[0000] - netstat source=node_exporter.go:148<br>INFO[0000] - sockstat source=node_exporter.go:148<br>INFO[0000] - version source=node_exporter.go:148<br>INFO[0000] Starting node_exporter v0.12.0rc3 at :9100 source=node_exporter.go:167<br> |
Unlike node_exporter, mysqld_exporter wants MySQL credentials. Those privileges should be sufficient:
|
1 |
mysql> GRANT REPLICATION CLIENT, PROCESS ON *.* TO 'prom'@'localhost' identified by 'abc123';<br>mysql> GRANT SELECT ON performance_schema.* TO 'prom'@'localhost';<br> |
Create .my.cnf and start mysqld_exporter in foreground:
|
1 |
[root@centos7 ~]# cd /opt/prometheus_exporters<br>[root@centos7 prometheus_exporters]# cat << EOF > .my.cnf<br>[client]<br>user=prom<br>password=abc123<br>EOF<br>[root@centos7 prometheus_exporters]# <br>[root@centos7 prometheus_exporters]# ./mysqld_exporter -config.my-cnf=".my.cnf"<br>INFO[0000] Starting Server: :9104 file=mysqld_exporter.go line=1997<br> |
At this point we should see our endpoints are up and running on the Prometheus Status page:
Install on the monitor host.
Grafana has RPM and DEB packages. The installation is as simple as installing one package.
RPM-based system:
|
1 |
yum install https://grafanarel.s3.amazonaws.com/builds/grafana-2.6.0-1.x86_64.rpm<br> |
or APT-based one:
|
1 |
wget https://grafanarel.s3.amazonaws.com/builds/grafana_2.6.0_amd64.deb<br>apt-get install -y adduser libfontconfig<br>dpkg -i grafana_2.6.0_amd64.deb<br> |
Open and edit the last section of /etc/grafana/grafana.ini resulting in the following ending:
|
1 |
[dashboards.json]<br>enabled = true<br>path = /var/lib/grafana/dashboards<br> |
Percona has built the predefined dashboards for Grafana with Prometheus for you.
Let’s get them deployed:
|
1 |
git clone https://github.com/percona/grafana-dashboards.git<br>cp -r grafana-dashboards/dashboards /var/lib/grafana<br> |
It is important to apply the following minor patch on Grafana 2.6 in order to use the interval template variable to get the good zoomable graphs. The fix is simply to allow variable in Step field on Grafana graph editor page. For more information, take a look at PR#3757 and PR#4257. We hope the last one will be released with the next Grafana version.
|
1 |
sed -i 's/step_input:""/step_input:c.target.step/; s/ HH:MM/ HH:mm/; s/,function(c)/,"templateSrv",function(c,g)/; s/expr:c.target.expr/expr:g.replace(c.target.expr,c.panel.scopedVars)/' /usr/share/grafana/public/app/plugins/datasource/prometheus/query_ctrl.js<br>sed -i 's/h=a.interval/h=g.replace(a.interval, c.scopedVars)/' /usr/share/grafana/public/app/plugins/datasource/prometheus/datasource.js<br> |
Those changes are idempotent.
Finally, start Grafana:
|
1 |
service grafana-server start<br> |
At this point, we are one step before being done. Login into Grafana web interface http://monitor_host:3000 (admin/admin).
Go to Data Sources and add one for Prometheus:
Now check out the dashboards and graphs. Say choose “System Overview” and period “Last 5 minutes” on top-right. You should see something similar:
If your graphs are not populating ensure the system time is correct on the monitor host.
Here are some real-world samples (images are clickable and scrollable):




Enjoy!
Prometheus and Grafana is a great tandem for enabling monitoring and graphing capabilities for MySQL. The tools are pretty easy to deploy, they are designed for time series with high efficiency in mind. In the next blog post, I will talk more about technical aspects, problems, and related stuff.