Обсуждение: Which signal to use for CANCEL from postmaster to backend?
Hmm. I find that SIGUSR1 and SIGUSR2 are both already in use for communication between backends. We can't really commandeer SIGURG, either, because it's apparently the same as SIGUSR1 on SCO (see src/include/port/sco.h ... so OOB wouldn't work there anyway!). All three of SIGINT, SIGHUP, SIGTERM currently do the same thing in a backend, so it looks like our best choice is to redefine one of those as the cancel request signal. Any preference? regards, tom lane
> Hmm. I find that SIGUSR1 and SIGUSR2 are both already in use for > communication between backends. We can't really commandeer SIGURG, > either, because it's apparently the same as SIGUSR1 on SCO > (see src/include/port/sco.h ... so OOB wouldn't work there anyway!). > > All three of SIGINT, SIGHUP, SIGTERM currently do the same thing in a > backend, so it looks like our best choice is to redefine one of those > as the cancel request signal. Any preference? > > regards, tom lane > > I like SIGQUIT. Looks to be unused. SIGINT is used too much from the command line, and SIGTERM used too much from scripts (the default kill arg.) -- Bruce Momjian | 830 Blythe Avenue maillist@candle.pha.pa.us | Drexel Hill, Pennsylvania 19026 + If your life is a hard drive, | (610) 353-9879(w) + Christ can be your backup. | (610) 853-3000(h)
Bruce Momjian <maillist@candle.pha.pa.us> writes: >> All three of SIGINT, SIGHUP, SIGTERM currently do the same thing in a >> backend, so it looks like our best choice is to redefine one of those >> as the cancel request signal. Any preference? > I like SIGQUIT. Looks to be unused. SIGINT is used too much from the > command line, and SIGTERM used too much from scripts (the default kill > arg.) I've been thinking about it a little more, and on the whole I like using SIGINT the best. Here's my reasoning: 1. SIGINT is not normally generated for non-interactive processes, so for the ordinary case of a backend running under the postmaster it wouldn't be generated by accident. (As you point out, the default signal from kill(1) is SIGTERM not SIGINT.) 2. The only case where it *would* be easy to direct SIGINT to a backend is in the case of a backend hand-invoked from the command line. In this case I think that having control-C do a Cancel rather than kill the process is a fine idea --- it is exactly parallel to the behavior that psql now offers. People will probably get used enough to psql's behavior that having an interactive backend work differently would be a bad idea. 3. SIGQUIT normally generates a coredump, and is one of the few non-error signals that do so. If we use it for the cancel signal we will eliminate the easiest, most standard way of externally forcing a backend to coredump. That seems like a loss of a useful debug tool. Also, in all Unix applications that I'm familiar with, SIGQUIT is a "more severe" signal than SIGINT --- one expects that an app may trap SIGINT and return keyboard control, but SIGQUIT is supposed to kill it. Inverting the severity of SIGINT and SIGQUIT for a pgsql backend doesn't sound like a good plan. So I think we should leave SIGTERM and SIGQUIT alone, and redefine SIGINT to perform a cancel. BTW, I realized that SIGHUP is not really free, it's what is used to return control from elog(ERROR) to the main loop. The code probably should refer to it as SIGHUP not signal "1". regards, tom lane PS: I've got these changes coded up, and am about to start testing.
> I've been thinking about it a little more, and on the whole I like using > SIGINT the best. Here's my reasoning: > > 1. SIGINT is not normally generated for non-interactive processes, > so for the ordinary case of a backend running under the postmaster > it wouldn't be generated by accident. (As you point out, the default > signal from kill(1) is SIGTERM not SIGINT.) > > 2. The only case where it *would* be easy to direct SIGINT to a backend > is in the case of a backend hand-invoked from the command line. In this > case I think that having control-C do a Cancel rather than kill the > process is a fine idea --- it is exactly parallel to the behavior that > psql now offers. People will probably get used enough to psql's > behavior that having an interactive backend work differently would be > a bad idea. > > 3. SIGQUIT normally generates a coredump, and is one of the few > non-error signals that do so. If we use it for the cancel signal we > will eliminate the easiest, most standard way of externally forcing a > backend to coredump. That seems like a loss of a useful debug tool. > Also, in all Unix applications that I'm familiar with, SIGQUIT is a > "more severe" signal than SIGINT --- one expects that an app may trap > SIGINT and return keyboard control, but SIGQUIT is supposed to kill it. > Inverting the severity of SIGINT and SIGQUIT for a pgsql backend doesn't > sound like a good plan. > > > So I think we should leave SIGTERM and SIGQUIT alone, and redefine > SIGINT to perform a cancel. All very good points. SIGINT is good. > > > BTW, I realized that SIGHUP is not really free, it's what is used to > return control from elog(ERROR) to the main loop. The code probably > should refer to it as SIGHUP not signal "1". Patch applied. > > regards, tom lane > > PS: I've got these changes coded up, and am about to start testing. > Cool. -- Bruce Momjian | 830 Blythe Avenue maillist@candle.pha.pa.us | Drexel Hill, Pennsylvania 19026 + If your life is a hard drive, | (610) 353-9879(w) + Christ can be your backup. | (610) 853-3000(h)
> > Bruce Momjian <maillist@candle.pha.pa.us> writes: > >> All three of SIGINT, SIGHUP, SIGTERM currently do the same thing in a > >> backend, so it looks like our best choice is to redefine one of those > >> as the cancel request signal. Any preference? > > > I like SIGQUIT. Looks to be unused. SIGINT is used too much from the > > command line, and SIGTERM used too much from scripts (the default kill > > arg.) > > I've been thinking about it a little more, and on the whole I like using > SIGINT the best. Here's my reasoning: > > 1. SIGINT is not normally generated for non-interactive processes, > so for the ordinary case of a backend running under the postmaster > it wouldn't be generated by accident. (As you point out, the default > signal from kill(1) is SIGTERM not SIGINT.) > > 2. The only case where it *would* be easy to direct SIGINT to a backend > is in the case of a backend hand-invoked from the command line. In this > case I think that having control-C do a Cancel rather than kill the > process is a fine idea --- it is exactly parallel to the behavior that > psql now offers. People will probably get used enough to psql's > behavior that having an interactive backend work differently would be > a bad idea. > > 3. SIGQUIT normally generates a coredump, and is one of the few > non-error signals that do so. If we use it for the cancel signal we > will eliminate the easiest, most standard way of externally forcing a > backend to coredump. That seems like a loss of a useful debug tool. > Also, in all Unix applications that I'm familiar with, SIGQUIT is a > "more severe" signal than SIGINT --- one expects that an app may trap > SIGINT and return keyboard control, but SIGQUIT is supposed to kill it. > Inverting the severity of SIGINT and SIGQUIT for a pgsql backend doesn't > sound like a good plan. > > > So I think we should leave SIGTERM and SIGQUIT alone, and redefine > SIGINT to perform a cancel. > > > BTW, I realized that SIGHUP is not really free, it's what is used to > return control from elog(ERROR) to the main loop. The code probably > should refer to it as SIGHUP not signal "1". > > regards, tom lane > > PS: I've got these changes coded up, and am about to start testing. These are the signals I'm using in my own current version of pgsql. The main changes to the old implementation are SIGQUIT instead of SIGHUP to handle warns, SIGHUP to reread pg_options and redirection to all backends of SIGHUP, SIGINT, SIGTERM, SIGUSR1 and SIGUSR2. In this way some of the signals sent to the postmaster can be sent automatically to all the backends. To shut down postgres one needs only to send a SIGTERM to postmaster and it will stop automatically all the backends. This new signal handling mechanism is also used to prevent SI cache table overflows: when a backend detects the SI table full at 70% it simply sends a signal to the postmaster which will wake up all idle backends and make them flush the cache. The use of SIGINT for the new functionality seems ok to me. Given your considerations I would also use SIGCHLD instead of SIGQUIT to handle warn from elog. signal postmaster backend SIGHUP kill(*,sighup) read_pg_options SIGINT kill(*,sigint), die die SIGCHLD reaper - SIGTTIN ignored - SIGTTOU ignored - SIGQUIT die handle_warn SIGTERM kill(*,sigterm), kill(*,9), die die SIGCONT dumpstatus - SIGPIPE ignored die SIGFPE - FloatExceptionHandler SIGTSTP - ignored (is_alive ?) SIGUSR1 kill(*,sigusr1), die quickdie SIGUSR2 kill(*,sigusr2) Async_NotifyHandler (also SI buffer full) -- Massimo Dal Zotto +----------------------------------------------------------------------+ | Massimo Dal Zotto e-mail: dz@cs.unitn.it | | Via Marconi, 141 phone: ++39-461-534251 | | 38057 Pergine Valsugana (TN) www: http://www.cs.unitn.it/~dz/ | | Italy pgp: finger dz@tango.cs.unitn.it | +----------------------------------------------------------------------+