How to abort JDBC Postgresql CopyManager copying?

前端 未结 2 942
野趣味
野趣味 2021-01-14 20:03

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

2条回答
  •  有刺的猬
    2021-01-14 20:14

    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:

    • client1: COPY starts
    • client2: connects to send cancel message
    • client1: copy finishes
    • client1: new separate copy starts
    • client2 sends pg_cancel_backend(...)

    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.

提交回复
热议问题