PostgreSQL: получить PID запроса через dblink до его завершения

Я хочу контролировать свои запросы, которые я отправляю через dblink dblink_send_query, и поэтому мне нужен его PID, чтобы я мог искать его в таблицах pg. Но до сих пор мне удавалось получить PID только после завершения dblink путем возврата значения pg_backend_pid() или делать это довольно неуклюже, получая его из pg_stat_activity путем поиска по строке запроса, которая не учитывает несколько одинаковых запросов или действительно не идеален для запросов, содержащих длинный текст.

Итак, как я могу получить для этого PID до его завершения?

select dblink_send_query('cn1', 'select pg_sleep(60)');
select dblink_send_query('cn2', 'select pg_sleep(60)');
select dblink_send_query('cn3', 'select pg_sleep(60)');

PostgreSQL 11.6 на x86_64-pc-linux-gnu, скомпилирован gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-39), 64-разрядная версия


person Baker    schedule 11.12.2019    source источник


Ответы (1)


Идентификатор внутреннего процесса останется неизменным на протяжении всего срока действия соединения dblink.

Поэтому, когда вы открываете соединение, сначала запустите SELECT pg_backend_pid() и сохраните результат в структуре данных, где он связан с соединением. Затем вы можете просто запросить эту структуру данных, чтобы получить идентификатор внутреннего процесса для этого соединения.

person Laurenz Albe    schedule 11.12.2019
comment
но проблема в том, что dblink создает собственное соединение, поэтому, если я использую SELECT pg_backend_pid (), он даст мне текущий, а не один из dblink, не могли бы вы показать мне, как это сделать в этом примере - person Baker; 11.12.2019
comment
do $$ begin выполнить dblink_connect ('cn1', 'fdw_cdc'); выполнить dblink_connect ('cn2', 'fdw_cdc'); выполнить dblink_connect ('cn3', 'fdw_cdc'); выполнить dblink_send_query ('cn1', 'выбрать pg_sleep (60)'); выполнить dblink_send_query ('cn2', 'выбрать pg_sleep (60)'); выполнить dblink_send_query ('cn3', 'выбрать pg_sleep (60)'); выполнить pg_sleep (60); выполнить dblink_disconnect ('cn1'); выполнить dblink_disconnect ('cn2'); выполнить dblink_disconnect ('cn3'); конец $$ - person Baker; 11.12.2019
comment
Нет. perform dblink_connect ('cn1', 'fdw_cdc');, затем SELECT dblink_send_query('cn1', 'select pg_backend_pid()') и запомните результат на потом. - person Laurenz Albe; 11.12.2019
comment
хорошо, я понимаю, что вы имеете в виду, но есть проблема, если я использую соединение dblink в функции, чтобы получить мне pid, я больше не могу использовать это соединение, потому что, когда я пытаюсь отправить свой запрос после того, как я получаю pid, я получаю сообщение об ошибке, не могу отправить запрос: другая команда уже выполняется, см. здесь codepile.net/pile/VdNJKndb - person Baker; 11.12.2019
comment
Я забыл ... Используйте dblink_exec для этого запроса, чтобы получить синхронное выполнение. - person Laurenz Albe; 11.12.2019
comment
но я использую его из-за параллельных возможностей использования нашего многоядерного сервера, и весь смысл моего мониторинга состоит в том, чтобы убедиться, что он работает без сбоев ... так есть ли способ получить PID для этих асинхронных dblinks? - person Baker; 11.12.2019
comment
Почему? Этот запрос будет очень быстрым, определенно быстрее, чем установление соединения. Считайте это частью процесса установления соединения dblink. - person Laurenz Albe; 11.12.2019
comment
ах, вы имели в виду dblink_exec только для получения PID, получите его :) .... но единственное, что он должен быть dblink, а не dblink_exec, потому что он получит сообщение об ошибке, возвращающее недопустимые результаты ... но большое спасибо за помощь, теперь это работает - person Baker; 11.12.2019
comment
Правильно, извините за то, что перепутали функции. - person Laurenz Albe; 11.12.2019