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

Commit7b05b3f

Browse files
committed
Provide support for multiplexing SIGUSR1 signal. The upcoming synchronous
replication patch needs a signal, but we've already used SIGUSR1 andSIGUSR2 in normal backends. This patch allows reusing SIGUSR1 for that,and for other purposes too if the need arises.
1 parent9edd720 commit7b05b3f

File tree

10 files changed

+143
-45
lines changed

10 files changed

+143
-45
lines changed

‎src/backend/access/transam/twophase.c

Lines changed: 2 additions & 1 deletion
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/access/transam/twophase.c,v 1.48 2008/11/19 10:34:50 heikki Exp $
10+
*$PostgreSQL: pgsql/src/backend/access/transam/twophase.c,v 1.49 2008/12/09 14:28:20 heikki Exp $
1111
*
1212
* NOTES
1313
*Each global transaction is associated with a global transaction
@@ -287,6 +287,7 @@ MarkAsPreparing(TransactionId xid, const char *gid,
287287
gxact->proc.databaseId=databaseid;
288288
gxact->proc.roleId=owner;
289289
gxact->proc.inCommit= false;
290+
MemSet(gxact->proc.signalFlags,0,NUM_PROCSIGNALS*sizeof(sig_atomic_t));
290291
gxact->proc.vacuumFlags=0;
291292
gxact->proc.lwWaiting= false;
292293
gxact->proc.lwExclusive= false;

‎src/backend/commands/async.c

Lines changed: 6 additions & 5 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/commands/async.c,v 1.142 2008/11/02 01:45:27 tgl Exp $
10+
* $PostgreSQL: pgsql/src/backend/commands/async.c,v 1.143 2008/12/09 14:28:20 heikki Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -915,9 +915,10 @@ EnableNotifyInterrupt(void)
915915
*a frontend command. Signal handler execution of inbound notifies
916916
*is disabled until the next EnableNotifyInterrupt call.
917917
*
918-
*The SIGUSR1 signal handler also needs to call this, so as to
919-
*prevent conflicts if one signal interrupts the other. So we
920-
*must return the previous state of the flag.
918+
*This also needs to be called when SIGUSR1 with
919+
*PROCSIG_CATCHUP_INTERRUPT is received, so as to prevent conflicts
920+
*if one signal interrupts the other. So we must return the previous
921+
*state of the flag.
921922
*/
922923
bool
923924
DisableNotifyInterrupt(void)
@@ -954,7 +955,7 @@ ProcessIncomingNotify(void)
954955
nulls[Natts_pg_listener];
955956
boolcatchup_enabled;
956957

957-
/* Must preventSIGUSR1 interrupt while I am running */
958+
/* Must preventcatchup interrupt while I am running */
958959
catchup_enabled=DisableCatchupInterrupt();
959960

960961
if (Trace_notify)

‎src/backend/postmaster/autovacuum.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@
5555
*
5656
*
5757
* IDENTIFICATION
58-
* $PostgreSQL: pgsql/src/backend/postmaster/autovacuum.c,v 1.88 2008/12/04 11:42:24 heikki Exp $
58+
* $PostgreSQL: pgsql/src/backend/postmaster/autovacuum.c,v 1.89 2008/12/09 14:28:20 heikki Exp $
5959
*
6060
*-------------------------------------------------------------------------
6161
*/
@@ -1477,7 +1477,7 @@ AutoVacWorkerMain(int argc, char *argv[])
14771477
pqsignal(SIGALRM,handle_sig_alarm);
14781478

14791479
pqsignal(SIGPIPE,SIG_IGN);
1480-
pqsignal(SIGUSR1,CatchupInterruptHandler);
1480+
pqsignal(SIGUSR1,proc_sigusr1_handler);
14811481
/* We don't listen for async notifies */
14821482
pqsignal(SIGUSR2,SIG_IGN);
14831483
pqsignal(SIGFPE,FloatExceptionHandler);

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

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/storage/ipc/sinval.c,v 1.86 2008/06/19 21:32:56 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/storage/ipc/sinval.c,v 1.87 2008/12/09 14:28:20 heikki Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -26,8 +26,8 @@
2626
* Because backends sitting idle will not be reading sinval events, we
2727
* need a way to give an idle backend a swift kick in the rear and make
2828
* it catch up before the sinval queue overflows and forces it to go
29-
* through a cache reset exercise.This is done by sending SIGUSR1
30-
* to any backend that gets too far behind.
29+
* through a cache reset exercise.This is done by sending
30+
*PROCSIG_CATCHUP_INTERRUPTto any backend that gets too far behind.
3131
*
3232
* State for catchup events consists of two flags: one saying whether
3333
* the signal handler is currently allowed to call ProcessCatchupEvent
@@ -144,9 +144,9 @@ ReceiveSharedInvalidMessages(
144144

145145

146146
/*
147-
*CatchupInterruptHandler
147+
*HandleCatchupInterrupt
148148
*
149-
* This isthe signal handler for SIGUSR1.
149+
* This iscalled when PROCSIG_CATCHUP_INTERRUPT signal is received.
150150
*
151151
* If we are idle (catchupInterruptEnabled is set), we can safely
152152
* invoke ProcessCatchupEvent directly. Otherwise, just set a flag
@@ -156,13 +156,11 @@ ReceiveSharedInvalidMessages(
156156
* since there's no longer any reason to do anything.)
157157
*/
158158
void
159-
CatchupInterruptHandler(SIGNAL_ARGS)
159+
HandleCatchupInterrupt(void)
160160
{
161-
intsave_errno=errno;
162-
163161
/*
164-
* Note: this is a SIGNAL HANDLER.You must be very wary what you do
165-
* here.
162+
* Note: this iscalled bya SIGNAL HANDLER.
163+
*You must be very wary what you dohere.
166164
*/
167165

168166
/* Don't joggle the elbow of proc_exit */
@@ -216,8 +214,6 @@ CatchupInterruptHandler(SIGNAL_ARGS)
216214
*/
217215
catchupInterruptOccurred=1;
218216
}
219-
220-
errno=save_errno;
221217
}
222218

223219
/*
@@ -289,7 +285,8 @@ DisableCatchupInterrupt(void)
289285
/*
290286
* ProcessCatchupEvent
291287
*
292-
* Respond to a catchup event (SIGUSR1) from another backend.
288+
* Respond to a catchup event (PROCSIG_CATCHUP_INTERRUPT) from another
289+
* backend.
293290
*
294291
* This is called either directly from the SIGUSR1 signal handler,
295292
* or the next time control reaches the outer idle loop (assuming

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

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/storage/ipc/sinvaladt.c,v 1.74 2008/07/18 14:45:48 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/storage/ipc/sinvaladt.c,v 1.75 2008/12/09 14:28:20 heikki Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -21,6 +21,7 @@
2121
#include"storage/backendid.h"
2222
#include"storage/ipc.h"
2323
#include"storage/proc.h"
24+
#include"storage/procarray.h"
2425
#include"storage/shmem.h"
2526
#include"storage/sinvaladt.h"
2627
#include"storage/spin.h"
@@ -136,9 +137,9 @@
136137
/* Per-backend state in shared invalidation structure */
137138
typedefstructProcState
138139
{
139-
/*procPid iszero in an inactive ProcState array entry. */
140-
pid_tprocPid;/*PID of backend, for signaling */
141-
/* nextMsgNum is meaningless ifprocPid ==0 or resetState is true. */
140+
/*proc isNULL in an inactive ProcState array entry. */
141+
PGPROC*proc;/*PGPROC entry of backend, for signaling */
142+
/* nextMsgNum is meaningless ifproc ==NULL or resetState is true. */
142143
intnextMsgNum;/* next message number to read */
143144
boolresetState;/* backend needs to reset its state */
144145
boolsignaled;/* backend has been sent catchup signal */
@@ -235,7 +236,7 @@ CreateSharedInvalidationState(void)
235236
/* Mark all backends inactive, and initialize nextLXID */
236237
for (i=0;i<shmInvalBuffer->maxBackends;i++)
237238
{
238-
shmInvalBuffer->procState[i].procPid=0;/* inactive */
239+
shmInvalBuffer->procState[i].proc=NULL;/* inactive */
239240
shmInvalBuffer->procState[i].nextMsgNum=0;/* meaningless */
240241
shmInvalBuffer->procState[i].resetState= false;
241242
shmInvalBuffer->procState[i].signaled= false;
@@ -266,7 +267,7 @@ SharedInvalBackendInit(void)
266267
/* Look for a free entry in the procState array */
267268
for (index=0;index<segP->lastBackend;index++)
268269
{
269-
if (segP->procState[index].procPid==0)/* inactive slot? */
270+
if (segP->procState[index].proc==NULL)/* inactive slot? */
270271
{
271272
stateP=&segP->procState[index];
272273
break;
@@ -278,7 +279,7 @@ SharedInvalBackendInit(void)
278279
if (segP->lastBackend<segP->maxBackends)
279280
{
280281
stateP=&segP->procState[segP->lastBackend];
281-
Assert(stateP->procPid==0);
282+
Assert(stateP->proc==NULL);
282283
segP->lastBackend++;
283284
}
284285
else
@@ -303,7 +304,7 @@ SharedInvalBackendInit(void)
303304
nextLocalTransactionId=stateP->nextLXID;
304305

305306
/* mark myself active, with all extant messages already read */
306-
stateP->procPid=MyProcPid;
307+
stateP->proc=MyProc;
307308
stateP->nextMsgNum=segP->maxMsgNum;
308309
stateP->resetState= false;
309310
stateP->signaled= false;
@@ -341,15 +342,15 @@ CleanupInvalidationState(int status, Datum arg)
341342
stateP->nextLXID=nextLocalTransactionId;
342343

343344
/* Mark myself inactive */
344-
stateP->procPid=0;
345+
stateP->proc=NULL;
345346
stateP->nextMsgNum=0;
346347
stateP->resetState= false;
347348
stateP->signaled= false;
348349

349350
/* Recompute index of last active backend */
350351
for (i=segP->lastBackend;i>0;i--)
351352
{
352-
if (segP->procState[i-1].procPid!=0)
353+
if (segP->procState[i-1].proc!=NULL)
353354
break;
354355
}
355356
segP->lastBackend=i;
@@ -374,7 +375,7 @@ BackendIdIsActive(int backendID)
374375
{
375376
ProcState*stateP=&segP->procState[backendID-1];
376377

377-
result= (stateP->procPid!=0);
378+
result= (stateP->proc!=NULL);
378379
}
379380
else
380381
result= false;
@@ -590,7 +591,7 @@ SICleanupQueue(bool callerHasWriteLock, int minFree)
590591
intn=stateP->nextMsgNum;
591592

592593
/* Ignore if inactive or already in reset state */
593-
if (stateP->procPid==0||stateP->resetState)
594+
if (stateP->proc==NULL||stateP->resetState)
594595
continue;
595596

596597
/*
@@ -644,18 +645,20 @@ SICleanupQueue(bool callerHasWriteLock, int minFree)
644645
segP->nextThreshold= (numMsgs /CLEANUP_QUANTUM+1)*CLEANUP_QUANTUM;
645646

646647
/*
647-
* Lastly, signal anyone who needs a catchup interrupt. Since kill()
648-
* might not be fast, we don't want to hold locks while executing it.
648+
* Lastly, signal anyone who needs a catchup interrupt. Since
649+
* SendProcSignal() might not be fast, we don't want to hold locks while
650+
* executing it.
649651
*/
650652
if (needSig)
651653
{
652-
pid_this_pid=needSig->procPid;
654+
PGPROC*his_proc=needSig->proc;
653655

654656
needSig->signaled= true;
655657
LWLockRelease(SInvalReadLock);
656658
LWLockRelease(SInvalWriteLock);
657-
elog(DEBUG4,"sending sinval catchup signal to PID %d", (int)his_pid);
658-
kill(his_pid,SIGUSR1);
659+
elog(DEBUG4,"sending sinval catchup signal to PID %d",
660+
(int)his_proc->pid);
661+
SendProcSignal(his_proc,PROCSIG_CATCHUP_INTERRUPT);
659662
if (callerHasWriteLock)
660663
LWLockAcquire(SInvalWriteLock,LW_EXCLUSIVE);
661664
}

‎src/backend/storage/lmgr/proc.c

Lines changed: 51 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/lmgr/proc.c,v 1.202 2008/11/02 21:24:52 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/storage/lmgr/proc.c,v 1.203 2008/12/09 14:28:20 heikki Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -289,6 +289,7 @@ InitProcess(void)
289289
MyProc->databaseId=InvalidOid;
290290
MyProc->roleId=InvalidOid;
291291
MyProc->inCommit= false;
292+
MemSet(MyProc->signalFlags,0,NUM_PROCSIGNALS*sizeof(sig_atomic_t));
292293
MyProc->vacuumFlags=0;
293294
if (IsAutoVacuumWorkerProcess())
294295
MyProc->vacuumFlags |=PROC_IS_AUTOVACUUM;
@@ -428,6 +429,7 @@ InitAuxiliaryProcess(void)
428429
MyProc->databaseId=InvalidOid;
429430
MyProc->roleId=InvalidOid;
430431
MyProc->inCommit= false;
432+
MemSet(MyProc->signalFlags,0,NUM_PROCSIGNALS*sizeof(sig_atomic_t));
431433
/* we don't set the "is autovacuum" flag in the launcher */
432434
MyProc->vacuumFlags=0;
433435
MyProc->lwWaiting= false;
@@ -1277,6 +1279,54 @@ ProcSendSignal(int pid)
12771279
PGSemaphoreUnlock(&proc->sem);
12781280
}
12791281

1282+
/*
1283+
* SendProcSignal - send the signal with the reason to a process.
1284+
*
1285+
* The process can be a backend or an auxiliary process that has a PGPROC
1286+
* entry, like an autovacuum worker.
1287+
*/
1288+
void
1289+
SendProcSignal(PGPROC*proc,ProcSignalReasonreason)
1290+
{
1291+
pid_tpid;
1292+
1293+
/*
1294+
* If the process is gone, do nothing.
1295+
*
1296+
* Since there's no locking, it's possible that the process detaches
1297+
* from shared memory and exits right after this test, before we set
1298+
* the flag and send signal. And the PGPROC entry might even be recycled
1299+
* by a new process, so it's remotely possible that we signal a wrong
1300+
* process. That's OK, all the signals are such that no harm is done.
1301+
*/
1302+
pid=proc->pid;
1303+
if (pid==0)
1304+
return;
1305+
1306+
/* Atomically set the proper flag */
1307+
proc->signalFlags[reason]= true;
1308+
/* Send SIGUSR1 to the process */
1309+
kill(pid,SIGUSR1);
1310+
}
1311+
1312+
/*
1313+
* CheckProcSignal - check to see if the particular reason has been
1314+
* signaled, and clear the signal flag. Should be called after
1315+
* receiving SIGUSR1.
1316+
*/
1317+
bool
1318+
CheckProcSignal(ProcSignalReasonreason)
1319+
{
1320+
/* Careful here --- don't clear flag if we haven't seen it set */
1321+
if (MyProc->signalFlags[reason])
1322+
{
1323+
MyProc->signalFlags[reason]= false;
1324+
return true;
1325+
}
1326+
1327+
return false;
1328+
}
1329+
12801330

12811331
/*****************************************************************************
12821332
* SIGALRM interrupt support

‎src/backend/tcop/postgres.c

Lines changed: 19 additions & 2 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.558 2008/11/30 20:51:25 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.559 2008/12/09 14:28:20 heikki Exp $
1212
*
1313
* NOTES
1414
* this is the "main" module of the postgres backend and
@@ -2436,6 +2436,23 @@ drop_unnamed_stmt(void)
24362436
* --------------------------------
24372437
*/
24382438

2439+
/*
2440+
* proc_sigusr1_handler - handle SIGUSR1 signal.
2441+
*
2442+
* SIGUSR1 is multiplexed to handle multiple different events. The signalFlags
2443+
* array in PGPROC indicates which events have been signaled.
2444+
*/
2445+
void
2446+
proc_sigusr1_handler(SIGNAL_ARGS)
2447+
{
2448+
intsave_errno=errno;
2449+
2450+
if (CheckProcSignal(PROCSIG_CATCHUP_INTERRUPT))
2451+
HandleCatchupInterrupt();
2452+
2453+
errno=save_errno;
2454+
}
2455+
24392456
/*
24402457
* quickdie() occurs when signalled SIGQUIT by the postmaster.
24412458
*
@@ -3180,7 +3197,7 @@ PostgresMain(int argc, char *argv[], const char *username)
31803197
* of output during who-knows-what operation...
31813198
*/
31823199
pqsignal(SIGPIPE,SIG_IGN);
3183-
pqsignal(SIGUSR1,CatchupInterruptHandler);
3200+
pqsignal(SIGUSR1,proc_sigusr1_handler);
31843201
pqsignal(SIGUSR2,NotifyInterruptHandler);
31853202
pqsignal(SIGFPE,FloatExceptionHandler);
31863203

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp