TiDB Cloud LakeのMySQL Endpointを有効にして、Grafanaからログを可視化してみた
こんにちは、ゲームソリューション部のsoraです。
今回は、TiDB Cloud LakeのMySQL Endpointを有効にして、Lakeに入れたログをGrafanaから可視化してみたことについて書いていきます。
MySQL Endpointを有効にする
GrafanaのMySQLデータソースのように、MySQLプロトコルでしか接続できないツールから繋ぐには、MySQL Endpointを有効にします。
MySQL Endpointはデフォルトで無効で、有効化にはサポートチケットでの申請が必要です。
申請が通るとアカウント単位で使えるようになり、そのうえでWarehouseごとにオン/オフを切り替える形です。
Admin > WarehousesからWarehouseの設定を開き、Advanced OptionsのEnable MySQL Endpointをオンにします。

オンにした瞬間に、Auto SuspendのドロップダウンがNeverに固定されてグレーアウトしました。
公式ドキュメントに書かれている以下の挙動が、画面ではこう見えます。
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.
つまりMySQL Endpointをオンにしたら、そのWarehouseは自分で止めるか削除するまで動き続けます。
トグルの下には、このWarehouse専用のホスト名が表示されます。
<tenant>-<warehouse名>-<id>.ep.aws-ap-northeast-1.default.lake.tidbcloud.comという形で、Warehouseごとに別のホスト名になります。
接続情報を確認する
Warehouse一覧のConnectを開いてみます。

