kill -9 กระบวนการ postgres


25

แบบสอบถาม SELECT postgres หมดการควบคุมบนเซิร์ฟเวอร์ DB ของเราและเริ่มกินหน่วยความจำจำนวนมากและสลับไปมาจนกว่าเซิร์ฟเวอร์หมดหน่วยความจำ ผมพบว่ากระบวนการโดยเฉพาะอย่างยิ่งผ่านทางและวิ่งps aux | grep postgres kill -9 pidสิ่งนี้ทำให้กระบวนการและหน่วยความจำว่างลงอย่างที่คาดไว้ ส่วนที่เหลือของระบบและแบบสอบถาม postgres ดูเหมือนจะไม่ได้รับผลกระทบ เซิร์ฟเวอร์นี้ใช้ postgres 9.1.3 ใน SLES 9 SP4

อย่างไรก็ตามหนึ่งในนักพัฒนาของเราเคี้ยวฉันออกมาเพื่อฆ่ากระบวนการ postgres ด้วยkill -9โดยบอกว่ามันจะลดการให้บริการ postgres ทั้งหมด ในความเป็นจริงมันไม่ได้ ฉันได้ทำสิ่งนี้มาแล้วไม่กี่ครั้งและไม่เคยเห็นผลข้างเคียงใด ๆ ในทางลบ

ด้วยที่กล่าวและหลังจากอ่านเพิ่มเติมดูเหมือนว่าkill pidไม่มีธงเป็นวิธีที่ต้องการฆ่ากระบวนการ postgres ที่หลบหนี แต่สำหรับผู้ใช้คนอื่น ๆ ในชุมชน postgres ก็ดูเหมือนว่า postgres จะ "ดีขึ้น" ในช่วงหลายปีที่ผ่านมาkill -9ในแต่ละกระบวนการ / เธรดการสืบค้นจะไม่มีประโยคตายอีกต่อไป

ใครบางคนสามารถสอนฉันเกี่ยวกับวิธีที่เหมาะสมในการฆ่ากระบวนการ postgres ที่ควบคุมkill -9ไม่ได้ ขอบคุณสำหรับความเข้าใจ

คำตอบ:


31

คำตอบของvoretaq7ครอบคลุมประเด็นสำคัญรวมถึงวิธีที่ถูกต้องในการยุติแบ็กเอนด์แต่ฉันต้องการเพิ่มคำอธิบายเพิ่มเติมอีกเล็กน้อย

kill -9(คือSIGKILL) ไม่ควรเคยเคยเป็นค่าเริ่มต้นตัวเลือกแรกของคุณ ควรเป็นทางเลือกสุดท้ายของคุณเมื่อกระบวนการไม่ตอบสนองต่อคำขอปิดระบบปกติและ a SIGTERM( kill -15) ไม่มีผลใด ๆ นั่นเป็นความจริงของ Pg และทุกอย่างก็สวยมาก

kill -9 ทำให้กระบวนการที่ถูกฆ่าไม่มีโอกาสที่จะทำการล้างข้อมูลใด ๆ เลย

เมื่อมันมากับ PostgreSQL, Pg เห็นได้รับการสนับสนุนว่ายกเลิกโดยkill -9เป็นความผิดพลาดที่ได้รับการสนับสนุน มันรู้ว่าแบ็คเอนด์อาจมีหน่วยความจำที่ใช้ร่วมกันที่เสียหาย - เพราะคุณสามารถขัดจังหวะมันได้ครึ่งทางโดยการเขียนหน้าเป็น shm หรือแก้ไขอย่างใดอย่างหนึ่ง - ดังนั้นมันจะยุติและรีสตาร์ทแบ็กเอนด์อื่น ๆ ทั้งหมดเมื่อสังเกตว่าแบ็กเอนด์ และออกด้วยรหัสข้อผิดพลาดที่ไม่ใช่ศูนย์

คุณจะเห็นรายงานนี้ในบันทึก

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

BTW ถ้าคุณkill -9ไปรษณีย์แล้วลบpostmaster.pidและเริ่มต้นอีกครั้งโดยไม่ต้องทำให้แน่ใจว่าทุกpostgresแบ็กเอนด์จะหายไปสิ่งที่ไม่ดีมากสามารถเกิดขึ้นได้ สิ่งนี้อาจเกิดขึ้นได้อย่างง่ายดายหากคุณเผลอฆ่า postmaster แทนแบ็กเอนด์โดยไม่ได้ตั้งใจเห็นฐานข้อมูลล้มเหลวพยายามรีสตาร์ทลบไฟล์. pid "stale" เมื่อรีสตาร์ทล้มเหลวและพยายามรีสตาร์ทอีกครั้ง นั่นเป็นหนึ่งในเหตุผลที่คุณควรหลีกเลี่ยงโบกทั่วหน้าและไม่ควรลบkill -9postmaster.pid

