Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Classic: Stopping Windows Service leaves one or more instances of fb_inet_server.exe running [CORE3622] #3975

Open
firebird-automations opened this issue Oct 7, 2011 · 20 comments

Comments

@firebird-automations
Copy link
Collaborator

Submitted by: F.D.Castel (fdcastel)

Votes: 2

Sometimes stopping Windows Service on Firebird Classic 2.5.0 can leave one or more instances of fb_inet_server.exe running.

This is highly undesirable, since it could lead one to think the database file isn't in use as the service status is "Stopped". A database file copy or file-level backup in this state can corrupt the database (actually this DID occur once with me, and that's why I flagged this issue as "critical").

The correct behavior should be:
- (preferred) The service STOPS, no more instances left running and all database files closed ; *OR*
- The service DON'T STOP, returning an error message.

Currently, running a

taskkill /im fb\_inet\_server\.exe /f

can surely kill every zombie process, but I don't know how harmful this can be.

@firebird-automations
Copy link
Collaborator Author

Commented by: @hvlad

This is how CS works : you can directly control listener process but not workers.
To make sure db file is closed you must shutdown database. This is the only correct way.

Nothing to fix, as for me.

@firebird-automations
Copy link
Collaborator Author

Commented by: @dyemanov

Stopping the service does not (and never did) shutdown working processes, so the current behavior is expected. File-level copying while the engine is accessing the database can surely corrupt the copy, but it cannot corrupt the original database. If you need to perform a file-level copy, shutdown the database instead of shutting down the service, or use ALTER DATABASE BEGIN/END BACKUP for that purpose.

I tend to think this ticket should rather be an enhancement request, as it describes a more or less "as designed" behavior.

@firebird-automations
Copy link
Collaborator Author

Commented by: F.D.Castel (fdcastel)

Vlad, Dmitry,

Please correct me if I'm wrong, but to my knowledge a shutdown database ALLOWS connections from a SYSDBA/DB owner. So it will not guarantee a closed database file (or I really didn't understand what you both tried to show me, sorry)

Philosophical questions about "how it was designed/should be/bug/enhancement/etc" apart, the fact is this behavior is both unnatural and unsafe. I'm failing to see one single reason to keep it this way (could you please, enlighten me?). I really can't remember any application or service which, once stopped, continues to access his data files (!?)

Dmitry, I agree that this could not corrupt the original database, but it doesn't diminishes the problem. Some unaware user could install a new, faster, drive in his server, stop the service, copy (or, worst, move) the db file to new drive, restart the service, and use it for several hours in a production environment before he notices something went south (probably on next backup).

(And if you are now asking yourself "who would do something as dumb as this?" -- Well... Hi! Nice to meet ya! :) )

So... If my sad story above indeed broke your hearts: Windows API CreateProcess [1] has a DEBUG_PROCESS flag [2] which, when passed into dwCreationFlags parameter, turns every child processes "chained" to this process. This way, killing the root process will also kill every other process created by it. Maybe this isn't the best way to accomplish this, but it is what I'm using with success it in some servers I've made.

What about to put this DEBUG_PROCESS flag into fb_inet_server creation?

Please, remember the users! ;)

[1] http://msdn.microsoft.com/en-us/library/windows/desktop/ms682425(v=vs.85).aspx
[2] http://msdn.microsoft.com/en-us/library/windows/desktop/ms684863(v=vs.85).aspx

@firebird-automations
Copy link
Collaborator Author

Commented by: Sean Leyne (seanleyne)

The current functionality is how Classic has always worked.

@firebird-automations
Copy link
Collaborator Author

Modified by: Sean Leyne (seanleyne)

status: Open [ 1 ] => Resolved [ 5 ]

resolution: Won't Fix [ 2 ]

@firebird-automations
Copy link
Collaborator Author

Commented by: @asfernandes

I do think F. D. Castel is correct. If service stopped successfully, it's expected that Firebird is then down.

Anything different than that smells like bug.

@firebird-automations
Copy link
Collaborator Author

Modified by: @pcisar

status: Resolved [ 5 ] => Closed [ 6 ]

@firebird-automations
Copy link
Collaborator Author

Commented by: @dyemanov

Reopened for further discussion. I'm not really sure whether it should be treated as a bug or as a room for improvement, but I do agree that shutting down the listener should also shut down the workers. Hereby I suggest to accept this ticket.

@firebird-automations
Copy link
Collaborator Author

Modified by: @dyemanov

status: Closed [ 6 ] => Reopened [ 4 ]

resolution: Won't Fix [ 2 ] =>

@firebird-automations
Copy link
Collaborator Author

Commented by: @dyemanov

F. D. Castel, a database shutdown has three modes starting with Firebird 2.0. And the "full shutdown" mode doesn't allow any connections, even SYSDBA ones.

@firebird-automations
Copy link
Collaborator Author

Commented by: @reevespaul

IMO this bug should be re-stated. There are two problems here.

1/ As reported shutting classic down on Windows just kills the listener process. Extant connections remain. This screws up maintenance (like software upgrade, integration with the cpl applet) and means that starting a new instance of the listener doesn't work correctly (or at least it didn't used to - maybe that was fixed. Can't remember.)

However, at least active connections have to be forcibly closed by an admin that knows how to use taskkill.

2/ With Super server we have the opposite - stopping the service will kill all connections. Without any warning.

Both these issues should be fixed. It should not be possible to 'accidentally' stop any engine flavour via the Windows services api if there are active connections. And it should be possible to forcibly bring take all instances down with a single extra switch such as -f[orce].

@firebird-automations
Copy link
Collaborator Author

Commented by: F.D.Castel (fdcastel)

Dmitry: Thanks! I was unaware of that.

---

Paul: I understand your care with existing connections in this case. But IMHO a service stop command, per se, already is a "brute force" way.

I cannot imagine a single reason to keep it honoring existing connections. When the sysadmin requests a service to stop, he/she must have a good reason. If a "softer" solution is needed, he could use FB shutdown modes instead.

And, again using others databases/applications as benchmark, I don't remember any service which cares of current requests when asked to shuts itself off.

It is really annoying when you, after asking for a service stop, get an error message saying some futile reasons to NOT stop it -- and keeps itself running. That's why I suggested (on my first message) we don't follow this way. A locomotive emergency brake must stop the car at any cost, without asking "Are you sure? People on this train could be late for work..."

@firebird-automations
Copy link
Collaborator Author

Commented by: F.D.Castel (fdcastel)

Removed affected versions. Changed issue type to "improvement"

@firebird-automations
Copy link
Collaborator Author

Modified by: F.D.Castel (fdcastel)

issuetype: Bug [ 1 ] => Improvement [ 4 ]

Version: 2.5.0 [ 10221 ] =>

@firebird-automations
Copy link
Collaborator Author

Commented by: F.D.Castel (fdcastel)

BTW: Some comments about the DEBUG_PROCESS flag?

And what about the other ports? By Vlad/Dmitry/Sean comments I understand this is the current behavior on every port, since it is by design (at first I thought it was a bug in the Windows port)

In this case, a more portable (albeit not so clean) solution would be to dispatch a taskkill/pskill for every fb_inet_server on service stop.

@firebird-automations
Copy link
Collaborator Author

Commented by: F.D.Castel (fdcastel)

Bad idea. Pskill "solution" would also kill every other instance of Firebird (in case of two or more services installed on same computer, but listening in different ports)

@firebird-automations
Copy link
Collaborator Author

Commented by: @hvlad

I agree that it will be good to have ability to *correctly* stop working processes by DBA request.
And this is already possible using database shutdown - since v2.5 it closed connections not waiting for client action.
Therefore i don't think this new feature should have big priority.
Also, I see no relation with listener process here.
Do you offer to stop all working Firebird processes when [x]inetd is stopped ?

> What about to put this DEBUG_PROCESS flag into fb_inet_server creation?
a) we will never kill processes as it will destroy database
b) this "solution" is not portable and prevents system from creating crash dumps

> Please, remember the users! ;)
Please, read the manuals. New shutdown modes and nbackup are present since v2.0 !

@firebird-automations
Copy link
Collaborator Author

Commented by: @AlexPeshkoff

What about xinetd - this is absolutely other case. It's typical for unixes to leave daemons, started by xinetd, active after xinetd shutdown. Therefore people should not expect firebird processes to be closed in that case. What about windows and it's services - looks like other behavior is typical. Probably because there are not too much multiprocess windows services.

@firebird-automations
Copy link
Collaborator Author

Commented by: @AlexPeshkoff

Certainly, use of DEBUG_PROCESS is not a solution and telling true it's nonsense for me. But probably sending some 'signal' and processing it like posix does (i.e. smart shutdown) will be very useful.

@firebird-automations
Copy link
Collaborator Author

Commented by: F.D.Castel (fdcastel)

Vlad: From your answer I'm assuming Firebird Classic uses inetd in unix-like ports (which makes perfect sense, of course -- It's just me who never used FB Classic on unixes)

As Alexander said, inetd is another kind of beast (a "generic" service dispatcher). I agree that, *WHEN USING INETD*, this behavior is the expected one. If you setup a subversion server using inetd, stopping inetd won't kill svn processes. No one would to expect otherwise.

*HOWEVER*, if you do the same setup using SVNSERVE, that's a completely different thing: stopping svnserve would terminate all current requests ASAP and exit.

It all boils down to the "principle of least surprise", here :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant