ぱと隊長日誌

ブログ運用もエンジニアとしての生き方も模索中

PostgreSQL のビルドで configure オプション変更時は make distclean を実行すべき

PostgreSQLソースコードからインストールしているケースでは、configure スクリプトのオプションを変更して再ビルドすることがあります。例えば、初回は configure のオプション無しでビルドしたが、--enable-debug オプション付きで再ビルドしたい、といったケースです。

このように PostgreSQL の configure オプションを変更して再ビルドする際には make distclean を実行すべきです。

PostgreSQL のマニュアルから該当箇所を引用します。

構築作業を行った後でconfigure用オプションが間違っていることに気付いた場合や、configureの調査結果に何らかの変更を加えた場合(例えば、ソフトウェアのアップグレードなど)、再設定と再構築の前にmake distcleanを行うことをお勧めします。 さもないと、設定選択肢の変更は、必要なところ全てには反映されない可能性があります。

17.4. インストール手順

ここでは「お勧め」と表現されていますが、make distclean を実行しないと、--enable-debug オプションの追加が反映されないという事象に遭遇しました。ビルド自体は成功してしまうのも厄介なところです。

また、マニュアルでは configure スクリプトの実行後に「ソフトウェアのアップグレード」を行った場合でも、make distclean の実行をお勧めしています。

PostgreSQL の調査や学習の際には同じソースツリーから何度もビルドすることがあります。2回目以降のビルドの際は make distclean を行うのが良いかもしれません。

VS Code Remote - SSH extension で Linux のリモートマシンに接続すると VS Code Server が自動でインストールされる

Visual Studio Code(以下、VS Code)Remote - SSH extension のマニュアルを参照します。
Developing on Remote Machines using SSH and Visual Studio Code

このマニュアルでは SSH 接続でリモート開発する際のアーキテクチャ概要図が示されています。

Developing on Remote Machines using SSH and Visual Studio Code

このアーキテクチャ概要図から以下のことが読み取れます。

  • ローカルとリモートの間を SSH トンネルで接続する
  • ローカルでは VS Code が稼働している
  • サーバでは VS Code Server が稼働している

先述のマニュアルの手順に従えば Linux マシンに SSH 接続してリモート開発できます。ですが、手順の中で VS Code Server のインストール手順は出てきません。にもかかわらずリモート開発できる秘密は初回接続時の処理にあります。初回接続時にリモートマシンのホームディレクトリに VS Code Server がインストールされます。

VS Code の出力を "Remote - SSH" に切り替えて、出力されていた内容を抜粋します。
[user]:リモートサーバのユーザ名
[hash]:何らかのハッシュ値

> [user]@192.168.0.8's password:
> [hash]: running
> Acquiring lock on /home/[user]/.vscode-server/bin/[hash]/vscode-remote-lock.[user].[hash]
> Installing to /home/[user]/.vscode-server/bin/[hash]...
> Downloading with wget
> Download complete
> Checking /home/[user]/.vscode-server/.[hash].log and /home/[user]/.vscode-server/.[hash].pid for a running server
> Running ssh connection command... /home/[user]/.vscode-server/bin/[hash]/bin/code-server --start-server --host=127.0.0.1 --accept-server-license-terms --enable-remote-auto-shutdown --port=0 --telemetry-level all &> "/home/[user]/.vscode-server/.[hash].log" < /dev/null

ホームディレクトリ配下に ".vscode-server" ディレクトリを作成し、VS Code Server をインストール・管理している様子がうかがえます。

Hyper-V の論理プロセッサにおけるコンテキストスイッチとパフォーマンスへの影響

概要

Windows 10 の Hyper-V 上で稼働する仮想マシンにて、PostgreSQL のデータベースとベンチマークツール (pgbench) が異なる仮想プロセッサで動作する時に大きく性能劣化すると以前に報告しました。
Hyper-V のルートスケジューラでは複数 CPU 動作時に大きく性能劣化することがあるのかも - ぱと隊長日誌

