Как убить / завершить запрос зависания PostgreSQL
Сегодня я обнаружил, что один из запросов SQL зависает в PostgreSQL и никогда не освобождает себя. Команда «Отменить запрос» не поможет, и запрос просто висит и показывает статус «idle in transaction». Это не оставило мне выбора, кроме как перейти в терминал Debian и ввести команду «kill», чтобы завершить его вручную.
Запрос зависает или не отвечает в PostgreSQL, потому что мы неправильно обработали диспетчер транзакций в веб-приложении. При случайном завершении работы системы текущий запрос будет зависать в PostgreSQL, и диспетчер транзакций (например,DataSourceTransactionManager
) не может откатить текущую транзакцию.
Note
После того, как я изменил диспетчер транзакций наJtaTransactionManager
, мое веб-приложение может прервать текущую транзакцию, даже если система была случайно выключена.
Однако здесь я покажу вам, как завершить зависший SQL-запрос. В PostgreSQL все зависшие запросы будут отображаться как «idle in transaction». Во-первых, вы должны вывести список всех существующих процессов PostgreSQL и выполнить команду kill terminate, чтобы вручную завершить зависший запрос.
1. Перечислите все процессы
Введите команду «ps -ef | grep postgres
», чтобы вывести список всех существующих процессов, принадлежащих пользователю postgres.
example:~# ps -ef | grep postgres postgres 13648 1 0 11:04 ? 00:00:00 /var/lib/postgresql/PostgresPlus8.3xxxxxxx postgres 13651 13648 0 11:04 ? 00:00:00 postgres: logger process postgres 13653 13648 0 11:04 ? 00:00:00 postgres: writer process postgres 13654 13648 0 11:04 ? 00:00:00 postgres: wal writer process postgres 13655 13648 0 11:04 ? 00:00:00 postgres: autovacuum launcher process postgres 13656 13648 0 11:04 ? 00:00:00 postgres: stats collector process postgres 13668 13648 0 11:04 ? 00:00:00 postgres: postgres postgres 10.70.1.27(3734) idle postgres 13689 13648 0 11:05 ? 00:00:00 postgres: usrdba db_test 10.70.1.67(4164) idle postgres 13714 13648 0 11:06 ? 00:00:00 postgres: usrdba db_test 10.70.0.61(57586) idle in transaction postgres 13721 13648 0 11:06 ? 00:00:16 postgres: usrdba db_test 10.70.1.67(4165) idle postgres 13832 13648 0 11:10 ? 00:00:00 postgres: usrdba db_test 10.70.0.61(57592) idle postgres 13833 13648 0 11:10 ? 00:00:00 postgres: usrdba db_test 10.70.0.61(57593) idle postgres 13834 13648 0 11:10 ? 00:00:00 postgres: usrdba db_test 10.70.0.61(57594) idle postgres 13835 13648 0 11:10 ? 00:00:00 postgres: usrdba db_test 10.70.0.61(57595) idle postgres 13836 13648 0 11:10 ? 00:00:00 postgres: usrdba db_test 10.70.0.61(57596) idle postgres 14201 13648 0 11:23 ? 00:00:00 postgres: nrsdba postgres 10.70.1.8(4419) idle postgres 14202 13648 0 11:23 ? 00:00:00 postgres: usrdba db_test 10.70.1.8(4420) idle postgres 14207 13648 0 11:24 ? 00:00:00 postgres: usrdba db_test 10.70.1.8(4421) idle root 18030 17992 0 13:46 pts/0 00:00:00 grep postgres example:~#
2. Найдите незанятую транзакцию + Kill
Обратите внимание на идентификатор процесса «13714, idle in transaction», это зависший запрос в PostgreSQL. Введите команду «kill», чтобы завершить процесс PostgreSQL вручную.
example:~# kill 13714
or
example:~# kill -TERM 13714
or
example:~# kill -15 13714
3. Убит! Готово.
Готово, зависший запрос пропал!
example:~# ps -ef | grep postgres postgres 13648 1 0 11:04 ? 00:00:00 /var/lib/postgresql/PostgresPlus8.3xxxxxxx postgres 13651 13648 0 11:04 ? 00:00:00 postgres: logger process postgres 13653 13648 0 11:04 ? 00:00:00 postgres: writer process postgres 13654 13648 0 11:04 ? 00:00:00 postgres: wal writer process postgres 13655 13648 0 11:04 ? 00:00:00 postgres: autovacuum launcher process postgres 13656 13648 0 11:04 ? 00:00:00 postgres: stats collector process postgres 13668 13648 0 11:04 ? 00:00:00 postgres: postgres postgres 10.70.1.27(3734) idle postgres 13689 13648 0 11:05 ? 00:00:00 postgres: usrdba db_test 10.70.1.67(4164) idle postgres 13721 13648 0 11:06 ? 00:00:16 postgres: usrdba db_test 10.70.1.67(4165) idle postgres 13832 13648 0 11:10 ? 00:00:00 postgres: usrdba db_test 10.70.0.61(57592) idle postgres 13833 13648 0 11:10 ? 00:00:00 postgres: usrdba db_test 10.70.0.61(57593) idle postgres 13834 13648 0 11:10 ? 00:00:00 postgres: usrdba db_test 10.70.0.61(57594) idle postgres 13835 13648 0 11:10 ? 00:00:00 postgres: usrdba db_test 10.70.0.61(57595) idle postgres 13836 13648 0 11:10 ? 00:00:00 postgres: usrdba db_test 10.70.0.61(57596) idle postgres 14201 13648 0 11:23 ? 00:00:00 postgres: nrsdba postgres 10.70.1.8(4419) idle postgres 14202 13648 0 11:23 ? 00:00:00 postgres: usrdba db_test 10.70.1.8(4420) idle postgres 14207 13648 0 11:24 ? 00:00:00 postgres: usrdba db_test 10.70.1.8(4421) idle root 18030 17992 0 13:46 pts/0 00:00:00 grep postgres example:~#