การสาธิต:

หากต้องการดูสิ่งที่เกิดขึ้นเมื่อคุณkill -9แบ็กเอนด์ลองขั้นตอนง่าย ๆ เหล่านี้ เปิดเทอร์มินัลสองเครื่องเปิด psql ในแต่ละรายการและในการรันแต่ละSELECT pg_backend_pid();ครั้ง ในเทอร์มินัลอื่นkill -9หนึ่งใน PIDs ตอนนี้ทำงานSELECT pg_backend_pid();ในทั้งสองเซสชัน psql อีกครั้ง สังเกตว่าพวกเขาทั้งคู่ขาดการเชื่อมต่ออย่างไร

ช่วงที่ 1 ซึ่งเราฆ่า:

$ psql regress
psql (9.1.4)
Type "help" for help.

regress=# select pg_backend_pid();
 pg_backend_pid 
----------------
           6357
(1 row)

[kill -9 of session one happens at this point]

regress=# select pg_backend_pid();
server closed the connection unexpectedly
        This probably means the server terminated abnormally
        before or while processing the request.
The connection to the server was lost. Attempting reset: Succeeded.
regress=# select pg_backend_pid();
 pg_backend_pid 
----------------
           6463
(1 row)

ช่วงที่ 2 ซึ่งเป็นความเสียหายของหลักประกัน:

$ psql regress
psql (9.1.4)
Type "help" for help.

regress=# select pg_backend_pid();
 pg_backend_pid 
----------------
           6283
(1 row)

[kill -9 of session one happens at this point]

regress=# select pg_backend_pid();
WARNING:  terminating connection because of crash of another server process
DETAIL:  The postmaster has commanded this server process to roll back the current transaction and exit, because another server process exited abnormally and possibly corrupted shared memory.
HINT:  In a moment you should be able to reconnect to the database and repeat your command.
server closed the connection unexpectedly
        This probably means the server terminated abnormally
        before or while processing the request.
The connection to the server was lost. Attempting reset: Succeeded.
regress=# select pg_backend_pid();
 pg_backend_pid 
----------------
           6464
(1 row)

ดูว่าทั้งสองเซสชันแตกอย่างไร นั่นเป็นเหตุผลที่คุณไม่kill -9ต้องแบ็กเอนด์


1
ทุกคำตอบที่ดีมากที่นี่และฉันอาจเพิ่มความอ่อนน้อมถ่อมตน ฉันสามารถทำเครื่องหมายพวกเขาทั้งหมดว่าเป็นที่ยอมรับ แต่ @Craig Ringer มีคะแนนพิเศษบางอย่างที่นี่และขับมันจริงๆ ขอบคุณ SF อีกครั้งสำหรับการทำความสะอาดนิสัยที่ไม่ดีของฉัน!
Banjer

2
@ Craig: ช่างเป็นคำตอบที่ยอดเยี่ยม และเพื่อรวมการสาธิตฉันหวังว่าฉันจะลงคะแนนได้ถึง 100 เท่า ฉันเป็นนักพัฒนาซอฟต์แวร์ที่ทำงานร่วมกับ PG ทุกวันและตั้งแต่ 6.x วันและการตอบสนองของคุณเป็นจุด! ดี!
กิโลกรัม

2
คำตอบที่ดี ภาคผนวก: หากคุณมีกระบวนการแบ็กเอนด์ที่จะไม่ตาย - ไม่ใช่ด้วยpg_terminate_backendไม่รีสตาร์ทเซิร์ฟเวอร์สแต็กไม่ใช่กับอะไรคุณสามารถฆ่ามันได้ตามที่คุณต้องการ แต่ให้แน่ใจว่าคุณมีการสำรองฐานข้อมูลของคุณ คุณสามารถทำได้สองวิธี: คุณสามารถใช้pg_basebackupหรือคล้ายกัน (หรือเพียงrsyncและpg_start\stop_backup) เพื่อสำรองไดเรกทอรีข้อมูลของคุณ (ทดสอบการสำรองข้อมูลก่อนดำเนินการต่อ!) หรือคุณสามารถใช้pg_dump[all]เพื่อกู้ข้อมูลของคุณ คุณควรพิจารณาkill -9หรือรีบูทหรืออะไรก็ตาม
Zac B

