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

Commit2dee799

Browse files
committed
Move more bgworker code to bgworker.c; also, some renaming.
Per discussion on pgsql-hackers.Michael Paquier, slightly modified by me. Original suggestionfrom Amit Kapila.
1 parentac76ec2 commit2dee799

File tree

3 files changed

+232
-213
lines changed

3 files changed

+232
-213
lines changed

‎src/backend/postmaster/bgworker.c

Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,24 @@
1212

1313
#include"postgres.h"
1414

15+
#include<unistd.h>
16+
#include<time.h>
17+
1518
#include"miscadmin.h"
19+
#include"libpq/pqsignal.h"
1620
#include"postmaster/bgworker_internals.h"
1721
#include"storage/barrier.h"
22+
#include"storage/ipc.h"
23+
#include"storage/latch.h"
1824
#include"storage/lwlock.h"
1925
#include"storage/pmsignal.h"
26+
#include"storage/proc.h"
27+
#include"storage/procsignal.h"
2028
#include"storage/shmem.h"
29+
#include"tcop/tcopprot.h"
2130
#include"utils/ascii.h"
31+
#include"utils/ps_status.h"
32+
#include"utils/timeout.h"
2233

2334
/*
2435
* The postmaster's list of registered background workers, in private memory.
@@ -354,6 +365,214 @@ SanityCheckBackgroundWorker(BackgroundWorker *worker, int elevel)
354365
return true;
355366
}
356367

368+
staticvoid
369+
bgworker_quickdie(SIGNAL_ARGS)
370+
{
371+
sigaddset(&BlockSig,SIGQUIT);/* prevent nested calls */
372+
PG_SETMASK(&BlockSig);
373+
374+
/*
375+
* We DO NOT want to run proc_exit() callbacks -- we're here because
376+
* shared memory may be corrupted, so we don't want to try to clean up our
377+
* transaction. Just nail the windows shut and get out of town. Now that
378+
* there's an atexit callback to prevent third-party code from breaking
379+
* things by calling exit() directly, we have to reset the callbacks
380+
* explicitly to make this work as intended.
381+
*/
382+
on_exit_reset();
383+
384+
/*
385+
* Note we do exit(0) here, not exit(2) like quickdie. The reason is that
386+
* we don't want to be seen this worker as independently crashed, because
387+
* then postmaster would delay restarting it again afterwards. If some
388+
* idiot DBA manually sends SIGQUIT to a random bgworker, the "dead man
389+
* switch" will ensure that postmaster sees this as a crash.
390+
*/
391+
exit(0);
392+
}
393+
394+
/*
395+
* Standard SIGTERM handler for background workers
396+
*/
397+
staticvoid
398+
bgworker_die(SIGNAL_ARGS)
399+
{
400+
PG_SETMASK(&BlockSig);
401+
402+
ereport(FATAL,
403+
(errcode(ERRCODE_ADMIN_SHUTDOWN),
404+
errmsg("terminating background worker \"%s\" due to administrator command",
405+
MyBgworkerEntry->bgw_name)));
406+
}
407+
408+
/*
409+
* Standard SIGUSR1 handler for unconnected workers
410+
*
411+
* Here, we want to make sure an unconnected worker will at least heed
412+
* latch activity.
413+
*/
414+
staticvoid
415+
bgworker_sigusr1_handler(SIGNAL_ARGS)
416+
{
417+
intsave_errno=errno;
418+
419+
latch_sigusr1_handler();
420+
421+
errno=save_errno;
422+
}
423+
424+
/*
425+
* Start a new background worker
426+
*
427+
* This is the main entry point for background worker, to be called from
428+
* postmaster.
429+
*/
430+
void
431+
StartBackgroundWorker(void)
432+
{
433+
sigjmp_buflocal_sigjmp_buf;
434+
charbuf[MAXPGPATH];
435+
BackgroundWorker*worker=MyBgworkerEntry;
436+
bgworker_main_typeentrypt;
437+
438+
if (worker==NULL)
439+
elog(FATAL,"unable to find bgworker entry");
440+
441+
/* we are a postmaster subprocess now */
442+
IsUnderPostmaster= true;
443+
IsBackgroundWorker= true;
444+
445+
/* reset MyProcPid */
446+
MyProcPid=getpid();
447+
448+
/* record Start Time for logging */
449+
MyStartTime=time(NULL);
450+
451+
/* Identify myself via ps */
452+
snprintf(buf,MAXPGPATH,"bgworker: %s",worker->bgw_name);
453+
init_ps_display(buf,"","","");
454+
455+
SetProcessingMode(InitProcessing);
456+
457+
/* Apply PostAuthDelay */
458+
if (PostAuthDelay>0)
459+
pg_usleep(PostAuthDelay*1000000L);
460+
461+
/*
462+
* If possible, make this process a group leader, so that the postmaster
463+
* can signal any child processes too.
464+
*/
465+
#ifdefHAVE_SETSID
466+
if (setsid()<0)
467+
elog(FATAL,"setsid() failed: %m");
468+
#endif
469+
470+
/*
471+
* Set up signal handlers.
472+
*/
473+
if (worker->bgw_flags&BGWORKER_BACKEND_DATABASE_CONNECTION)
474+
{
475+
/*
476+
* SIGINT is used to signal canceling the current action
477+
*/
478+
pqsignal(SIGINT,StatementCancelHandler);
479+
pqsignal(SIGUSR1,procsignal_sigusr1_handler);
480+
pqsignal(SIGFPE,FloatExceptionHandler);
481+
482+
/* XXX Any other handlers needed here? */
483+
}
484+
else
485+
{
486+
pqsignal(SIGINT,SIG_IGN);
487+
pqsignal(SIGUSR1,bgworker_sigusr1_handler);
488+
pqsignal(SIGFPE,SIG_IGN);
489+
}
490+
pqsignal(SIGTERM,bgworker_die);
491+
pqsignal(SIGHUP,SIG_IGN);
492+
493+
pqsignal(SIGQUIT,bgworker_quickdie);
494+
InitializeTimeouts();/* establishes SIGALRM handler */
495+
496+
pqsignal(SIGPIPE,SIG_IGN);
497+
pqsignal(SIGUSR2,SIG_IGN);
498+
pqsignal(SIGCHLD,SIG_DFL);
499+
500+
/*
501+
* If an exception is encountered, processing resumes here.
502+
*
503+
* See notes in postgres.c about the design of this coding.
504+
*/
505+
if (sigsetjmp(local_sigjmp_buf,1)!=0)
506+
{
507+
/* Since not using PG_TRY, must reset error stack by hand */
508+
error_context_stack=NULL;
509+
510+
/* Prevent interrupts while cleaning up */
511+
HOLD_INTERRUPTS();
512+
513+
/* Report the error to the server log */
514+
EmitErrorReport();
515+
516+
/*
517+
* Do we need more cleanup here? For shmem-connected bgworkers, we
518+
* will call InitProcess below, which will install ProcKill as exit
519+
* callback. That will take care of releasing locks, etc.
520+
*/
521+
522+
/* and go away */
523+
proc_exit(1);
524+
}
525+
526+
/* We can now handle ereport(ERROR) */
527+
PG_exception_stack=&local_sigjmp_buf;
528+
529+
/* Early initialization */
530+
BaseInit();
531+
532+
/*
533+
* If necessary, create a per-backend PGPROC struct in shared memory,
534+
* except in the EXEC_BACKEND case where this was done in
535+
* SubPostmasterMain. We must do this before we can use LWLocks (and in
536+
* the EXEC_BACKEND case we already had to do some stuff with LWLocks).
537+
*/
538+
#ifndefEXEC_BACKEND
539+
if (worker->bgw_flags&BGWORKER_SHMEM_ACCESS)
540+
InitProcess();
541+
#endif
542+
543+
/*
544+
* If bgw_main is set, we use that value as the initial entrypoint.
545+
* However, if the library containing the entrypoint wasn't loaded at
546+
* postmaster startup time, passing it as a direct function pointer is
547+
* not possible. To work around that, we allow callers for whom a
548+
* function pointer is not available to pass a library name (which will
549+
* be loaded, if necessary) and a function name (which will be looked up
550+
* in the named library).
551+
*/
552+
if (worker->bgw_main!=NULL)
553+
entrypt=worker->bgw_main;
554+
else
555+
entrypt= (bgworker_main_type)
556+
load_external_function(worker->bgw_library_name,
557+
worker->bgw_function_name,
558+
true,NULL);
559+
560+
/*
561+
* Note that in normal processes, we would call InitPostgres here. For a
562+
* worker, however, we don't know what database to connect to, yet; so we
563+
* need to wait until the user code does it via
564+
* BackgroundWorkerInitializeConnection().
565+
*/
566+
567+
/*
568+
* Now invoke the user-defined worker code
569+
*/
570+
entrypt(worker->bgw_main_arg);
571+
572+
/* ... and if it returns, we're done */
573+
proc_exit(0);
574+
}
575+
357576
/*
358577
* Register a new background worker while processing shared_preload_libraries.
359578
*

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp