จะเกิดอะไรขึ้นหากทั้งสองกระบวนการพยายามที่จะดูข้อมูลอ้างอิงใหม่อย่างต่อเนื่องในเวลาเดียวกัน


13

ตามเอกสาร:

รีเฟรชมุมมองที่เป็นรูปธรรมอย่างไม่หยุดยั้งโดยไม่ล็อคออกพร้อมกันเลือกบนมุมมองที่ปรากฏ ( ... )

... เนื้อหาอื่น ๆ ...

แม้จะมีตัวเลือกนี้REFRESH ครั้งละหนึ่งอาจทำงานกับ มุมมองที่ปรากฏขึ้นใด ๆ

ฉันมีฟังก์ชั่นที่ตรวจสอบเวลารีเฟรชครั้งล่าสุดสำหรับ VIEW MATERIALIZED และถ้าผ่านไป 60 วินาทีมันจะรีเฟรช

อย่างไรก็ตามจะเกิดอะไรขึ้นหากฉันพยายามรีเฟรชมุมมองที่เป็นรูปธรรมจากกระบวนการที่แยกกันสองกระบวนการในเวลาเดียวกัน พวกเขาจะจัดคิวหรือจะเพิ่มข้อผิดพลาดหรือไม่

มีวิธีการตรวจจับหรือไม่เมื่อมุมมองแบบ MATERIALIZED กำลังถูกรีเฟรชและหลีกเลี่ยงการสัมผัส

ขณะนี้ฉันได้ทำการเติมข้อมูลในตารางก่อนที่จะรีเฟรช (ตั้งค่าrefreshingเป็นtrue) จากนั้นตั้งค่าเป็นfalseเมื่อกระบวนการเสร็จสิ้น

EXECUTE 'INSERT INTO refresh_status (last_update, refreshing) 
         VALUES (clock_timestamp(), true) RETURNING id') INTO refresh_id;
EXECUTE 'REFRESH MATERIALIZED VIEW CONCURRENTLY my_mat_view';
EXECUTE 'UPDATE refresh_status SET refreshing=false WHERE id=$1' USING refresh_id;

จากนั้นเมื่อใดก็ตามที่ฉันเรียกขั้นตอนนี้ฉันจะตรวจสอบล่าสุดlast_updateและความrefreshingคุ้มค่า ถ้าrefreshingเป็นจริงอย่าพยายามรีเฟรชมุมมองที่ปรากฏ

EXECUTE 'SELECT 
           extract(epoch FROM now() - (last_update))::integer, 
           refreshing
         FROM refresh_status
         ORDER BY last_update DESC
         LIMIT 1' INTO update_seconds_ago, refreshing;

IF(updated_seconds_ago > 60 AND refreshing = FALSE) THEN
  -- the refresh block above
END IF;

อย่างไรก็ตามฉันไม่แน่ใจว่าการตั้งค่าสถานะการรีเฟรชได้รับการอัปเดตแบบซิงโครนัส (ฉันหมายถึงมันจะรอให้การรีเฟรชเสร็จสมบูรณ์จริง ๆ )

นี่เป็นวิธีการที่มีเหตุผลหรือฉันขาดอะไรที่นี่ไหม?

คำตอบ:


13

ดังที่ได้กล่าวไว้ในคำตอบนี้ " REFRESH MATERIALIZED VIEW CONCURRENTLYใช้การEXCLUSIVEล็อก" บนโต๊ะ จากการติดตามเศษเสี้ยวไปยังเอกสารเราสามารถอ่านได้ว่าการEXCLUSIVEล็อกบนโต๊ะ "อนุญาตให้ACCESS SHAREล็อคแบบพร้อมกันเท่านั้นคือการอ่านจากตารางเท่านั้นสามารถดำเนินการได้" ในย่อหน้าเดียวกันเราจะเห็นว่า " EXCLUSIVEขัดแย้งกับ ... EXCLUSIVE" ซึ่งหมายความว่าREFRESH MATERIALIZED VIEW CONCURRENTLYคำสั่งอื่นที่ร้องขอการEXCLUSIVEล็อกเดียวกันจะต้องรอจนกว่าการEXCLUSIVEล็อกก่อนหน้านี้จะถูกนำออกใช้

หากคุณต้องการหลีกเลี่ยงการรอการล็อคนี้เป็นระยะเวลาที่ไม่ได้กำหนดคุณอาจต้องการตั้งค่าตัวแปรเซสชั่นlock_timeoutเป็นค่าที่เหมาะสม