1
@ZacB ใช่แล้วและถ้าคุณฆ่ามันให้แน่ใจว่าแบ็กเอนด์ทั้งหมดตาย ส่วนใหญ่อย่างจำเป็นไม่เคยpostmaster.pidลบ เคย
Craig Ringer

29

I found the particular process via ps aux | grep postgres and ran kill -9 pid.
NO! ไม่ดี! ขั้นตอนออกมาจากแบ็กเอนด์!

อย่างจริงจัง - อย่าฆ่าแบ็กเอนด์ Postgres แบบนั้น - สิ่งที่น่ากลัวสามารถเกิดขึ้นได้ (แม้จะมีการปรับปรุงเสถียรภาพทั้งหมดที่ทำมาตั้งแต่ 7.x วัน) ซึ่งสามารถทำลายฐานข้อมูลทั้งหมดของคุณและนักพัฒนาของคุณค่อนข้างเคี้ยว คุณออกไปทำสิ่งนี้

ในความเป็นจริงแล้วเป็นวิธีที่มีความสุขและได้รับการอนุมัติในการทำเช่นนี้จากใน Postgres - มันเป็นแม้กระทั่งในคู่มือ Postgresแม้ว่าโพสต์ SO จะทำงานได้ดีกว่าในการอธิบาย ...

SELECT pg_cancel_backend(pid)
ส่งSIGINTสัญญาณยกเลิก ( ) ไปยังแบ็กเอนด์ที่ระบุซึ่งจะยกเลิกการสืบค้นที่กำลังทำงานอยู่

select pg_terminate_backend(pid)
ส่งSIGTERMสัญญาณยุติ ( ) ไปยังแบ็กเอนด์ที่ระบุซึ่งจะยกเลิกเคียวรีและยกเลิกแบ็กเอนด์ (ปล่อยการเชื่อมต่อ)

Backend ID สามารถรับได้จากpg_stat_activityตาราง (หรือps)


4
ในกรณีที่มีใครสงสัยเกี่ยวกับสิ่งที่น่ากลัวเพราะkill -9มันไม่ได้แตกต่างกันในทันทีที่ปิดระบบในขณะที่กระบวนการฆ่านั้นเกี่ยวข้อง: Pg ทนต่อการล่มแบ็กเอนด์ (เช่น a kill -9) และไม่ควรมีข้อมูลเสียหาย มีจะเป็นความเสียหายถ้าคุณฆ่าไปรษณีย์ลบ postmaster.pid และเริ่มต้นใหม่ได้โดยไม่ฆ่าทุกแบ็กเอนด์ครั้งแรก สิ่งนี้จะทำลายฐานข้อมูลของคุณ แต่ใช้เวลามากกว่าkill -9แบ็กเอนด์ kill -9ไม่ได้ให้เวลาไปรษณีย์สำหรับฆ่าแบ็กเอนด์ซึ่งเป็นสาเหตุที่อันตราย
Craig Ringer

2
... เช่นกรณีการให้คำปรึกษาฉุกเฉินเมื่อสัปดาห์ที่แล้ว ฐานข้อมูลของพวกเขาแย่มากและสูญเสียงานสองวันเนื่องจากการสำรองข้อมูลล้มเหลว (และพวกเขาไม่ได้ทำการทดสอบการกู้คืนอัตโนมัติ) ลงมาเป็นเวลา 48 ชั่วโมง postmaster.pidอย่าลบ
Craig Ringer

8

การฆ่ากระบวนการไคลเอนต์ PostgreSQL ควรเป็นเรื่องปกติ การฆ่ากระบวนการ PostgreSQL daemon อาจทำให้คุณดุ

เนื่องจาก SQL daemons มีการควบคุมกระบวนการภายในด้วยวิธีที่ต้องการคือลองใช้ช่องสัญญาณนั้นก่อน

ดูStop (ยาว) ที่รันการสืบค้น SQL ใน PostgreSQL ...จาก StackOverflow


4
kill -9ไม่ควรเป็นตัวเลือกเริ่มต้นของคุณอย่างไรก็ตามเป็นทางเลือกสุดท้าย ส่งSIGTERMด้วยkill -TERMหรือธรรมดาkillและหากผู้รับไม่ตอบกลับหลังจากผ่านไประยะหนึ่งคุณควรพิจารณาkill -KILL( kill -9)
Craig Ringer
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.