Saya memiliki instalasi lokal dari database 9.1 dengan beberapa tabel yang memiliki cca. 300 juta catatan dan basis data tumbuh sekitar 20 GB. Setelah itu saya mengeluarkan delete from
perintah untuk menghapus semua catatan dari itu (saya seharusnya menggunakan truncate
, tapi saya tidak tahu itu). Jadi saya melakukan vakum penuh pada db saya untuk merebut kembali ruang disk, tetapi itu tidak membantu. Masalah saya terlihat identik dengan yang satu ini , tetapi tidak ada solusi yang diberikan. Saya telah memeriksa utas ini dan dokumentasi tentang "memulihkan ruang disk" , tetapi masih tidak dapat menemukan solusi. Saya menggunakan kode ini untuk mendapatkan ukuran semua tabel
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;
Namun, totalnya kurang dari 1GB
SELECT pg_database.datname, pg_size_pretty(pg_database_size(pg_database.datname)) AS size FROM pg_database
masih menunjukkan sekitar 20 GB. Setiap saran sangat dihargai.
sumber
pg_catalog
, dan tabel diinformation_schema
. Jadi coba lihat apakah itu salah satunya dengan menghapus batasan-batasan dalamWHERE
klausa. Tolong tunjukkan versi PostgreSQL yang tepat (SELECT version()
) dan apa yang sebenarnya Anda lakukan untuk "menyedot database lengkap", yaitu perintah yang tepat. Jika memungkinkan, jalankanVACUUM FULL VERBOSE;
(tanpa argumen) dan tempel output di suatu tempat kemudian tautkan ke sini.Jawaban:
Meskipun Anda tidak menyatakannya, saya menganggap dari referensi Anda ke dokumen yang telah Anda ikuti bahwa Anda telah melakukan PENUH VACUUM pada database dan / atau tabel yang terpengaruh. Anda juga tidak menentukan versi postgresql apa yang Anda gunakan - Saya akan menganggap itu> 9.0 (VACUUM FULL berperilaku berbeda sebelum ini).
VACUUM FULL akan menulis ulang tabel yang terpengaruh ke file baru, lalu menghapus file lama. Namun, jika ada proses yang masih memiliki file lama terbuka, sistem operasi tidak akan benar-benar menghapus file - sampai proses terakhir telah menutupnya.
Jika praktis, me-restart database akan memastikan bahwa semua file yang terbuka ditutup.
Jika itu tidak praktis, maka Anda mungkin dapat memverifikasi apakah ini masalah Anda, dan mencari tahu proses mana yang membuka file.
Jika menggunakan Linux (atau sebagian besar sistem mirip Unix lainnya) Anda dapat menggunakan perintah 'lsof' untuk mendapatkan daftar semua file yang terbuka di semua proses. File yang terbuka tetapi yang sudah dihapus akan memiliki '(dihapus)' ditambahkan ke nama file. Jadi, Anda dapat menangkap output lsof, mencari file yang dihapus, seperti ini:
Jika itu mengidentifikasi proses yang masih membuka file lama, Anda dapat menggunakan pg_terminate_backend untuk mengakhiri proses itu:
di mana xxx adalah PID dari proses, ditemukan di output lsof.
Jika menggunakan Windows, prinsip yang sama dapat diterapkan, karena postgres membuka file menggunakan flag FILE_SHARE_DELETE, yang memungkinkannya untuk menghapus file yang terbuka di proses lain. Perintah ' handle ' adalah setara dengan lsof, walaupun saya tidak yakin apakah Anda dapat mengetahui apakah file-file tersebut dihapus atau tidak sehingga beberapa pekerjaan tambahan mungkin diperlukan.
Ini adalah pertanyaan lain mengapa proses seperti itu akan bergantung pada pegangan file lama. Namun dalam utas yang Anda kutip dalam pertanyaan Anda, Tom Lane tampaknya menyiratkan bahwa itu bisa terjadi.
sumber