PS: คุณคิดว่ามันสมเหตุสมผลไหมที่จะทำให้ตารางที่คุ้นเคยนี้บอกความพร้อมกัน (ไม่มีการเล่นสำนวน) พยายามที่ MAT VIEW ไม่ว่างและดังนั้นจึงควรปล่อยให้อยู่ตามลำพังแม้ว่ามันจะต้องการการรีเฟรช?
ffflabs

มันเป็นเรื่องของความเห็น ถ้าคุณคิดว่ามันช่วยให้คุณสามารถรักษาตรรกะของคุณได้ อย่างไรก็ตามโปรดทราบว่าฟังก์ชั่นของคุณขึ้นอยู่กับสภาพการแข่งขันและดังนั้นจึงไม่น่าเชื่อถือ 100%
mustaccio

คุณคิดว่าเป็นไปได้หรือไม่ที่จะตรวจสอบ pg_locks เพื่อดูว่ามีการอ้างอิงมุมมองเสื่อหรือไม่
ffflabs

สภาพการแข่งขันเป็นไปได้อีกครั้ง: มีโอกาสที่ล็อคจะถูกวางไว้ระหว่างคุณตรวจสอบpg_locksและเริ่มการรีเฟรช วิธีที่เหมาะสมในการจัดการข้อขัดแย้งของการล็อกคือการตั้งค่าการหมดเวลาและจัดการข้อผิดพลาด
mustaccio

3

เท่าที่สังเกตจากmustaccioคำถามนี้คาบเกี่ยวอย่างมีนัยสำคัญกับPostgres รีเฟรช materialized ดูล็อค

อย่างไรก็ตามในขณะที่คำตอบที่ยอมรับสำหรับคำถามนั้นมีลิงก์ที่ตอบคำถามนี้คำตอบสำหรับคำถามนี้ไม่ได้รวมอยู่ในคำถามนั้นโดยตรง

ดังนั้นเพื่อให้มีความเฉพาะเจาะจง: ตามหน้าคู่มือของ PostgreSQL เกี่ยวกับการล็อคอย่างชัดเจน (ลิงก์คือไปยังหน้าเวอร์ชันปัจจุบันสำหรับ PostGres 10) REFRESH MATERIALIZED VIEW CONCURRENTLYจะทำการEXCLUSIVEล็อค การEXCLUSIVEล็อคปรากฏขึ้นเพื่อบล็อกการล็อคอื่น ๆยกเว้น ACCESS SHARE - ที่มีการEXCLUSIVEล็อคอื่น ๆ

ดังนั้นREFRESH MATERIALIZED VIEW CONCURRENTLYคำขอที่สองในมุมมองเดียวกันจะรอการล็อกที่ได้รับจากการเปิดตัวครั้งแรก


ขอบคุณ. ฉันยังคงทำเครื่องหมายคำตอบของ @ mustaccio ว่าเป็นที่ยอมรับเนื่องจากเขาแก้ไขข้อความของเขาให้เฉพาะเจาะจงกับคำถามของฉันมากขึ้น
ffflabs

0

ขอบคุณคำตอบของmustaccioและRDFozzในที่สุดฉันก็เข้าใจว่าREFRESH ... CONCURRENTLYการล็อกแบบเอกสิทธิ์เฉพาะบุคคลคือเหตุผลที่เอกสาร PostgreSQL บอกว่า :

แม้จะมีตัวเลือกนี้REFRESH ครั้งละหนึ่งอาจทำงานกับ มุมมองที่ปรากฏขึ้นใด ๆ

ฉันกลัวว่านี่หมายถึงความพยายามในการรีเฟรชพร้อมกันจะทำให้เกิดข้อผิดพลาดแต่ในแง่ของคำตอบพวกเขาไม่มีข้อผิดพลาดพิเศษใด ๆ ที่เกี่ยวข้อง มันเป็นเพียงเรื่องของการล็อคที่จะเข้าคิวความพยายามพร้อมกัน ดังนั้นเอกสารอาจตีความได้ดังนี้:

ล็อคที่ได้รับระหว่างการดำเนินการนี้จะป้องกันการดำเนินการอื่น ๆ นอกเหนือจากการอ่านจากมุมมองที่เป็นวัสดุ ความพยายามเพิ่มเติมในการรีเฟรชมุมมอง Materialized ในขณะที่ REFRESH ... ดำเนินการต่อเนื่องอย่างต่อเนื่องจะเข้าคิวจนกว่าการล็อกแรกจะถูกนำออกใช้

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