Thank You so much Krystian Bigaj. Since last 2 years I had suffering this problem. But today I got solution from you. I am developing .Net application with Postgres. I am using WCF service (host as windows service) to connect postgres database.
*My workaround: own service which will start/stop Postgres (mainly to wait for our service to stop, running initdb.exe in context of NetworkService, etc.).* *I've also written small Postgres module loaded via shared_preload_libraries which will call SetConsoleCtrlHandler, and my HandlerRoutine which simply returns TRUE. Because of this pg_console_handler won't be called (so no processing CTRL_SHUTDOWN_EVENT by any Postgress process).* * I need to wait first that our service stops, and then I let Postgres to stop (I have my own service - not pg_ctl - which will start/stop postgres.exe process).* I have similar situation to you. I also want create my own service to start /stop postgres. Please let me know how to start/stop postgres without pg_ctl. Could you share code for your small postgres module loaded via shared_preloaded libraries? Thanks & Regards Kalai On Thu, Jul 24, 2014 at 3:59 AM, Krystian Bigaj <krystian.bi...@gmail.com> wrote: > On 23 July 2014 22:16, Tom Lane <t...@sss.pgh.pa.us> wrote: > >> Krystian Bigaj <krystian.bi...@gmail.com> writes: >> > - when pg_console_handler receives CTRL_SHUTDOWN_EVENT from OS, then it >> > calls pg_queue_signal(SIGINT). >> >> > Problems: >> > - when OS is in shutdown path, then it sends CTRL_SHUTDOWN_EVENT, and >> *all* >> > Postgres processes (main and sub/forked) will call >> pg_queue_signal(SIGINT) >> > - so main and sub processes will start to shutdown independently? Can >> this >> > have any bad consequences? >> >> Hm. We ought to have that sending SIGTERM instead, so as to mimic the >> situation when Unix "init" is trying to shut down the system. It might be >> that SIGINT will more or less work, but the postmaster logic is designed >> to work with global SIGTERM as being the clean-up-ASAP trigger. As an >> example, backends servicing remote applications (which will *not* have >> already gotten killed) would not exit in response to SIGINT. >> >> > I think that CTRL_SHUTDOWN_EVENT should be removed from >> pg_console_handler, >> >> That does not sound like a good idea, at least not if Windows has the >> same behavior as "init" does of proceeding to hard kills after some >> grace period. >> >> regards, tom lane >> > > I'm not really familiar with Unix and it's SIG-commands. I know only > about SIGINT/SIGTERM from Postgres documentation. > > However form what I see is that when Postgress is running by pg_ctl from > service, then it will receive SIGINT (independently and in general in > unspecified order) > - *each* postgres.exe process will queue itself SIGINT (because of > CTRL_SHUTDOWN_EVENT), > - pg_ctl will send SIGINT to main postmaster process (and possibly it will > pass that command to sub-processes) > So there are two independent paths where SIGINT are sent, and pg_ctl > doesn't have really a control when postgres.exe receives SIGINT. > This CTRL_SHUTDOWN_EVENT is not used when postgres.exe is run on *user > session* - so removing it won't change anything. > > I see only two cases where CTRL_SHUTDOWN_EVENT might be need (all of there > where postgres.exe is run on service session): > - postgres.exe run by pg_ctl.exe, but pg_ctl service process was > terminated/killed, and then system was shutdown > - someone starts postgres.exe from own service, but doesn't send > SIGINT/SIGTERM command to postgres.exe on service system shutdown (but he > must for service stop) > As I previously wrote, I have workaround for it, so if you think that this > change would break compatibility and don't want to change it, then I'm > really fine with it. > > However I've probably found something with pg_ctl.c regarding shutdown and > maybe that suspicious postgres.exe process termination on Windows. > > 1) shutdownEvent is signaled in pgwin32_ServiceMain > by SERVICE_CONTROL_STOP/SERVICE_CONTROL_SHUTDOWN in pgwin32_ServiceHandler > There is dwWaitHint = 10000. > > 2) > ... > /* Wait for quit... */ > ret = WaitForMultipleObjects(2, shutdownHandles, FALSE, INFINITE); > > pgwin32_SetServiceStatus(SERVICE_STOP_PENDING); > switch (ret) > { > case WAIT_OBJECT_0: /* shutdown event */ > kill(postmasterPID, SIGINT); > > /* > * Increment the checkpoint and try again Abort after 12 > * checkpoints as the postmaster has probably hung > */ > while (WaitForSingleObject(postmasterProcess, 5000) == WAIT_TIMEOUT && > status.dwCheckPoint < 12) > status.dwCheckPoint++; <---- missing call > to pgwin32_SetServiceStatus(SERVICE_STOP_PENDING) > or SetServiceStatus(hStatus, (LPSERVICE_STATUS) &status); > break; > ... > > There is incremented dwCheckPoint every 5000ms, but that status is not > updated (missing pgwin32_SetServiceStatus/SetServiceStatus), so SCM after > 10s (dwWaitHint = 10000) will not receive incremented dwCheckPoint, and > it's allowed to kill that process (because this service didn't respond with > dwWaitHint). It kills pg_ctl.exe, but when all services stops, then it > simply terminates other remaining processes - in this case postgres.exe > > > http://msdn.microsoft.com/en-us/library/windows/desktop/ms685996(v=vs.85).aspx > dwWaitHint: > ... > If the amount of time specified by dwWaitHint passes, and dwCheckPoint has > not been incremented or dwCurrentState has not changed, the service control > manager or service control program can assume that an error has occurred > and the service should be stopped. > ... > > So if main postgres.exe (run by pg_ctl.exe service process) won't shutdown > in 10s (for any reason) it might be terminated/killed by Windows/SCM. > > Best regards, > Krystian Bigaj > >