Skip to content

Commit 7117cd3

Browse files
committed
Cause ShutdownPostgres to do a normal transaction abort during backend
exit, instead of trying to take shortcuts. Introduce some additional shutdown callback routines to eliminate kluges like having ProcKill be responsible for shutting down the buffer manager. Ensure that the order of operations during shutdown is predictable and what you would expect given the module layering.
1 parent 89439b8 commit 7117cd3

File tree

11 files changed

+119
-100
lines changed

11 files changed

+119
-100
lines changed

src/backend/bootstrap/bootstrap.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/bootstrap/bootstrap.c,v 1.205 2005/07/04 04:51:45 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/bootstrap/bootstrap.c,v 1.206 2005/08/08 03:11:30 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -378,9 +378,14 @@ BootstrapMain(int argc, char *argv[])
378378

379379
BaseInit();
380380

381-
/* needed to get LWLocks */
381+
/*
382+
* We aren't going to do the full InitPostgres pushups, but there
383+
* are a couple of things that need to get lit up even in a dummy
384+
* process.
385+
*/
382386
if (IsUnderPostmaster)
383387
{
388+
/* set up proc.c to get use of LWLocks */
384389
switch (xlogop)
385390
{
386391
case BS_XLOG_BGWRITER:
@@ -391,6 +396,9 @@ BootstrapMain(int argc, char *argv[])
391396
InitDummyProcess(DUMMY_PROC_DEFAULT);
392397
break;
393398
}
399+
400+
/* finish setting up bufmgr.c */
401+
InitBufferPoolBackend();
394402
}
395403

396404
/*

src/backend/postmaster/pgstat.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
*
1414
* Copyright (c) 2001-2005, PostgreSQL Global Development Group
1515
*
16-
* $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.102 2005/07/29 19:30:04 tgl Exp $
16+
* $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.103 2005/08/08 03:11:40 tgl Exp $
1717
* ----------
1818
*/
1919
#include "postgres.h"
@@ -665,7 +665,7 @@ pgstat_report_autovac(void)
665665
* pgstat_bestart() -
666666
*
667667
* Tell the collector that this new backend is soon ready to process
668-
* queries. Called from tcop/postgres.c before entering the mainloop.
668+
* queries. Called from InitPostgres.
669669
* ----------
670670
*/
671671
void
@@ -686,7 +686,7 @@ pgstat_bestart(void)
686686
* Set up a process-exit hook to ensure we flush the last batch of
687687
* statistics to the collector.
688688
*/
689-
on_proc_exit(pgstat_beshutdown_hook, 0);
689+
on_shmem_exit(pgstat_beshutdown_hook, 0);
690690
}
691691

692692
/* ---------
@@ -738,9 +738,7 @@ pgstat_report_analyze(Oid tableoid, bool shared, PgStat_Counter livetuples,
738738
/*
739739
* Flush any remaining statistics counts out to the collector at process
740740
* exit. Without this, operations triggered during backend exit (such as
741-
* temp table deletions) won't be counted. This is an on_proc_exit hook,
742-
* not on_shmem_exit, so that everything interesting must have happened
743-
* already.
741+
* temp table deletions) won't be counted.
744742
*/
745743
static void
746744
pgstat_beshutdown_hook(int code, Datum arg)

src/backend/storage/buffer/buf_init.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/storage/buffer/buf_init.c,v 1.73 2005/05/19 21:35:46 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/storage/buffer/buf_init.c,v 1.74 2005/08/08 03:11:44 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -149,6 +149,7 @@ InitBufferPool(void)
149149
* NB: this is called before InitProcess(), so we do not have a PGPROC and
150150
* cannot do LWLockAcquire; hence we can't actually access stuff in
151151
* shared memory yet. We are only initializing local data here.
152+
* (See also InitBufferPoolBackend, over in bufmgr.c.)
152153
*/
153154
void
154155
InitBufferPoolAccess(void)

src/backend/storage/buffer/bufmgr.c

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/storage/buffer/bufmgr.c,v 1.190 2005/08/02 20:52:08 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/storage/buffer/bufmgr.c,v 1.191 2005/08/08 03:11:44 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -45,6 +45,7 @@
4545
#include "storage/buf_internals.h"
4646
#include "storage/bufmgr.h"
4747
#include "storage/bufpage.h"
48+
#include "storage/ipc.h"
4849
#include "storage/proc.h"
4950
#include "storage/smgr.h"
5051
#include "utils/relcache.h"
@@ -93,6 +94,7 @@ static void buffer_write_error_callback(void *arg);
9394
static BufferDesc *BufferAlloc(Relation reln, BlockNumber blockNum,
9495
bool *foundPtr);
9596
static void FlushBuffer(BufferDesc *buf, SMgrRelation reln);
97+
static void AtProcExit_Buffers(int code, Datum arg);
9698
static void write_buffer(Buffer buffer, bool unpin);
9799

98100

@@ -1080,10 +1082,25 @@ AtEOXact_Buffers(bool isCommit)
10801082
}
10811083

10821084
/*
1083-
* Ensure we have released all shared-buffer locks and pins during backend exit
1085+
* InitBufferPoolBackend --- second-stage initialization of a new backend
1086+
*
1087+
* This is called after we have acquired a PGPROC and so can safely get
1088+
* LWLocks. We don't currently need to do anything at this stage ...
1089+
* except register a shmem-exit callback. AtProcExit_Buffers needs LWLock
1090+
* access, and thereby has to be called at the corresponding phase of
1091+
* backend shutdown.
10841092
*/
10851093
void
1086-
AtProcExit_Buffers(void)
1094+
InitBufferPoolBackend(void)
1095+
{
1096+
on_shmem_exit(AtProcExit_Buffers, 0);
1097+
}
1098+
1099+
/*
1100+
* Ensure we have released all shared-buffer locks and pins during backend exit
1101+
*/
1102+
static void
1103+
AtProcExit_Buffers(int code, Datum arg)
10871104
{
10881105
int i;
10891106

@@ -1105,6 +1122,9 @@ AtProcExit_Buffers(void)
11051122
Assert(PrivateRefCount[i] == 0);
11061123
}
11071124
}
1125+
1126+
/* localbuf.c needs a chance too */
1127+
AtProcExit_LocalBuffers();
11081128
}
11091129

11101130
/*

src/backend/storage/file/fd.c

Lines changed: 29 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
99
* IDENTIFICATION
10-
* $PostgreSQL: pgsql/src/backend/storage/file/fd.c,v 1.119 2005/08/07 18:47:19 tgl Exp $
10+
* $PostgreSQL: pgsql/src/backend/storage/file/fd.c,v 1.120 2005/08/08 03:11:49 tgl Exp $
1111
*
1212
* NOTES:
1313
*
@@ -296,6 +296,33 @@ pg_fdatasync(int fd)
296296
return 0;
297297
}
298298

299+
/*
300+
* InitFileAccess --- initialize this module during backend startup
301+
*
302+
* This is called during either normal or standalone backend start.
303+
* It is *not* called in the postmaster.
304+
*/
305+
void
306+
InitFileAccess(void)
307+
{
308+
Assert(SizeVfdCache == 0); /* call me only once */
309+
310+
/* initialize cache header entry */
311+
VfdCache = (Vfd *) malloc(sizeof(Vfd));
312+
if (VfdCache == NULL)
313+
ereport(FATAL,
314+
(errcode(ERRCODE_OUT_OF_MEMORY),
315+
errmsg("out of memory")));
316+
317+
MemSet((char *) &(VfdCache[0]), 0, sizeof(Vfd));
318+
VfdCache->fd = VFD_CLOSED;
319+
320+
SizeVfdCache = 1;
321+
322+
/* register proc-exit hook to ensure temp files are dropped at exit */
323+
on_proc_exit(AtProcExit_Files, 0);
324+
}
325+
299326
/*
300327
* count_usable_fds --- count how many FDs the system will let us open,
301328
* and estimate how many are already open.
@@ -622,25 +649,7 @@ AllocateVfd(void)
622649

623650
DO_DB(elog(LOG, "AllocateVfd. Size %d", SizeVfdCache));
624651

625-
if (SizeVfdCache == 0)
626-
{
627-
/* initialize header entry first time through */
628-
VfdCache = (Vfd *) malloc(sizeof(Vfd));
629-
if (VfdCache == NULL)
630-
ereport(FATAL,
631-
(errcode(ERRCODE_OUT_OF_MEMORY),
632-
errmsg("out of memory")));
633-
MemSet((char *) &(VfdCache[0]), 0, sizeof(Vfd));
634-
VfdCache->fd = VFD_CLOSED;
635-
636-
SizeVfdCache = 1;
637-
638-
/*
639-
* register proc-exit call to ensure temp files are dropped at
640-
* exit
641-
*/
642-
on_proc_exit(AtProcExit_Files, 0);
643-
}
652+
Assert(SizeVfdCache > 0); /* InitFileAccess not called? */
644653

645654
if (VfdCache[0].nextFree == 0)
646655
{

src/backend/storage/lmgr/proc.c

Lines changed: 12 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/storage/lmgr/proc.c,v 1.161 2005/07/31 17:19:19 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/storage/lmgr/proc.c,v 1.162 2005/08/08 03:11:55 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -144,7 +144,7 @@ InitProcGlobal(void)
144144
ShmemInitStruct("Proc Header", sizeof(PROC_HDR), &foundProcGlobal);
145145

146146
/*
147-
* Create or attach to the PGPROC structures for dummy (checkpoint)
147+
* Create or attach to the PGPROC structures for dummy (bgwriter)
148148
* processes, too. These do not get linked into the freeProcs list.
149149
*/
150150
DummyProcs = (PGPROC *)
@@ -289,9 +289,10 @@ InitProcess(void)
289289
/*
290290
* InitDummyProcess -- create a dummy per-process data structure
291291
*
292-
* This is called by checkpoint processes so that they will have a MyProc
293-
* value that's real enough to let them wait for LWLocks. The PGPROC and
294-
* sema that are assigned are the extra ones created during InitProcGlobal.
292+
* This is called by bgwriter and similar processes so that they will have a
293+
* MyProc value that's real enough to let them wait for LWLocks. The PGPROC
294+
* and sema that are assigned are the extra ones created during
295+
* InitProcGlobal.
295296
*
296297
* Dummy processes are presently not expected to wait for real (lockmgr)
297298
* locks, nor to participate in sinval messaging.
@@ -485,27 +486,12 @@ ProcKill(int code, Datum arg)
485486

486487
Assert(MyProc != NULL);
487488

488-
/* Release any LW locks I am holding */
489-
LWLockReleaseAll();
490-
491489
/*
492-
* Make real sure we release any buffer locks and pins we might be
493-
* holding, too. It is pretty ugly to do this here and not in a
494-
* shutdown callback registered by the bufmgr ... but we must do this
495-
* *after* LWLockReleaseAll and *before* zapping MyProc.
490+
* Release any LW locks I am holding. There really shouldn't be any,
491+
* but it's cheap to check again before we cut the knees off the LWLock
492+
* facility by releasing our PGPROC ...
496493
*/
497-
AtProcExit_Buffers();
498-
499-
/* Get off any wait queue I might be on */
500-
LockWaitCancel();
501-
502-
/* Remove from the standard lock table */
503-
LockReleaseAll(DEFAULT_LOCKMETHOD, true);
504-
505-
#ifdef USER_LOCKS
506-
/* Remove from the user lock table */
507-
LockReleaseAll(USER_LOCKMETHOD, true);
508-
#endif
494+
LWLockReleaseAll();
509495

510496
/* Remove our PGPROC from the PGPROC array in shared memory */
511497
ProcArrayRemove(MyProc);
@@ -523,7 +509,7 @@ ProcKill(int code, Datum arg)
523509
}
524510

525511
/*
526-
* DummyProcKill() -- Cut-down version of ProcKill for dummy (checkpoint)
512+
* DummyProcKill() -- Cut-down version of ProcKill for dummy (bgwriter)
527513
* processes. The PGPROC and sema are not released, only marked
528514
* as not-in-use.
529515
*/
@@ -539,14 +525,9 @@ DummyProcKill(int code, Datum arg)
539525

540526
Assert(MyProc == dummyproc);
541527

542-
/* Release any LW locks I am holding */
528+
/* Release any LW locks I am holding (see notes above) */
543529
LWLockReleaseAll();
544530

545-
/* Release buffer locks and pins, too */
546-
AtProcExit_Buffers();
547-
548-
/* I can't be on regular lock queues, so needn't check */
549-
550531
/* Mark dummy proc no longer in use */
551532
MyProc->pid = 0;
552533

src/backend/storage/smgr/smgr.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
*
1212
*
1313
* IDENTIFICATION
14-
* $PostgreSQL: pgsql/src/backend/storage/smgr/smgr.c,v 1.91 2005/06/20 18:37:01 tgl Exp $
14+
* $PostgreSQL: pgsql/src/backend/storage/smgr/smgr.c,v 1.92 2005/08/08 03:12:02 tgl Exp $
1515
*
1616
*-------------------------------------------------------------------------
1717
*/
@@ -136,11 +136,12 @@ static void smgr_internal_unlink(RelFileNode rnode, int which,
136136

137137

138138
/*
139-
* smgrinit(), smgrshutdown() -- Initialize or shut down all storage
139+
* smgrinit(), smgrshutdown() -- Initialize or shut down storage
140140
* managers.
141141
*
142-
* Note: in the normal multiprocess scenario with a postmaster, these are
143-
* called at postmaster start and stop, not per-backend.
142+
* Note: smgrinit is called during backend startup (normal or standalone
143+
* case), *not* during postmaster start. Therefore, any resources created
144+
* here or destroyed in smgrshutdown are backend-local.
144145
*/
145146
void
146147
smgrinit(void)
@@ -162,6 +163,9 @@ smgrinit(void)
162163
on_proc_exit(smgrshutdown, 0);
163164
}
164165

166+
/*
167+
* on_proc_exit hook for smgr cleanup during backend shutdown
168+
*/
165169
static void
166170
smgrshutdown(int code, Datum arg)
167171
{

src/backend/tcop/postgres.c

Lines changed: 1 addition & 8 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.455 2005/07/21 03:56:11 momjian Exp $
11+
* $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.456 2005/08/08 03:12:12 tgl Exp $
1212
*
1313
* NOTES
1414
* this is the "main" module of the postgres backend and
@@ -2953,13 +2953,6 @@ PostgresMain(int argc, char *argv[], const char *username)
29532953
ALLOCSET_DEFAULT_INITSIZE,
29542954
ALLOCSET_DEFAULT_MAXSIZE);
29552955

2956-
/* ----------
2957-
* Tell the statistics collector that we're alive and
2958-
* to which database we belong.
2959-
* ----------
2960-
*/
2961-
pgstat_bestart();
2962-
29632956
/*
29642957
* Remember stand-alone backend startup time
29652958
*/

0 commit comments

Comments
 (0)