OpenTelemetry MySQL Monitoring [step by step]
Monitoring MySQL performance is crucial to ensure the optimal operation of your database and catch issues like slow queries, connection exhaustion, and replication lag before they impact your application.
This tutorial explains how to use OpenTelemetry Collector's MySQL receiver to collect database metrics and export them to Uptrace for visualization and alerting.
Prerequisites
Before you begin, make sure you have:
- A running MySQL 8.0+ or MariaDB 10.11+ instance
- OpenTelemetry Collector Contrib installed on a host that can reach your MySQL server
- An Uptrace DSN (cloud or self-hosted)
Create a dedicated MySQL user for monitoring with the necessary permissions:
CREATE USER 'otel'@'localhost' IDENTIFIED BY 'your_secure_password';
GRANT PROCESS, REPLICATION CLIENT, SELECT ON *.* TO 'otel'@'localhost';
FLUSH PRIVILEGES;
The PROCESS privilege allows access to server status variables, REPLICATION CLIENT enables replication lag monitoring, and SELECT is needed for performance_schema queries.
What is OpenTelemetry Collector?
OpenTelemetry Collector is a vendor-agnostic agent that pulls telemetry data from systems you want to monitor and exports the collected data to an OpenTelemetry backend.
The Collector supports a pipeline architecture with receivers (data sources), processors (data transformation), and exporters (destinations). This lets you collect MySQL metrics alongside application traces and logs in a single agent.
OpenTelemetry MySQL receiver
The MySQL receiver connects to your MySQL instance and periodically queries server status variables, InnoDB metrics, and performance_schema statement digests.
To start monitoring MySQL, configure the receiver in /etc/otel-contrib-collector/config.yaml using your Uptrace DSN:
receivers:
otlp:
protocols:
grpc:
http:
mysql:
endpoint: localhost:3306
username: otel
password: ${env:MYSQL_PASSWORD}
database: otel
collection_interval: 10s
statement_events:
digest_text_limit: 120
time_limit: 24h
limit: 250
exporters:
otlp/uptrace:
endpoint: api.uptrace.dev:4317
headers: { 'uptrace-dsn': '<FIXME>' }
processors:
resourcedetection:
detectors: [env, system]
cumulativetodelta:
batch:
timeout: 10s
service:
pipelines:
traces:
receivers: [otlp]
processors: [batch]
exporters: [otlp/uptrace]
metrics:
receivers: [otlp, mysql]
processors: [cumulativetodelta, batch, resourcedetection]
exporters: [otlp/uptrace]
Key configuration options:
| Option | Description |
|---|---|
collection_interval | How often to collect metrics (default: 10s) |
statement_events.digest_text_limit | Max length of SQL digest text |
statement_events.time_limit | Only include statements executed within this period |
statement_events.limit | Max number of statement digests to collect |
Restart OpenTelemetry Collector to apply the configuration:
sudo systemctl restart otelcol-contrib
Check the logs to verify the receiver started successfully:
sudo journalctl -u otelcol-contrib -f
You should see a line like Receiver started with name=mysql in the output.
Key MySQL metrics
The MySQL receiver collects metrics that fall into several categories:
Connection metrics track how many clients are connected and whether you're approaching the max_connections limit:
mysql.connection.count— current open connectionsmysql.connection.errors— connection errors by type (max connections, internal, etc.)
Query performance metrics help identify slow queries and throughput issues:
mysql.statement_event.count— statement executions by digestmysql.statement_event.wait.time— total wait time per statement digestmysql.operations— command counts (SELECT, INSERT, UPDATE, DELETE)
Buffer pool metrics reveal how effectively InnoDB is caching data:
mysql.buffer_pool.pages— pages by state (data, free, dirty)mysql.buffer_pool.operations— read requests vs disk reads (cache hit ratio)mysql.buffer_pool.data_pages— percentage of buffer pool used for data
Replication metrics (when applicable) help monitor replica lag:
mysql.replica.time_behind_source— seconds the replica is behind the sourcemysql.replica.sql_delay— configured replication delay
Troubleshooting
"Access denied" errors: Verify the monitoring user has the correct privileges. Run SHOW GRANTS FOR 'otel'@'localhost'; to check.
No statement events data: Ensure performance_schema is enabled in your MySQL configuration (performance_schema = ON in my.cnf). This is enabled by default in MySQL 8.0+.
High collection overhead: If the receiver adds noticeable load, increase collection_interval to 30s or 60s, and reduce the statement_events.limit.
Connection refused: Check that the Collector host can reach MySQL on port 3306. Test with mysql -h localhost -u otel -p from the Collector host.
OpenTelemetry Backend
Once the metrics are collected and exported, you can visualize them using a compatible backend system. For example, you can use Uptrace to create dashboards that display metrics from the OpenTelemetry Collector.
Uptrace is an OpenTelemetry backend that supports distributed tracing, metrics, and logs. You can use it to monitor applications and troubleshoot issues. Compare with top APM tools for MySQL monitoring.

Uptrace comes with an intuitive query builder, rich dashboards, alerting rules with notifications, and integrations for most languages and frameworks.
Uptrace can process billions of spans and metrics on a single server and allows you to monitor your applications at 10x lower cost.
In just a few minutes, you can try Uptrace by visiting the cloud demo (no login required) or running it locally with Docker. The source code is available on GitHub.
Available metrics
Uptrace automatically creates the following dashboard when MySQL metrics are available:

What's next?
MySQL monitoring is now configured to collect database performance metrics and query statistics. For alternative databases, check out PostgreSQL monitoring, or add Redis monitoring to track caching performance.