時間は味方:アクティブタイム


このブログ投稿の名前が頭の中にあるローリング ストーンズの曲を聞いていただければ幸いです.そうでない場合は、youtube にアクセスしてください.

データベースのチューニングは時間の問題であり、時間の経過を理解することです.残念ながら、postgresql には、合計アクティブ時間とアクティブなセッションの平均量を計算できるように、費やされた時間を計算する機能がありません.

postgres バックエンドの状態のインジケーターはデータベースの pg_stat_activity.state で確認でき、状態は pgstat.h header file で確認できます.

pg_stat_activity.state に値を設定する関数は pgstat_report_activity で、状態はこの関数の引数として使用されます.

これは、perf を使用して pgstat_report_activity にプローブを設定し、CPU レジスタの関数の引数リストから状態を取得できることを意味します.

私の環境は次のようになります.
  • アルマ Linux 8.4 (x86_64).
  • PGDG postgres yum リポジトリからの Postgres 11.13.

  • pgstat_report_activity に perf プローブを設定し、状態引数を取得するには、次を使用します.perf probe -x /usr/pgsql-11/bin/postgres pgstat_report_activity %di
    プローブが追加されると、何もしなくなります.そのためには、プローブ アクティビティを記録する必要があります.これは次の方法で行われます: perf record -e 'probe_postgres:*' .実行後、perf 実行可能ファイルはビジーで、プローブ アクティビティを記録します.ctrl-C を押すと、現在の作業ディレクトリにある perf.data というファイルに結果が書き込まれます.

    システムで関数 pgstat_report_activity の実行を記録したい場合は、perf record -e '..' を使用できます.さらに、 -p PID を使用して 1 つのバックエンド プロセスのみを記録するか、 -p PID,PID を使用して複数のバックエンド プロセスを記録することができます.

    アクティビティを記録した場合は、まだ完了していません. perf script を使用して記録された出力を表示できます.次のようになります.

    [[email protected] ~]# perf script
          postmaster  3288 [000]  6542.445581: probe_postgres:pgstat_report_activity: (6eea90) arg1=0x2
          postmaster  3288 [000]  6542.445731: probe_postgres:pgstat_report_activity: (6eea90) arg1=0x1
          postmaster  3288 [000]  6543.303748: probe_postgres:pgstat_report_activity: (6eea90) arg1=0x2
          postmaster  3288 [000]  6543.303859: probe_postgres:pgstat_report_activity: (6eea90) arg1=0x1
          postmaster  3288 [000]  6543.952743: probe_postgres:pgstat_report_activity: (6eea90) arg1=0x2
          postmaster  3288 [000]  6543.952855: probe_postgres:pgstat_report_activity: (6eea90) arg1=0x1
          postmaster  3133 [001]  6545.933558: probe_postgres:pgstat_report_activity: (6eea90) arg1=0x2
          postmaster  3133 [001]  6545.933734: probe_postgres:pgstat_report_activity: (6eea90) arg1=0x1
          postmaster  3133 [001]  6546.584847: probe_postgres:pgstat_report_activity: (6eea90) arg1=0x2
          postmaster  3133 [001]  6546.584958: probe_postgres:pgstat_report_activity: (6eea90) arg1=0x1
          postmaster  3133 [001]  6547.236539: probe_postgres:pgstat_report_activity: (6eea90) arg1=0x2
          postmaster  3133 [001]  6547.236644: probe_postgres:pgstat_report_activity: (6eea90) arg1=0x1
    


    最初の列はプロセスの名前で、2 番目の列は PID です.そのため、2 つのプロセスを記録しました.3 列目は CPU 番号、4 列目は相対タイムスタンプ、5 列目はプローブ グループと名前、6 列目はプローブ アドレス、7 列目は要求した追加の引数です. (引数を運ぶ CPU レジスタである %di).これは、pgstat_report_activity がバックエンドを設定した状態を示します: 1 = アイドル、2 = 実行中.

    これは、データを意味のあるものにするために、このデータを処理する必要があることを意味します.

    データを処理し、データを操作できるように出力する postgres_activity.awk という小さな awk スクリプトを作成しました.次のように使用する必要があります.perf script | ./postgres_activity.awk上記の生のパフォーマンス データから、次の概要が作成されます.

    [[email protected] ~]# perf script | ./dbtime.awk
    total time in file                                                    4.791063 s 100.00 %
    
    pid:    3133                                                          1.303086 s  27.20 %
     state idle                                                  2        1.302694 s  99.97 %
     state running                                               3        0.000392 s   0.03 %
    
    pid:    3288                                                          1.507274 s  31.46 %
     state idle                                                  2        1.506901 s  99.98 %
     state running                                               3        0.000373 s   0.02 %
    
    


    これにより、負荷の計算に重要ないくつかの統計を計算できます.
  • ファイルに記録された合計時間は 4.791063 秒です.
  • 合計アクティブ時間は、実行中の状態の合計です: 0.000392+0.000373=0.000765.それがいわゆる dbtime です.
  • これは、アクティビティの平均量が 0.000765/4.791063=0.0001596722898 であることを意味します.これは、いわゆる平均アクティブ セッション時間です.

  • もちろん、上記の数値はばかげていますが、これらの数値を使用する主な機能はそうではありません.平均アクティブ セッション時間を直接使用して CPU の数と照合し、postgres によってどれだけの CPU 負荷が生成されているかを確認できます.

    プローブを削除するには、次を実行します.perf probe --del 'probe_postgres:pgstat_report_activity'または、1 つのプローブを取得した場合、またはすべてのプローブを削除したい場合は、さらに簡単です.perf probe --del '*'