ไม่มีระเบียนที่เชื่อถือได้และเชื่อถือได้ของเวลาที่แก้ไขล่าสุดของตาราง การใช้ relfilenode นั้นผิดด้วยเหตุผลหลายประการ:
ตอนแรกการเขียนจะถูกบันทึกลงในบันทึกการเขียนหัว (WAL) จากนั้นก็ขี้เกียจไปที่ฮีป (ไฟล์ตาราง) เมื่อเร็กคอร์ดอยู่ใน WAL แล้ว Pg ก็ไม่รีบเร่งที่จะเขียนมันไปยังกองและมันอาจจะไม่ถูกเขียนจนกว่าจะถึงด่านต่อไป
ตารางที่ใหญ่กว่ามีส้อมหลายอันคุณต้องตรวจสอบส้อมทั้งหมดและเลือกการประทับเวลาใหม่ล่าสุด
วิSELECT
สามารถสร้างกิจกรรมการเขียนไปยังตารางพื้นฐานเนื่องจากการตั้งค่า hint-bit;
autovaccum และการบำรุงรักษาอื่น ๆ ที่ไม่ได้เปลี่ยนข้อมูลที่ผู้ใช้มองเห็นยังคงแก้ไขไฟล์ความสัมพันธ์;
การดำเนินการบางอย่างเช่นvaccum full
จะแทนที่ relfilenode อาจไม่ใช่ที่ที่คุณคาดหวังหากคุณพยายามมองมันไปพร้อม ๆ กันโดยไม่ต้องล็อคที่เหมาะสม
ตัวเลือกน้อย
หากคุณไม่จำเป็นต้องมีความน่าเชื่อถือคุณอาจจะสามารถใช้ข้อมูลในและpg_stat_database
pg_stat_all_tables
สิ่งเหล่านี้สามารถให้เวลาคุณในการรีเซ็ตสถิติล่าสุดและสถิติกิจกรรมนับตั้งแต่มีการรีเซ็ตสถิติล่าสุด ไม่ได้บอกคุณว่ากิจกรรมล่าสุดเกิดขึ้นเมื่อใดนับตั้งแต่มีการรีเซ็ตสถิติครั้งล่าสุดและไม่มีข้อมูลเกี่ยวกับสิ่งที่เกิดขึ้นก่อนที่จะมีการรีเซ็ตสถิติ ดังนั้นมันจึงมี จำกัด แต่ก็มีอยู่แล้ว
ทางเลือกหนึ่งสำหรับการทำอย่างน่าเชื่อถือคือการใช้ทริกเกอร์เพื่ออัปเดตตารางที่มีเวลาที่แก้ไขล่าสุดสำหรับแต่ละตาราง โปรดทราบว่าการทำเช่นนี้จะทำให้การเขียนทั้งหมดเป็นแบบอนุกรมลงในตารางทำลายการเกิดพร้อมกัน นอกจากนี้ยังจะเพิ่มค่าใช้จ่ายที่เป็นธรรมในทุกธุรกรรม ฉันไม่แนะนำ
ทางเลือกที่น่ากลัวเล็กน้อยน้อยคือการใช้และLISTEN
NOTIFY
มีกระบวนการ daemon ภายนอกเชื่อมต่อกับ PostgreSQL และLISTEN
สำหรับเหตุการณ์ ใช้ON INSERT OR UPDATE OR DELETE
ทริกเกอร์เพื่อส่งNOTIFY
s เมื่อตารางเปลี่ยนแปลงโดยมีตาราง oid เป็น payload แจ้งเตือน สิ่งเหล่านี้จะถูกส่งเมื่อมีการทำธุรกรรม ภูตของคุณสามารถสะสมการแจ้งเตือนการเปลี่ยนแปลงและขี้เกียจเขียนกลับไปที่ตารางในฐานข้อมูล หากระบบขัดข้องคุณจะสูญเสียการบันทึกการแก้ไขล่าสุด แต่ก็ไม่เป็นไรคุณแค่ถือว่าตารางทั้งหมดเป็นแบบที่เพิ่งแก้ไขถ้าคุณเริ่มต้นใหม่หลังจากเกิดความผิดพลาด
เพื่อหลีกเลี่ยงปัญหาที่เกิดขึ้นพร้อมกันที่เลวร้ายที่สุดคุณสามารถบันทึกการเปลี่ยนแปลงการประทับเวลาโดยใช้before insert or update or delete or truncate on tablename for each statement execute
ทริกเกอร์โดยทั่วไปจะใช้ความสัมพันธ์ oid เป็นพารามิเตอร์ สิ่งนี้จะแทรก(relation_oid, timestamp)
คู่ลงในตารางการบันทึกการเปลี่ยนแปลง จากนั้นคุณมีกระบวนการผู้ช่วยในการเชื่อมต่อที่แยกต่างหากหรือเรียกเป็นระยะ ๆ โดยแอปของคุณรวมตารางนั้นสำหรับข้อมูลล่าสุดรวมเข้ากับตารางสรุปการเปลี่ยนแปลงล่าสุดและตัดทอนตารางบันทึก ข้อได้เปรียบเพียงข้อเดียวของวิธีนี้ในการฟัง / แจ้งเตือนคือไม่ให้ข้อมูลสูญหายเมื่อเกิดการขัดข้อง - แต่ก็มีประสิทธิภาพน้อยลงเช่นกัน
อีกวิธีหนึ่งที่อาจจะมีการเขียนฟังก์ชั่นการขยาย C ที่ใช้ (เช่น) ProcessUtility_hook
, ExecutorRun_hook
ฯลฯ ที่จะดักเปลี่ยนแปลงตารางและการปรับปรุงสถิติอย่างเฉื่อยชา ฉันไม่ได้ดูว่ามันจะเป็นไปได้จริง ดูตัวเลือก _hook ต่างๆในแหล่งที่มา
วิธีที่ดีที่สุดคือการแก้ไขรหัสสถิติเพื่อบันทึกข้อมูลนี้และส่งแพตช์ไปยัง PostgreSQL เพื่อรวมไว้ในคอร์ อย่าเพิ่งเริ่มต้นด้วยการเขียนโค้ด เพิ่มความคิดของคุณในแฮ็คเกอร์เมื่อคุณคิดพอที่จะมีวิธีที่ชัดเจนที่จะทำ (เช่นเริ่มจากการอ่านโค้ดอย่าเพิ่งโพสต์ถามว่า "ฉันจะทำอย่างไร ... ") อาจเป็นการดีที่จะเพิ่มเวลาที่อัปเดตครั้งล่าสุดpg_stat_...
แต่คุณจะต้องโน้มน้าวให้ชุมชนเห็นว่ามันคุ้มค่ากับค่าใช้จ่ายหรือให้วิธีการติดตามทางเลือก - และคุณต้องเขียนรหัสเพื่อเก็บสถิติและ ส่งแพทช์เพราะมีเพียงคนที่ต้องการคุณลักษณะนี้เท่านั้นที่จะไปสนใจ
ฉันจะทำยังไง
หากฉันต้องทำสิ่งนี้และไม่มีเวลาเขียนโปรแกรมแก้ไขเพื่อทำอย่างถูกต้องฉันอาจใช้วิธีการฟัง / แจ้งเตือนที่อธิบายไว้ข้างต้น
อัปเดตสำหรับ PostgreSQL 9.5 กำหนดการประทับเวลา
ปรับปรุง : PostgreSQL 9.5 มีกระทำการประทับเวลา หากคุณเปิดใช้งานไว้ในpostgresql.conf
(และเคยทำเช่นนั้นในอดีต) คุณสามารถตรวจสอบการประทับเวลาสำหรับแถวที่มีค่ามากที่สุดxmin
ในการประมาณเวลาที่แก้ไขล่าสุด มันเป็นเพียงการประมาณค่าเพราะหากแถวล่าสุดถูกลบไปแถวนั้นจะไม่ถูกนับ
นอกจากนี้การคอมมิตบันทึกการประทับเวลาจะถูกเก็บไว้ในเวลาที่ จำกัด เท่านั้น ดังนั้นหากคุณต้องการที่จะบอกว่าเมื่อใดที่ตารางที่ไม่ได้รับการแก้ไขจะได้รับการแก้ไขมากคำตอบคือ "dunno เมื่อไม่นานมานี้"