Hostに<tenant>.gw.aws-ap-northeast-1.default.lake.tidbcloud.com、Portに443が出ていますが、これはLakeSQLや各言語ドライバが使うlake://用の接続情報です。
先ほどの設定画面に出ていたMySQL Endpointのホスト名(<tenant>-<warehouse名>-<id>.ep....)とは別のもので、MySQL Endpointをオンにしたsora-test-lakeを選んだ状態でも、この画面の表示は変わりませんでした。
MySQLで接続するときは、ホスト名は設定画面に出ていたMySQL Endpointのものを使い、ポートはMySQL標準の3306番で繋がりました。
ユーザー名とパスワードはConnectダイアログのものがそのまま使えました。
2つの経路を並べると以下のとおりです。
| 項目 | lake://(LakeSQL、各言語ドライバ) |
MySQL Endpoint |
|---|---|---|
| ホスト | <tenant>.gw.<region>...(テナント共通) |
<tenant>-<warehouse>-<id>.ep.<region>...(Warehouseごと) |
| ポート | 443 | 3306 |
| Warehouseの指定 | ?warehouse=のクエリパラメータ |
ホスト名に含まれる |
mysqlクライアントで接続してみます。
ログは以下の記事でLakeに入れたappdb.app_logsをそのまま使います。
level / service / messageと、JSONのattributes(Lake側ではVARIANT)、logged_atを持つログが500,000行入っています。
$ 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()はMySQL 8.0系の形式で始まり、後ろにRustのビルド情報が付いています。
TiDB Cloud LakeはDatabendをベースにしているので、それがここにも出ています。
ちなみに、SHOW STATUSのようなMySQL固有の文は通りません。
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`?
エラーを返しているのはMySQLではなくLakeのパーサです。
プロトコルだけがMySQLで、SQLはLakeのまま、という構造になっています。
TLSは強制されていない
--ssl-mode=DISABLEDでも接続できました。
$ mysql -h $H -P 3306 -u cloudapp --ssl-mode=DISABLED -e "SELECT 1;"
1
1
サーバー側でTLSを強制していないので、クライアントが何も指定しなければ平文で接続されます。
GrafanaにMySQLデータソースを追加する
GrafanaはECS Fargateにセルフホストしたもので、バージョンはOSS版の13.2.2です。
左メニューのConnections > Add new connectionでMySQLを検索して追加します。
コア組み込みのデータソースなので、プラグインのインストールはありません。
設定画面は以下のとおりです。

Host URLに<MySQL Endpointのホスト名>:3306、Database nameにappdb、UsernameとPasswordにConnectダイアログの値を入れます。
TLSはWith CA Certをオンにして、TLS/SSL Root CertificateにLet's EncryptのルートであるISRG Root X1を貼りました。
GrafanaのMySQLデータソースは、TLS系のトグルを何も入れないと平文で接続します。
先ほど見たとおりLake側は平文も受け付けるので、何も設定しなくてもSave & testは通ります。
Save & testを押すとDatabase Connection OKになりました。
Exploreでログを見る
Exploreでデータソースにmysqlを選び、生ログをTable形式で出します。
GrafanaのMySQLデータソースには時間範囲を扱うマクロがあり、通常は$__timeFilter(logged_at)と書きます。
ただしこのマクロはMySQLのFROM_UNIXTIMEに展開され、Lakeにはその関数が無いのでUnknownFunctionになります。
時系列用の$__timeGroupも同じで、こちらはUNIX_TIMESTAMPに展開されます。
代わりに、時刻を秒単位の数値(UNIX時間)で持つ列向けの$__unixEpochFilterと$__unixEpochGroupを使いました。
これらは関数を挟まず数値の比較に展開されるので、LakeのTO_UNIX_TIMESTAMPでlogged_atを秒単位の数値に変換した列を渡せば通ります。
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

messageとlevelとserviceが行として並び、ログ専用のフォーマットへの変換は要りませんでした。
時系列にする
レベル別の件数推移も同じ形で書けます。
FormatをTime seriesにして、$__unixEpochGroupで1時間ごとに丸めます。
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

DEBUG / ERROR / INFO / WARNの4系列が出ました。
time列は秒単位の数値のままですが、Grafanaは数値のtimeをUNIX時間として解釈します。
3列目の文字列列をmetricという名前にすると系列名になる、というMySQLデータソースのルールもそのまま使えています。
ダッシュボードにする
Exploreで通ったクエリをパネルにして、Grafanaでダッシュボードを作りました。

左上がレベル別、右上がHTTPステータス別の件数推移で、左下はservice別のエラー率をBar gaugeにしたものです。
エラー率のような時間軸を持たない集計は、FormatをTableにしないとdb has no time columnで失敗します。
TiDB Cloud Lake側にもDashboard機能があるので、同じ集計をWorksheetで実行して折れ線にしてみました。
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;

Chartの設定でX-Axisにhour、Linesにcnt、Seriesにlevelを指定すると、Grafanaと同じ形のグラフになりました。
補足: タイムゾーンはSET GLOBALで変える
Exploreの結果をよく見ると、Lake上で2026-08-29 00:00:51だった行が2026-08-29 09:00:51と表示されていました。
logged_atはタイムゾーンを持たないTIMESTAMPで、LakeのデフォルトのタイムゾーンがUTCだからです。
Lakeのコンソールにはタイムゾーンの設定項目が無く、SQLのSET GLOBALで変更します。
Worksheetで現在の値を見てみます。
SHOW SETTINGS LIKE 'timezone';

valueがUTC、levelがDEFAULTです。
rangeにはタイムゾーン名の一覧が入っています。
SET GLOBAL timezone = 'Asia/Tokyo';

valueがAsia/Tokyo、levelがGLOBALに変わりました。
補足: MySQL Endpoint経由のクエリはSQL Historyに残らない
LakeのMonitoring > SQL Historyには、Worksheetから実行したクエリが残ります。
ところがGrafanaが投げたSQLも、mysqlクライアントから投げたクエリも、1件も出ていませんでした。
同じ時間帯にWorksheetから実行したクエリは出ているので、MySQL Endpoint経由は記録の対象外になっています。
Grafanaが実際に何を投げたかはGrafana側のログでしか追えないので、Grafanaのログを外に出しておく必要がありました。
料金
XSmallのWarehouseは$1.60/hです。
MySQL EndpointをオンにするとAuto SuspendがNeverに固定されるので、1日で$38.4、30日で$1,152になります。
Warehouseを止めていれば0で、XSmallを1日1時間だけ使うなら月$48程度ですが、Grafanaを繋いだ時点でこの前提が成り立たなくなります。
MySQL EndpointをオンにしたWarehouseは、Grafanaを見ていない時間も動き続けるためです。
BIツールを常時接続する前提なら、Warehouse1台分の常時稼働を最初から見込む必要があります。
見たいときだけ見る用途なら、開いたときだけWarehouseが動くLake組み込みのDashboardの方が安く済みます。
検証が終わったあとはWarehouseを削除しました。
最後に
今回は、TiDB Cloud LakeのMySQL Endpointを有効にして、Lakeに入れたログをGrafanaのMySQLデータソースから可視化してみました。
この記事がどなたかの参考になれば幸いです。







