MySQL documentation major improvements (#107690)

* added keywords and fixed description

* Update (dateColumn) description

Signed-off-by: Sheikh-Abubaker <sheikhabubaker761@gmail.com>

* Mount docs from the current repository

Signed-off-by: Jack Baldry <jack.baldry@grafana.com>

* Clean up variables

Signed-off-by: Jack Baldry <jack.baldry@grafana.com>

* Improve timeFilter and timeGroup macro description

Signed-off-by: Sheikh-Abubaker <sheikhabubaker761@gmail.com>

* Fix timefilter macro example formatting

Signed-off-by: Sheikh-Abubaker <sheikhabubaker761@gmail.com>

* Fix time macro example formatting

Signed-off-by: Sheikh-Abubaker <sheikhabubaker761@gmail.com>

* Remove extra spaces from timefilter macro example

Signed-off-by: Sheikh-Abubaker <sheikhabubaker761@gmail.com>

* Introduce new table and Add examples for time, timeFilter and timeGroup Macros

Signed-off-by: Sheikh-Abubaker <sheikhabubaker761@gmail.com>

* Improve existing examples of timeGroupAlias Macro

Signed-off-by: Sheikh-Abubaker <sheikhabubaker761@gmail.com>

* Remove data frame description

Signed-off-by: Sheikh-Abubaker <sheikhabubaker761@gmail.com>

* fixed the homepage with valid links

Signed-off-by: Usman Ahmad <usman.ahmad@grafana.com>

* Add Table Panel results for Macros

Signed-off-by: Sheikh-Abubaker <sheikhabubaker761@gmail.com>

* fixed and define the configuration part for grafana mysql user

Signed-off-by: Usman Ahmad <usman.ahmad@grafana.com>

* fixed port typo

Signed-off-by: Usman Ahmad <usman.ahmad@grafana.com>

* remove the sqlDatasourceDatabaseSelection based https://github.com/grafana/grafana/issues/105232

Signed-off-by: Usman Ahmad <usman.ahmad@grafana.com>

* added annotation single tag example

Signed-off-by: Usman Ahmad <usman.ahmad@grafana.com>

* Change format type

Signed-off-by: Sheikh-Abubaker <sheikhabubaker761@gmail.com>

* fix minor typos and run prettier

Signed-off-by: Usman Ahmad <usman.ahmad@grafana.com>

* Address Macros specific changes

Signed-off-by: Sheikh-Abubaker <sheikhabubaker761@gmail.com>

* Revert column name and replace URL with version substitution

Signed-off-by: Sheikh-Abubaker <sheikhabubaker761@gmail.com>

* re-added the text for the feature flag

Signed-off-by: Usman Ahmad <usman.ahmad@grafana.com>

* revert back the changes for the grafana mysql usage

Signed-off-by: Usman Ahmad <usman.ahmad@grafana.com>

* fixed links as per writers toolkit guide

* run prettier

Signed-off-by: Usman Ahmad <usman.ahmad@grafana.com>

* Update docs/sources/datasources/mysql/query-editor/_index.md

thanks

Co-authored-by: Zoltán Bedi <zoltan.bedi@gmail.com>

---------

Signed-off-by: Sheikh-Abubaker <sheikhabubaker761@gmail.com>
Signed-off-by: Jack Baldry <jack.baldry@grafana.com>
Signed-off-by: Usman Ahmad <usman.ahmad@grafana.com>
Co-authored-by: Sheikh-Abubaker <sheikhabubaker761@gmail.com>
Co-authored-by: Jack Baldry <jack.baldry@grafana.com>
Co-authored-by: Zoltán Bedi <zoltan.bedi@gmail.com>
This commit is contained in:
Usman Ahmad 2025-07-30 16:03:44 +02:00 committed by GitHub
parent 04c53678fa
commit f7f8a52bda
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 128 additions and 88 deletions

View File

@ -2,10 +2,11 @@
aliases:
- ../data-sources/mysql/
- ../features/datasources/mysql/
description: introduction to the MySQL data source in Grafana
description: Introduction to the MySQL data source in Grafana
keywords:
- grafana
- mysql
- data source
- guide
labels:
products:
@ -45,7 +46,7 @@ refs:
# MySQL data source
Grafana ships with a built-in MySQL data source plugin that allows you to query and visualize data from a MySQL-compatible database like MariaDB or Percona Server. You don't need to install a plugin in order to add the MySQL data source to your Grafana instance.
Grafana ships with a built-in MySQL data source plugin that allows you to query and visualize data from a MySQL-compatible database like [MariaDB](https://mariadb.org/) or [Percona Server](https://www.percona.com/). You don't need to install a plugin in order to add the MySQL data source to your Grafana instance.
Grafana offers several configuration options for this data source as well as a visual and code-based query editor.

View File

@ -45,10 +45,14 @@ This document provides instructions for configuring the MySQL data source and ex
You must have the `Organization administrator` role in order to configure the MySQL data source.
Administrators can also [configure the data source via YAML](#provision-the-data-source) with Grafana's provisioning system.
Grafana ships with the MySQL plugin, so no additional installation is required.
{{< admonition type="note" >}}
When adding a data source, ensure the database user you specify has only `SELECT` permissions on the relevant database and tables. Grafana does not validate the safety of queries, which means they can include potentially harmful SQL statements, such as `USE otherdb;` or `DROP TABLE user;`, which could get executed. To minimize this risk, Grafana strongly recommends creating a dedicated MySQL user with restricted permissions.
Grafana ships with the MySQL data source by default, so no additional installation is required.
{{< /admonition >}}
{{< admonition type="caution" >}}
When adding a data source, ensure the database user you specify has only `SELECT` permissions on the relevant database and tables. Grafana does not validate the safety of queries, which means they can include potentially harmful SQL statements, such as `USE otherdb;` or `DROP TABLE user;`, which could get executed.
To minimize this risk, Grafana strongly recommends creating a dedicated MySQL user with restricted permissions.
{{< /admonition >}}
Example:
@ -81,7 +85,7 @@ Following is a list of MySQL configuration options:
**Connection:**
- **Host URL** - Enter the IP address/hostname and optional port of your MySQL instance. If the port is omitted the default 3306 port will be used.
- **Host URL** - Enter the IP address/hostname and optional port of your MySQL instance. If the port is omitted the default `3306` port will be used.
- **Database** - Enter the name of your MySQL database.
**Authentication:**

View File

@ -58,6 +58,9 @@ refs:
destination: /docs/grafana/<GRAFANA_VERSION>/alerting/alerting-rules/templates/
- pattern: /docs/grafana-cloud/
destination: /docs/grafana-cloud/alerting-and-irm/alerting/alerting-rules/templates/
configure-standard-options:
- pattern: /docs/grafana/
- destination: /docs/grafana/<GRAFANA_VERSION>/panels-visualizations/configure-standard-options/
---
# MySQL query editor
@ -125,26 +128,26 @@ Changes made to a query in Code mode will not transfer to Builder mode and will
You can add macros to your queries to simplify the syntax and enable dynamic elements, such as date range filters.
| Macro example | Description |
| ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `$__time(dateColumn)` | Replaces the value with an expression to convert to a UNIX timestamp and renames the column to `time_sec`. Example: _UNIX_TIMESTAMP(dateColumn) AS time_sec_. |
| `$__timeEpoch(dateColumn)` | Replaces the value with an expression to convert to a UNIX Epoch timestamp and renames the column to `time_sec`. Example: _UNIX_TIMESTAMP(dateColumn) AS time_sec_. |
| `$__timeFilter(dateColumn)` | Replaces the value a time range filter using the specified column name. Example: _dateColumn BETWEEN FROM_UNIXTIME(1494410783) AND FROM_UNIXTIME(1494410983)_ |
| `$__timeFrom()` | Replaces the value with the start of the currently active time selection. Example: _FROM_UNIXTIME(1494410783)_ |
| `$__timeTo()` | Replaces the value with the end of the currently active time selection. Example: _FROM_UNIXTIME(1494410983)_ |
| `$__timeGroup(dateColumn,'5m')` | Replaces the value with an expression suitable for use in a GROUP BY clause. Example: *cast(cast(UNIX_TIMESTAMP(dateColumn)/(300) as signed)*300 as signed),\* |
| `$__timeGroup(dateColumn,'5m', 0)` | Same as the `$__timeGroup(dateColumn,'5m')` macro, but includes a fill parameter to ensure missing points in the series are added by Grafana, using 0 as the default value. **This applies only to time series queries.** |
| `$__timeGroup(dateColumn,'5m', NULL)` | Same as the `$__timeGroup(dateColumn,'5m', 0)` but NULL is used as the value for missing points. **This applies only to time series queries.** |
| `$__timeGroup(dateColumn,'5m', previous)` | Same as the `$__timeGroup(dateColumn,'5m', previous)` macro, but uses the previous value in the series as the fill value. If no previous value exists,`NULL` will be used. **This applies only to time series queries.** |
| `$__timeGroupAlias(dateColumn,'5m')` | Replaces the value identical to $\_\_timeGroup but with an added column alias. |
| `$__unixEpochFilter(dateColumn)` | Replaces the value by a time range filter using the specified column name with times represented as a UNIX timestamp. Example: _dateColumn > 1494410783 AND dateColumn < 1494497183_ |
| `$__unixEpochFrom()` | Replaces the value with the start of the currently active time selection as a UNIX timestamp. Example: _1494410783_ |
| `$__unixEpochTo()` | Replaces the value with the end of the currently active time selection as UNIX timestamp. Example: _1494497183_ |
| `$__unixEpochNanoFilter(dateColumn)` | Replaces the value with a time range filter using the specified column name with time represented as a nanosecond timestamp. Example: _dateColumn > 1494410783152415214 AND dateColumn < 1494497183142514872_ |
| `$__unixEpochNanoFrom()` | Replaces the value with the start of the currently active time selection as nanosecond timestamp. Example: _1494410783152415214_ |
| `$__unixEpochNanoTo()` | Replaces the value with the end of the currently active time selection as nanosecond timestamp. Example: _1494497183142514872_ |
| `$__unixEpochGroup(dateColumn,'5m', [fillmode])` | Same as $\_\_timeGroup but for times stored as Unix timestamp. **Note that `fillMode` only works with time series queries.** |
| `$__unixEpochGroupAlias(dateColumn,'5m', [fillmode])` | Same as $\_\_timeGroup but also adds a column alias. **Note that `fillMode` only works with time series queries.** |
| Macro example | Description |
| ----------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `$__time(dateColumn)` | Replaces the value with an expression to convert to a UNIX timestamp and renames the column to `time_sec`. It also helps to recognize the `time` column, as required in Time Series format. Example: _UNIX_TIMESTAMP(dateColumn) AS time_sec_. |
| `$__timeEpoch(dateColumn)` | Replaces the value with an expression to convert to a UNIX Epoch timestamp and renames the column to `time_sec`. Example: _UNIX_TIMESTAMP(dateColumn) AS time_sec_. |
| `$__timeFilter(dateColumn)` | Applies a time range filter using the specified column name and fetches only the data that falls within that range. Example: _dateColumn BETWEEN FROM_UNIXTIME(1494410783) AND FROM_UNIXTIME(1494410983)_ |
| `$__timeFrom()` | Replaces the value with the start of the currently active time selection. Example: _FROM_UNIXTIME(1494410783)_ |
| `$__timeTo()` | Replaces the value with the end of the currently active time selection. Example: _FROM_UNIXTIME(1494410983)_ |
| `$__timeGroup(dateColumn,'5m')` | Replaces the value with an expression suitable for use in a GROUP BY clause and creates the bucket timestamps at a fixed interval. Example: *cast(cast(UNIX_TIMESTAMP(dateColumn)/(300) as signed)*300 as signed),\* |
| `$__timeGroup(dateColumn,'5m', 0)` | Same as the `$__timeGroup(dateColumn,'5m')` macro, but includes a fill parameter to ensure missing points in the series are added by Grafana, using 0 as the default value. **This applies only to time series queries.** |
| `$__timeGroup(dateColumn,'5m', NULL)` | Same as the `$__timeGroup(dateColumn,'5m', 0)` but NULL is used as the value for missing points. **This applies only to time series queries.** |
| `$__timeGroup(dateColumn,'5m', previous)` | Same as the `$__timeGroup(dateColumn,'5m', previous)` macro, but uses the previous value in the series as the fill value. If no previous value exists,`NULL` will be used. **This applies only to time series queries.** |
| `$__timeGroupAlias(dateColumn,'5m')` | Replaces the value identical to $\_\_timeGroup but with an added column alias. |
| `$__unixEpochFilter(dateColumn)` | Replaces the value by a time range filter using the specified column name with times represented as a UNIX timestamp. Example: _dateColumn > 1494410783 AND dateColumn < 1494497183_ |
| `$__unixEpochFrom()` | Replaces the value with the start of the currently active time selection as a UNIX timestamp. Example: _1494410783_ |
| `$__unixEpochTo()` | Replaces the value with the end of the currently active time selection as UNIX timestamp. Example: _1494497183_ |
| `$__unixEpochNanoFilter(dateColumn)` | Replaces the value with a time range filter using the specified column name with time represented as a nanosecond timestamp. Example: _dateColumn > 1494410783152415214 AND dateColumn < 1494497183142514872_ |
| `$__unixEpochNanoFrom()` | Replaces the value with the start of the currently active time selection as nanosecond timestamp. Example: _1494410783152415214_ |
| `$__unixEpochNanoTo()` | Replaces the value with the end of the currently active time selection as nanosecond timestamp. Example: _1494497183142514872_ |
| `$__unixEpochGroup(dateColumn,'5m', [fillmode])` | Same as $\_\_timeGroup but for times stored as Unix timestamp. **Note that `fillMode` only works with time series queries.** |
| `$__unixEpochGroupAlias(dateColumn,'5m', [fillmode])` | Same as $\_\_timeGroup but also adds a column alias. **Note that `fillMode` only works with time series queries.** |
## Table SQL queries
@ -180,106 +183,127 @@ The examples in this section refer to the data in the following table:
+---------------------+--------------+---------------------+----------+
| time_date_time | value_double | CreatedAt | hostname |
+---------------------+--------------+---------------------+----------+
| 2020-01-02 03:05:00 | 3.0 | 2020-01-02 03:05:00 | 10.0.1.1 |
| 2020-01-02 03:06:00 | 4.0 | 2020-01-02 03:06:00 | 10.0.1.2 |
| 2020-01-02 03:10:00 | 6.0 | 2020-01-02 03:10:00 | 10.0.1.1 |
| 2020-01-02 03:11:00 | 7.0 | 2020-01-02 03:11:00 | 10.0.1.2 |
| 2020-01-02 03:20:00 | 5.0 | 2020-01-02 03:20:00 | 10.0.1.2 |
| 2025-01-02 03:05:00 | 3.0 | 2025-01-02 03:05:00 | 10.0.1.1 |
| 2025-01-02 03:06:00 | 4.0 | 2025-01-02 03:06:00 | 10.0.1.2 |
| 2025-01-02 03:10:00 | 6.0 | 2025-01-02 03:10:00 | 10.0.1.1 |
| 2025-01-02 03:11:00 | 7.0 | 2025-01-02 03:11:00 | 10.0.1.2 |
| 2025-01-02 03:20:00 | 5.0 | 2025-01-02 03:20:00 | 10.0.1.2 |
+---------------------+--------------+---------------------+----------+
```
A time series query result is returned in a [wide data frame format](https://grafana.com/developers/plugin-tools/key-concepts/data-frames#wide-format). Any column except time or of type string transforms into value fields in the data frame query result. Any string column transforms into field labels in the data frame query result.
{{< admonition type="note" >}}
For backward compatibility, an exception to the aforementioned rule applies to queries returning three columns, including a string column named `metric`. Instead of converting the metric column into field labels, it is used as the field name, and the series name is set to the value of the metric column. Refer to the following example with a metric column.
{{< /admonition >}}
**Example with `metric` column:**
**Example with `$__time(dateColumn)` Macro:**
```sql
SELECT
$__time(time_date_time),
value_double
FROM my_data
ORDER BY time_date_time
```
Table panel result:
{{< figure alt="output of time macro" src="/media/docs/grafana/data-sources/mysql/screenshot-time-and-timefilter-macro.png" >}}
In the following example, the result includes two columns, `Time` and `value_double`, which represent the data associated with fixed timestamps. This query does not apply a time range filter and returns all rows from the table.
**Example with `$__timeFilter(dateColumn)` Macro:**
```sql
SELECT
$__time(time_date_time),
value_double
FROM my_data
WHERE $__timeFilter(time_date_time)
ORDER BY time_date_time
```
Table panel result:
{{< figure alt="output of time filter macro" src="/media/docs/grafana/data-sources/mysql/screenshot-time-and-timefilter-macro.png" >}}
This example returns the same result as the previous one, but adds support for filtering data using the Grafana time picker.
**Example with `$__timeGroup(dateColumn,'5m')` Macro:**
```sql
SELECT
$__timeGroup(time_date_time, '5m') AS time,
sum(value_double) AS sum_value
FROM my_data
WHERE $__timeFilter(time_date_time)
GROUP BY time
ORDER BY time
```
Table panel result:
{{< figure alt="output of time group macro" src="/media/docs/grafana/data-sources/mysql/screenshot-timegroup-macro.png" >}}
Given the result in the following example, the data is grouped and aggregated within buckets with timestamps of fixed interval i.e. 5 mins. To customize the default series name formatting (optional), refer to [Standard options definitions](ref:configure-standard-options).
**Example with `$__timeGroupAlias(dateColumn,'5m')` Macro:**
```sql
SELECT
$__timeGroupAlias(time_date_time,'5m'),
min(value_double),
'min' as metric
FROM test_data
FROM my_data
WHERE $__timeFilter(time_date_time)
GROUP BY time
ORDER BY time
```
Data frame result:
Table panel result:
```text
+---------------------+-----------------+
| Name: time | Name: min |
| Labels: | Labels: |
| Type: []time.Time | Type: []float64 |
+---------------------+-----------------+
| 2020-01-02 03:05:00 | 3 |
| 2020-01-02 03:10:00 | 6 |
| 2020-01-02 03:20:00 | 5 |
+---------------------+-----------------+
```
{{< figure alt="output of time group alias macro" src="/media/docs/grafana/data-sources/mysql/screenshot-timeGroupAlias-macro.png" >}}
To customize the default series name formatting (optional), refer to [Standard options definitions](ref:configure-standard-options-display-name).
The following result is similar to the result of the `$__timeGroup(dateColumn,'5m')` macro, except it uses a built-in alias for the time column.
To customize the default series name formatting (optional), refer to [Standard options definitions](ref:configure-standard-options).
**Example using the fill parameter in the $\_\_timeGroupAlias macro to convert null values to be zero instead:**
**Example with `$__timeGroupAlias` Macro to convert null values to zero instead:**
```sql
SELECT
$__timeGroupAlias(createdAt,'5m',0),
sum(value_double) as value,
hostname
FROM test_data
FROM my_data
WHERE
$__timeFilter(createdAt)
GROUP BY time, hostname
ORDER BY time
```
Given the data frame result in the following example and using the graph panel, you will get two series named _value 10.0.1.1_ and _value 10.0.1.2_. To render the series with a name of _10.0.1.1_ and _10.0.1.2_ , use a [Standard options definitions](ref:configure-standard-options-display-name) display value of `${__field.labels.hostname}`.
Table panel result:
Data frame result:
{{< figure alt="output of null values to zero case, for time group alias macro" src="/media/docs/grafana/data-sources/mysql/screenshot-timeGroupAlias-macro-conv-null-to-zero.png" >}}
```text
+---------------------+---------------------------+---------------------------+
| Name: time | Name: value | Name: value |
| Labels: | Labels: hostname=10.0.1.1 | Labels: hostname=10.0.1.2 |
| Type: []time.Time | Type: []float64 | Type: []float64 |
+---------------------+---------------------------+---------------------------+
| 2020-01-02 03:05:00 | 3 | 4 |
| 2020-01-02 03:10:00 | 6 | 7 |
| 2020-01-02 03:15:00 | 0 | 0 |
| 2020-01-02 03:20:00 | 0 | 5 |
+---------------------+---------------------------+---------------------------+
```
Given the result in the following example, null values within bucket timestamps are replaced by zero and also add the `Time` column alias by default. To customize the default series name formatting (optional), refer to [Standard options definitions](ref:configure-standard-options) to display the value of `${__field.labels.hostname}`.
**Example with multiple columns:**
**Example with multiple columns for `$__timeGroupAlias(dateColumn,'5m')` Macro:**
```sql
SELECT
$__timeGroupAlias(time_date_time,'5m'),
min(value_double) as min_value,
max(value_double) as max_value
FROM test_data
FROM my_data
WHERE $__timeFilter(time_date_time)
GROUP BY time
ORDER BY time
```
Data frame result:
Table panel result:
```text
+---------------------+-----------------+-----------------+
| Name: time | Name: min_value | Name: max_value |
| Labels: | Labels: | Labels: |
| Type: []time.Time | Type: []float64 | Type: []float64 |
+---------------------+-----------------+-----------------+
| 2020-01-02 03:05:00 | 3 | 4 |
| 2020-01-02 03:10:00 | 6 | 7 |
| 2020-01-02 03:20:00 | 5 | 5 |
+---------------------+-----------------+-----------------+
```
{{< figure alt="output with multiple colummns for time group alias macro" src="/media/docs/grafana/data-sources/mysql/screenshot-timeGroupAlias-macro-multiple-columns.png" >}}
The query returns multiple columns representing minimum and maximum values within the defined range.
## Templating
@ -392,6 +416,21 @@ WHERE
$__unixEpochFilter(epoch_time)
```
You may use one or more tags to show them as annotations in a common-separate string.
**Example query using a `time` column with epoch values for a single tag:**
```sql
SELECT
epoch_time as time,
metric1 as text,
tag1 as tag
FROM
my_data
WHERE
$__unixEpochFilter(epoch_time)
```
**Example region query using `time` and `timeend` columns with epoch values:**
```sql

View File

@ -1,11 +1,7 @@
# List of projects to provide to the make-docs script.
PROJECTS := grafana
# Use the doc-validator image defined in CI by default.
export DOC_VALIDATOR_IMAGE := $(shell sed -En 's, *image: "(grafana/doc-validator[^"]+)",\1,p' "$(shell git rev-parse --show-toplevel)/.github/workflows/doc-validator.yml")
# Skip some doc-validator checks.
export DOC_VALIDATOR_SKIP_CHECKS := $(shell sed -En "s, *'--skip-checks=(.+)',\1,p" "$(shell git rev-parse --show-toplevel)/.github/workflows/doc-validator.yml")
# Only run on sections that have been enabled in CI.
export DOC_VALIDATOR_INCLUDE := $(shell sed -En "s, *'--include=\\^docs/sources/(.+)',/hugo/content/docs/grafana/latest/\1,p" "$(shell git rev-parse --show-toplevel)/.github/workflows/doc-validator.yml")
# Format is PROJECT[:[VERSION][:[REPOSITORY][:[DIRECTORY]]]]
# The following PROJECTS value mounts content into the "grafana" project, at the "latest" version, which is the default if not explicitly set.
# This results in the content being served at /docs/grafana/latest/.
# The source of the content is the current repository which is determined by the name of the parent directory of the git root.
# This overrides the default behavior of assuming the repository directory is the same as the project name.
PROJECTS := grafana::$(notdir $(basename $(shell git rev-parse --show-toplevel)))