Upgrade to Pro — share decks privately, control downloads, hide ads and more …

MySQL, PostgreSQLのオブザーバビリティをGrafanaで向上させた話

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
Avatar for GO Inc. dev GO Inc. dev
January 28, 2026
280

MySQL, PostgreSQLのオブザーバビリティをGrafanaで向上させた話

GO TechTalk #32 タクシーアプリ『GO』の最強SREチーム で発表した資料です。

■ YouTube
https://www.youtube.com/watch?v=JKqmWhSqusg
■ connpass
https://jtx.connpass.com/event/379672/

Avatar for GO Inc. dev

GO Inc. dev

January 28, 2026
Tweet

More Decks by GO Inc. dev

Transcript

  1. © GO Inc. プロフィール写真 2 自己紹介 GO株式会社 開発本部 SREグループ /

    古越 勇樹 略歴 • 前職にてAWS, GCP等の構築運用 • 2021年 GO株式会社へ入社しSREグループへ配属 ◦ CI/CDのGitHub Actions移行やDBの運用周りを担当 趣味: ゲーム、インラインスケート
  2. © GO Inc. • 事業的背景 ◦ 『GO』の重要性が年々高まる ▪ 利用者の増加などで公共性の高いサービスへと成長してきた ▪

    DB起因の障害影響やメンテによるダウンタイムの影響が大きくなっている • 規模感:2025/12時点 • Cluster : 110+ (Production) • 歴史的経緯でAWS, GoogleCloud x MySQL, PostgreSQLを併用 • 月額:四桁万 4 『GO』におけるデータベース基盤の規模感
  3. © GO Inc. • DBのオブザーバビリティの向上策として、 「LGTMスタック」を導入していた ◦ Loki:ログのストレージと検索 ◦ Grafana

    : GUI ◦ Tempo:トレース情報のストレージと検索 ◦ Mimir:メトリクスのストレージと検索 • Prometheus形式のメトリクスを収集すれば Grafana Mimirに格納し、可視化ができる下 地がある • LGTMの導入時の技術選定は以下ブログ参考 ◦ LGTM!オブザーバビリティ基盤第1話 - GO Tech Blog 5 「LGTMスタック」を導入し運用している
  4. © GO Inc. • CloudWatch等 標準メトリクスでDB全体の負荷はわかるが不十分 ◦ 単発クエリ問題は特定容易だが、複数クエリの積み重ねによる問題は特定が困難 ◦ 例えば「意図しないロック待ち発生」、「細かなロック待ちによる性能劣化」など

    ◦ テーブル単位の統計情報を見る方法が乏しい ◦ QPSの高いDBではクエリログの吐き出しもパフォーマンス影響がある →DBのオブザーバビリティの向上が必要という事で取り組む 9 課題
  5. © GO Inc. 11 Prometheus Exporterとは Prometheus Exporter • ターゲットシステムのメトリクスを収集し

    Prometheus形式に変換するツールの総称 • OS情報を読み込む Node exporter が有名 • Prometheus Serverがスクレイピング起点, Exporterはパッシブな動き ◦ httpサーバーを起動して待ち受け、リクエス トに応じてターゲットのメトリクスを取得 pager duty
  6. © GO Inc. PostgreSQL Server Exporter • https://github.com/prometheus-community/postgres_exporter MySQL Server

    Exporter • https://github.com/prometheus/mysqld_exporter 収集できる情報 12 DB観測に使える Prometheus Exporter PostgreSQL Server Exporter MySQL Server Exporter pg_* システムビューが元のメトリクス • pg_stat_user_tables • pg_stat_activity • pg_locks • etc... システム情報が元のメトリクス • MySQLサーバーステータス変数 • information_schema の一部テーブル • performance_schema の一部テーブル • etc...
  7. © GO Inc. PostgreSQL, MySQLで基本的な使い方は似てる • 構成方法は2パターン ◦ DBサーバーに横付け サイドカー構成でプロセス(またはコンテナ)起動

    ◦ 外部のDBサーバーを観測するコンテナ起動 (マネージドDBを利用している場合はこの方法) • collector を指定して起動 ◦ postgres: collector.database, collector.locks, collector.stat_database etc… ◦ mysql: collect.global_status ,collect.perf_schema.tablelocks, collect.info_schema.tables etc ◦ 注意: collector有効化はDBに負荷を与えるリスクあり ▪ Exporterからシステム情報を拾うためにSQLを叩くケース ◦ 起動オプション等でcollectorを個別にon/off指定出来る PostgreSQL, MySQLで違う箇所 • Exporterの起動port • 観測用DBユーザ名やパスワードの入力方式 • 個々のDB依存のパラメータ,collector名など 13 DB観測に使える Prometheus Exporter
  8. © GO Inc. ポイント • 観測用に権限を絞ったDBユーザを作る • インスタンス毎にExporterを作る (DBInstance: Exporter

    = 1:1) ◦ Exporterは1プロセスでDBのホスト1台を参照する前提で作られている ◦ 例えばCluster EndpointやReader Endpointを指定すると、ラウンドロビンやフェイルオーバに より複数のインスタンスをまたいで、意味のないものになってしまう • Exporterの collector を最低限に設定する ◦ DBに負荷を与えるリスクあり ◦ collector毎にon/off指定出来るので必要最低限に設定 • helm chartのtemplateを準備しインスタンス増減時の対応工数削減 ◦ 数行の設定追加で増やせるようにする • デプロイ後 Exporter本体のメモリ周りに注意 ◦ 対象テーブル数が多いとOOMでExporterが落ちるケースあり 15 DB系 Exporterデプロイのポイント
  9. © GO Inc. • 元々DBの中にある統計データをExporterを使って収集できる • 実装にはDBエンジンと各Exporterの理解が必要 ◦ Exporter側のドキュメンテーションは割とざっくり ▪

    PromQLで使えるメトリクス名を確認する方法が乏しい ▪ 手元で動かす or コードリーディングが必要 ◦ collectorやメトリクスの意味を理解するためにDBエンジン側の理解も必要 ▪ pg_stat系 に何の情報があり何がわかるか ▪ MySQL サーバーステータス変数, info_schema に何の情報があり何がわかるか など • 取得したメトリクスから「DBの気持ち」を少し深堀りできる ◦ テーブル単位のメトリクスを追える ◦ 障害発生時の初動で大まかな問題点を洗う場面で活かせる ▪ 統計情報から採取したデータなので具体性は乏しい ▪ 怪しいポイントに気づいて深堀りを始める情報元として活きる 16 所感
  10. © GO Inc. sum by(mode) ( pg_locks_count{ job="postgres-exporter", db_cluster=~"$db_cluster", db_instance=~"$db_instance",

    datname=~"$database" } ) > 0 20 グラフ例 PostgreSQL テーブルロックの発生数 AccessExclusiveLockなど強いテーブル ロックが持続している事を観測できる 持続している場合にアラートも出せる
  11. © GO Inc. sum by(schemaname, relname) ( idelta(pg_stat_user_tables_n_tup_ins{ job="postgres-exporter", db_app=~"$db_app",

    db_cluster=~"$db_cluster", db_instance=~"$db_instance", datname=~"$database", schemaname=~"$schema", relname=~"$table" }[$__range]) ) > 0 同様に以下メトリクスもクエリ。1パネルに集約 pg_stat_user_tables_n_tup_del pg_stat_user_tables_n_tup_upd pg_stat_user_tables_n_tup_hot_upd 21 グラフ例 PostgreSQL テーブル毎の更新行数 どのテーブルにReadWriteが集中しているか観 測できる。パフォーマンスのボトルネックとな るテーブルを探れる
  12. © GO Inc. 22 グラフ例 PostgreSQL Scan行数の推移(テーブル単位) sum by (schemaname,relname)

    ( idelta(pg_stat_user_tables_seq_tup_read{ job="postgres-exporter", db_app=~"$db_app", db_cluster=~"$db_cluster", db_instance=~"$db_instance", datname!~"postgres|rdsadmin", datname=~"$database", schemaname=~"$schema", relname=~"$table" }[$__range]) ) > 0 同様に pg_stat_user_tables_idx_tup_fetch もクエリし1パネルに集約 Indexを使わないsequential scanが 多発している事を観測できる Indexチューニングに活かせる
  13. © GO Inc. immediate ... テーブルロック要求が即座に許可された回数 waited ... テーブルロック要求が即座に許可されず待機が必要 だった回数

    テーブルロックの解放待ちを検知出来る 23 グラフ例 MySQL テーブルロック発生数 avg by (db_instance) ( idelta( mysql_global_status_table_locks_immediate{ job="mysql-exporter", db_app=~"$db_app", db_cluster=~"$db_cluster", db_instance=~"$db_instance" }[$__range] ) ) 同様に mysql_global_status_table_locks_waited もクエリし1パネルに集約
  14. © GO Inc. perfomance_schema.table_io_waits_summary_by_table が情報ソースのメトリクスから抽出 どのテーブルでI/O Waitが発生しているか視覚的に把握出来 る。パフォーマンスのボトルネックを洗うときに活きる。 24 グラフ例

    MySQL テーブル毎のI/O Waitイベント avg by (operation, name) ( idelta( mysql_perf_schema_table_io_waits_seconds_total{ job="mysql-exporter", db_app=~"$db_app", db_cluster=~"$db_cluster", db_instance=~"$db_instance", schema=~"$database", name=~"$table" }[$__range] ) ) > 0
  15. © GO Inc. サーバーステータス変数のslow query発生数が 情報ソースのメトリクス Aurora MySQLでは標準で取得出来ずログ監視 を仕込む必要あり。痒い所に手が届く 25

    グラフ例 MySQL Slow Query発生数 avg by (db_instance) ( idelta( mysql_global_status_slow_queries{ job="mysql-exporter", db_app=~"$db_app", db_cluster=~"$db_cluster", db_instance=~"$db_instance" }[$__range] ) )
  16. © GO Inc. • ピークのDB性能劣化時に怪しいポイントを絞り込めた ◦ トラフィックのピークタイムにてDBの性能劣化発生 -> DB接続エラー多発 という症状

    ◦ 行ロック待ちが多数発生している事を観測 ◦ 特定テーブルの I/O Waitが増えている挙動を確認できた • 想定外のロックが発生した際、アラートを出すようにし、オペミスを予防できた ◦ PostgreSQLのパーティション再配置作業で想定外のロックが発生した事があった ◦ そこで、pg_locks関係のメトリクスを監視し、競合が多い強いロックが滞留した時にアラートを 出すことにした ◦ 作業中にSlack通知がくるため問題に気づけるように 27 オブザーバビリティ向上の恩恵
  17. © GO Inc. • 『GO』の規模拡大 • LGTMスタックを導入していたが、DBオブザーバビリティの観点では不十分 • DBのメトリクスはPrometheus Exporterを使って追加で収集

    • Grafanaを使ってテーブル単位の統計情報やロックの情報などを可視化 • 結果 DB性能劣化時の問題箇所特定の迅速化や、オペレーションミス予防できた とはいえDBオブザーバビリティとしては改善余地あり SREチームはDBREに興味あるメンバーを募集しています 29 まとめ