I tried enabling the MySQL Endpoint of TiDB Cloud Lake and visualizing logs from Grafana

I tried enabling the MySQL Endpoint of TiDB Cloud Lake and visualizing logs from Grafana

I enabled the MySQL Endpoint for TiDB Cloud Lake and tried visualizing logs stored in Lake from Grafana. I will walk you through the entire implementation, from configuration and connection to query optimization and important notes on pricing.
2026.09.18

This page has been translated by machine translation. View original

Hello, I'm sora from the Game Solutions Division.
This time, I'll write about enabling the MySQL Endpoint in TiDB Cloud Lake and visualizing logs stored in Lake from Grafana.

Enabling the MySQL Endpoint

To connect from tools that can only connect via the MySQL protocol, such as Grafana's MySQL data source, you need to enable the MySQL Endpoint.

https://docs.pingcap.com/tidbcloudlake/warehouse/

The MySQL Endpoint is disabled by default, and enabling it requires submitting a support ticket.
Once the request is approved, it becomes available at the account level, and you can then toggle it on/off per Warehouse.

Open the Warehouse settings from Admin > Warehouses and turn on Enable MySQL Endpoint under Advanced Options.

01-sr-mysql-endpoint-on

The moment I turned it on, the Auto Suspend dropdown was fixed to Never and grayed out.
This is how the following behavior described in the official documentation appears on screen.

When MySQL Endpoint is enabled, Auto Suspend is automatically disabled (set to 0) for the warehouse. This means the warehouse will remain running continuously and incur costs even when idle.

In other words, once the MySQL Endpoint is turned on, that Warehouse will keep running until you stop or delete it yourself.

Below the toggle, the hostname dedicated to this Warehouse is displayed.
It takes the form <tenant>-<warehouse name>-<id>.ep.aws-ap-northeast-1.default.lake.tidbcloud.com, with a different hostname for each Warehouse.

Checking the Connection Information

Let's open Connect from the Warehouse list.

02-sr-connect-dialog

Host shows <tenant>.gw.aws-ap-northeast-1.default.lake.tidbcloud.com and Port shows 443, but this is the connection information for lake:// used by LakeSQL and various language drivers.
This is different from the MySQL Endpoint hostname (<tenant>-<warehouse name>-<id>.ep....) shown in the settings screen, and even when selecting sora-test-lake with the MySQL Endpoint turned on, the display on this screen did not change.

When connecting via MySQL, use the MySQL Endpoint hostname from the settings screen, and it connected on the standard MySQL port 3306.
The username and password from the Connect dialog could be used as-is.

Comparing the two connection methods:

Item lake:// (LakeSQL, language drivers) MySQL Endpoint
Host <tenant>.gw.<region>... (shared across tenant) <tenant>-<warehouse>-<id>.ep.<region>... (per Warehouse)
Port 443 3306
Warehouse specification ?warehouse= query parameter Included in the hostname

Let's try connecting with the mysql client.
The logs used are the appdb.app_logs that were loaded into Lake in the following article.

https://dev.classmethod.jp/articles/tidb-cloud-lake-migrate-from-tidb/

There are 500,000 rows of logs with level / service / message, a JSON attributes field (stored as VARIANT on the Lake side), and logged_at.

$ mysql -h $H -P 3306 -u cloudapp --ssl-mode=REQUIRED -e "SELECT VERSION();"
version()
8.0.90-v1.2.942-nightly-43828ad679(rust-1.94.0-nightly-2026-09-13T22:15:15.214402223Z)

$ mysql -h $H -P 3306 -u cloudapp --ssl-mode=REQUIRED -D appdb -e "SELECT COUNT(*) FROM app_logs;"
COUNT(*)
500000

VERSION() starts in the MySQL 8.0 format, followed by Rust build information.
TiDB Cloud Lake is based on Databend, which also shows up here.

Note that MySQL-specific statements like SHOW STATUS do not work.

ERROR 1105 (HY000) at line 1: SyntaxException. Code: 1005, Text = error:
  --> SQL:1:6
  |
1 | SHOW STATUS LIKE 'Ssl_cipher'
  |      ^^^^^^ unexpected `STATUS`. Did you mean `SHOW STAGES`, `SHOW DATABASES`, or `SHOW FUNCTIONS`?

The error is returned by Lake's parser, not MySQL.
The structure is such that only the protocol is MySQL, while the SQL remains Lake's own.

TLS Is Not Enforced

It was also possible to connect with --ssl-mode=DISABLED.

$ mysql -h $H -P 3306 -u cloudapp --ssl-mode=DISABLED -e "SELECT 1;"
1
1

Since TLS is not enforced on the server side, if the client specifies nothing, the connection will be made in plaintext.

Adding a MySQL Data Source to Grafana

Grafana is self-hosted on ECS Fargate, running OSS version 13.2.2.
Search for MySQL under Connections > Add new connection in the left menu and add it.
Since it's a core built-in data source, no plugin installation is required.

The settings screen looks like this:

03-sr-grafana-datasource-settings

Enter <MySQL Endpoint hostname>:3306 for Host URL, appdb for Database name, and the values from the Connect dialog for Username and Password.

For TLS, I enabled With CA Cert and pasted the ISRG Root X1, the Let's Encrypt root certificate, into TLS/SSL Root Certificate.
Grafana's MySQL data source connects in plaintext if no TLS-related toggles are configured.

https://grafana.com/docs/grafana/latest/datasources/mysql/configure/

As we saw earlier, the Lake side also accepts plaintext, so Save & test will pass even without any configuration.

