bunuh -9 proses postgres

25

Permintaan SELECT postgres kehabisan kendali pada server DB kami dan mulai memakan banyak memori dan bertukar sampai server kehabisan memori. Saya menemukan proses tertentu melalui ps aux | grep postgresdan berlari kill -9 pid. Ini membunuh proses dan memori dibebaskan seperti yang diharapkan. Sisa permintaan sistem dan postgres tampaknya tidak terpengaruh. Server ini menjalankan postgres 9.1.3 pada SLES 9 SP4.

Namun, salah satu pengembang kami mengusir saya karena membunuh proses postgres dengan kill -9, mengatakan bahwa itu akan menghapus seluruh layanan postgres. Pada kenyataannya, ternyata tidak. Saya sudah melakukan ini sebelum beberapa kali dan belum melihat efek samping negatif.

Dengan mengatakan itu, dan setelah membaca lebih lanjut, sepertinya kill pidtanpa bendera adalah cara yang disukai untuk membunuh proses postgres pelarian, tetapi per pengguna lain dalam komunitas postgres, sepertinya postgres telah "menjadi lebih baik" selama bertahun-tahun sehingga kill -9pada proses permintaan individu / utas bukan lagi hukuman mati.

Dapatkah seseorang mencerahkan saya tentang cara yang tepat untuk membunuh proses postgres pelarian serta bagaimana bencana (atau jinak) menggunakan kill -9Postgres hari ini? Terima kasih atas wawasannya.

Banjer
sumber

Jawaban:

31

voretaq7 's jawabannya mencakup poin-poin penting, termasuk cara yang benar untuk mengakhiri backends tapi saya ingin menambahkan sedikit penjelasan lebih.

kill -9(Yaitu SIGKILL) seharusnya tidak pernah, menjadi default pilihan pertama Anda . Ini harus menjadi pilihan terakhir Anda ketika proses tidak menanggapi permintaan penutupan normal dan a SIGTERM( kill -15) tidak berpengaruh. Itu berlaku untuk Pg dan hampir semuanya.

kill -9 memberi proses membunuh tidak ada kesempatan untuk melakukan pembersihan sama sekali.

Ketika datang ke PostgreSQL, Pg melihat cadangan yang diakhiri oleh kill -9sebagai macet yang didukung . Ia tahu bahwa backend mungkin telah merusak memori bersama - karena Anda bisa menginterupsi setengah jalan dengan menulis halaman ke shm atau memodifikasi satu, misalnya - jadi itu mengakhiri dan me-restart semua backend lainnya ketika mengetahui bahwa backend tiba-tiba menghilang dan keluar dengan kode kesalahan non-nol.

Anda akan melihat ini dilaporkan dalam log.

Jika tampaknya tidak ada salahnya, itu karena Pg me-restart semuanya setelah crash dan aplikasi Anda pulih dari koneksi yang hilang dengan bersih. Itu tidak membuatnya menjadi ide yang bagus. Jika tidak ada crash backend yang kurang teruji dengan baik daripada bagian Pg yang berfungsi normal dan jauh lebih rumit / bervariasi, sehingga kemungkinan bug yang bersembunyi dalam penanganan crash backend dan pemulihan lebih tinggi.

BTW, jika Anda kill -9kepala kantor kemudian menghapus postmaster.piddan mulai lagi tanpa memastikan setiap postgresbackend hilang, hal-hal yang sangat buruk dapat terjadi . Ini dapat dengan mudah terjadi jika Anda secara tidak sengaja membunuh kepala kantor alih-alih backend, melihat database telah turun, mencoba me-restart itu, menghapus file .pid "basi" ketika restart gagal, dan mencoba untuk me-restart lagi. Itulah salah satu alasan Anda harus menghindari melambaikan kill -9Pg, dan tidak boleh menghapus postmaster.pid.

Demonstrasi:

Untuk melihat apa yang terjadi ketika Anda kill -9menjadi backend, coba langkah-langkah sederhana ini. Buka dua terminal, buka psql di masing-masing, dan di setiap jalankan SELECT pg_backend_pid();. Di terminal lain kill -9salah satu PID. Sekarang jalankan SELECT pg_backend_pid();di kedua sesi psql lagi. Perhatikan bagaimana mereka berdua kehilangan koneksi?

Sesi 1, yang kami bunuh:

$ 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)

Sesi 2, yang merupakan kerusakan jaminan:

$ 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)

Lihat bagaimana kedua sesi rusak? Itu sebabnya Anda bukan kill -9backend.

Craig Ringer
sumber
1
Semua jawaban yang sangat baik di sini, dan sangat merendahkan saya dapat menambahkan. Saya bisa menandai mereka semua sebagai diterima, tetapi @Craig Ringer memiliki beberapa poin tambahan di sini dan benar-benar mengendarainya di rumah. Terima kasih lagi SF karena telah membersihkan saya dari kebiasaan buruk saya!
Banjer
2
@Craig: Respons yang luar biasa; dan untuk menyertakan demonstrasi, saya berharap bisa memberikan suara 100x ini. Saya seorang pengembang perangkat lunak yang bekerja dengan PG setiap hari dan sejak 6.x hari dan respons Anda tepat! Bagus!
Kilo
2
Jawaban bagus. Tambahan: jika Anda memiliki proses backend yang benar-benar tidak akan mati - tidak dengan pg_terminate_backend, tidak dengan restart server stack, tidak dengan apa pun, Anda dapat membunuhnya seperti yang Anda inginkan, tetapi pastikan Anda memiliki cadangan database Anda yang berfungsi. Anda dapat melakukannya dengan beberapa cara: Anda dapat menggunakan pg_basebackupatau serupa (atau hanya rsyncdan pg_start\stop_backup) untuk membuat cadangan direktori data Anda (menguji cadangan sebelum melanjutkan!), Atau Anda dapat menggunakan pg_dump[all]untuk menyimpan data Anda. Baru setelah itu Anda dapat mempertimbangkan kill -9, atau reboot, atau apa pun.
Zac B
1
@ ZacB Yap, dan jika Anda membunuhnya pastikan semua backend mati. Paling penting, tidak pernah menghapus postmaster.pid. Pernah.
Craig Ringer
29

I found the particular process via ps aux | grep postgres and ran kill -9 pid.
TIDAK! BURUK! LANGKAH JAUH DARI BACKEND!

Serius - Jangan bunuh backgres Postgres seperti itu - hal-hal yang MENGERIKAN bisa terjadi (bahkan dengan semua peningkatan stabilitas yang telah dibuat sejak 7 hari) yang dapat menghancurkan seluruh DB Anda, dan pengembang Anda cukup tepat untuk mengunyah Anda keluar untuk melakukan ini.

Sebenarnya, ada cara yang diberkati dan disetujui untuk melakukan ini dari dalam Postgres - Bahkan dalam manual Postgres sekalipun pos SO melakukan pekerjaan yang lebih baik untuk menjelaskannya ...

SELECT pg_cancel_backend(pid)
Mengirim SIGINTsinyal pembatalan ( ) ke backend yang ditentukan, yang membatalkan permintaan yang sedang berjalan.

select pg_terminate_backend(pid)
Mengirim SIGTERMsinyal terminate ( ) ke backend yang ditentukan, yang membatalkan kueri dan membatalkan backend (menjatuhkan koneksinya).

ID Backend dapat diperoleh dari pg_stat_activitytabel (atau ps)

voretaq7
sumber
4
Jika ada orang yang bertanya-tanya tentang hal-hal mengerikan, mengingat hal kill -9itu tidak berbeda dengan tiba-tiba mematikan sistem sejauh menyangkut proses pembunuhan: Pg sangat toleran terhadap tabrakan backend (seperti a kill -9) dan tidak boleh ada korupsi data. Ada akan menjadi korupsi jika Anda membunuh kepala kantor pos , menghapus postmaster.pid, dan restart tanpa juga membunuh setiap backend pertama. Itu akan memusnahkan basis data Anda, tetapi membutuhkan lebih banyak dari sekadar a kill -9ke backend. kill -9tidak memberi waktu kepada kepala kantor pos untuk membunuh backend, oleh karena itu berbahaya.
Craig Ringer
2
... seperti kasus konsultasi darurat yang saya lakukan minggu lalu. Database mereka rusak parah, kehilangan dua hari kerja karena cadangan mereka gagal (dan mereka tidak menguji secara otomatis pemulihan mereka), turun selama 48 jam. Jangan hapus postmaster.pid.
Craig Ringer
8

Membunuh proses klien PostgreSQL harus baik-baik saja. Membunuh proses daemon PostgreSQL bisa membuat Anda dimarahi.

Karena daemon SQL juga memiliki kontrol proses internal, cara yang disukai adalah mencoba menggunakan saluran itu terlebih dahulu.

Lihat Berhenti (lama) menjalankan kueri SQL di PostgreSQL ... dari StackOverflow.

Jeff Ferland
sumber
4
kill -9seharusnya tidak menjadi pilihan default Anda, itu pilihan terakhir. Kirim SIGTERMdengan kill -TERMatau polos killdan jika penerima tidak merespons setelah beberapa saat, hanya itu yang harus Anda pertimbangkan kill -KILL( kill -9).
Craig Ringer