VACUUM FULL
ที่จะกลับพื้นที่ในการปฏิบัติการการใช้ VACUUM FULL ANALYZE
ในขณะที่ถูกที่มันฉันคิดว่าคุณเรียก ฉันพูดคู่มือ :
FULL
เลือกสูญญากาศ "เต็ม" ซึ่งสามารถเรียกคืนพื้นที่เพิ่มเติมแต่ใช้เวลานานกว่าและล็อคตารางโดยเฉพาะ วิธีนี้ยังต้องการพื้นที่ดิสก์เพิ่มเติมเนื่องจากจะเขียนสำเนาใหม่ของตารางและไม่ปล่อยสำเนาเก่าจนกว่าการดำเนินการจะเสร็จสมบูรณ์ โดยปกติควรใช้สิ่งนี้เฉพาะเมื่อจำเป็นต้องเรียกคืนพื้นที่จำนวนมากจากภายในตาราง
ฉันเน้นตัวหนา
CLUSTER
ประสบความสำเร็จเช่นกันในฐานะที่เป็นหลักประกัน
ธรรมดาVACUUM
ไม่บรรลุเป้าหมายของคุณ ( "หนึ่งหน้าขึ้นไปที่ท้ายตารางโดยสิ้นเชิง" ) มันไม่ได้เรียงลำดับของแถวใหม่และจะตัดเฉพาะหน้าที่ว่างเปล่าจากจุดสิ้นสุดทางกายภาพของไฟล์เมื่อมีโอกาสเกิดขึ้น - เช่นคำพูดของคุณจากคู่มือแนะนำ
คุณสามารถรับหน้าว่างในตอนท้ายของฟิสิคัลไฟล์เมื่อคุณINSERT
แบทช์ของแถวและDELETE
พวกมันก่อนที่จะมีการเพิ่ม tuples อื่น ๆ หรืออาจเกิดขึ้นโดยบังเอิญหากมีการลบแถวออกมากพอ
นอกจากนี้ยังมีการตั้งค่าพิเศษที่อาจป้องกันไม่ให้VACUUM FULL
เรียกคืนพื้นที่ ดู:
เตรียมหน้าว่างที่ท้ายตารางเพื่อทำการทดสอบ
คอลัมน์ระบบctid
แสดงถึงตำแหน่งทางกายภาพของแถว คุณต้องเข้าใจคอลัมน์นั้น:
เราสามารถทำงานกับมันและเตรียมตารางโดยการลบแถวทั้งหมดออกจากหน้าสุดท้าย:
DELETE FROM tbl t
USING (
SELECT (split_part(ctid::text, ',', 1) || ',0)')::tid AS min_tid
, (split_part(ctid::text, ',', 1) || ',65535)')::tid AS max_tid
FROM tbl
ORDER BY ctid DESC
LIMIT 1
) d
WHERE t.ctid BETWEEN d.min_tid AND d.max_tid;
ตอนนี้หน้าสุดท้ายว่างเปล่า สิ่งนี้จะละเว้นการเขียนพร้อมกัน ไม่ว่าคุณจะเป็นคนเดียวที่เขียนลงในตารางนั้นหรือคุณจำเป็นต้องล็อคการเขียนเพื่อหลีกเลี่ยงสัญญาณรบกวน
แบบสอบถามได้รับการปรับให้เหมาะสมเพื่อระบุแถวที่มีคุณสมบัติได้อย่างรวดเร็ว จำนวนที่สองของ a tid
คือดัชนี tuple ที่เก็บไว้เป็น unsigned int2
และ65535
เป็นค่าสูงสุดสำหรับประเภทนั้น ( 2^16 - 1
) ดังนั้นนั่นจึงเป็นขอบเขตที่ปลอดภัย
SQL Fiddle (การใช้ตารางอย่างง่ายจากกรณีอื่น)
เครื่องมือในการวัดขนาดแถว / ตาราง:
ดิสก์เต็ม
คุณต้องมีพื้นที่เลื้อยบนดิสก์สำหรับการดำเนินการใด ๆ เหล่านี้ นอกจากนี้ยังมีเครื่องมือที่ชุมชนpg_repack
แทน/VACUUM FULL
CLUSTER
มันหลีกเลี่ยงการล็อคพิเศษ แต่ต้องการพื้นที่ว่างในการทำงานด้วยเช่นกัน คู่มือ:
ต้องการพื้นที่ว่างในดิสก์ใหญ่เป็นสองเท่าของตารางเป้าหมายและดัชนี
เป็นทางเลือกสุดท้ายคุณสามารถเรียกใช้รอบการถ่ายโอนข้อมูล / เรียกคืน ซึ่งจะลบ Bloat ทั้งหมดออกจากตารางและดัชนีด้วย คำถามที่เกี่ยวข้องอย่างใกล้ชิด:
คำตอบตรงนั้นค่อนข้างรุนแรง หากสถานการณ์ของคุณอนุญาต (ไม่มีคีย์ต่างประเทศหรือการอ้างอิงอื่นป้องกันการลบแถว) และไม่มีการเข้าถึงตารางพร้อมกัน) คุณสามารถ:
ดัมพ์ตารางไปยังดิสก์ที่เชื่อมต่อจากคอมพิวเตอร์ระยะไกลที่มีพื้นที่ดิสก์มากมาย ( -a
สำหรับ--data-only
):
จากรีโมตเชลล์ข้อมูลดัมพ์ตาราง:
pg_dump -h <host_name> -p <port> -t mytbl -a mydb > db_mytbl.sql
ในเซสชัน pg TRUNCATE
ตาราง:
-- drop all indexes and constraints here for best performance
TRUNCATE mytbl;
จากเปลือกระยะไกลเรียกคืนไปยังตารางเดียวกัน:
psql -h <host_name> -p <port> mydb -f db_mytbl.sql
-- recreate all indexes and constraints here
ตอนนี้ไม่มีแถวหรือ bloat ที่ตายแล้ว
แต่บางทีคุณอาจมีที่ง่ายกว่า?
คุณสามารถเพิ่มเนื้อที่ว่างในดิสก์ได้โดยการลบ (ย้าย) ไฟล์ที่ไม่เกี่ยวข้องหรือไม่?
คุณสามารถVACUUM FULL
เล็กลงตารางแรกทีละคนดังนั้นเนื้อที่ว่างบนดิสก์เพียงพอหรือไม่
คุณสามารถเรียกใช้REINDEX TABLE
หรือREINDEX INDEX
เพิ่มพื้นที่ดิสก์จากดัชนีป่องได้หรือไม่
สิ่งที่คุณทำไม่เป็นผื่น หากมีข้อสงสัยให้สำรองข้อมูลทุกอย่างไปยังสถานที่ปลอดภัยก่อน