Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit82170c7

Browse files
committed
Fix (some of the) breakage introduced into query-cancel processing by HS.
It is absolutely not okay to throw an ereport(ERROR) in any random place inthe code just because DoingCommandRead is set; interrupting, say, OpenSSLin the midst of its activities is guaranteed to result in heartache.Instead of that, undo the original optimizations that threw awayQueryCancelPending anytime we were starting or finishing a command read, andinstead discard the cancel request within ProcessInterrupts if we find thatthere is no HS reason for forcing a cancel and we are DoingCommandRead.In passing, may I once again condemn the practice of changing the codeand not fixing the adjacent comment that you just turned into a lie?
1 parent6fb7911 commit82170c7

File tree

1 file changed

+60
-37
lines changed

1 file changed

+60
-37
lines changed

‎src/backend/tcop/postgres.c

Lines changed: 60 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.580 2010/01/02 16:57:52 momjian Exp $
11+
* $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.581 2010/01/07 16:29:58 tgl Exp $
1212
*
1313
* NOTES
1414
* this is the "main" module of the postgres backend and
@@ -476,11 +476,10 @@ prepare_for_client_read(void)
476476
EnableNotifyInterrupt();
477477
EnableCatchupInterrupt();
478478

479-
/* Allow"die" interrupt to be processed while waiting */
479+
/* Allowcancel/die interrupts to be processed while waiting */
480480
ImmediateInterruptOK= true;
481481

482482
/* And don't forget to detect one that already arrived */
483-
QueryCancelPending= false;
484483
CHECK_FOR_INTERRUPTS();
485484
}
486485
}
@@ -494,7 +493,6 @@ client_read_ended(void)
494493
if (DoingCommandRead)
495494
{
496495
ImmediateInterruptOK= false;
497-
QueryCancelPending= false;/* forget any CANCEL signal */
498496

499497
DisableNotifyInterrupt();
500498
DisableCatchupInterrupt();
@@ -2640,12 +2638,11 @@ StatementCancelHandler(SIGNAL_ARGS)
26402638
QueryCancelPending= true;
26412639

26422640
/*
2643-
* If it's safe to interrupt, and we're waiting for a lock, service
2644-
* the interrupt immediately. No point in interrupting if we're
2645-
* waiting for input, however.
2641+
* If it's safe to interrupt, and we're waiting for input or a lock,
2642+
* service the interrupt immediately
26462643
*/
2647-
if (InterruptHoldoffCount==0&&CritSectionCount==0&&
2648-
(DoingCommandRead||ImmediateInterruptOK))
2644+
if (ImmediateInterruptOK&&InterruptHoldoffCount==0&&
2645+
CritSectionCount==0)
26492646
{
26502647
/* bump holdoff count to make ProcessInterrupts() a no-op */
26512648
/* until we are done getting ready for it */
@@ -2717,25 +2714,36 @@ ProcessInterrupts(void)
27172714
if (QueryCancelPending)
27182715
{
27192716
QueryCancelPending= false;
2720-
ImmediateInterruptOK= false;/* not idle anymore */
2721-
DisableNotifyInterrupt();
2722-
DisableCatchupInterrupt();
2723-
/* As in quickdie, don't risk sending to client during auth */
2724-
if (ClientAuthInProgress&&whereToSendOutput==DestRemote)
2725-
whereToSendOutput=DestNone;
27262717
if (ClientAuthInProgress)
2718+
{
2719+
ImmediateInterruptOK= false;/* not idle anymore */
2720+
DisableNotifyInterrupt();
2721+
DisableCatchupInterrupt();
2722+
/* As in quickdie, don't risk sending to client during auth */
2723+
if (whereToSendOutput==DestRemote)
2724+
whereToSendOutput=DestNone;
27272725
ereport(ERROR,
27282726
(errcode(ERRCODE_QUERY_CANCELED),
27292727
errmsg("canceling authentication due to timeout")));
2730-
elseif (cancel_from_timeout)
2728+
}
2729+
if (cancel_from_timeout)
2730+
{
2731+
ImmediateInterruptOK= false;/* not idle anymore */
2732+
DisableNotifyInterrupt();
2733+
DisableCatchupInterrupt();
27312734
ereport(ERROR,
27322735
(errcode(ERRCODE_QUERY_CANCELED),
27332736
errmsg("canceling statement due to statement timeout")));
2734-
elseif (IsAutoVacuumWorkerProcess())
2737+
}
2738+
if (IsAutoVacuumWorkerProcess())
2739+
{
2740+
ImmediateInterruptOK= false;/* not idle anymore */
2741+
DisableNotifyInterrupt();
2742+
DisableCatchupInterrupt();
27352743
ereport(ERROR,
27362744
(errcode(ERRCODE_QUERY_CANCELED),
27372745
errmsg("canceling autovacuum task")));
2738-
else
2746+
}
27392747
{
27402748
intcancelMode=MyProc->recoveryConflictMode;
27412749

@@ -2756,34 +2764,50 @@ ProcessInterrupts(void)
27562764
switch (cancelMode)
27572765
{
27582766
caseCONFLICT_MODE_FATAL:
2759-
Assert(RecoveryInProgress());
2760-
ereport(FATAL,
2767+
ImmediateInterruptOK= false;/* not idle anymore */
2768+
DisableNotifyInterrupt();
2769+
DisableCatchupInterrupt();
2770+
Assert(RecoveryInProgress());
2771+
ereport(FATAL,
27612772
(errcode(ERRCODE_QUERY_CANCELED),
27622773
errmsg("canceling session due to conflict with recovery")));
27632774

27642775
caseCONFLICT_MODE_ERROR:
2765-
/*
2766-
* We are aborting because we need to release
2767-
* locks. So we need to abort out of all
2768-
* subtransactions to make sure we release
2769-
* all locks at whatever their level.
2770-
*
2771-
* XXX Should we try to examine the
2772-
* transaction tree and cancel just enough
2773-
* subxacts to remove locks? Doubt it.
2774-
*/
2775-
Assert(RecoveryInProgress());
2776-
AbortOutOfAnyTransaction();
2777-
ereport(ERROR,
2776+
/*
2777+
* We are aborting because we need to release
2778+
* locks. So we need to abort out of all
2779+
* subtransactions to make sure we release
2780+
* all locks at whatever their level.
2781+
*
2782+
* XXX Should we try to examine the
2783+
* transaction tree and cancel just enough
2784+
* subxacts to remove locks? Doubt it.
2785+
*/
2786+
ImmediateInterruptOK= false;/* not idle anymore */
2787+
DisableNotifyInterrupt();
2788+
DisableCatchupInterrupt();
2789+
Assert(RecoveryInProgress());
2790+
AbortOutOfAnyTransaction();
2791+
ereport(ERROR,
27782792
(errcode(ERRCODE_QUERY_CANCELED),
27792793
errmsg("canceling statement due to conflict with recovery")));
2780-
return;
27812794

27822795
default:
2783-
/* No conflict pending, so fall through */
2784-
break;
2796+
/* No conflict pending, so fall through */
2797+
break;
27852798
}
2799+
}
27862800

2801+
/*
2802+
* If we are reading a command from the client, just ignore the
2803+
* cancel request --- sending an extra error message won't
2804+
* accomplish anything. Otherwise, go ahead and throw the error.
2805+
*/
2806+
if (!DoingCommandRead)
2807+
{
2808+
ImmediateInterruptOK= false;/* not idle anymore */
2809+
DisableNotifyInterrupt();
2810+
DisableCatchupInterrupt();
27872811
ereport(ERROR,
27882812
(errcode(ERRCODE_QUERY_CANCELED),
27892813
errmsg("canceling statement due to user request")));
@@ -3626,7 +3650,6 @@ PostgresMain(int argc, char *argv[], const char *username)
36263650
* conditional since we don't want, say, reads on behalf of COPY FROM
36273651
* STDIN doing the same thing.)
36283652
*/
3629-
QueryCancelPending= false;/* forget any earlier CANCEL signal */
36303653
DoingCommandRead= true;
36313654

36323655
/*

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp