© 2021 NTT DATA Corporation PostgreSQL 14 モニタリング新機能紹介 2021年6月8日 株式会社NTTデータ 鳥越 淳
© 2021 NTT DATA Corporation 2 自己紹介 • 鳥越 淳(とりこし あつし) 2008年頃からオープンソースソフトウェアを扱う業務に従事 PostgreSQLは9.6頃から 『PostgreSQL徹底入門 第4版』(翔泳社) 8~13章執筆
© 2021 NTT DATA Corporation 3 本講演について PostgreSQL 14導入予定のモニタリング新機能のうち、主にNTTデータが開発したものを2つご紹介します • メモリ利用状況に関する情報 • ロック取得待ち時間の確認 本講演で紹介する機能や仕様は、Beta 1リリース時点のものです。 将来的に変更される可能性があることにご注意ください。 その他、記載されている会社名、商品名、又はサービス名は、 各社の登録商標又は商標です。
© 2021 NTT DATA Corporation 4 バックエンドプロセスのメモリ利用状況に関する情報 ~MemoryContextの確認~
© 2021 NTT DATA Corporation 5 PostgreSQLのメモリ構造とMemoryContext MemoryContextは、PostgreSQLのバックエンドプロセスが動的にメモリを確保するために利用 ワークメモリ メンテナンス ワークメモリ バックエンド プロセス … ワークメモリ メンテナンス ワークメモリ バックエンド プロセス … 共有メモリバッファ WALバッファ 共有メモリ こっちの話 こっちじゃない … こっちの話
© 2021 NTT DATA Corporation 6 MemoryContextとは PostgreSQLでは、MemoryContextと呼ばれる単位を使って、Tree構造でメモリを管理 TopMemoryContext CacheMemoryContext TopPortalContext TopTransactionContext … … … 親は1つ 子は複数可 ※TopMemoryContextは親なし
© 2021 NTT DATA Corporation 7 MemoryContextとは TopMemoryContext CacheMemoryContext TopPortalContext TopTransactionContext … … … PostgreSQLでは、MemoryContextと呼ばれる単位を使って、Tree構造でメモリを管理 • 用途に応じてMemoryContextを作成、メモリを割り当てる(palloc) CachedPlanSource Prepared statement※作成時の例 … 作成 メモリ割り当て 作成 ※Prepared statementとは.. クエリ実行に必要な処理の一部 (パース・リライトなど)を予め実行し ておきキャッシュする仕組み
© 2021 NTT DATA Corporation 8 MemoryContextとは PostgreSQLでは、MemoryContextと呼ばれる単位を使って、Tree構造でメモリを管理 • 親のMemoryContextが削除されると、その子孫のMemoryContextも全て削除される TopMemoryContext CacheMemoryContext TopPortalContext TopTransactionContext … … … CachedPlanSource … Prepared statement削除時の例 削除 削除
© 2021 NTT DATA Corporation 9 MemoryContextの情報を取得する必要性 特定のMemoryContextが肥大化したり、大量のMemoryContextが作成されることで、メモリが逼迫するこ とがある 例) • 大量のPrepared statement • PostgreSQL内部のキャッシュ(relcacheなど)増加 • メモリリーク OSからはPostgreSQLプロセスのメモリが肥大化していることまでしかわからないが、MemoryContextを確認 すれば、PostgreSQL内部でのメモリの用途が把握可能
© 2021 NTT DATA Corporation 10 V13までのMemoryContextの確認 デバッグ用関数MemoryContextStats()で指定したContext以下の全Contextの状況を把握可能 • 使い方 デバッガから呼び出す (gdb) call MemoryContextStats(TopMemoryContext) , • 出力例 階層の深さはインデントで表現 総計も出力 出力先はstderr ⇒ “logging_collector”がonの 場合、ログファイルに出力
© 2021 NTT DATA Corporation 11 V13までのMemoryContextの確認のつらみ • 商用環境で利用しづらい • デバッグシンボルがインストールされていること(ソースからビルド configure --enable-debug) • デバッガがインストールされていること • 出力が集計しづらい、やや見にくい • 出力例(再掲) 起動直後idle状態でも80行くらい省略している
© 2021 NTT DATA Corporation 12 V14でできるようになること pg_backend_memory_contextsビューから、ローカルプロセスのMemoryContextが確認可能 • 内容はMemoryContextStatsDetail()と同等 Contextを特定する情報があれば、identに出力される 例) Prepared Statementを実行した場合 階層の深さはlevelで表現
© 2021 NTT DATA Corporation 13 V14でできるようになること pg_log_backend_memory_contexts()で任意のバックエンドプロセスのMemoryContextが確認 可能 • 出力先はログファイル • 内容はMemoryContextStatsDetail()と同等 • 1つの親MemoryContextが出力する子MemoryContext数は、100に制限。101以降の MemoryContextの情報はサマリのみ出力 • 出力例 • 出力例 =# SELECT pg_log_backend_memory_contexts(取得したいバックエンドのPID); _
© 2021 NTT DATA Corporation 14 V14のMemoryContext出力の注意点 • pg_backend_memory_contextsビューの参照、pg_log_backend_memory_contexts()の実 行は、いずれもスーパーユーザ権限が必要 • pg_backend_memory_contextsビューの参照権限は、GRANT文で一般ユーザへ付与可能 • pg_log_backend_memory_contexts()の実行権限は、一般ユーザには付与できない • 本関数を大量に実行してDoS攻撃されるのを予防するため
© 2021 NTT DATA Corporation 15 (参考)V13以前でSQLによるMemeoryContext確認 エクステンションpg_cheat_funcs[1]を利用すれば、同様のことがV9.6~でも可能 • pg_stat_get_memory_context() • というかほぼこの機能をPostgreSQL本体に移植 • “ident”相当の情報はない • pg_cheat_funcsでは、ほかにもPostgreSQLで取り扱い可能な全UTF-8文字を返す関数 (pg_all_utf8())、トランザクションIDを変更する関数など、いろいろな機能が提供されている [1] https://github.com/MasaoFujii/pg_cheat_funcs
© 2021 NTT DATA Corporation 16 ロック取得待ち時間の確認 ~pg_locksビューへのwaitstart列追加~
© 2021 NTT DATA Corporation 17 V13までのpg_locks • pg_locksビューは、PostgreSQLプロセスによって取得されているロックの情報を表示するビュー • PostgreSQL 13以前では、ロック待ちを開始した時刻や、ロック待ちしている時間を取得する方法は提供 されていなかった • pg_stat_activityとpidでJOINしてquery_startやstate_changeで時刻を取得できるが、これ らはクエリの開始時刻や状態が変化した時刻 列名 概要 locktype ロック対象オブジェクトの種類。relation, page, tupleなど relation, page, tuple ロックの対象となるリレーションのOID、ページ番号、タプル番号 pid ロックを保持、もしくは待っているサーバプロセスのプロセスID mode このプロセスで保持または要求するロックモードの名称 granted ロックが保持されている場合は真、ロックが待ち状態の場合は偽 pg_locksビューの列(一部)
© 2021 NTT DATA Corporation 18 V14のpg_locks • ロック待ちを開始した時刻を表示するwaitstart列を追加 • ロックを保持している場合はNULL • 現在時刻との差分を見れば、ロック待ち時間が取得可能 … =# SELECT relation, pid, mode, granted, waitstart FROM pg_locks; _ =# SELECT relation, pid, mode, granted, now() – waitstart AS duration FROM pg_locks; _
© 2021 NTT DATA Corporation 19 V14のpg_locksの注意点 • タイミングによってはロック取得待ち状態(grantedがfalse)なのに、waitstartがNULLになるケースがある 点に一応注意 • これは、オーバーヘッドを削減するために、ロックを取得せずにwaitstartを更新しているために発生 • この状況はごく短時間しか発生しない、かつwaitstartが必要になるのは長時間ロックが解放されな い場合なので、実質的な影響はないはず …
© 2021 NTT DATA Corporation 20 まとめ 今回ご紹介したv14の新機能 • MemoryContextの情報を確認する手段が提供された • バックエンドローカル: pg_backend_memory_contexts ビュー • バックエンドローカル以外: pg_log_backend_memory_contexts() • ロック待ちを開始した時刻をpg_locksビューのwaitstart列から確認できるようになった … こんなものもモニタリングしたいというご要望があれば教えてください!!
© 2021 NTT DATA Corporation

