MySQL and PostgreSQL Data Sources
Grafana provides native support for querying MySQL and PostgreSQL relational databases. Both data sources share similar features and SQL query capabilities.Overview
The MySQL and PostgreSQL data sources support:- Standard SQL queries for time series and table data
- SQL query builder and code editor
- Macros for time-based filtering and grouping
- Template variables from query results
- Multi-value variables
Source:
public/app/plugins/datasource/mysql/ and public/app/plugins/datasource/grafana-postgresql-datasource/Configuration
MySQL Configuration
Configure Connection
Set connection parameters:
- Host:
localhost:3306 - Database:
mydatabase - User: Database username
- Password: Database password
PostgreSQL Configuration
Configure Connection
Set connection parameters:
- Host:
localhost:5432 - Database:
postgres - User: Database username
- Password: Database password
- TLS/SSL Mode:
disable,require, orverify-full
Connection Settings
Database host and port (e.g.,
localhost:3306, db.example.com:5432)Database name to connect to
Database username
Database password (stored encrypted)
PostgreSQL only: SSL mode (
disable, require, verify-ca, verify-full)Maximum number of open connections to the database
Maximum number of idle connections
Maximum connection lifetime in seconds
Query Requirements
Queries must return specific columns based on visualization type:Time Series Queries
Time series queries must return:
- A column named
time,time_sec, or timestamp column (in UTC) - One or more columns with numeric data type as values
- Optional: A column named
metricfor series names
Source:
public/app/plugins/datasource/mysql/CheatSheet.tsx:12-28 and public/app/plugins/datasource/grafana-postgresql-datasource/CheatSheet.tsx:12-27Table Queries
Table queries can return any set of columns. Grafana displays them in a table panel.SQL Macros
Grafana provides macros to simplify time-based queries:MySQL Macros
$__time(column)
$__time(column)
Converts a timestamp column to Unix timestamp:Expands to:
Source:
public/app/plugins/datasource/mysql/CheatSheet.tsx:35$__timeEpoch(column)
$__timeEpoch(column)
Same as
$__time(), returns Unix epoch:Source:
public/app/plugins/datasource/mysql/CheatSheet.tsx:36$__timeFilter(column)
$__timeFilter(column)
Filters by dashboard time range:Expands to:
Source:
public/app/plugins/datasource/mysql/CheatSheet.tsx:37$__unixEpochFilter(column)
$__unixEpochFilter(column)
Filters Unix epoch timestamps:Expands to:
Source:
public/app/plugins/datasource/mysql/CheatSheet.tsx:38$__timeGroup(column, interval, [fillvalue])
$__timeGroup(column, interval, [fillvalue])
Groups time into intervals:MySQL expands to:Optional
fillvalue fills missing intervals:- Literal value:
0,NULL previous: Use previous value
Source:
public/app/plugins/datasource/mysql/CheatSheet.tsx:42-47$__timeGroupAlias(column, interval)
$__timeGroupAlias(column, interval)
Groups time and aliases as
time:Source:
public/app/plugins/datasource/mysql/CheatSheet.tsx:48-50PostgreSQL Macros
$__time(column)
$__time(column)
Aliases column as Expands to:
time:Source:
public/app/plugins/datasource/grafana-postgresql-datasource/CheatSheet.tsx:34$__timeEpoch(column)
$__timeEpoch(column)
Converts to Unix epoch:Expands to:
Source:
public/app/plugins/datasource/grafana-postgresql-datasource/CheatSheet.tsx:35$__timeFilter(column)
$__timeFilter(column)
Filters by time range:Expands to:
Source:
public/app/plugins/datasource/grafana-postgresql-datasource/CheatSheet.tsx:36-39$__timeGroup(column, interval, [fillvalue])
$__timeGroup(column, interval, [fillvalue])
Groups time into buckets:PostgreSQL expands to:
Source:
public/app/plugins/datasource/grafana-postgresql-datasource/CheatSheet.tsx:44-48$__timeGroupAlias(column, interval)
$__timeGroupAlias(column, interval)
Groups and aliases as
time:Source:
public/app/plugins/datasource/grafana-postgresql-datasource/CheatSheet.tsx:56-66Macro Value Functions
Macros that return values for custom conditionals: MySQL:$__timeFrom()→FROM_UNIXTIME(1492750877)$__timeTo()→FROM_UNIXTIME(1492750877)$__unixEpochFrom()→1492750877$__unixEpochTo()→1492750877
Source:
public/app/plugins/datasource/mysql/CheatSheet.tsx:79-86$__timeFrom()→'2017-04-21T05:01:17Z'$__timeTo()→'2017-04-21T05:01:17Z'$__unixEpochFrom()→1492750877$__unixEpochTo()→1492750877
Source:
public/app/plugins/datasource/grafana-postgresql-datasource/CheatSheet.tsx:68-76Query Examples
Time Series Example
MySQL:Source:
public/app/plugins/datasource/mysql/CheatSheet.tsx:56-76Multiple Series
Use themetric column to create multiple series:
Multiple Values
Return multiple value columns:metric column is used as a prefix: server-01 cpu, server-01 memory.
Table Query
Aggregation by Label
Template Variables
Query Variables
Populate variables from query results: MySQL:Multi-Value Variables
UseIN clause with multi-value variables:
Variable with Filters
Performance Optimization
Use Indexes
Create indexes on time columns and filter columns:
Limit Time Range
Always use time filters to reduce query scope:
Use Connection Pooling
Configure appropriate connection pool sizes:
Aggregate at Database
Let the database do aggregations:
TimescaleDB Support (PostgreSQL)
For PostgreSQL with TimescaleDB:Enable TimescaleDB
Check “TimescaleDB” in data source settings for optimized time-series queries.Hypertable Queries
Continuous Aggregates
Troubleshooting
Connection failed
Connection failed
- Verify host and port are correct
- Check database firewall rules allow Grafana IP
- Confirm database is running:
systemctl status mysql/postgresql - Test connection from Grafana server:
mysql -h host -u user -p - Review database logs for connection errors
No data in time series
No data in time series
- Ensure query returns column named
timeortime_sec - Verify time values are in UTC
- Check time range includes data:
SELECT MIN(time), MAX(time) FROM table - Confirm numeric value columns exist
- Results must be ordered by time:
ORDER BY time
Query timeout
Query timeout
- Add indexes on filtered columns
- Reduce time range
- Use
LIMITclause for testing - Check database slow query log
- Increase query timeout in database config
Variable not populating
Variable not populating
- Verify query returns results in database client
- Check variable query syntax
- Review Grafana server logs for query errors
- Ensure proper permissions for user
Best Practices
- Always filter by time: Use
$__timeFilter()in WHERE clause - Create proper indexes: Index time columns and frequently filtered fields
- Use macros: Leverage Grafana macros for time operations
- Limit result sets: Use LIMIT for table queries
- Use connection pooling: Configure appropriate pool sizes
- Aggregate in database: Use GROUP BY instead of post-processing
- Order results by time: Required for time series visualization
- Monitor database performance: Watch for slow queries and optimize