У меня есть много фоновых заданий, которые ставят в очередь один и тот же запрос.
У меня была ситуация, когда они застряли, и я хотел бы каким-то простым способом убить действительно длинные запросы, которые не снимут всю БД.
Как я могу сделать это с помощью запроса?
Предположим, что мой запрос выглядит следующим образом, и я хочу убить все, что работает более 60 минут.
select * from some_big_table
;
Это лучшее, что я мог придумать. Примечание. Я работаю на Mac
Сначала я сгенерировал MD5 своего запроса в командной строке. Я сделал это, чтобы упростить внешний вид запроса, чтобы убедиться, что я сопоставил только свой целевой запрос, и чтобы избежать «внедрения sql» самостоятельно, если я ошибся в своем запросе.
# on linux, use 'md5sum' instead.
$ echo -n 'select * from some_big_table;' | md5
65007f37ff78f1e66645105412430b7c
Затем я просто использовал подзапрос, чтобы отфильтровать любые другие запросы, которые не выполнялись более 60 минут.
SELECT pg_cancel_backend(pid)
FROM pg_stat_activity
WHERE
now() - pg_stat_activity.query_start >= interval '60 minutes' AND
md5(query) = '65007f37ff78f1e66645105412430b7c' AND
state = 'active';
который, казалось, работал нормально
pg_cancel_backend
-------------------
t
t
(2 rows)