この原因を改めて調査したところ、ワークロードによっては論理プロセッサでのコンテキストスイッチを多発させ、これがパフォーマンスに影響を与えているのでは、という仮説に至りました。

この仮説に至った調査をまとめます。

検証環境

検証環境 1

ホスト
プロセッサ Intel Core i5-6600 CPU @ 3.30GHz ※ 4 コアのCPUです
OS Windows 10 Pro バージョン 21H2
Hyper-V
構成バージョン 9.2
プロセッサ 4個の仮想プロセッサ
OS Red Hat Enterprise Linux release 9.1

検証環境 2

ホスト
プロセッサ AMD A10-5800K ※ 4 コアのCPUです
OS Windows 10 Pro バージョン 21H2
Hyper-V
構成バージョン 9.2
プロセッサ 4個の仮想プロセッサ
OS Red Hat Enterprise Linux release 9.1

ソフトウェア

ソフトウェア バージョン
Apache HTTP Server 2.4.53
PostgreSQL 14.6

用語

本記事においては下記の略記を用います。

略記 名称
LP 論理プロセッサ
VP 仮想プロセッサ
従来スケジューラ 従来のスケジューラ、SMT は無効化

調査

他のワークロードでも再現するのか?

以前の検証では PostgreSQL のデータベースとベンチマークツールを異なる VP で動作させたときに性能劣化していました。

PostgreSQLベンチマークはデータベースとベンチマークツールの間で通信があります。ここにポイントがあるのではないかと仮説を立てました。

そこで、プロセス間の通信があるワークロードとして、Apache HTTP Server と Apache Bench を同一もしくは異なる VP で動作させたときにパフォーマンスの差異が出るかを確認しました。

検証環境 1 を利用しました。

-- 同一 VP で動作
# taskset -c 0 httpd -k start
# taskset -c 0 ab -c 1 -n 1000000 http://localhost/

-- 異なる VP で動作
# taskset -c 0 httpd -k start
# taskset -c 1 ab -c 1 -n 1000000 http://localhost/
動作 VP Requests per second
同一 3575.65
異なる 2720.01

Apacheベンチマークでも同一 VP で動作させた方が高い性能となりました。この結果より、プロセス間通信のあるワークロードを異なる VP で動作させたときに性能劣化する可能性が強まりました。

ルートスケジューラ固有の問題なのか?

マニュアルには下記の記載があります。

サーバー システムでのルート スケジューラの使用
現時点では、サーバー上の Hyper-V でのルート スケジューラの使用は推奨されていません。これは、多くのサーバー仮想化のデプロイで一般的なさまざまなワークロードに対応するためのパフォーマンス特性がまだ完全に特徴付けられたり調整されていないためです。

Hyper-V Hypervisor のさまざまな種類のスケジューラを理解して使用する | Microsoft Learn

以前の検証ではこれを根拠として、ルートスケジューラの調整不足の可能性があるとしました。

以前の検証以降の調査でこのような記述も見つけました。

ルートスケジューラが有効になっている場合のコンテキストスイッチは、他のハイパーバイザースケジューラの実装に比べてコストがかかります。
引用元:インサイドWindows 第7版 下 (マイクロソフト公式解説書)

以前の検証でも PostgreSQLベンチマークを 異なる VP で動作させたとき、コンテキストスイッチが増加していました。これがルートスケジューラでの性能に影響を与えた可能性があります。

そこで、ハイパーバイザースケジューラの違いによって、性能にどのような影響があるかを検証しました。

検証環境 2 を利用し、Apache, PostgreSQLベンチマークで比較します。ベンチマークで比較した値は Apache が Requests per second、PostgreSQL が TPS です。

-- 同一 VP で動作
# taskset -c 0 httpd -k start
# taskset -c 0 ab -c 1 -n 1000000 http://localhost/

-- 異なる VP で動作
# taskset -c 0 httpd -k start
# taskset -c 1 ab -c 1 -n 1000000 http://localhost/
-- select1.pgbench ファイルの中身
SELECT 1;

-- 同一 VP で動作
$ taskset -c 0 pg_ctl start -D /usr/local/pgsql/data/
$ taskset -c 0 pgbench -f /home/postgres/select1.pgbench -c 1 -j 1 -n -T 180 testdb

-- 異なる VP で動作
$ taskset -c 0 pg_ctl start -D /usr/local/pgsql/data/
$ taskset -c 1 pgbench -f /home/postgres/select1.pgbench -c 1 -j 1 -n -T 180 testdb

Apache

スケジューラ 同一 VP 異なる VP
従来スケジューラ 3192.26 3051.46
ルートスケジューラ 2947.49 1854.98

PostgreSQL

スケジューラ 同一 VP 異なる VP
従来スケジューラ 30746.633136 19519.17893
ルートスケジューラ 29655.280981 5663.156913

従来スケジューラにおいても異なる VP で動作させたときにパフォーマンス低下がみられました。ただし、Apache ではその低下幅が小さかったです。

この結果より、異なる VP でのパフォーマンス低下はルートスケジューラ固有の問題と言えないことが分かりました。

パフォーマンス低下の原因は何か?

検証環境 2 での Apache, PostgreSQLベンチマークと LP の測定結果を掲載します。

LP はパフォーマンスモニターの "Hyper-V Hypervisor Logical Processor" カテゴリより、以下のカウンタを測定しました。

測定項目 カウンタ名
ゲスト実行時間 [%] % Guest Run Time
ハイパーバイザー実行時間 [%] % Hypervisor Run Time
コンテキストスイッチ [回数/秒] Context Switches/sec

Apache, 従来スケジューラ≫

測定項目 同一 VP 異なる VP
リクエスト [回数/秒] 3192.26 3051.46
ゲスト実行時間 [%] 28.363 33.882
ハイパーバイザー実行時間 [%] 0.900 3.174
コンテキストスイッチ [回数/秒] 2341.129 26765.782

Apache, ルートスケジューラ≫

測定項目 同一 VP 異なる VP
リクエスト [回数/秒] 2947.49 1854.98
ゲスト実行時間 [%] 31.232 30.055
ハイパーバイザー実行時間 [%] 1.913 13.638
コンテキストスイッチ [回数/秒] 6087.158 58926.69

PostgreSQL, 従来スケジューラ≫

測定項目 同一 VP 異なる VP
TPS 30746.633136 19519.17893
ゲスト実行時間 [%] 27.951 28.137
ハイパーバイザー実行時間 [%] 0.569 9.246
コンテキストスイッチ [回数/秒] 1534.912 80417.244

PostgreSQL, ルートスケジューラ≫

測定項目 同一 VP 異なる VP
TPS 29655.280981 5663.156913
ゲスト実行時間 [%] 28.677 22.924
ハイパーバイザー実行時間 [%] 1.041 20.864
コンテキストスイッチ [回数/秒] 3422.084 87479.341


これらの結果より、以下の考察を導きました。

  • 同一 VP / 異なる VP 間での違い
    • 異なる VP で動作するとパフォーマンスが低下する
    • ゲスト実行時間には差異がある場合もない場合もある
    • 異なる VP で動作するとハイパーバイザー実行時間が大きくなる
    • 異なる VP で動作するとコンテキストスイッチ頻度が大きくなる
  • 従来スケジューラ / ルートスケジューラ間での違い
    • 同一 VP で比較するとルートスケジューラのほうが若干パフォーマンス低下する
    • 異なる VP で比較するとルートスケジューラのほうが大幅にパフォーマンス低下する
    • ルートスケジューラでコンテキストスイッチ頻度が大きくなる

これらの結果より、ハイパーバイザー実行時間とコンテキストスイッチ頻度が大きくなると、パフォーマンスは低下する傾向にあるようです。

インサイド Windows 第7版 下」のルートスケジューラの節でこんな説明がありました。

ゲストVPが現在の物理プロセッサで最後に実行された場合、スケジューラはゲストVPスレッドをすぐにディスパッチできます。それ以外の場合、スケジューラは、ゲストPVが最後に実行されたプロセッサにフラッシュ要求を送信し、リモートプロセッサがVPコンテキストをフラッシュするのを待つ必要があります。
引用元:インサイドWindows 第7版 下 (マイクロソフト公式解説書)

※「ゲストPV」は「ゲストVP」の誤字と思われます。

これがコンテキストスイッチの事であれば、フラッシュ処理によるオーバーヘッドでパフォーマンス低下を説明できそうです。

以前の記事で VP と LP の対応は動的に決定することを確認しました。
Hyper-V で論理プロセッサの利用状況は環境やワークロードに左右される - ぱと隊長日誌
パフォーマンスを高めるためには VP と LP の対応をなるべく固定化することが理想のように思えます。これをしないのは仮想環境が CPU のオーバーコミットを前提とし、VP と LP の対応を動的にすることで柔軟性を高めたのでは…?と推測しています。ただ、こちらに関して裏付ける資料を見つけることはできませんでした。

CPU指定なしでスレッド数を変化させるとどうなるか?

ここまでは taskset コマンドで CPU(仮想マシンの VP)を指定してきました。ここでは通常通り、VP を指定せずに測定します。

以下の条件を組み合わせて、検証環境 2 で測定を行いました。

# httpd -k start

-- 1クライアント
# ab -c 1 -n 1000000 http://localhost/

-- 4クライアント
# ab -c 4 -n 1000000 http://localhost/
-- select1.pgbench ファイルの中身
SELECT 1;

$ pg_ctl start -D /usr/local/pgsql/data/

-- 1クライアント
$ pgbench -f /home/postgres/select1.pgbench -c 1 -j 1 -n -T 180 testdb

-- 4クライアント
$ pgbench -f /home/postgres/select1.pgbench -c 4 -j 4 -n -T 180 testdb

Apacheベンチマークによるスケジューラの違い。従来スケジューラのほうがパフォーマンスが良い。

PostgreSQLベンチマークによるスケジューラの違い。スレッド数が少ないときに、従来スケジューラのほうがパフォーマンスが良い。

ベンチマークの傾向だけで見ればルートスケジューラと従来スケジューラは似ています。

スケジューラの違いをベンチマークの成績で比較します。Apache はルートスケジューラより従来スケジューラの成績が良いです。PostgreSQL はスレッド数が少ないときに、ルートスケジューラより従来スケジューラの成績が良いです。

スレッド数の観点でベンチマークの成績を比較します。Apache はスレッド数に応じて徐々に向上しています。PostgreSQL は 4 スレッドを境に大きく変化しました。

ApacheベンチマークとLPカウンタを従来スケジューラで測定した。

ApacheベンチマークとLPカウンタをルートスケジューラで測定した。

スケジューラの違いを Apache の例で比較します。従来スケジューラよりルートスケジューラでコンテキストスイッチ頻度が多いです。ハイパーバイザー実行時間はルートスケジューラのほうが2倍超となっています。

PostgreSQLベンチマークとLPカウンタを従来スケジューラで測定した。

PostgreSQLベンチマークとLPカウンタをルートスケジューラで測定した。

スケジューラの違いを PostgreSQL の例で比較します。スケジューラが異なってもコンテキストスイッチ頻度はほぼ同じです。ハイパーバイザー実行時間はルートスケジューラのほうが2倍程度となっています。

このように、スケジューラとベンチマークによって結果は大きく異なりますが、共通点を見出せました。ハイパーバイザー実行時間とコンテキストスイッチ頻度が減ればベンチマークの成績は良くなること。そして、ハイパーバイザー実行時間とコンテキストスイッチ頻度の間には相関がありそうだということです。

まとめ

今回の検証で用いたワークロードでは、ルートスケジューラより従来スケジューラのほうがパフォーマンスの良い傾向にあることが分かりました。

また、コンテキストスイッチ頻度・ハイパーバイザー実行時間・パフォーマンスの間には相関がありそうだということも示されました。今回の検証でこのメカニズムを突き止めることまでは至らなかったので、今後の課題とします。