Is there a way to cancel the copying process started by calling copyIn()
method in a separate thread?
Say, I have a list of csv-files which I need to co
PostgreSQL doesn't actually support in-band query cancels.
When you request a query cancel from the JDBC driver it makes a new connection to send the cancel message. (This means that if you're at max_connections
a cancel will fail, which is kind of perverse).
The upshot of this is that you can do the same thing yourself:
Use pg_backend_pid()
to get the process ID of the worker before starting the copy operation;
When you want to cancel a copy, open a new connection and issue pg_cancel_backend(?)
with the pid recorded earlier. If it doesn't stop, you can wait a bit then do a pg_terminate_backend(?)
.
These are ordinary SQL-level functions.
The only real issue is that the cancel and terminate requests are session-level not statement level. So they can race with statement completion and the start of a new statement, eg:
At this point, the second copy will be terminated, which may not be what you wanted. So you must make sure to use appropriate exclusion client-side to prevent this from happening, making sure any outstanding cancel requests are finished before starting a new statement.
IIRC the JDBC driver has the same issue internally anyway. It's one of the reasons the team really want a way to cancel a particular unique per-session statement sequence number, like a (currently non-existent) pg_cancel_backend(pid, statementnumber)
that aborts with an error if the statement has already terminated, instead of sending the cancel anyway.