Skip Navigation
Show nav
Dev Center
  • Get Started
  • ドキュメント
  • Changelog
  • Search
  • Get Started
    • Node.js
    • Ruby on Rails
    • Ruby
    • Python
    • Java
    • PHP
    • Go
    • Scala
    • Clojure
    • .NET
  • ドキュメント
  • Changelog
  • More
    Additional Resources
    • Home
    • Elements
    • Products
    • Pricing
    • Careers
    • Help
    • Status
    • Events
    • Podcasts
    • Compliance Center
    Heroku Blog

    Heroku Blog

    Find out what's new with Heroku on our blog.

    Visit Blog
  • Log inorSign up
View categories

Categories

  • Heroku のアーキテクチャ
    • コンピューティング (dyno)
      • dyno の管理
      • dyno の概念
      • dyno の動作
      • dyno の参照資料
      • dyno のトラブルシューティング
    • スタック (オペレーティングシステムイメージ)
    • ネットワーキングと DNS
    • プラットフォームポリシー
    • プラットフォームの原則
  • 開発者ツール
    • コマンドライン
    • Heroku の VS Code 拡張機能
  • デプロイ
    • Git を使用したデプロイ
    • Docker によるデプロイ
    • デプロイ統合
  • 継続的デリバリーとインテグレーション
    • 継続的統合
  • 言語サポート
    • Node.js
      • Node.js アプリのトラブルシューティング
      • Heroku での Node.js の動作
      • Node.js の操作
    • Ruby
      • Rails のサポート
      • Bundler の使用
      • Ruby の操作
      • Heroku での Ruby の動作
      • Ruby アプリのトラブルシューティング
    • Python
      • Python の操作
      • Python でのバックグラウンドジョブ
      • Heroku での Python の動作
      • Django の使用
    • Java
      • Heroku での Java の動作
      • Java の操作
      • Maven の使用
      • Spring Boot の使用
      • Java アプリのトラブルシューティング
    • PHP
      • PHP の操作
      • Heroku での PHP の動作
    • Go
      • Go の依存関係管理
    • Scala
    • Clojure
    • .NET
      • Working with .NET
  • データベースとデータ管理
    • Heroku Postgres
      • Postgres の基礎
      • Postgres スターターガイド
      • Postgres のパフォーマンス
      • Postgres のデータ転送と保持
      • Postgres の可用性
      • Postgres の特別なトピック
      • Heroku Postgres への移行
    • Heroku Key-Value Store
    • Apache Kafka on Heroku
    • その他のデータストア
  • AI
    • Vector Database
    • Working with AI
    • Heroku Inference
      • AI Models
      • Inference Essentials
      • Heroku Inference Quick Start Guides
      • Inference API
    • Model Context Protocol
  • モニタリングとメトリクス
    • ログ記録
  • アプリのパフォーマンス
  • アドオン
    • すべてのアドオン
  • 共同作業
  • セキュリティ
    • アプリのセキュリティ
    • ID と認証
      • シングルサインオン (SSO)
    • Private Space
      • インフラストラクチャネットワーキング
    • コンプライアンス
  • Heroku Enterprise
    • Enterprise Accounts
    • Enterprise Team
    • Heroku Connect (Salesforce 同期)
      • Heroku Connect の管理
      • Heroku Connect のリファレンス
      • Heroku Connect のトラブルシューティング
  • パターンとベストプラクティス
  • Heroku の拡張
    • Platform API
    • アプリの Webhook
    • Heroku Labs
    • アドオンのビルド
      • アドオン開発のタスク
      • アドオン API
      • アドオンのガイドラインと要件
    • CLI プラグインのビルド
    • 開発ビルドパック
    • Dev Center
  • アカウントと請求
  • トラブルシューティングとサポート
  • Salesforce とのインテグレーション
  • データベースとデータ管理
  • Heroku Postgres
  • Postgres のパフォーマンス
  • Heroku Postgres での VACUUM の管理

Heroku Postgres での VACUUM の管理

日本語 — Switch to English

最終更新日 2024年06月04日(火)

Table of Contents

  • データベースのバキューム
  • 肥大化の確認
  • VACUUM のバリアント
  • 自動バキュームを使用した自動的なバキューム
  • 手動バキューム

Postgres は MVCC​ と呼ばれるメカニズムを使用してデータベースの変更を追跡します。副作用として、一部の行が “使用されない” 状態になり、実行中のどのトランザクションにも表示されなくなります。使用されなくなった行は DELETE​ 操作だけでなく、UPDATE​ や、ロールバックする必要があるトランザクションによっても生成されます。

