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@mxu.nes.nec.co.jp
---