0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

pgbenchで見るPostgreSQL 17の変化 ─ t3.microで確かめるWAL改善とVACUUM強化

0
Posted at

1. はじめに

本記事は、PostgreSQL16パフォーマンスチューニングシリーズの17対応版の一本です。

前回の記事でPostgreSQL16から17へのバージョンアップ手順を確認しました。本記事はその17環境を使って、WAL書き込み改善VACUUM強化の2点をt3.microという低スペック環境で実測します。

SRA OSSの「PostgreSQL 17検証レポート」では大規模サーバ(多vCPU・大メモリ)での計測結果が示されています。本記事はt3.micro(2vCPU・1GiB)でも差が出るのかという切り口で検証します。

1.1 この記事でわかること

  • WAL書き込み改善はt3.microで効果が出るのか
  • VACUUMの速度・WAL出力量は16と17でどう変わるのか
  • 低スペック環境でのPostgreSQL17の実力

2. 検証環境

2.1 環境構成

項目 内容
OS Amazon Linux 2023
インスタンス t3.micro(2vCPU・1GiB)EBS 30GB
PostgreSQL 16 AMIから復元した16環境(16.12)
PostgreSQL 17 前回記事でバージョンアップした17環境(17.8)
データ規模 pgbench -s 100(約1500万行) / VACUUM計測は300万行

2.2 postgresql.conf(16・17共通)

# === 今回の計測用設定 ===

# メモリ
shared_buffers = 256MB
work_mem = 4MB
maintenance_work_mem = 512MB

# 接続
max_connections = 200

# チェックポイント
checkpoint_timeout = 30min
checkpoint_completion_target = 0.9
max_wal_size = 1GB

# bgwriter(デフォルト維持)
bgwriter_delay = 200ms
bgwriter_lru_maxpages = 100
bgwriter_lru_multiplier = 2.0

# ログ
log_checkpoints = on

# VACUUM(計測中は自動実行を停止)
autovacuum = off

# 拡張(今回は不要)
# shared_preload_libraries = 'pg_stat_statements'

