Windows and MV DBMS Shutdown
Most MV environments don’t need to be shutdown when Windows is taken down. D3 does. I thought I’d document how I boot and shutdown my MV environments for you. I lead with D3NT but comment on other platforms as well.
D3NT is the only MV DBMS that has a VME “blob”. At any given moment, the environment is in an “in-use” state. Frames are in various states of linking or unlinking, overflow is being updated, indexes may be in the process of being regenerated, files may be in a state of resizing, and data may still be in the queue to flush to disk. If the process controlling D3 is brutally terminated, there’s no telling what state the environment will be in when it comes back up.
Over the years, D3 has been made more resilient, with updates made more “atomic” to avoid corruption from large but partially completed updates. Local overflow is employed to avoid having every user dip into the global overflow table every time a new frame is required or released. Because of these and other enhancements you’ve probably noticed that D3 doesn’t get many (any?) GFE’s anymore.
I honestly don’t know if D3NT is subject to corruption if we shutdown Windows without taking down D3 first. But I don’t want to get my answer the hard way. I do know that if D3 is up and we shutdown Windows, it does intercept what’s called the QueryShutdown message and it attempts to shutdown cleanly. If you watch a console during shutdown you should notice a dialog that pops up to tell you D3 is shutting down and it offers you an OK or Cancel message.
I’m glad to see a sort of “please wait” message but I think that particular dialog doesn’t explain clearly what’s happening or what’s expected of the user. What happens if we Cancel? Are we taking a chance of having a corrupted database when the system comes back up? What happens if we click OK? I’m hoping nothing happens and that it continues to shutdown D3.
One thing that bothers me is that Windows may not hang around and wait for D3 to terminate itself. Here is how the shutdown process works:
When you tell Windows to shutdown it sends a WM_QUERYENDSESSION message to all running processes. Notice that’s a query, like “hey, we’re closing down, do you have anything you need to do?” I believe in Vista and WPF applications can also get this with the SessionEnding event. Windows programs can optionally listen for that message and execute an event handler when it comes in. The handler should operate quickly and return a response back to Windows that it’s OK to continue. Processes can optionally terminate the shutdown if user interaction is absolutely required, but that can make people very upset if it’s not used properly so it’s rarely used. Most programs will terminate whatever they’re doing and send an OK back to Windows which will then terminate the now inactive processes.
There is no guarantee that the QueryShutdown message will come (for example if you just pull the power on the system) so you can’t rely 100% on your event handler executing. Windows gives each process some amount of time (about 30 seconds) to do whatever it needs to do, but it doesn’t wait indefinitely. Almost everyone has seen a dialog popup at shutdown that says an application has not been terminated properly and it will be terminated. This can happen if a program intercepts the QueryEndSession message but it doesn’t return an OK back to Windows within the timeout period.
With regard to MV, and in particular D3 – what happens if D3 takes too long to shutdown? Well, Windows will probably display that second dialog that says the process hasn’t wrapped itself up, and it will give the user/admin the option to terminate. That prompt doesn’t wait forever for confirmation either. If you don’t respond to the terminate prompt, Windows will go ahead and take itself down anyway.
You can minimize the time taken to shutdown D3 by reducing the number of workspace processes that it needs to wrapup. This is done in the D3 Device Manager in the “D3 Settings” tab where you specify the number of PIBs and Phantoms. Do NOT change this without consulting with TigerLogic, your VAR, or with me! But unless you have a system with less than a total of something like 50 configured processes (not licenses, I mean PIBS+Phantoms), you can’t guarantee that D3 will be able to shutdown completely in the limited timeout period allowed by QueryShutdown.
Years ago Pierre Trinephi wrote a program called D3Tray. It listens for the QueryShutdown message and then sends a message back to Windows telling it to terminate the shutdown. I mentioned above that this can make people mad but it’s OK in this case.) So Windows is no longer standing there tapping it’s virtual foot and waiting for D3 to shutdown. Then D3Tray issues a shutdown command (which I’ll get to soon). When D3 is down, D3Tray re-starts a shutdown. At that point Windows just sends a new message to all processes and everything is expected to come down properly. D3Tray became a property of Pick Systems and it was published on the freeware page of the PS/RD/TL website, but it was never maintained or enhanced. You can still get the utility and I understand TigerLogic says they’d support it, but I don’t know if anyone there actually has the source anymore. I know some people still use D3Tray just for this functionality, but my recommendation would be to let this old little applet fall into disuse, and find something that can be supported if you really need it. I have written tray utilities like this too and can provide the software with source on a commission basis.
What this all comes to is that letting D3 take itself down with the Windows shutdown is probably not the best practice. The best way to take down D3 is to execute the “shutdown” verb at TCL, and then to do the Windows shutdown. But unless we automate the process with something like D3Tray, we may forget to shutdown D3, so it would be better to automate that process.
Maybe it’s a little late to document how to do something with Windows 2003 server but I happen to have a W2k3 up in front of me so I’ll use this as an example. This might apply to Windows 2008 too, I don’t know yet. The goal is to have D3 cleanly shutdown when Windows is on the way down.
In Win2003, put the script below into:
C:\WINDOWS\system32\GroupPolicy\Machine\Scripts\Shutdown\ShutdownD3.bat
sc query | findstr /C:"D3 Virtual"
if %errorlevel%==0 goto Running
if %errorlevel%==1 goto NotRunning
GOTO End
:Running
cd "\Program Files\RainingData\D3\D3Programs"
d3tcl -c "log-msg Windows shutdown" -c "shutdown (y"
GOTO End
:NotRunning
echo D3 is Not Running ...
:End
Now execute gpedit.msc from Windows Start/Run. (I don’t know if or where that would be in any menu.) Under Computer Configuration>Windows Settings, open “Scripts (Startup/Shutdown)”. Open Shutdown, Add, then browse to the above script.
When you’re done, the process to shutdown is modified, so Windows executes the script, and when that is done, it then sends QueryShutdown around to all processes. But by then D3 is already down, so the shutdown moves along quickly. The important point here is that there is no timeout on the script, so even on a larger system D3 will have the time it needs to properly shutdown – and you never need to remember to do it manually anymore.
Let’s quickly pick apart that script:
- “sc” is a command-line program for the Service Control manager. The line above says “is anything running with a name that includes ‘D3 Virtual’?”
- The result is either a 0 or 1 put into an environment variable called “errorlevel”.
- We change to the directory where the D3TCL.exe command is found
- Then execute a command from DOS which will get executed within D3. There are actually two TCL commands that get executed. First is log-msg which I use to tell the D3 log file that D3 has been shutdown from outside. Second is the D3 shutdown verb, using the ‘y’ option which means “take it down immediately, don’t pause or send messages.”
That’s it for D3. For other databases it’s much easier. I use BAT files to terminate all of my databases, though frankly you can just shutdown Windows and these databases never seem to get corrupted. Maybe this is because I just have 2 user licenses on all of my developer/personal DBMS products, and there’s never really anything running in the background. In the absence of “shutdown” verbs for the other environments, I’m wondering if anyone has suggestions for properly stopping the other database beyond my suggestions here.
If you do want to gracefully terminate your DBMS environments, even just to turn them off for a while when they’re not in use, you’re welcome to use the following code.
Here is my script for terminating my MV databases from the desktop. There’s really no need to execute these from a Windows shutdown script as with D3, since these terminate the DBMS services gracefully in exactly the same way as Windows does during shutdown … if you believe that to be incorrect, please post a comment to this blog:
cmd /c "Stop U2.bat"
net stop "Cache_c-_databases_cache"
cmd /c "Stop jBASE.bat"
cmd /c "Stop Reality.bat"
cmd /c "Stop QM.bat"
cmd /c "C:\WINDOWS\system32\GroupPolicy\Machine\Scripts\Shutdown\ShutdownD3.bat"
I don’t have a separate script for Caché because that runs as a tray item which is easily shutdown with just a couple clicks.
The “net” command is used for “net start” and “net stop”. Ironically this has nothing to do with networking but it manages Windows Services. You get the name of the service by opening the Services console and going to Properties.
Here are each of my database-specific scripts – I won’t label them, the DBMS is obvious from the text:
net stop jLicense
net stop jSLIM
net stop "jBASE Telnetd Server"net stop "Reality 14.0"
net stop "QMSvc"
net stop "UniVerse Telnet Service"
net stop "UniVerse Resource Service"
net stop "UniData Telnet Service 7.2"
net stop "UniData Database Service 7.2"
net stop "Uni RPC Service"
I’m not running mvBase at the moment but here is my script for that platform:
net start mvBaseServer
net start mvBaseWorkStation
Starting the processes is done in exactly the opposite order as stopping. For reference, I start/stop MySQL, SQL Server, Fax, IIS, and other processes like this too. I manage individual processes with a quick icon click, rather than leaving all processes running all the time. You can have processes listed in the Services console that are on automatic startup, but unless you really use them all the time, why have services running and consuming CPU cycles and memory unless you’re using them?
Topics not covered here
- Unix/Linux
- OpenInsight, Univision, and maybe other databases
- Windows XP, Vista, and Windows 7
If you wish to fill in the gaps or if there’s something else I missed, please feel free to comment below.