PostgreSQL 14 モニタリング新機能紹介(PostgreSQL カンファレンス #24、2021/06/08)

  • 1.
    © 2021 NTTDATA Corporation PostgreSQL 14 モニタリング新機能紹介 2021年6月8日 株式会社NTTデータ 鳥越 淳
  • 2.
    © 2021 NTTDATA Corporation 2 自己紹介 • 鳥越 淳(とりこし あつし) 2008年頃からオープンソースソフトウェアを扱う業務に従事 PostgreSQLは9.6頃から 『PostgreSQL徹底入門 第4版』(翔泳社) 8~13章執筆
  • 3.
    © 2021 NTTDATA Corporation 3 本講演について PostgreSQL 14導入予定のモニタリング新機能のうち、主にNTTデータが開発したものを2つご紹介します • メモリ利用状況に関する情報 • ロック取得待ち時間の確認 本講演で紹介する機能や仕様は、Beta 1リリース時点のものです。 将来的に変更される可能性があることにご注意ください。 その他、記載されている会社名、商品名、又はサービス名は、 各社の登録商標又は商標です。
  • 4.
    © 2021 NTTDATA Corporation 4 バックエンドプロセスのメモリ利用状況に関する情報 ~MemoryContextの確認~
  • 5.
    © 2021 NTTDATA Corporation 5 PostgreSQLのメモリ構造とMemoryContext MemoryContextは、PostgreSQLのバックエンドプロセスが動的にメモリを確保するために利用 ワークメモリ メンテナンス ワークメモリ バックエンド プロセス … ワークメモリ メンテナンス ワークメモリ バックエンド プロセス … 共有メモリバッファ WALバッファ 共有メモリ こっちの話 こっちじゃない … こっちの話
  • 6.
    © 2021 NTTDATA Corporation 6 MemoryContextとは PostgreSQLでは、MemoryContextと呼ばれる単位を使って、Tree構造でメモリを管理 TopMemoryContext CacheMemoryContext TopPortalContext TopTransactionContext … … … 親は1つ 子は複数可 ※TopMemoryContextは親なし
  • 7.
    © 2021 NTTDATA Corporation 7 MemoryContextとは TopMemoryContext CacheMemoryContext TopPortalContext TopTransactionContext … … … PostgreSQLでは、MemoryContextと呼ばれる単位を使って、Tree構造でメモリを管理 • 用途に応じてMemoryContextを作成、メモリを割り当てる(palloc) CachedPlanSource Prepared statement※作成時の例 … 作成 メモリ割り当て 作成 ※Prepared statementとは.. クエリ実行に必要な処理の一部 (パース・リライトなど)を予め実行し ておきキャッシュする仕組み
  • 8.
    © 2021 NTTDATA Corporation 8 MemoryContextとは PostgreSQLでは、MemoryContextと呼ばれる単位を使って、Tree構造でメモリを管理 • 親のMemoryContextが削除されると、その子孫のMemoryContextも全て削除される TopMemoryContext CacheMemoryContext TopPortalContext TopTransactionContext … … … CachedPlanSource … Prepared statement削除時の例 削除 削除
  • 9.
    © 2021 NTTDATA Corporation 9 MemoryContextの情報を取得する必要性 特定のMemoryContextが肥大化したり、大量のMemoryContextが作成されることで、メモリが逼迫するこ とがある 例) • 大量のPrepared statement • PostgreSQL内部のキャッシュ(relcacheなど)増加 • メモリリーク OSからはPostgreSQLプロセスのメモリが肥大化していることまでしかわからないが、MemoryContextを確認 すれば、PostgreSQL内部でのメモリの用途が把握可能
  • 10.
    © 2021 NTTDATA Corporation 10 V13までのMemoryContextの確認 デバッグ用関数MemoryContextStats()で指定したContext以下の全Contextの状況を把握可能 • 使い方 デバッガから呼び出す (gdb) call MemoryContextStats(TopMemoryContext) , • 出力例 階層の深さはインデントで表現 総計も出力 出力先はstderr ⇒ “logging_collector”がonの 場合、ログファイルに出力
  • 11.
    © 2021 NTTDATA Corporation 11 V13までのMemoryContextの確認のつらみ • 商用環境で利用しづらい • デバッグシンボルがインストールされていること(ソースからビルド configure --enable-debug) • デバッガがインストールされていること • 出力が集計しづらい、やや見にくい • 出力例(再掲) 起動直後idle状態でも80行くらい省略している
  • 12.
    © 2021 NTTDATA Corporation 12 V14でできるようになること pg_backend_memory_contextsビューから、ローカルプロセスのMemoryContextが確認可能 • 内容はMemoryContextStatsDetail()と同等 Contextを特定する情報があれば、identに出力される 例) Prepared Statementを実行した場合 階層の深さはlevelで表現
  • 13.
    © 2021 NTTDATA Corporation 13 V14でできるようになること pg_log_backend_memory_contexts()で任意のバックエンドプロセスのMemoryContextが確認 可能 • 出力先はログファイル • 内容はMemoryContextStatsDetail()と同等 • 1つの親MemoryContextが出力する子MemoryContext数は、100に制限。101以降の MemoryContextの情報はサマリのみ出力 • 出力例 • 出力例 =# SELECT pg_log_backend_memory_contexts(取得したいバックエンドのPID); _
  • 14.
    © 2021 NTTDATA Corporation 14 V14のMemoryContext出力の注意点 • pg_backend_memory_contextsビューの参照、pg_log_backend_memory_contexts()の実 行は、いずれもスーパーユーザ権限が必要 • pg_backend_memory_contextsビューの参照権限は、GRANT文で一般ユーザへ付与可能 • pg_log_backend_memory_contexts()の実行権限は、一般ユーザには付与できない • 本関数を大量に実行してDoS攻撃されるのを予防するため
  • 15.
    © 2021 NTTDATA Corporation 15 (参考)V13以前でSQLによるMemeoryContext確認 エクステンションpg_cheat_funcs[1]を利用すれば、同様のことがV9.6~でも可能 • pg_stat_get_memory_context() • というかほぼこの機能をPostgreSQL本体に移植 • “ident”相当の情報はない • pg_cheat_funcsでは、ほかにもPostgreSQLで取り扱い可能な全UTF-8文字を返す関数 (pg_all_utf8())、トランザクションIDを変更する関数など、いろいろな機能が提供されている [1] https://github.com/MasaoFujii/pg_cheat_funcs
  • 16.
    © 2021 NTTDATA Corporation 16 ロック取得待ち時間の確認 ~pg_locksビューへのwaitstart列追加~
  • 17.
    © 2021 NTTDATA Corporation 17 V13までのpg_locks • pg_locksビューは、PostgreSQLプロセスによって取得されているロックの情報を表示するビュー • PostgreSQL 13以前では、ロック待ちを開始した時刻や、ロック待ちしている時間を取得する方法は提供 されていなかった • pg_stat_activityとpidでJOINしてquery_startやstate_changeで時刻を取得できるが、これ らはクエリの開始時刻や状態が変化した時刻 列名 概要 locktype ロック対象オブジェクトの種類。relation, page, tupleなど relation, page, tuple ロックの対象となるリレーションのOID、ページ番号、タプル番号 pid ロックを保持、もしくは待っているサーバプロセスのプロセスID mode このプロセスで保持または要求するロックモードの名称 granted ロックが保持されている場合は真、ロックが待ち状態の場合は偽 pg_locksビューの列(一部)
  • 18.
    © 2021 NTTDATA Corporation 18 V14のpg_locks • ロック待ちを開始した時刻を表示するwaitstart列を追加 • ロックを保持している場合はNULL • 現在時刻との差分を見れば、ロック待ち時間が取得可能 … =# SELECT relation, pid, mode, granted, waitstart FROM pg_locks; _ =# SELECT relation, pid, mode, granted, now() – waitstart AS duration FROM pg_locks; _
  • 19.
    © 2021 NTTDATA Corporation 19 V14のpg_locksの注意点 • タイミングによってはロック取得待ち状態(grantedがfalse)なのに、waitstartがNULLになるケースがある 点に一応注意 • これは、オーバーヘッドを削減するために、ロックを取得せずにwaitstartを更新しているために発生 • この状況はごく短時間しか発生しない、かつwaitstartが必要になるのは長時間ロックが解放されな い場合なので、実質的な影響はないはず …
  • 20.
    © 2021 NTTDATA Corporation 20 まとめ 今回ご紹介したv14の新機能 • MemoryContextの情報を確認する手段が提供された • バックエンドローカル: pg_backend_memory_contexts ビュー • バックエンドローカル以外: pg_log_backend_memory_contexts() • ロック待ちを開始した時刻をpg_locksビューのwaitstart列から確認できるようになった … こんなものもモニタリングしたいというご要望があれば教えてください!!
  • 21.
    © 2021 NTTDATA Corporation