Saya perlu menjalankan VACUUM FULL tanpa ruang disk yang tersedia

27

Saya punya satu meja yang mengambil hampir 90% ruang hd di server kami. Saya telah memutuskan untuk menjatuhkan beberapa kolom untuk membebaskan ruang. Tapi saya perlu mengembalikan ruang ke OS. Masalahnya, bagaimanapun, adalah bahwa saya tidak yakin apa yang akan terjadi jika saya menjalankan VACUUM FULL dan tidak ada cukup ruang kosong untuk membuat salinan tabel.

Saya mengerti bahwa VACUUM FULL tidak boleh digunakan tetapi saya pikir itu adalah pilihan terbaik dalam skenario ini.

Setiap ide akan dihargai.

Saya menggunakan PostgreSQL 9.0.6

Justin
sumber

Jawaban:

19

Karena Anda tidak memiliki cukup ruang untuk menjalankan vacumm atau membangun kembali, Anda selalu dapat membangun kembali database postgresql Anda dengan mengembalikannya. Mengembalikan basis data, tabel, indeks akan membebaskan ruang dan defragment. Setelah itu, Anda dapat mengatur pemeliharaan otomatis untuk mengosongkan basis data Anda secara teratur.

1 Cadangkan semua database di server postgresql Anda

Anda ingin mencadangkan semua basis data Anda ke partisi yang memiliki cukup ruang. Jika Anda menggunakan Linux, Anda dapat menggunakan gzip untuk mengompres cadangan lebih lanjut untuk menghemat ruang

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

2 Cadangkan file konfigurasi Anda

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

3 Hentikan Postgresql

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

4 hapus isi direktori data

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

5 Jalankan initdb untuk menghidupkan kembali direktori data Anda

initdb -D /path/to/postgresql/data_directory

6 Kembalikan file konfigurasi

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

7 Mulai Postgresql

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

8 Kembalikan dump semua database yang Anda buat

gunzip /some/partition/all.dbs.out.gz
psql -f /some/partition/all.dbs.out
Craig Efrein
sumber
1
Terima kasih, inilah yang akhirnya saya lakukan, dengan beberapa perbedaan. Saya baru saja menjatuhkan basis data setelah mencadangkannya. Kemudian buat yang baru dan mengembalikannya.
Justin
Sama-sama. Saya pikir menghapus isi direktori data dan melakukan initdb sudah cukup.
Craig Efrein
Bekerja dengan baik, saya hanya merekomendasikan melewatkan gzipbagian untuk menghemat waktu.
Rafael Barbosa
17

CATATAN: Saya telah menguji ini pada 9.1. Saya tidak memiliki server 9.0 di sini. Saya sedikit yakin meskipun itu akan bekerja pada 9.0 sekalipun.


HATI-HATI (Sebagaimana dicatat dalam komentar oleh @erny):

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

Anda dapat melakukan ini dengan tidak ada down-time dengan menggunakan tablespace sementara. Waktu henti akan berupa kunci eksklusif. Tetapi hanya di atas meja Anda menyedot debu. Jadi semua yang akan terjadi adalah bahwa permintaan klien hanya akan menunggu kunci diperoleh jika mereka mengakses tabel tersebut. Anda tidak perlu menutup koneksi yang ada.

Satu hal yang perlu diperhatikan, adalah menggerakkan meja dan ruang hampa sendiri perlu menunggu kunci eksklusif terlebih dahulu!


Pertama, Anda jelas membutuhkan penyimpanan tambahan. Seperti Stéphanedisebutkan dalam komentar, ini harus setidaknya dua kali lebih besar dari tabel yang dimaksud seperti VACUUM FULLhalnya salinan lengkap. Jika Anda beruntung dan secara dinamis dapat menambahkan disk ke mesin, lakukan itu. Dalam kasus terburuk Anda hanya dapat memasang disk USB (berisiko dan lambat)!

Selanjutnya, pasang perangkat baru dan buat tersedia sebagai tablespace:

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

Anda dapat membuat daftar tablespace dengan mudah menggunakan:

\db

Periksa kembali tablespace tablespace Anda saat ini (Anda perlu tahu ke mana harus memindahkannya kembali):

SELECT tablespace FROM pg_tables WHERE tablename = 'mytable';

Jika itu NULL, itu akan berada di tablespace default:

SHOW default_tablespace;

Jika itu adalah NULLjuga, kemungkinan akan pg_default(memeriksa dokumen resmi dalam kasus itu berubah).

Sekarang pindahkan meja:

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

Vakum itu:

VACUUM FULL mytable;

Pindahkan kembali:

-- 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

Hapus ruang sementara:

DROP TABLESPACE tempspace;
exhuma
sumber
NB: langkah ini tampaknya menggunakan lebih banyak ruang disk dalam direktori data asli ...
Chris Withers
Hanya mengujinya di 9.3 dan bekerja seperti pesona.
Bartek Jablonski
Berhasil digunakan dalam produksi pada 9.1. Setelah mengubah tablespace ruang yang digunakan asli dirilis. Perhatikan bahwa beban CPU yang tinggi karena operasi I / O mungkin diharapkan.
erny
2
Kiat yang luar biasa, terima kasih atas penjelasan terperinci ini. Perhatikan bahwa pada tablespace sementara Anda setidaknya membutuhkan size of table x 2, karena VACUUM FULLmembuat salinan tabel secara penuh.
Stéphane
Terima kasih @ Stéphane. Saya menambahkan informasi ke badan utama.
exhuma
2

Cepat dan kotor:

  • Hentikan Postgres
  • Pindahkan direktori database utama ke disk lain di mana ada cukup ruang untuk menyedot debu
  • Di lokasi asli utama, tambahkan symlink ke lokasi baru
  • Kekosongan
  • Hapus symlink dan pindahkan direktori utama kembali ke lokasi aslinya
  • Mulai Postgres

Misalnya,:

$ 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

Roger Dahl
sumber
0

Jika Anda memiliki ruang disk untuk melakukan dump dan restore, Anda harus memiliki ruang disk untuk melakukan vacuumdb --full. Masalahnya adalah bahwa vacuumdb --full akan membuat salinan dari seluruh file data. Jadi, yang bisa Anda lakukan adalah:

  1. salin file yang memegang meja besar ke drive yang berbeda, misalnya, drive yang lebih lambat, lebih besar.
  2. buat tautan simbolis dari lokasi asli ke tempat baru di drive lain.
  3. jalankan vacuumdb --full, sekarang seharusnya membaca data dari disk lain, dan tulis tabel akhir ke disk data asli Anda.
Gunther
sumber