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 -9
sebagai 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 -9
kepala kantor kemudian menghapus postmaster.pid
dan mulai lagi tanpa memastikan setiap postgres
backend 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 -9
Pg, dan tidak boleh menghapus postmaster.pid
.
Demonstrasi:
Untuk melihat apa yang terjadi ketika Anda kill -9
menjadi 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 -9
salah 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 -9
backend.
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 menggunakanpg_basebackup
atau serupa (atau hanyarsync
danpg_start\stop_backup
) untuk membuat cadangan direktori data Anda (menguji cadangan sebelum melanjutkan!), Atau Anda dapat menggunakanpg_dump[all]
untuk menyimpan data Anda. Baru setelah itu Anda dapat mempertimbangkankill -9
, atau reboot, atau apa pun.postmaster.pid
. Pernah.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
SIGINT
sinyal pembatalan ( ) ke backend yang ditentukan, yang membatalkan permintaan yang sedang berjalan.select pg_terminate_backend(pid)
Mengirim
SIGTERM
sinyal terminate ( ) ke backend yang ditentukan, yang membatalkan kueri dan membatalkan backend (menjatuhkan koneksinya).ID Backend dapat diperoleh dari
pg_stat_activity
tabel (ataups
)sumber
kill -9
itu tidak berbeda dengan tiba-tiba mematikan sistem sejauh menyangkut proses pembunuhan: Pg sangat toleran terhadap tabrakan backend (seperti akill -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 akill -9
ke backend.kill -9
tidak memberi waktu kepada kepala kantor pos untuk membunuh backend, oleh karena itu berbahaya.postmaster.pid
.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.
sumber
kill -9
seharusnya tidak menjadi pilihan default Anda, itu pilihan terakhir. KirimSIGTERM
dengankill -TERM
atau poloskill
dan jika penerima tidak merespons setelah beberapa saat, hanya itu yang harus Anda pertimbangkankill -KILL
(kill -9
).