これらの使用されなくなった行を消去するために、データベースには定期的なメンテナンスが必要です。これは基本的に、ガベージコレクションの形式になります。通常、このメンテナンスは自動的に実行されますが、その詳細を理解し、必要に応じてメンテナンス設定をチューニングすると有効な場合があります。

データベースのバキューム

このクリーンアップを管理するための組み込みのメカニズムは VACUUM​ と呼ばれます。これは通常のコマンドとして実行できますが、Postgres には、VACUUM​ プロセスをメンテナンスタスクとしてバックグラウンドで自動的に実行し、必要に応じて古いデータの定期的な消去を試みるための機能も含まれています。このプロセスは、一連の設定パラメータに基づいてメンテナンスを実行します。

多くのアプリケーションでは Heroku のデフォルト設定で十分ですが、状況によっては、いくつかの変更を行ったり、手動のアクションを実行したりすることが必要です。

肥大化の確認

VACUUM を実行する必要があるかどうかを確認するには、テーブルとインデックスの “肥大化” に関する情報を提供するクエリを実行できます。肥大化とは、使用されなくなった行のために、ディスク上のこれらのデータベースオブジェクトによって占有される余分な領域のことです。これを確認するための最も簡単な方法は、Heroku CLI の pg-extras​ プラグインのインストールです。

インストールしたら、次のコマンドを実行して肥大化を確認できます。

$ heroku pg:bloat DATABASE_URL --app example-app
 type  | schemaname |    object_name          | bloat |   waste
-------+------------+-------------------------+-------+-----------
 table | public     | users                   |   1.0 | 109 MB
 table | public     | logs                    |   1.0 | 47 MB
 index | public     | queue_classic_jobs_pkey |   3.1 | 25 MB
 table | public     | reviews                 |   2.2 | 16 MB
 table | public     | queue_classic_jobs      |  32.5 | 1512 kB
...

“bloat” 列は、肥大化として存在する元のテーブルの部分の係数である肥大化係数を示しています。これは比率であるため、単位はありません。"waste" 列は、システム内の各テーブルとインデックスの合計の肥大化 (バイト単位) を示しています。

Postgres では肥大化を考慮せずにクエリが計画されるため、テーブルまたはインデックスの肥大化係数が非常に大きいと、一部のクエリでパフォーマンスが低下する場合があります。

過剰な肥大化のしきい値はクエリパターンやテーブルのサイズによって異なります。特に 100 MB を超えるテーブルの場合、一般に肥大化係数が 10 を超えるときは常に調査する必要があります。

データベースでのバキュームを確認するには、別の pg-extras コマンドを使用できます。

$ heroku pg:vacuum-stats DATABASE_URL --app example-app
 schema |         table      | last_vacuum | last_autovacuum  |    rowcount    | dead_rowcount  | autovacuum_threshold | expect_autovacuum
--------+--------------------+-------------+------------------+----------------+----------------+----------------------+-------------------
 public | queue_classic_jobs |             | 2013-05-20 16:54 |         82,617 |         36,056 |         16,573       | yes
 public | logs               |             | 2013-05-20 16:27 |              1 |             18 |             50       |
 public | reviews            |             | 2013-05-20 01:36 |             87 |              0 |             67       |
 public | users              |             | 2013-05-20 16:28 |              0 |             23 |             50       |
...

これにより、各テーブルが最後にバキュームされた日時と、それが手動のアクションまたは自動バキュームバックグラウンドワーカーのどちらで行われたかが通知されます。また、その特定のテーブルの自動バキュームをトリガーする使用されなくなった行のしきい値の行数と、自動バキュームの実行が予測されるかどうかも表示されます。

VACUUM のバリアント

VACUUM​ を定期的に実行することで、肥大化を抑えることができます。自動バキュームプロセスは、通常の FULL ではない VACUUM​ コマンドのみを実行します。制御不能になった場合は、VACUUM FULL​ を実行することで肥大化を軽減できます。

VACUUM FULL​ はより徹底的なクリーンアップを行い、通常の VACUUM​ のように空き容量をフラグ付けするだけでなく、実際に肥大化を軽減します。ただし、その分非常に重い操作でもあります。VACUUM FULL​ はテーブル全体を書き換えるため、単純な SELECT​ クエリのような他のステートメントが同時に実行されるのを防ぎます。

