PostgreSQLでディスク領域を再利用するにはどうすればよいですか?


25

私はccaを持っていたいくつかのテーブルを持つ9.1データベースのローカルインストールを持っています。300のmioレコードとデータベースは約20 GBに成長しました。その後、delete fromすべてのレコードを削除するコマンドを発行しました(使用する必要がありましたがtruncate、それを知りませんでした)。だから、ディスク領域を再利用するためにdbを完全に空にしましたが、それはまったく役に立ちません。私の問題はこれと同じように見えますが、解決策は提供されていません。私はすでにこのスレッド「ディスク領域の回復」に関するドキュメントをチェックしましたが、それでも解決策が見つかりません。このコードを使用して、すべてのテーブルのサイズを取得します

 SELECT nspname || '.' || relname AS "relation",
 pg_size_pretty(pg_total_relation_size(C.oid)) AS "total_size"
 FROM pg_class C
 LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
 WHERE nspname NOT IN ('pg_catalog', 'information_schema')
 AND C.relkind <> 'i'
 AND nspname !~ '^pg_toast'
 ORDER BY pg_total_relation_size(C.oid) DESC
 LIMIT 15;

ただし、合計で1GB未満

SELECT pg_database.datname, pg_size_pretty(pg_database_size(pg_database.datname)) AS size FROM pg_database 

それでも約20 GBが表示されます。アドバイスをいただければ幸いです。


さて、サイズクエリは除外します:インデックス、テーブルpg_catalog、およびテーブルinformation_schema。そのため、WHERE句の制限を削除して、それらのいずれかであるかどうかを確認してください。正確なPostgreSQLバージョン(SELECT version())と「データベース全体をバキュームする」ために正確に何をしているか、つまり正確なコマンドを表示してください。可能であれば、VACUUM FULL VERBOSE;(引数なしで)実行し、出力をどこかに貼り付けてから、ここにリンクします。
クレイグリンガー14年

データベースを削除してみてください。また、データベースをダンプしてから復元すると、ガベージが削除されます。
jb。

1
@jbうまくいきますが、必要ではありません。問題が何であるかを学ぶ方が良い。
クレイグリンガー14年

回答:


22

あなたはそれを述べていませんでしたが、私があなたが従ったドキュメントへの参照から、あなたはデータベースおよび/または影響を受けたテーブルでVACUUM FULLをしたと仮定します。また、使用しているpostgresqlのバージョンも指定しませんでした-9.0よりも大きいと仮定します(この前は、VACUUM FULLの動作が異なりました)。

VACUUM FULLは、影響を受けるテーブルを新しいファイルに書き換え、古いファイルを削除します。ただし、いずれかのプロセスがまだ古いファイルを開いている場合、オペレーティングシステムは実際にファイルを削除しません-最後のプロセスがファイルを閉じるまで。

実用的な場合、データベースを再起動すると、開いているファイルがすべて閉じられます。

それが実用的でない場合、これが問題であるかどうかを確認し、どのプロセスがファイルを開いているかを調べることができるかもしれません。

Linux(または他のほとんどのUnixライクなシステム)を使用している場合、「lsof」コマンドを使用して、すべてのプロセスで開いているすべてのファイルのリストを取得できます。開いているが、その後削除されたファイルには、ファイル名に「(削除済み)」が追加されます。したがって、次のように、lsofの出力をgrepして、削除されたファイルを探すことができます。

sudo lsof -u postgres | grep 'deleted'

古いファイルがまだ開いているプロセスを特定する場合、pg_terminate_backendを使用してそのプロセスを終了できます。

SELECT pg_terminate_backend(xxx);

ここで、xxxはlsof出力にあるプロセスのPIDです。

Windowsを使用している場合、postgresはFILE_SHARE_DELETEフラグを使用してファイルを開き、別のプロセスで開いているファイルを削除できるため、同じ原則を適用できます。' handle 'コマンドはlsofとほぼ同じですが、ファイルが削除されているかどうかを確認できるかどうかわかりませんが、追加の作業が必要になる場合があります。

これは、そのようなプロセスが古いファイルハンドルに依存する理由に関する別の質問です。しかし、質問で引用したスレッドでは、Tom Laneはそれが起こる可能性があることを暗示しているようです。


緊急にディスク領域を取り戻す必要があったため、データベースを削除し、バックアップから復元しました。ただし、この問題を解決する「方法」は、将来のケースにとって非常に貴重です。私のデータベースは9.1で、勝つ8 64ビットですが、ファイルの命名(開いているファイルの場合)はLinuxと同じ方法で適用されますか?

@arcull OK、Windowsを使用していることに気づきませんでした。これがWindowsにどのように適用されるかについての回答に情報を追加しました。役に立つ答えだと思われる場合は、他の人が見つけやすくなるため、賛成を検討してください。
害14年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.