TRUNCATEステートメントを使用してテーブルデータをクリーンアップしたり、DROP tableステートメントを使用してPostgreSQLデータベースのテーブルを削除したりすると、ディスク領域がすぐに解放されない場合があります。 このトピックでは、問題の原因について説明し、トラブルシューティングと解決策を提供します。
発生原因
PostgreSQLデータベースでTRUNCATEステートメントとDROP TABLEステートメントを実行すると、トランザクションのコミット時に削除するファイルごとにリンク解除呼び出しが開始されます。 リンク解除呼び出しは、ファイルとそのiノード間のリンクを削除します。 ただし、ファイルがプロセスによって開かれている間にリンクが解除された場合、ファイルデータはディスクに保持され、関連するディスクスペースはすぐには解放されません。 次のいずれかの条件が満たされた場合にのみ、ディスク容量を再利用します。
削除するファイルを開くすべてのプロセスが終了します。
削除されるファイルを開くプロセスでは、ファイルを閉じるためにファイル記述子 (fd) にクローズコールが行われます。
TRUNCATEおよびDROP tableステートメントが実行される前に接続がテーブルファイルにアクセスし、ステートメントが実行された後も接続がアイドル状態のままである場合、接続にはファイルへの参照が残っている可能性があります。 この場合、システムは関連するディスクスペースをすぐには再利用しません。
ソリューション
TRUNCATEまたはDROP TABLEステートメントの実行後にディスク領域が解放されない場合は、次の方法を使用して問題を解決できます。
ディスク領域を解放するデータベースへのすべてのアイドル接続を閉じます。
SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE state='idle' AND backend_type='client backend';
自己管理型データベースのディスク領域を解放する場合は、リンクされていないファイルを開いたプロセスを特定して終了する必要があります。
データベースのサーバーでlsofコマンドを実行して、削除されているがプロセスによってまだ開いているファイルを見つけます。
lsof + L1
次のSQL文を実行してプロセスを終了します。
SELECT pg_terminate_backend(pid);
pidは終了するセッションのプロセスIDを指定します。