Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PostgreSQL: cancel query from C/C++ program

I'm using PostgreSQL 8.3, and writing a program in C++ that uses the libpq API. I execute commands asynchronously with the PQsendQuery() function. I'm trying to implement a timeout processing feature. I implemented it by calling PQcancel() when the timeout expires. I tested it with a query that returns 100 000 rows (it lasts about 0.5 s) with a timeout of 1 ms, and found that instead of cancelling the command, PQcancel() blocks until the server finishes execution, then returns with a successful query.

I understand that the documentation says that even with a successful cancel request the query may still be executed. My problem is that PQcancel() blocks my thread of execution, which is not acceptable because I use asynchronous processing (using the Boost Asio framework) so my program, which may have other tasks to do other than executing the SQL query, runs only on one thread.

Is it normal that PQcancel() blocks? Is there any way to make a non-blocking cancel request?

like image 858
petersohn Avatar asked Aug 02 '13 10:08

petersohn


People also ask

How do I cancel a PostgreSQL query?

In an interactive psql session, you can simply hit Ctrl+C to send a cancel request, and GUI clients usually have a button for that purpose. But it is also possible to cancel somebody else's query by calling the database function pg_cancel_backend() .

How do I terminate a connection in PostgreSQL?

In PostgreSQL there are two functions we need to take into consideration when talking about cancellation or termination: pg_cancel_backend(pid) : Terminate a query but keep the connection alive. pg_terminate_backend(pid) : Terminate a query and kill the connection.

How do you stop a query execution in Pgadmin?

Click the Stop icon to cancel the execution of the currently running query.


1 Answers

I looked at the implementation of PQcancel. It creates a separate TCP connection to the server, that's why it is blocking. This code part is exactly the same in the newest version of PostgreSQL too. So I concluded that there is no way to make it nonblocking other than starting the cancel in a separate thread. This is also the preferred way of using this feature, as the cancel object is completely independent from the connection object thus it is completely thread safe to use.

like image 140
petersohn Avatar answered Oct 09 '22 01:10

petersohn