設定の考え方:今回はWAL改善とVACUUMの素の性能差を見たいため、チューニングは最小限にしています。過去記事(#3・#4)で使った劣化用・改善用の値は使わず、デフォルトに近い状態で16と17を比較します。autovacuum = off は計測中に自動VACUUMが走って結果がブレるのを防ぐためです。計測後は必ず on に戻してください。

パラメータ デフォルト値 過去記事の値 今回の値 理由
shared_buffers 128MB 512MB / 8MB 256MB t3.microの1/4。基準値として
work_mem 4MB 64MB / 128MB 4MB WAL/VACUUM計測に影響しない
maintenance_work_mem 64MB 2GB 512MB t3.micro範囲内に収める
max_connections 100 400 200 pgbench -c 50まで対応
checkpoint_timeout 5min 30s / 15min 30min 計測中にチェックポイントが走らないよう延長
checkpoint_completion_target 0.9 0.001 / 0.9 0.9 劣化検証不要のためデフォルト
max_wal_size 1GB 126MB / 4GB 1GB デフォルトのまま
bgwriter_delay 200ms 10s / 100ms 200ms bgwriter影響を排除
bgwriter_lru_maxpages 100 0 / 300 100 bgwriter影響を排除
bgwriter_lru_multiplier 2.0 2(参考) 2.0 デフォルトのまま
log_checkpoints off on on チェックポイント発生を監視
shared_preload_libraries (空) 'pg_stat_statements' (空) 余計な負荷を排除
autovacuum on - off 計測中の自動VACUUM実行を防ぐ

2.3 設定の適用手順(16・17両環境で実施)

sudo vi /var/lib/pgsql/data/postgresql.conf
sudo systemctl restart postgresql

# 設定確認
psql -U postgres -d pgbench_test -c "SHOW shared_buffers;"
psql -U postgres -d pgbench_test -c "SHOW autovacuum;"
psql -U postgres -d pgbench_test -c "SHOW max_wal_size;"

2.4 pg_hba.confの設定

sudo vi /var/lib/pgsql/data/pg_hba.conf
# ローカル接続・TCP接続ともにscram-sha-256に統一
local   all             all                                     scram-sha-256
host    all             all             127.0.0.1/32            scram-sha-256
host    all             all             ::1/128                 scram-sha-256
sudo systemctl restart postgresql

# 接続確認
psql -U postgres -d pgbench_test -c "SELECT version();"

3. WAL書き込み改善を実測する

3.1 背景

PostgreSQL 17ではWAL排他処理が改良され、高並列時の書き込みスループットが向上しました。64bit値のアトミックな交換をサポートするCPUで、多数の書き込みトランザクションの同時実行において性能改善が期待できます。

SRA OSSの検証レポートでは1024並列で大幅な差異が確認されています。t3.microの2vCPUでは並列数の上限が低いため、同様の差が出るかどうかを確認します。

3.2 実測コマンド

# スケール作成
pgbench -i -s 100 -U postgres pgbench_test

# 並列数を変えてTPS計測
for c in 5 10 20 50; do
    echo "=== -c $c ==="
    pgbench -c $c -j 2 -T 60 -U postgres pgbench_test
done

実行結果の例(-c 20 の場合):

=== -c 20 ===
pgbench (17.8)
starting vacuum...end.
transaction type: <builtin: TPC-B (sort of)>
scaling factor: 100
query mode: simple
number of clients: 20
number of threads: 2
maximum number of tries: 1
duration: 60 s
number of transactions actually processed: 74066
number of failed transactions: 0 (0.000%)
latency average = 16.178 ms
initial connection time = 154.921 ms
tps = 1236.248538 (without initial connection time)

3.3 結果

並列数 PG16 TPS PG17 TPS 差異
-c 5 1,194.43 1,228.07 +2.8%
-c 10 1,199.26 1,201.57 +0.2%
-c 20 1,229.02 1,236.25 +0.6%
-c 50 1,260.66 1,249.49 -0.9%

3.4 考察

t3.microでは16と17でほぼ同等の結果(±3%以内)となりました。

SRA OSSの検証レポートでも256並列・512並列まではほとんど性能向上が見られず、1024並列で初めて大幅な差異が出ています。 t3.microの2vCPUでは並列数の上限が低く、WAL排他処理の競合が発生しにくい環境のため、同様の傾向となりました。

WAL改善の恩恵を得るには多vCPU・高並列の環境が必要です。


4. VACUUMのメモリ・速度改善を実測する

4.1 背景

PostgreSQL 17ではVACUUMの内部実装が刷新されました。主な変更点は以下の通りです。

  • dead tupleの整理とtuple凍結を一括で行い、WAL出力量を軽減
  • インデックスのないテーブルのVACUUMを効率化

16.xまではVACUUM処理におけるメモリの使い方に課題があり、大量のdead tupleを処理する場合に本来不要なテーブルの再走査が発生していました。17ではこの課題が解消されています。

4.2 実測コマンド

# テーブル作成(300万行・インデックスあり)
psql -U postgres -d pgbench_test <<EOF
DROP TABLE IF EXISTS t_vacuum_test;
CREATE TABLE t_vacuum_test (id int, v text);
CREATE INDEX ON t_vacuum_test (id);
INSERT INTO t_vacuum_test
  SELECT g, 'x' FROM generate_series(1, 3000000) g;
EOF

# 95%更新でdead tupleを発生させる
psql -U postgres -d pgbench_test -c "
UPDATE t_vacuum_test SET v = 'y' WHERE id % 20 != 1;"

# VACUUM実行時間を計測
psql -U postgres -d pgbench_test \
  -c "\timing on" \
  -c "VACUUM VERBOSE t_vacuum_test;"

実行結果の例(PostgreSQL 17・95%更新・インデックスあり):

Timing is on.
INFO:  vacuuming "pgbench_test.public.t_vacuum_test"
INFO:  finished vacuuming "pgbench_test.public.t_vacuum_test": index scans: 1
pages: 0 removed, 25885 remain, 25885 scanned (100.00% of total)
tuples: 2850000 removed, 3000000 remain, 0 are dead but not yet removable
removable cutoff: 567348, which was 0 XIDs old when operation ended
new relfrozenxid: 567346, which is 2 XIDs ahead of previous value
frozen: 10745 pages from table (41.51% of total) had 121418 tuples frozen
index scan needed: 13275 pages from table (51.28% of total) had 2850000 dead item identifiers removed
index "t_vacuum_test_id_idx": pages: 16454 in total, 0 newly deleted, 0 currently deleted, 0 reusable
avg read rate: 83.671 MB/s, avg write rate: 128.000 MB/s
buffer usage: 62293 hits, 19266 misses, 29473 dirtied
WAL usage: 68831 records, 24019 full page images, 75252272 bytes
system usage: CPU: user: 1.27 s, system: 0.12 s, elapsed: 1.79 s
VACUUM
Time: 1814.569 ms (00:01.815)

【注意】max_wal_sizeは1GBに設定すること
max_wal_size = 4GBのままUPDATEを実行するとWALが蓄積してディスクが満杯になりPANICが発生します。VACUUM計測時は必ず max_wal_size = 1GB に設定してください。

4.3 更新割合を変えたパターン

# テーブルを作り直してから各パターンを実施

# 50%更新
psql -U postgres -d pgbench_test <<EOF
DROP TABLE IF EXISTS t_vacuum_test;
CREATE TABLE t_vacuum_test (id int, v text);
CREATE INDEX ON t_vacuum_test (id);
INSERT INTO t_vacuum_test
  SELECT g, 'x' FROM generate_series(1, 3000000) g;
EOF

psql -U postgres -d pgbench_test -c "
UPDATE t_vacuum_test SET v = 'y' WHERE id % 2 = 1;"

psql -U postgres -d pgbench_test \
  -c "\timing on" \
  -c "VACUUM VERBOSE t_vacuum_test;"

# 5%更新
psql -U postgres -d pgbench_test <<EOF
DROP TABLE IF EXISTS t_vacuum_test;
CREATE TABLE t_vacuum_test (id int, v text);
CREATE INDEX ON t_vacuum_test (id);
INSERT INTO t_vacuum_test
  SELECT g, 'x' FROM generate_series(1, 3000000) g;
EOF

psql -U postgres -d pgbench_test -c "
UPDATE t_vacuum_test SET v = 'y' WHERE id % 20 = 1;"

psql -U postgres -d pgbench_test \
  -c "\timing on" \
  -c "VACUUM VERBOSE t_vacuum_test;"

# インデックスなし・95%更新
psql -U postgres -d pgbench_test <<EOF
DROP TABLE IF EXISTS t_vacuum_test;
CREATE TABLE t_vacuum_test (id int, v text);
INSERT INTO t_vacuum_test
  SELECT g, 'x' FROM generate_series(1, 3000000) g;
EOF

psql -U postgres -d pgbench_test -c "
UPDATE t_vacuum_test SET v = 'y' WHERE id % 20 != 1;"

psql -U postgres -d pgbench_test \
  -c "\timing on" \
  -c "VACUUM VERBOSE t_vacuum_test;"

4.4 結果

実行時間

更新割合 インデックス PG16 PG17 改善率
95% あり 10,431ms 1,815ms 約5.7倍高速
95% なし 511ms 392ms 約1.3倍高速
50% あり 1,913ms 1,096ms 約1.7倍高速
5% あり 413ms 333ms 約1.2倍高速

WAL出力量

更新割合 インデックス PG16 PG17 削減率
95% あり 約226MB 約71MB 約69%削減
95% なし 約53MB 約7.6MB 約86%削減
50% あり 約168MB 約34MB 約80%削減
5% あり 約3.4MB 約3.4MB ほぼ同等

4.5 考察

インデックスあり95%更新で約5.7倍高速、WAL出力量は約69%削減という結果になりました。

注目すべきポイントは以下の3点です。

① インデックスの有無で改善率が大きく異なる
インデックスありの95%更新では5.7倍の改善に対し、インデックスなしでは1.3倍にとどまっています。17の改善はインデックスを持つテーブルのVACUUMで特に効果が大きくなっています。

② 更新割合が高いほど改善率が大きい
95%更新で5.7倍、50%更新で1.7倍、5%更新で1.2倍と、更新割合が高いほど改善率が大きくなっています。dead tupleが多いほど効果が出やすい傾向があります。

③ t3.microでも効果がはっきり出た
WAL改善とは対照的に、VACUUM改善はt3.microという低スペック環境でも明確な差が出ました。本番環境ではさらに大きな効果が期待できます。


5. まとめ

項目 PG16 PG17 結果
TPS(並列50) 1,260.66 1,249.49 ほぼ同等(±1%)
VACUUM時間(95%・インデックスあり) 10,431ms 1,815ms 約5.7倍高速
VACUUM WAL出力(95%・インデックスあり) 約226MB 約71MB 約69%削減
  • WAL改善:t3.microでは差が出ない。恩恵を得るには256並列以上の高並列環境が必要
  • VACUUM改善:t3.microでも劇的な効果。特にインデックスありの高更新率テーブルで顕著

6. 計測後の後片付け

# autovacuumを必ず戻す
sudo vi /var/lib/pgsql/data/postgresql.conf
# autovacuum = on に変更

sudo systemctl restart postgresql
psql -U postgres -d pgbench_test -c "SHOW autovacuum;"

7. 参考資料

ページ URL
PostgreSQL 17 リリースノート https://www.postgresql.org/docs/17/release-17.html
SRA OSS PostgreSQL 17検証レポート https://www.sraoss.co.jp/

8. さいごに

次回も、PostgreSQL17で改善された点について試していきたいと考えています。pgbenchを利用することで、大量のデータを利用した機能検証が容易に可能です。以前までの記事で、主にpostgresql.confの変更により、結果がどのように変わるかを見てきましたが、バージョンの差による機能差を見ていきたいと思います。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?