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

Commit316c4c5

Browse files
committed
Clean up some problems in error recovery --- elog() was pretty broken
for the case of errors in backend startup, and proc_exit's method forcoping with errors during proc_exit was *completely* busted. Fixed perdiscussions on pghackers around 11/6/99.
1 parentbb203c7 commit316c4c5

File tree

3 files changed

+66
-70
lines changed

3 files changed

+66
-70
lines changed

‎src/backend/storage/ipc/ipc.c

Lines changed: 35 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/*-------------------------------------------------------------------------
1+
/*-------------------------------------------------------------------------
22
*
33
* ipc.c
44
* POSTGRES inter-process communication definitions.
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/storage/ipc/ipc.c,v 1.42 1999/11/06 19:46:57 momjian Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/storage/ipc/ipc.c,v 1.43 1999/11/22 02:06:31 tgl Exp $
1111
*
1212
* NOTES
1313
*
@@ -28,8 +28,8 @@
2828
#include<sys/file.h>
2929
#include<errno.h>
3030

31-
3231
#include"postgres.h"
32+
3333
#include"storage/ipc.h"
3434
#include"storage/s_lock.h"
3535
/* In Ultrix, sem.h and shm.h must be included AFTER ipc.h */
@@ -43,6 +43,13 @@
4343
#include<sys/ipc.h>
4444
#endif
4545

46+
/*
47+
* This flag is set during proc_exit() to change elog()'s behavior,
48+
* so that an elog() from an on_proc_exit routine cannot get us out
49+
* of the exit procedure. We do NOT want to go back to the idle loop...
50+
*/
51+
boolproc_exit_inprogress= false;
52+
4653
staticintUsePrivateMemory=0;
4754

4855
staticvoidIpcMemoryDetach(intstatus,char*shmaddr);
@@ -70,7 +77,8 @@ typedef struct _PrivateMemStruct
7077
char*memptr;
7178
}PrivateMem;
7279

73-
PrivateMemIpcPrivateMem[16];
80+
staticPrivateMemIpcPrivateMem[16];
81+
7482

7583
staticint
7684
PrivateMemoryCreate(IpcMemoryKeymemKey,
@@ -105,45 +113,34 @@ PrivateMemoryAttach(IpcMemoryId memid)
105113
*-cim 2/6/90
106114
* ----------------------------------------------------------------
107115
*/
108-
staticintproc_exit_inprogress=0;
109-
110116
void
111117
proc_exit(intcode)
112118
{
113-
inti;
114-
115-
TPRINTF(TRACE_VERBOSE,"proc_exit(%d) [#%d]",code,proc_exit_inprogress);
116-
117119
/*
118-
*If proc_exit is called too many times something bad is happening, so
119-
*exit immediately. This is crafted in two if's for a reason.
120+
*Once we set this flag, we are committed to exit. Any elog() will
121+
*NOT send control back to the main loop, but right back here.
120122
*/
123+
proc_exit_inprogress= true;
121124

122-
if (++proc_exit_inprogress==9)
123-
elog(ERROR,"infinite recursion in proc_exit");
124-
if (proc_exit_inprogress >=9)
125-
gotoexit;
126-
127-
/* ----------------
128-
*if proc_exit_inprocess > 1, then it means that we
129-
*are being invoked from within an on_exit() handler
130-
*and so we return immediately to avoid recursion.
131-
* ----------------
132-
*/
133-
if (proc_exit_inprogress>1)
134-
return;
125+
TPRINTF(TRACE_VERBOSE,"proc_exit(%d)",code);
135126

136127
/* do our shared memory exits first */
137128
shmem_exit(code);
138129

139130
/* ----------------
140131
*call all the callbacks registered before calling exit().
132+
*
133+
*Note that since we decrement on_proc_exit_index each time,
134+
*if a callback calls elog(ERROR) or elog(FATAL) then it won't
135+
*be invoked again when control comes back here (nor will the
136+
*previously-completed callbacks). So, an infinite loop
137+
*should not be possible.
141138
* ----------------
142139
*/
143-
for (i=on_proc_exit_index-1;i >=0;--i)
144-
(*on_proc_exit_list[i].function) (code,on_proc_exit_list[i].arg);
140+
while (--on_proc_exit_index >=0)
141+
(*on_proc_exit_list[on_proc_exit_index].function) (code,
142+
on_proc_exit_list[on_proc_exit_index].arg);
145143

146-
exit:
147144
TPRINTF(TRACE_VERBOSE,"exit(%d)",code);
148145
exit(code);
149146
}
@@ -154,44 +151,23 @@ proc_exit(int code)
154151
* semaphores after a backend dies horribly
155152
* ------------------
156153
*/
157-
staticintshmem_exit_inprogress=0;
158-
159154
void
160155
shmem_exit(intcode)
161156
{
162-
inti;
163-
164-
TPRINTF(TRACE_VERBOSE,"shmem_exit(%d) [#%d]",
165-
code,shmem_exit_inprogress);
166-
167-
/*
168-
* If shmem_exit is called too many times something bad is happenig,
169-
* so exit immediately.
170-
*/
171-
if (shmem_exit_inprogress>9)
172-
{
173-
elog(ERROR,"infinite recursion in shmem_exit");
174-
exit(-1);
175-
}
176-
177-
/* ----------------
178-
*if shmem_exit_inprocess is true, then it means that we
179-
*are being invoked from within an on_exit() handler
180-
*and so we return immediately to avoid recursion.
181-
* ----------------
182-
*/
183-
if (shmem_exit_inprogress++)
184-
return;
157+
TPRINTF(TRACE_VERBOSE,"shmem_exit(%d)",code);
185158

186159
/* ----------------
187-
*call all the callbacks registered before calling exit().
160+
*call all the registered callbacks.
161+
*
162+
*As with proc_exit(), we remove each callback from the list
163+
*before calling it, to avoid infinite loop in case of error.
188164
* ----------------
189165
*/
190-
for (i=on_shmem_exit_index-1;i >=0;--i)
191-
(*on_shmem_exit_list[i].function) (code,on_shmem_exit_list[i].arg);
166+
while (--on_shmem_exit_index >=0)
167+
(*on_shmem_exit_list[on_shmem_exit_index].function) (code,
168+
on_shmem_exit_list[on_shmem_exit_index].arg);
192169

193170
on_shmem_exit_index=0;
194-
shmem_exit_inprogress=0;
195171
}
196172

197173
/* ----------------------------------------------------------------
@@ -202,7 +178,7 @@ shmem_exit(int code)
202178
* ----------------------------------------------------------------
203179
*/
204180
int
205-
on_proc_exit(void (*function) (),caddr_targ)
181+
on_proc_exit(void (*function) (),caddr_targ)
206182
{
207183
if (on_proc_exit_index >=MAX_ON_EXITS)
208184
return-1;
@@ -223,7 +199,7 @@ int
223199
* ----------------------------------------------------------------
224200
*/
225201
int
226-
on_shmem_exit(void (*function) (),caddr_targ)
202+
on_shmem_exit(void (*function) (),caddr_targ)
227203
{
228204
if (on_shmem_exit_index >=MAX_ON_EXITS)
229205
return-1;

‎src/backend/utils/error/elog.c

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/utils/error/elog.c,v 1.51 1999/11/1606:13:36 tgl Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/utils/error/elog.c,v 1.52 1999/11/22 02:06:31 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -30,6 +30,7 @@
3030
#include"libpq/libpq.h"
3131
#include"libpq/pqformat.h"
3232
#include"miscadmin.h"
33+
#include"storage/ipc.h"
3334
#include"storage/proc.h"
3435
#include"tcop/tcopprot.h"
3536
#include"utils/trace.h"
@@ -371,21 +372,38 @@ elog(int lev, const char *fmt, ...)
371372
*/
372373
if (lev==ERROR||lev==FATAL)
373374
{
374-
if (InError)
375+
/*
376+
* If we have not yet entered the main backend loop (ie, we are in
377+
* the postmaster or in backend startup), then go directly to
378+
* proc_exit. The same is true if anyone tries to report an error
379+
* after proc_exit has begun to run. (It's proc_exit's responsibility
380+
* to see that this doesn't turn into infinite recursion!) But in
381+
* the latter case, we exit with nonzero exit code to indicate that
382+
* something's pretty wrong.
383+
*/
384+
if (proc_exit_inprogress|| !Warn_restart_ready)
375385
{
376-
/* error reported during error recovery; don't loop forever */
377-
elog(REALLYFATAL,"elog: error during error recovery, giving up!");
386+
fflush(stdout);
387+
fflush(stderr);
388+
ProcReleaseSpins(NULL);/* get rid of spinlocks we hold */
389+
ProcReleaseLocks();/* get rid of real locks we hold */
390+
/* XXX shouldn't proc_exit be doing the above?? */
391+
proc_exit((int)proc_exit_inprogress);
378392
}
393+
/*
394+
* Guard against infinite loop from elog() during error recovery.
395+
*/
396+
if (InError)
397+
elog(REALLYFATAL,"elog: error during error recovery, giving up!");
379398
InError= true;
399+
/*
400+
* Otherwise we can return to the main loop in postgres.c.
401+
* In the FATAL case, postgres.c will call proc_exit, but not
402+
* till after completing a standard transaction-abort sequence.
403+
*/
380404
ProcReleaseSpins(NULL);/* get rid of spinlocks we hold */
381-
if (!Warn_restart_ready)
382-
{
383-
/* error reported before there is a main loop to return to */
384-
elog(REALLYFATAL,"elog: error in postmaster or backend startup, giving up!");
385-
}
386405
if (lev==FATAL)
387406
ExitAfterAbort= true;
388-
/* exit to main loop */
389407
siglongjmp(Warn_restart,1);
390408
}
391409

‎src/include/storage/ipc.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
*
77
* Copyright (c) 1994, Regents of the University of California
88
*
9-
* $Id: ipc.h,v 1.36 1999/10/06 21:58:17 vadim Exp $
9+
* $Id: ipc.h,v 1.37 1999/11/22 02:06:30 tgl Exp $
1010
*
1111
* NOTES
1212
* This file is very architecture-specific.This stuff should actually
@@ -71,6 +71,8 @@ typedef int IpcMemoryId;
7171

7272

7373
/* ipc.c */
74+
externboolproc_exit_inprogress;
75+
7476
externvoidproc_exit(intcode);
7577
externvoidshmem_exit(intcode);
7678
externinton_shmem_exit(void (*function) (),caddr_targ);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp