ฉันต้องเรียกใช้ VACUUM FULL โดยไม่มีพื้นที่ว่างในดิสก์


27

ฉันมีหนึ่งตารางที่ใช้พื้นที่เกือบ 90% ของ hd พื้นที่บนเซิร์ฟเวอร์ของเรา ฉันตัดสินใจที่จะวางคอลัมน์ไม่กี่คอลัมน์เพื่อเพิ่มพื้นที่ว่าง แต่ฉันต้องคืนพื้นที่ไปยังระบบปฏิบัติการ อย่างไรก็ตามปัญหาคือฉันไม่แน่ใจว่าจะเกิดอะไรขึ้นถ้าฉันเรียกใช้ VACUUM FULL และมีพื้นที่ว่างไม่เพียงพอที่จะทำสำเนาของตาราง

ฉันเข้าใจว่าไม่ควรใช้สูญญากาศเต็มรูปแบบ แต่ฉันคิดว่านี่เป็นตัวเลือกที่ดีที่สุดในสถานการณ์นี้

ความคิดใด ๆ ที่จะได้รับการชื่นชม

ฉันใช้ PostgreSQL 9.0.6

คำตอบ:


19

เนื่องจากคุณมีพื้นที่ไม่เพียงพอในการเรียกใช้ 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/

3 หยุด 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

1
ขอบคุณนี่คือสิ่งที่ฉันทำลงเอยด้วยความแตกต่างสองสามอย่าง ฉันทิ้งฐานข้อมูลหลังจากสำรองข้อมูล จากนั้นสร้างขึ้นใหม่และเรียกคืน
จัสติน

ไม่เป็นไร ฉันคิดว่าการลบเนื้อหาของไดเรกทอรีข้อมูลและการทำ initdb น่าจะเพียงพอแล้ว
Craig Efrein

ทำงานได้ดีฉันแค่แนะนำให้ข้ามgzipส่วนนี้เพื่อประหยัดเวลา
Rafael Barbosa

17

หมายเหตุ: ฉันได้ทดสอบสิ่งนี้ใน 9.1 ฉันไม่มีเซิร์ฟเวอร์ 9.0 วางอยู่แถวนี้ ฉัน preeeettty แน่ใจว่ามันจะทำงานบน 9.0 แม้ว่า


ข้อควรระวัง (ตามที่ระบุไว้ในความคิดเห็นโดย @erny):

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

คุณสามารถทำได้โดยไม่ต้องหยุดทำงานโดยใช้พื้นที่ตารางชั่วคราว เวลาหยุดทำงานจะอยู่ในรูปของการล็อคแบบเอกสิทธิ์ แต่เฉพาะบนโต๊ะที่คุณกำลังดูดฝุ่น ดังนั้นสิ่งที่จะเกิดขึ้นก็คือการสอบถามลูกค้าจะรอให้ได้รับการล็อคหากพวกเขาเข้าถึงตารางที่เป็นปัญหา คุณไม่จำเป็นต้องปิดการเชื่อมต่อที่มีอยู่

สิ่งหนึ่งที่ต้องระวังคือการย้ายโต๊ะและสูญญากาศเต็มจะต้องรอการล็อคพิเศษก่อน!


ก่อนอื่นคุณต้องมีที่เก็บข้อมูลเพิ่มเติม ในฐานะที่เป็นStéphaneที่กล่าวถึงในความคิดเห็นที่ตอบสนองความต้องการนี้จะมีอย่างน้อยสองครั้งเป็นใหญ่เป็นตารางในคำถามเป็นVACUUM FULLไม่ฉบับเต็ม หากคุณโชคดีและสามารถเพิ่มดิสก์ในเครื่องได้ให้ทำเช่นนั้น ในกรณีที่เลวร้ายที่สุดคุณเพียงแค่แนบดิสก์ USB (เสี่ยงและช้า)!

ถัดไปติดตั้งอุปกรณ์ใหม่และทำให้พร้อมใช้งานเป็น tablespace:

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

คุณสามารถแสดงรายการพื้นที่ตารางได้อย่างง่ายดายโดยใช้:

\db

ตรวจสอบพื้นที่ตารางปัจจุบันของตารางของคุณอีกครั้ง (คุณจำเป็นต้องทราบว่าจะย้ายกลับไปที่ใด):

SELECT tablespace FROM pg_tables WHERE tablename = 'mytable';

หากเป็นNULLเช่นนั้นจะอยู่ในพื้นที่ตารางเริ่มต้น:

SHOW default_tablespace;

ถ้าว่าเป็นNULLเช่นกันก็มีแนวโน้มที่จะ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;

หมายเหตุ: การย้ายดูเหมือนจะใช้พื้นที่ดิสก์มากขึ้นในไดเรกทอรีข้อมูลเดิม ...
คริสวิเธอร์ส

เพิ่งทดสอบใน 9.3 และใช้งานได้อย่างมีเสน่ห์
Bartek Jablonski

ใช้สำเร็จในการผลิตใน 9.1 หลังจากเปลี่ยน tablespace แล้วพื้นที่ใช้งานเดิมจะถูกปล่อยออกมา โปรดทราบว่าอาจมีการโหลด CPU สูงเนื่องจากการดำเนินการ I / O อาจเป็นไปได้
erny

2
เคล็ดลับที่น่าทึ่งขอบคุณสำหรับการอธิบายอย่างละเอียด โปรดทราบว่าในพื้นที่ตารางชั่วคราวคุณจะต้องใช้อย่างน้อยsize of table x 2เนื่องจากVACUUM FULLจะทำสำเนาตารางแบบเต็ม
Stéphane

ขอบคุณ @ Stéphane ฉันเพิ่มข้อมูลไปยังเนื้อหาหลัก
exhuma

2

รวดเร็วและสกปรก:

  • หยุด Postgres
  • ย้ายไดเรกทอรีฐานข้อมูลหลักไปยังดิสก์อื่นที่มีพื้นที่เพียงพอสำหรับการดูดฝุ่น
  • ในตำแหน่งเดิมของ main ให้เพิ่ม symlink ไปยังตำแหน่งใหม่
  • สูญญากาศ
  • ลบ symlink และย้ายไดเรกทอรีหลักกลับไปที่ตำแหน่งเดิม
  • เริ่ม 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


0

หากคุณมีพื้นที่ดิสก์ที่จะทำการถ่ายโอนข้อมูลและเรียกคืนคุณควรมีพื้นที่ดิสก์ที่จะทำ vacuumdb --full ปัญหาคือสูญญากาศ - เต็มจะทำสำเนาของไฟล์ข้อมูลทั้งหมด ดังนั้นสิ่งที่คุณสามารถทำได้คือ:

  1. คัดลอกไฟล์ที่เก็บตารางขนาดใหญ่ไปยังไดรฟ์อื่นตัวอย่างเช่นไดรฟ์ที่ช้ากว่าและใหญ่กว่า
  2. สร้างลิงก์สัญลักษณ์จากตำแหน่งดั้งเดิมไปยังตำแหน่งใหม่บนไดรฟ์อื่น
  3. เรียกใช้ vacuumdb - เต็มตอนนี้ควรอ่านข้อมูลจากดิสก์อื่นและเขียนตารางสุดท้ายลงในดิสก์ข้อมูลดั้งเดิมของคุณ
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.