バキューム/オートバキューム操作にはどれくらい時間がかかりますか?


18

私は、さまざまなロールを持つテーブルを含む大きな(数百ギグの)データベースを管理しており、その中には数百万のレコードを保持しているものもあります。いくつかのテーブルは、多数の挿入と削除のみを受け取り、他のいくつかの挿入と多数の更新のみを受け取ります。

データベースは、16ギガバイトのRAMを備えたDebian 6.0 amd64システム上のPostgreSQL 8.4で実行されます。

質問は、テーブル上の自動バキュームプロセスであり、完了するまでに非常に長い時間(日)かかります。特定のバキュームコマンドにかかる時間を大まかに伝えて、キャンセルするかどうかを判断できるようにしたいと思います。また、postgresバキューム操作の進行状況インジケーターがある場合、それは本当に役立ちます。

編集:

私は防弾ソリューションを探していません。デッドタプルまたは必要なI / Oバイトの数についての大まかなヒントで十分です。いつVACUUM終了するかわからないのは本当に迷惑です。

pg_catalog.pg_stat_all_tablesデッドタプルの数の列があることを見てきました。そのためANALYZE、前にテーブルにアクセスする必要がある場合でも、見積もりを行うことができます。一方、autovacuum_vacuum_thresholdおよびautovacuum_vacuum_scale_factor設定だけではpostgres自身があることを証明知っているテーブル上の変化量について何かを、おそらくあまりにもDBAの手にそれを置きます。

実行するクエリがVACUUM VERBOSEわかりません。実行すると、テーブルだけでなくインデックスも処理されていることがわかります。

回答:


34

PostgreSQL(8.3)では、次のトリックを使用します。

  1. を使用してテーブルのディスクサイズを取得しますpg_total_relation_size()-これには、インデックスとTOASTサイズが含まれ、これがVACUUM処理されます。これにより、VACUUM読み取りが必要なバイト数がわかります。
  2. VACUUMテーブルの上で走ります。
  3. 私は見つけるpidVACUUMプロセス(中にpg_catalog.pg_stat_activity)。
  4. Linuxシェルで実行しますwhile true; do cat /proc/123/io | grep read_bytes; sleep 60; done123pidはどこにあります)-これは、プロセスがこれまでにディスクから読み取ったバイト数を示しています。

これにより、によって毎分処理される(読み取られる)バイト数に関する大まかなアイデアが得られますVACUUMVACUUM手順1でディスクサイズがわかっているテーブル全体(インデックスとTOASTを含む)を読み取る必要があると思います。

テーブルはページの大部分をディスクから読み取る必要があるため(Postgres共有メモリには存在しないため)、テーブルは十分に大きく、read_bytesフィールドは進捗カウンターとして使用するのに十分であると思います。

私がこれを行うたびに、プロセスによって読み取られた合計バイトは合計リレーションサイズの5%未満であったため、このアプローチで十分であると思われます。


意地の悪い:)これは後のバージョンでも動作しますか?そして、さらに重要なことは、自動バキュームのためですか?
-dezso

新しいバージョンでは試していません。VACUUM FULLテーブルを完全に書き換えるので、9.0 +で動作するはずです。通常のVACUUM場合でも動作するはずですが、まだテストしていません。autovacuumあなたが与えられたテーブルの上に自動バキュームワーカープロセスをキャッチすることができましたならば、それは動作しますが、私はこれを達成する方法がわかりません。
ロマンホッケ

RDSでこれを達成する方法について何か提案はありますか?当然、RDSを使用する場合、Linuxシェルにアクセスすることはできませんが、これも同様に見積もることができます。
jwg2s

@ jwg2s「RDS」とはどういう意味ですか?Amazonのデータベースサービス?もしそうなら、私は残念ながら、それに慣れていないよ:-(たぶん彼らのサポートが役立つだろう。
ローマHocke

1
PG 10でバキュームがいっぱいの場合でもうまく機能するようです。
DylanYoung

9

これを判断するのは非常に困難です。自動バキューム調整して、より積極的または穏やかにできます。しかし、マイルドに設定され、遅れており、ベースI / Oの負荷が高すぎると、適切なバキューム状態に到達しないことがあります。プロセスが実行され、実行され、実行されていることがわかります。さらに、後のPostreSQLエディションではautovacuum機能が大幅に改善されており、これだけでそのうちの1つ(できれば最新の9.2)に移行するのに十分な場合があります。

プログレスバーは良いアイデアに聞こえますが、意味のある実装はそれほど簡単ではないと思います。テーブルに一定の負荷がかかっているため、進行状況が明らかに逆行している可能性があります(つまり、デッドローカウント/パーセンテージが減少するのではなく増加することを意味します)。


2
何もしないのではなく、後方に進んでも、何らかの進行状況インジケーターを表示することを好みます。
-zaadeh

3
VACUUM ANALYZE VERBOSE少なくとも、何らかのアクティビティをコンソールに出力します。静的なプロンプトをじっと見つめて、何かが何時間も動かなくなっているのではないかと考えた方が良いでしょう。
偽の名前

質問は「真空/自動真空」について尋ねます。上記はVACUUMautovacuumではなくにのみ有用ですが、それでも何かです。
偽の名前

@FakeNameええ、私は質問を読み違えました-手動真空部分を見逃しました。申し訳ありませんが、コメントを削除しています。
-dezso

3

本番環境では、最大のテーブルの1つにこのログがありました。

pages: 0 removed, 1801722 remain
tuples: 238912 removed, 42582083 remain, 1396 are dead but not yet removable
buffer usage: 9477565 hits, 3834218 misses, 2220101 dirtied
avg read rate: 2.976 MB/s, avg write rate: 1.723 MB/s
system usage: CPU 68.47s/177.49u sec elapsed 10065.08 sec

これは間違いなく最悪のリソース消費であり、他のすべてのテーブルの所要時間は2秒未満です。

これらのタイプのログを表示するには、これを実行する必要があります。

alter system set log_autovacuum_min_duration TO 5; 

(5ミリ秒)、構成ファイルを再読み込みします。


3

私が見つかりました。この記事この記事が役立ちますが、他の人が言及したように、プロセスは、いくつかの別々の操作を必要とするので、真空の全体的な進捗状況を計算するのが困難な場合があります。

このクエリを使用して、バキュームのテーブルスキャンの進行状況を監視します。

SELECT heap_blks_scanned/cast(heap_blks_total as numeric)*100 as heap_blks_percent, progress.*, activity.query
FROM pg_stat_progress_vacuum AS progress
INNER JOIN pg_stat_activity AS activity ON activity.pid = progress.pid;

ただし、これにはインデックススキャンは含まれません。インデックススキャンは後で行われ、大量のインデックスがある場合は、長くないにしても同じくらい時間がかかります。残念ながら、インデックススキャン/バキュームを監視する方法はありません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.