SELECT ลบแถวที่ตายแล้วเช่น VACUUM หรือไม่


9

ฉันเล่นซอVACUUMและสังเกตเห็นพฤติกรรมที่ไม่คาดคิดบางอย่างที่SELECTไอเอ็นจีแถวจากตารางดูเหมือนว่าจะลดงานที่VACUUMต้องทำหลังจากนั้น

ทดสอบข้อมูล

หมายเหตุ: autovacuum ถูกปิดใช้งาน

CREATE TABLE numbers (num bigint);
ALTER TABLE numbers SET (
  autovacuum_enabled = 'f',
  toast.autovacuum_enabled = 'f'
);

INSERT INTO numbers SELECT generate_series(1, 5000);

ทดลอง 1

ตอนนี้เราทำการอัพเดทในทุกแถว

UPDATE numbers SET num = 0;

และเมื่อเราวิ่งVACUUM (VERBOSE) numbers;เราได้

INFO:  vacuuming "public.numbers"
INFO:  "numbers": removed 5000 row versions in 23 pages
INFO:  "numbers": found 5000 removable, 5000 nonremovable row versions in 45 out of 45 pages
DETAIL:  0 dead row versions cannot be removed yet, oldest xmin: 6585
There were 0 unused item pointers.

ทดลอง 2

ตอนนี้เราออกอีกUPDATEอัน แต่คราวนี้เราเพิ่มอีกSELECTอัน

UPDATE numbers SET num = 1;
SELECT * FROM numbers;

และเมื่อเราวิ่งVACUUM (VERBOSE) numbers;เราได้

INFO:  vacuuming "public.numbers"
INFO:  "numbers": removed 56 row versions in 22 pages
INFO:  "numbers": found 56 removable, 5000 nonremovable row versions in 45 out of 45 pages
DETAIL:  0 dead row versions cannot be removed yet, oldest xmin: 6586
There were 56 unused item pointers.

เกิดอะไรขึ้นที่นี่กันแน่? ทำไมรุ่นที่สองผมทำงานหลังจากที่SELECTลบ tuples ตายจากหน้าเว็บที่เข้าชมค่อนข้างชอบVACUUMไม่?

ฉันใช้งาน Postgres 11.3 บน macOS 10.14.5


2
ไคลเอนต์ใดที่คุณใช้เพื่อเรียกใช้คำสั่งของคุณ? Autocommit เปิดใช้งานอยู่หรือไม่
mustaccio

2
ฉันจะลบคำถาม"ตาราง VACUUM โดยทั่วไปเพียงแค่เลือก * จากตารางด้านล่างประทุนหรือไม่" (ไม่ใช่) ฉันคิดว่ามันเป็นการติดตามที่ดีคำตอบที่นี่ก็คือ SELECT สามารถลบแถวที่ตายแล้วออกและมันแบ่งปันสิ่งนั้นร่วมกับ VACUUM ความแตกต่างของพวกเขาจะเป็นการสนทนาที่ละเอียดถี่ถ้วนเกี่ยวกับ XID แบบโรลโอเวอร์และอีกหลายสิ่ง คำถามนั้นก็คือ "สิ่งอื่น ๆ ที่สุญญากาศทำนอกจากลบแถวที่ตายแล้วออกไป" (ซึ่งจะเป็นชนิดของคลุมเครือ)
อีวานคาร์โรลล์

@ustaccio ฉันทำการทดสอบด้วยสคริปต์ Ruby โดยใช้ ActiveRecord ซึ่งใช้อัญมณี PG ภายใต้ประทุน ฉันเชื่อว่าการเปิดใช้งานการเติมข้อความอัตโนมัติจะเปิดใช้งานตามค่าเริ่มต้นเนื่องจากคุณไม่จำเป็นต้องออกคำสั่งใด ๆ ยกเว้นว่าจะใช้ BEGIN อย่างชัดเจน
rafbm

คำตอบ:


5

จากโพสต์นี้ใน / r / PostgreSQLถึงคำตอบโดย Laurenz Albeดูเหมือนว่าการอัปเดต Heap Only Tuples (HOT) อาจต้องรับผิดชอบ จากคำอธิบายของการอัปเดต HOT ในsrc/backend/access/heap/README.HOT

อย่างมีประสิทธิภาพการเรียกคืนพื้นที่เกิดขึ้นระหว่างการดึงข้อมูล tuple เมื่อหน้าเกือบเต็ม (ฟรี <10%) และสามารถล็อคการล้างบัฟเฟอร์ได้ ซึ่งหมายความว่าUPDATE, DELETEและSELECTสามารถทริกเกอร์การเรียกคืนพื้นที่ แต่มักจะไม่ได้อยู่ในช่วงINSERT ... VALUESเพราะไม่ได้เรียกแถว

คำพูดไม่ได้อยู่ในคำตอบเดิม แต่ส่วนที่เหลือเป็นคำพูด

เพื่อสนับสนุนหรือปฏิเสธทฤษฎีนี้ให้เรียกใช้แบบสอบถามต่อไปนี้:

SELECT n_tup_upd, n_tup_hot_upd
FROM pg_stat_user_tables
WHERE schemaname = 'public' AND relname = 'TABLE_NAME';

หากn_tup_hot_updมากกว่าศูนย์เราได้รับคดี


ตอนนี้เรากำลังพูดถึง +1
mustaccio

HOT น่าจะเป็นคำอธิบายที่ดี ถ้าผมเอาท์พุทสูญญากาศเปลี่ยนแปลงไปCREATE INDEX idx_numbers ON numbers USING btree (num) INFO: "numbers": removed 5000 row versions in 45 pagesอย่างไรก็ตามโปรดทราบว่าในสถานการณ์ที่มีดัชนีน้อยกว่าn_tup_hot_updจะมีค่าเป็น 0 เสมอทั้งระหว่าง UPDATE และ SELECT และระหว่าง SELECT และ VACUUM ฉันยังแน่ใจว่าทำงานSELECT pg_sleep(10)ระหว่างแต่ละคำสั่งเพื่อให้สถิติทันสมัย ​​(ฉันเห็นseq_scan: 2หนึ่งสำหรับการปรับปรุงและหนึ่งสำหรับการเลือก)
rafbm

ตัวเลือกสร้าง WAL ในกรณีนี้หรือไม่? ฉันอยู่ภายใต้การแสดงผลที่เลือกไม่ได้สร้าง WAL เลย ถ้าใช่นี่หมายความว่าการลบแถวที่ตายแล้วนั้นจะถูกแพร่กระจายไปยังทาสใด ๆ หากไม่แสดงว่าการดูดฝุ่นยังจำเป็นต่อทาส มันก็หมายความว่าเจ้านายและทาสไม่เหมือนกัน อืมฉันอาจต้องทำวิจัยและโพสต์คำถามและ / หรือคำตอบหรือสองข้อ
โคลิน 't ฮาร์ต

1

ในกรณีพิเศษของตารางที่ไม่ได้ทำดัชนีใช่ SELECT สามารถทำงานเหมือนกับ VACUUM (เท่าที่เกี่ยวข้องกับการลบแถวที่ไม่เกี่ยวข้อง)


3
คุณสามารถเพิ่มคำอธิบายได้ไหม?
Laurenz Albe
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.