web-dev-qa-db-ja.com

使用可能なディスク領域がない状態でVACUUM FULLを実行する必要がある

サーバーのhdスペースの90%近くを占める1つのテーブルがあります。スペースを空けるために、いくつかの列をドロップすることにしました。しかし、そのスペースをOSに戻す必要があります。ただし、問題は、VACUUM FULLを実行し、テーブルのコピーを作成するための十分な空き領域がない場合にどうなるかわからないことです。

VACUUM FULLを使用すべきではないことは理解していますが、このシナリオではそれが最良のオプションであると考えました。

任意のアイデアをいただければ幸いです。

PostgreSQL 9.0.6を使用しています

31
Justin

Vacummを実行したり再構築したりするための十分なスペースがないため、postgresqlデータベースを復元することでいつでも再構築できます。データベース、テーブル、インデックスを復元すると、スペースが解放され、最適化されます。その後、自動メンテナンスを設定して、定期的にデータベースを空にすることができます。

1 postgresqlサーバー上のすべてのデータベースをバックアップします

すべてのデータベースを、十分なスペースのあるパーティションにバックアップする必要があります。 Linuxを使用している場合は、gzipを使用してバックアップをさらに圧縮し、スペースを節約できます。

su - postgres
pg_dumpall | gzip -9 > /some/partition/all.dbs.out.gz

2設定ファイルをバックアップ

cp /path/to/postgresql/data_directory/*.conf /some/partition/

Postgresqlを停止

pg_ctl -D /path/to/postgresql/data_directory stop

4データディレクトリの内容を消去

rm -Rf /path/to/postgresql/data_directory/*

5 initdbを実行してデータディレクトリを再初期化します

initdb -D /path/to/postgresql/data_directory

6構成ファイルの復元

cp /some/partition/*.conf /path/to/postgresql/data_directory/*.conf 

7 Postgresqlを開始

pg_ctl -D /path/to/postgresql/data_directory start

8作成したすべてのデータベースのダンプを復元します

gunzip /some/partition/all.dbs.out.gz
psql -f /some/partition/all.dbs.out
20
Craig Efrein

注:これは9.1でテストしました。ここには9.0サーバーはありません。それは9.0でも動作しますが、私はpreeeetttyと確信しています。


[〜#〜]注意[〜#〜](@ernyのコメントに記載されています):

Note that high CPU load due to I/O operations may be expected.

一時テーブルスペースを使用することで、ほとんどダウンタイムなしでこれを行うことができます。ダウンタイムは排他ロックの形になります。しかし、あなたが掃除しているのはテーブルの上だけです。つまり、クライアントクエリは、問題のテーブルにアクセスする場合、ロックが取得されるのを単に待つだけですif。既存の接続を閉じる必要はありません。

ただし、テーブルとバキュームを完全に移動すると、最初に排他ロックを待機する必要があることに注意してください。


まず、明らかに追加のストレージが必要です。なので Stéphaneはコメントで言及されていますが、これは問題のテーブルの少なくとも2倍の大きさである必要がありますVACUUM FULLは完全なコピーを行います。運がよく、動的にディスクをマシンに追加できる場合は、それを行います。 最悪の場合、USBディスクを接続することができます(危険で遅いですが)!

次に、新しいデバイスをマウントし、テーブルスペースとして使用できるようにします。

CREATE TABLESPACE tempspace LOCATION '/path/to/new/folder';

以下を使用して、テーブルスペースを簡単にリストできます。

\db

テーブルの現在のテーブルスペースを再確認します(移動先を知っておく必要があります)。

SELECT tablespace FROM pg_tables WHERE tablename = 'mytable';

NULLの場合、デフォルトのテーブルスペースに配置されます。

SHOW default_tablespace;

thatNULLの場合もpg_default(変更された場合は 公式ドキュメント を確認してください)。

次に、テーブルを上に移動します。

ALTER TABLE mytable SET TABLESPACE tempspace;
COMMIT;  -- if autocommit is off

掃除機をかける:

VACUUM FULL mytable;

元に戻す:

-- assuming you are using the defaults, the tablespace will be "pg_default".
-- Otherwise use the value from the SELECT we did earlier.
ALTER TABLE mytable SET TABLESPACE pg_default;
COMMIT;  -- if autocommit is off

一時スペースを削除します。

DROP TABLESPACE tempspace;
18
exhuma

素早く汚い:

  • Postgresを停止する
  • メインデータベースディレクトリを、掃除機をかけるのに十分なスペースがある別のディスクに移動します。
  • Mainの元の場所に、シンボリックリンクを新しい場所に追加します
  • 真空
  • シンボリックリンクを削除し、メインディレクトリを元の場所に戻します
  • Postgresを起動する

例えば。、:

$ service postgresql stop $ mv /var/lib/postgresql/9.5/main /mnt/bigdisk $ ln -sr /mnt/bigdisk/main /var/lib/postgresql/9.5 $ vacuumdb --all --full $ rm /var/lib/postgresql/9.5/main $ mv /mnt/bigdisk/main /var/lib/postgresql/9.5 $ service postgresql start

3
Roger Dahl

ダンプと復元を行うためのディスク容量がある場合は、vacuumdb --fullを実行するためのディスク容量が必要です。問題は、vacuumdb --fullがデータファイル全体のコピーを作成することです。だから、あなたができることは:

  1. 巨大なテーブルを保持しているファイルを別のドライブ、たとえば低速で大きなドライブにコピーします。
  2. 元の場所から他のドライブの新しい場所へのシンボリックリンクを作成します。
  3. vacuumdb --fullを実行すると、もう一方のディスクからデータが読み込まれ、最終的なテーブルが元のデータディスクに書き込まれます。
0
Gunther