一般には、VACUUM FULL​ を実行する必要がないように、積極的に自動バキュームを行うように設定しておくことをお勧めします。VACUUM FULL​ は時間がかかる可能性があるため、代わりに特定のテーブルに対して VACUUM​ を実行できます。たとえば、VACUUM table_name​ とします。

一時的なデータ (ワークキューなど) を追跡するためにのみテーブルを使用している場合は、代わりに TRUNCATE​ コマンドを実行すると役立ちます。このコマンドにより、テーブル内のすべてのデータがバッチ操作で削除されます。非常に肥大化したテーブルの場合は、これが DELETE​ や VACUUM FULL​ よりはるかに高速になる場合があります。

自動バキュームを使用した自動的なバキューム

肥大化を管理するための最も効果的な方法として、必要に応じて自動バキューム設定を調整します。

テーブルが VACUUM​ の対象になるタイミングは、4 つの設定から変更できます。Heroku では、これらの変更はテーブルごとにしか行えません。

$ heroku pg:psql
=> ALTER TABLE users SET (autovacuum_vacuum_threshold = 50);
ALTER TABLE
=> ALTER TABLE users SET (autovacuum_vacuum_scale_factor = 0.2);
ALTER TABLE
=> ALTER TABLE users SET (autovacuum_vacuum_insert_threshold = 1000);
ALTER TABLE
=> ALTER TABLE users SET (autovacuum_vacuum_insert_scale_factor = 0.2);
ALTER TABLE

Postgres は、前回の VACUUM​ 操作以降の使用されなくなった行数が定義されたしきい値を超えた場合、および最後の VACUUM​ 操作以降に挿入された行数が定義された挿入しきい値を超えた場合に、自動バキュームをトリガーします。

バキュームしきい値は、必要とされる使用されなくなった行の未加工の数であり、バキュームスケール係数は、使用されなくなった行として存在する必要があるテーブル内のライブ行の部分の係数です。これらのデフォルト値は 50​ と 0.2​ です。

挿入しきい値はバキュームを開始する前の最小の行挿入数であり、挿入スケール係数は挿入バキュームを開始するテーブルサイズに対する挿入数の割合です。これらのデフォルト値は 1000​ と 0.2​ です。

これらの設定を組み合わせることで、次の式に従って実際のしきい値と挿入しきい値が構成されます。

vacuum threshold = autovacuum_vacuum_threshold +
    autovacuum_vacuum_scale_factor * number of rows

vacuum insert threshold = autovacuum_vacuum_​insert_threshold +
    autovacuum_vacuum_​insert_scale_​factor * number of inserts

大きなテーブルでは、このスケール係数を減らしてバキュームの進行をより早く開始できるようにする必要があります。非常に小さなテーブルの場合は、このしきい値を増やすことができますが、一般には必要ありません。

さらに、自動バキュームにはコストベースの速度制限メカニズムが組み込まれており、VACUUM​ アクティビティによるシステムの過負荷を回避します。ただし、ビジー状態のデータベースでは、このメカニズムによって自動バキュームの進行が遅くなり、過剰な肥大化につながる場合があります。

これを回避するには、より積極的にバックオフを行うようにバックアップ設定を変更できます。これらの変更は、データベースレベルで行うことができます。

$ heroku pg:psql
=> select current_database();
 current_database
------------------
 dd5ir2j6frrtr0
(1 row)
=> ALTER DATABASE dd5ir2j6frrtr0 SET vacuum_cost_limit = 300;
ALTER DATABASE
=> ALTER DATABASE dd5ir2j6frrtr0 SET vacuum_cost_page_dirty = 25;
ALTER DATABASE
=> ALTER DATABASE dd5ir2j6frrtr0 SET vacuum_cost_page_miss = 7;
ALTER DATABASE
=> ALTER DATABASE dd5ir2j6frrtr0 SET vacuum_cost_page_hit = 0;
ALTER DATABASE

コスト制限によって、自動バキュームが強制的に中断されるまでに獲得できる “コスト” の大きさ (I/O 操作の単位) が決定されます。また、コスト遅延によって、その中断の期間 (ミリ秒単位) が決定されます。これらの設定は、自動バキュームと手動バキュームの両方に影響を与えます (自動バキュームのみのバリアントが存在しますが、現時点で Heroku Postgres ではテーブルごとにしか設定できません)。コスト制限は、デフォルトでは 200​ に設定されています。コスト制限を増やす (最大 1000​ 程度) か、vacuum_cost_page_*​ パラメータを調整すると、自動バキュームの進行がより効率的になります。

