"cancelling statement due to user request error" occurs but the transaction has committed.

From: Naoya Anzai <anzai-naoya(at)mxu(dot)nes(dot)nec(dot)co(dot)jp>
To: "pgsql-hackers(at)postgresql(dot)org" <pgsql-hackers(at)postgresql(dot)org>
Cc: Akio Iwaasa <iwaasa(at)mxs(dot)nes(dot)nec(dot)co(dot)jp>
Subject: "cancelling statement due to user request error" occurs but the transaction has committed.
Date: 2014-06-06 08:41:53
Message-ID: 116262CF971C844FB6E793F8809B51C6BB3E90@BPXM02GP.gisp.nec.co.jp
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hi All,

When log_duration is true ( or log_min_duration_statement>=0 ),
If a transaction has internally been commited receives a SIGINT signal
then a query cancellation error is output.

For example,
1. A query like a TRUNCATE is removing bigger table files.
2. The session receives SIGINT signal.
3. Query cancellation error occurs.
4. But the query has commited.

e.g.)
---
naoya=# \d
List of relations
Schema | Name | Type | Owner
--------+------+-------+-------
public | hoge | table | naoya
(1 row)

naoya=# set log_duration=on;
SET
naoya=# select count(*) from hoge;
count
--------
100000
(1 row)

naoya=# truncate hoge;
Cancel request sent
ERROR: canceling statement due to user request
naoya=# select count(*) from hoge;
count
-------
0
(1 row)
---

This is because ProcessInterrupts function is called by errfinish ( in query-duration ereport).

I think this cancellation request must not interrupt the internal commited transaction.

This is because clients may misunderstand "the transaction has rollbacked".

Now,
I tried to fix the problem.

--- postgresql-fe7337f/src/backend/utils/error/elog.c 2014-06-06 11:57:44.000000000 +0900
+++ postgresql-fe7337f.new/src/backend/utils/error/elog.c 2014-06-06 13:10:51.000000000 +0900
@@ -580,7 +580,8 @@
* can stop a query emitting tons of notice or warning messages, even if
* it's in a loop that otherwise fails to check for interrupts.
*/
- CHECK_FOR_INTERRUPTS();
+ if (IsTransactionState())
+ CHECK_FOR_INTERRUPTS();
}

Thereby,
When ereport(non error level) calls and not in-transaction state,
PostgreSQL never calls ProcessInterrupts function by errfinish.

But I have a anxiety to fix errfinish function because
errfinish is called in many many situations..

Could you please confirm it?

Regards,

Naoya

---
Naoya Anzai
Engineering Department
NEC Solution Inovetors, Ltd.
E-Mail: anzai-naoya(at)mxu(dot)nes(dot)nec(dot)co(dot)jp
---

Attachment Content-Type Size
postgresql-fe7337f_elog.patch application/octet-stream 555 bytes

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Gurjeet Singh 2014-06-06 11:04:29 Re: Proposing pg_hibernate
Previous Message David Rowley 2014-06-06 08:36:28 Re: Allowing join removals for more join types