แบบสอบถามแบบยาวของ Postgres ถูกยกเลิกหรือไม่หากการเชื่อมต่อขาดหายไป


20

ถ้าฉันเปิดการเชื่อมต่อกับ Postgres และออกแบบสอบถามที่ใช้เวลานานแล้วหยุดการเชื่อมต่อ (เช่นฆ่ากระบวนการไคลเอนต์ที่เปิดการเชื่อมต่อ) แบบสอบถามที่ใช้เวลานานจะยังคงทำงานต่อไปหรือจะถูกยกเลิกโดยอัตโนมัติหรือไม่ สามารถกำหนดค่านี้ได้หรือไม่

(ฉันใช้ Postgresql 9.2.9)

คำตอบ:


32

"มันขึ้นอยู่กับ".

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

หากไคลเอ็นต์ถูกฆ่าด้วยวิธีที่ระบบปฏิบัติการของไคลเอ็นต์สามารถรายงานไปยังเซิร์ฟเวอร์ผ่าน TCP RST (เช่นไคลเอนต์ segfault / crash, SIGTERM, SIGKILL, ฯลฯ ) เซิร์ฟเวอร์ PostgreSQL จะตั้งค่าสถานะอินเตอร์รัปต์ ครั้งต่อไปที่แบบสอบถามตรวจสอบการขัดจังหวะขณะที่เรียกใช้งานมันจะเห็นการตั้งค่าสถานะและยกเลิก บางครั้งการสืบค้นอาจทำงานหนัก CPU ภายในรหัสที่ไม่ตรวจสอบการขัดจังหวะ - ส่วนขยายบางส่วนและบางสถานที่ภายในแกนหลัก PostgreSQL - ซึ่งในกรณีนี้อาจไม่สังเกตเห็นการขัดจังหวะเป็นเวลานานและยังคงทำงานต่อไป มันจะเห็นการขัดจังหวะและการยกเลิกก่อนที่จะเสร็จสิ้นและยอมรับเสมอถ้าเป็นการทำสำเนาอัตโนมัติ

หากไคลเอ็นต์ถูกฆ่าโดยบางสิ่งบางอย่างเช่นการรีบูตระบบทันทีทันใดเพื่อให้โฮสต์ไคลเอนต์ไม่รู้อะไรเลยเกี่ยวกับการเชื่อมต่อ TCP แต่ยังคงสามารถตอบสนองต่อเครือข่ายได้แบบสอบถามอาจจะถูกยกเลิกในครั้งแรกที่ทดสอบแถวเช่น Jeff กล่าวว่าเนื่องจากโฮสต์ของไคลเอ็นต์จะส่ง TCP RST เพื่อตอบกลับแพ็คเก็ตแรกที่ส่งจากเซิร์ฟเวอร์หลังจากรีบูต PostgreSQL ตรวจสอบการขัดจังหวะที่แต่ละแถวที่ส่ง

พฤติกรรมนี้ไม่สามารถกำหนดค่าได้ เท่าที่ PostgreSQL มีความกังวลหากลูกค้าไม่ทำงานหน้าที่ของมันคือการยุติการสืบค้นใด ๆ ที่ลูกค้ากำลังทำงานอยู่ หากต้องการเปลี่ยนโทเค็นการสืบค้นให้สมบูรณ์ที่คุณสามารถหาได้เมื่อเริ่มต้นคิวรีให้ใช้วิธีสอบถามจากเซิร์ฟเวอร์เพื่อสอบถามเกี่ยวกับการค้นหาผ่านการเชื่อมต่ออื่นในภายหลัง เป็นหลักคุณจะต้องใช้แบบสอบถามแบบอะซิงโครนัส / พื้นหลัง อาจเป็นคุณลักษณะที่ดี แต่ไม่รองรับในปัจจุบัน

หากแบบสอบถามเป็นแบบอัตโนมัติิหรือหากข้อความค้นหาของคุณเป็นข้อความCOMMITบนเครื่องบินในเวลาที่คุณฆ่าลูกค้า / ขาดการเชื่อมต่ออาจเป็นไปได้ที่การทำธุรกรรมจะอยู่ในสถานะไม่แน่นอนซึ่งลูกค้าไม่ทราบว่าหรือ ไม่ได้มุ่งมั่น ไม่มีวิธีการค้นหาที่แท้จริงนอกจากการมองหาผลกระทบของการทำธุรกรรมกับข้อมูล

ในกรณีที่ไม่สามารถยอมรับได้คุณสามารถใช้การมอบหมายสองขั้นตอนและตัวจัดการธุรกรรมฝั่งไคลเอ็นต์


1
ว้าวสิ่งที่ฉันกำลังมองหาคือคำตอบที่ยอดเยี่ยม! ขอบคุณ @Craig_Ringer!
Rob Bednark


2

มันจะยังคงทำงานต่อไปจนกว่าจะพยายามที่จะกลับแถวไปที่การเชื่อมต่อและตรวจพบการแตก ดังนั้นสำหรับเคียวรีที่ทำงานทั้งหมดก่อนที่จะส่งคืนแถวใด ๆ มันจะทำงานจนจบ


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