手動バキューム

データベースに定期性の高いワークロードが存在する場合は、単純なワーカープロセスを使用して “手動で”VACUUM​ (ロックが問題にならない場合は VACUUM FULL​ でも) を実行し、ピーク時間外に Heroku Scheduler​ などのツールでそれをトリガーする方がより効率的です。

手動 VACUUM​ には、いつ “開始するか” に関するしきい値はありません。VACUUM​ コマンドを実行すると必ずトリガーされます。コストベースのバックオフも (自動バキュームと同様に) 適用されますが、これはデフォルトで無効になっています (vacuum_cost_delay​ は 0 に設定)。手動の VACUUM​ が通常のワークロードに与える影響が大きすぎることがわかった場合は、この値をテーブルごとに増やすことができます。

VACUUM​ を実行するには、目的のデータベースへの psql シェルを開き、次のコマンドを入力します。

$ heroku pg:psql
=> VACUUM;
WARNING:  skipping "pg_authid" --- only superuser can vacuum it
WARNING:  skipping "pg_database" --- only superuser can vacuum it
WARNING:  skipping "pg_tablespace" --- only superuser can vacuum it
WARNING:  skipping "pg_pltemplate" --- only superuser can vacuum it
WARNING:  skipping "pg_auth_members" --- only superuser can vacuum it
WARNING:  skipping "pg_shdepend" --- only superuser can vacuum it
WARNING:  skipping "pg_shdescription" --- only superuser can vacuum it
WARNING:  skipping "pg_db_role_setting" --- only superuser can vacuum it
VACUUM

表示される警告は予測されるものであり、無視できます。また、手動バキュームを必要とするテーブルが 1 つまたは 2 つだけの場合は、VACUUM​ を特定のテーブルに制限することもできます。

 $ heroku pg:psql
 => VACUUM users;
 VACUUM

VACUUM​ を実行する場合は、その進行状況に関するより詳細な情報を得るために VERBOSE​ キーワードを追加できます。

$ heroku pg:psql
d7lrq1eg4otc3i=> VACUUM VERBOSE;
INFO:  vacuuming "public.reviews"
INFO:  index "reviews_pkey" now contains 0 row versions in 1 pages
DETAIL:  0 index row versions were removed.
0 index pages have been deleted, 0 are currently reusable.
CPU 0.00s/0.00u sec elapsed 0.00 sec.
INFO:  index "reviews_user_index" now contains 0 row versions in 1 pages
DETAIL:  0 index row versions were removed.
0 index pages have been deleted, 0 are currently reusable.
CPU 0.00s/0.00u sec elapsed 0.00 sec.
INFO:  "users": found 0 removable, 0 nonremovable row versions in 0 out of 0 pages
DETAIL:  0 dead row versions cannot be removed yet.
There were 0 unused item pointers.
0 pages are entirely empty.
CPU 0.00s/0.00u sec elapsed 0.00 sec.
...
VACUUM

自動バキューム設定を慎重に管理すれば、手動バキュームが必要になることはめったにありませんが、その仕組みを理解しておくことが重要です。

関連カテゴリー

  • Postgres のパフォーマンス
高コストなクエリ Heroku Postgres のサーバー側接続プール

Information & Support

  • Getting Started
  • Documentation
  • Changelog
  • Compliance Center
  • Training & Education
  • Blog
  • Support Channels
  • Status

Language Reference

  • Node.js
  • Ruby
  • Java
  • PHP
  • Python
  • Go
  • Scala
  • Clojure
  • .NET

Other Resources

  • Careers
  • Elements
  • Products
  • Pricing
  • RSS
    • Dev Center Articles
    • Dev Center Changelog
    • Heroku Blog
    • Heroku News Blog
    • Heroku Engineering Blog
  • Twitter
    • Dev Center Articles
    • Dev Center Changelog
    • Heroku
    • Heroku Status
  • Github
  • LinkedIn
  • © 2025 Salesforce, Inc. All rights reserved. Various trademarks held by their respective owners. Salesforce Tower, 415 Mission Street, 3rd Floor, San Francisco, CA 94105, United States
  • heroku.com
  • Legal
  • Terms of Service
  • Privacy Information
  • Responsible Disclosure
  • Trust
  • Contact
  • Cookie Preferences
  • Your Privacy Choices