yandex-qatools / postgresql-embedded

Embedded PostgreSQL Server
Other
493 stars 90 forks source link

Postgresql master do not stop on windows #129

Open acommuni opened 6 years ago

acommuni commented 6 years ago

When stopping the embedded postgtresql is does not stop Postgresql.

It is due of the processid which is not the good one at stop.

During startup the method onAfterProcessStart is called and set the pid with the method setProcessId. It reads postmaster.pid file in order to get postgresql pid and set processId attribute.

During the stop the method getProcessId is called.

   _public long getProcessId() {
    **Long pid = process.getPid();**
    return pid!=null ? **pid** : processId;
}_

It returns process id which is pgctl id and not the postmaster id.

The method isProcessRunning is returning false because pg_ctl is stopped as far as it launched postgresql process

   public boolean isProcessRunning() {
    if (getProcessId() > 0) {
        return Processes.isProcessRunning(distribution.getPlatform(), getProcessId());
    }
    return false;
}

The method stopInternal skip the stop phase and only delete files.

  protected synchronized void stopInternal() {
    if (**!stopped && isProcessRunning()**) {
        stopped = true;
        LOGGER.info("trying to stop postgresql");
        if (!sendStopToPostgresqlInstance() && !sendTermToProcess() && waitUntilProcessHasStopped(2000)) {
            LOGGER.warn("could not stop postgresql with pg_ctl/SIGTERM, trying to kill it...");
            if (!sendKillToProcess() && !tryKillToProcess() && waitUntilProcessHasStopped(3000)) {
                LOGGER.warn("could not kill postgresql within 4s!");
            }
        }
    }
    if (waitUntilProcessHasStopped(5000)) {
        LOGGER.error("Postgres has not been stopped within 10s! Something's wrong!");
    }
    deleteTempFiles();
}

I do not understand why isProcessRunning uses getProcessId() and not processId like other method

dbardbar commented 5 years ago

I'm also seeing this problem on Windows. My guess is due to the execution of the postgres.exe via the 'runas' command. I considered hacking a solution by inheriting from PostgressPorcess and from EmbeddedPostgres and overwriting getProcessId() and perhaps some more methods. But this seems too fragile to me. I'll probably do an even worse hack of implementing a shutdown hook myself that would read postmaster.pid file and kill the process.

LukeButters commented 5 years ago

That is what I will do in my tests until this is fixed.