web-dev-qa-db-ja.com

PostgreSQLのディスク領域を再利用する方法は?

9.1データベースのローカルインストールで、ccaがあったテーブルがほとんどありません。 300 mioレコードとデータベースは約20 GBに成長しました。その後、私はdelete fromコマンドを使用して、すべてのレコードを削除します(truncateを使用する必要がありましたが、それを知りませんでした)。したがって、ディスク領域を再利用するためにdbに完全なバキュームを実行しましたが、それでも効果がありません。私の問題は これ と同じに見えますが、解決策はありません。私はすでに this thread "recovering disk space"に関するドキュメントを確認しましたが、まだ解決策が見つかりません。このコードを使用してすべてのテーブルのサイズを取得します

 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;

ただし、合計で1 GB未満です。

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

まだ約20 GBを示しています。アドバイスは大歓迎です。

26
arcull

あなたはそれを述べていませんが、あなたが従ったドキュメントへの参照から、あなたはデータベースや影響を受けたテーブルで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とほぼ同じですが、ファイルが削除されているかどうかを確認できないため、追加の作業が必要になる場合があります。

なぜそのようなプロセスが古いファイルハンドルにぶら下がっているのかについての別の質問です。ただし、質問で引用した thread で、Tom Laneはそれが発生する可能性があることを示唆しているようです。

23
harmic