After clicking Save & test, it returned Database Connection OK.

Viewing Logs in Explore

In Explore, select mysql as the data source and display raw logs in Table format.

Grafana's MySQL data source has macros for handling time ranges, and normally you would write $__timeFilter(logged_at).
However, this macro expands to MySQL's FROM_UNIXTIME, which doesn't exist in Lake, resulting in UnknownFunction.
The same applies to $__timeGroup for time series, which expands to UNIX_TIMESTAMP.

https://grafana.com/docs/grafana/latest/datasources/mysql/query-editor/

Instead, I used $__unixEpochFilter and $__unixEpochGroup, which are intended for columns that store time as a numeric value (UNIX time) in seconds.
These expand to numeric comparisons without any function wrapping, so they work by passing a column where logged_at has been converted to a numeric value in seconds using Lake's TO_UNIX_TIMESTAMP.

SELECT logged_at AS time, message, level, service
FROM (SELECT *, TO_UNIX_TIMESTAMP(logged_at) AS ts FROM appdb.app_logs) t
WHERE $__unixEpochFilter(ts)
ORDER BY logged_at DESC
LIMIT 500

04-sr-explore-logs-table

message, level, and service are listed as rows, with no need for conversion to a log-specific format.

Making It a Time Series

The trend of counts by level can be written in the same form.
Set Format to Time series and use $__unixEpochGroup to round to hourly intervals.

SELECT
  $__unixEpochGroup(ts, '1h') AS time,
  level AS metric,
  COUNT(*) AS value
FROM (SELECT *, TO_UNIX_TIMESTAMP(logged_at) AS ts FROM appdb.app_logs) t
WHERE $__unixEpochFilter(ts)
GROUP BY 1, 2
ORDER BY 1

05-sr-explore-timeseries

Four series for DEBUG / ERROR / INFO / WARN appeared.
The time column remains a numeric value in seconds, but Grafana interprets a numeric time as UNIX time.
The MySQL data source rule that naming the third string column metric makes it the series name also works as expected.

Creating a Dashboard

I took the queries that worked in Explore, turned them into panels, and created a dashboard in Grafana.

06-sr-grafana-dashboard

The top-left shows the count trend by level, the top-right by HTTP status, and the bottom-left is the error rate by service displayed as a Bar gauge.
Aggregations without a time axis, such as error rate, will fail with db has no time column unless Format is set to Table.

TiDB Cloud Lake also has a Dashboard feature, so I ran the same aggregation in a Worksheet and turned it into a line chart.

SELECT DATE_TRUNC(HOUR, logged_at) AS hour, level, COUNT(*) AS cnt
FROM appdb.app_logs
WHERE logged_at BETWEEN '2026-08-19' AND '2026-08-31'
GROUP BY 1, 2
ORDER BY 1;

07-sr-lake-worksheet-chart

By specifying hour for X-Axis, cnt for Lines, and level for Series in the Chart settings, I got the same style of graph as in Grafana.

Note: Change the Time Zone with SET GLOBAL

Looking closely at the Explore results, a row that was 2026-08-29 00:00:51 in Lake was displayed as 2026-08-29 09:00:51.
This is because logged_at is a TIMESTAMP without a time zone, and Lake's default time zone is UTC.

There is no time zone setting in Lake's console, so you change it with the SQL SET GLOBAL.

https://docs.pingcap.com/tidbcloudlake/set/

Check the current value in a Worksheet.

SHOW SETTINGS LIKE 'timezone';

08-sr-show-settings-timezone-default

value is UTC and level is DEFAULT.
range contains a list of time zone names.

SET GLOBAL timezone = 'Asia/Tokyo';

09-sr-set-global-timezone

value changed to Asia/Tokyo and level changed to GLOBAL.

Note: Queries via MySQL Endpoint Do Not Appear in SQL History

Queries executed from Worksheets appear in Lake's Monitoring > SQL History.
However, neither the SQL sent by Grafana nor the queries sent from the mysql client appeared there at all.
Queries executed from a Worksheet during the same time period did appear, so queries via MySQL Endpoint are not recorded.

Since what Grafana actually sent can only be tracked through Grafana's own logs, it was necessary to export Grafana's logs externally.

Pricing

An XSmall Warehouse costs $1.60/h.
Since enabling the MySQL Endpoint fixes Auto Suspend to Never, that comes to $38.4 per day and $1,152 for 30 days.

It would be $0 if the Warehouse is stopped, and if you use an XSmall for just one hour a day, it would be about $48 per month — but that assumption no longer holds once Grafana is connected.
This is because a Warehouse with the MySQL Endpoint enabled keeps running even when Grafana is not being viewed.

If the assumption is that a BI tool will be connected at all times, you need to plan for one Warehouse running continuously from the start.
For use cases where you only want to view dashboards occasionally, the Lake built-in Dashboard, which only runs the Warehouse when it's open, will be cheaper.

After finishing the verification, I deleted the Warehouse.

Closing Thoughts

This time, I enabled the MySQL Endpoint in TiDB Cloud Lake and visualized logs stored in Lake using Grafana's MySQL data source.
I hope this article is helpful to someone.


TiDB Cloudの導入・サポートはクラスメソッドにお任せください

クラスメソッドでは、TiDB Cloudの導入から運用支援まで、豊富なノウハウでお客様をサポートしています。パフォーマンスの最適化やスケーラビリティに課題を抱えている方は、ぜひご相談ください。
詳細な導入事例やサービス内容について知りたい方は、こちらからご確認いただけます。

TiDB Cloudのサポート詳細を見る

Share this article