How to remotely Start/Stop SQLServer services kicking off existing connections? - sql-server

I know there is already a question about this but my issue is more oriented to remote scenarios.
With net start/stop you can specify a /y parameter to bounce users off current sessions but you cannot start/stop remotely.
With sc you can start/stop remotely but if the SQLServer instance is being used it won't let you stop the service (with a "[SC] ControlService FAILED 1051: A stop control has been sent to a service that other running services are dependent on." message)
So my question is: what's the best way of kicking out users stopping the SqlServer service remotely?

I think the /y just answers Yes to the "Are you sure?" prompt. I'd think that sc could be used as well, though it may time out waiting for the service to stop if there's a lot of inflight transactions. Does it give you any specifics of why it can't stop?
Here's a couple of other methods to stop a remote SQL instance. Except for SHUTDOWN WITH NOWAIT, I'd recommend any of them.
psexec will let you run net stop remotely.
There's also the SQL SHUTDOWN command - you can issue that WITH NOWAIT to avoid waiting for current transactions to finish and checkpointing, which will make shutdown faster (but subsequent startup slower, and could lead to lost data).
Or you could use either Configuration Manager or Management Studio to stop a remote instance.
Edit: The error is pretty self explanatory. It means you must stop dependent services first. Sql Agent is probably at least one of them. Checking Admin Tools->Services will show you the rest.

Using SSMS is the best make sure you have the proper privileges to shutdown and check to see the status of replications and ALWAYS ON and Log Shipping.

Related

Offline and online execution problem with multiples queries incoming

I have a SQL Server service and multiple Windows Service doing some backgrounds work on same server.
One of them (I'm calling it "A") have a routine executing "single_user/offline" and "online/multi_user" to active databases to do some backup operations at midnight. The another ones executes multiple queries over that databases (I'm calling it "B").
The problem is the following:
1.- Windows Service "A" executes SET ONLINE.
2.- Windows Service "B" executes a random SELECT.
3.- Windows Service "A" tries to execute SET MULTI_USER. This execution is dropped because there is an active connection made from Windows Service "B".
I've tried executing SET ONLINE and SET MULTI_USER on same CommandText of the SqlCommand, but this doesn't denies the incoming query from Windows Service "B", breaking my process and keeping the database locked (because the SINGLE_USER).
How can I make an ONLINE and MULTI_USER commands at same time on the Windows Service "A" to make Windows Service "B" being cancelled or wait the process finished? (It's not a problem that Windows Service "B" being cancelled)
Could be sp_dettach_db or sp_attach_db useful?
It sounds like Service A is closing it's connection after bringing the database into Single User mode. This frees up Service B to become the single user, at which point Service A can no longer change the mode until it can grab the single connection back, which it won't be able to do as long as Service B, or any other client for that matter, has it.
I can think of a couple of things you could do here:
Once your offline operations are complete, begin polling until Service A can become the single user again
Find the SPID of the connection from Service B and kill it.
See the limitations and restrictions section about single user mode at this link for more info.
Thanks to all, but I reanalyzed the problem I was having from the beginning, and concluded that the action "SET SINGLE_USER" was not necessary, since the process does not require actions in that mode, so finally with the action "SET OFFLINE" and "SET ONLINE" could prevent intermediate connection problems.

Error 17886 - The server will drop the connection

We are running a website on a vps server with sql server 2008 x64 r2. We are being bombarded with 17886 errors - namely:
The server will drop the connection, because the client driver has
sent multiple requests while the session is in single-user mode. This
error occurs when a client sends a request to reset the connection
while there are batches still running in the session, or when the
client sends a request while the session is resetting a connection.
Please contact the client driver vendor.
This causes sql statements to return corrupt results. I have tried pretty much all of the suggestions I have found on the net, including:
with mars, and without.
with pooling and without
with async=true and without
we only have one database and it is absolutely multi-user.
Everything has been installed recently so it is up to date. They may be correlated with high cpu (though not exclusively according to the monitors I have seen). Also correlated with high request rates from search engines. However, high cpu/requests shouldn't cause sql connections to reset - at worst we should have high response times or iis refusing to send response.
Any suggestions? I am only a developer not dba - do i need a dba to solve this problem?
Not sure but some of your queries might cause deadlocks on the server.
At the point you detect this error again
Open Management Studio (on the server, install it if necessary)
Open a new query window
Run sp_who2
Check the blkby column which is short for Blocked By. If there is any data in that column you have a deadlock problem (Normally it should be like the screenshot I attached, completely empty).
If you have a deadlock then we can continue with next steps. But right now please check that.
To fix the error above, ”MultipleActiveResultSets=True” needs to be added to the connection string.
via Event ID 17886 MSSQLServer – The server will drop the connection
I would create an eventlog task to email you whenever 17886 is thrown. Then go immediately to the db and execute the sp_who2, get the blkby spid and run a dbcc inputbuffer. Hopefully the eventinfo will give you something a bit more tangible to go on.
sp_who2
DBCC INPUTBUFFER(62)
GO
Use a "Instance Per Request" strategy in your DI-instantiation code and your problem will be solved
Most probably you are using dependency injection. During web development you have to take into account the possibility of concurrent requests. Therefor you have to make sure every request gets new instances during DI, otherwise you will get into concurrency issues. Don't be cheap by using ".SingleInstance" for services and contexts.
Enabling MARS will probably decrease the number of errors, but the errors that are encountered will be less clear. Enabling MARS is always never the solution, do not use this unless you know what you're doing.

SQL Server job timeout

So, it seems that it is not possible to set the timeout for each single step in a SQL Server job (article from StackExchange).
MSDN points out that you can of course set the Agent timeout:
Sql Server Agent properties.
Set Job execution shutdown.
Questions
How does Agent time-out work?
Is there any other way (preferably by configuration) to setup the single step timeout?
Is there any other way (preferably by configuration) to setup the whole job timeout?
To answer question 2, I'm not sure if this is the best option but you could use OPENROWSET to control a single step timeout.
http://msdn.microsoft.com/en-us/library/ms190312.aspx
Just because OPENROWSET is normally used to access remote servers doesn't mean it has to be.
Probably this is similar to how agent timeout works.
You could even use this to control the whole job timeout although if you want to do it by configuration you'd have to create your own tables.
I'm not sure this is the best solution but it's a solution at least.

Using nHibernate in a windows service

I want to use nHibernate in a windows service. If the systems boots, it might start my service before the database. In that case, configuration of nHibernate fails and the service crashes. So now I'm wondering how I can check if the database service has already been started. In case it has not yet started, my service should wait a bit and try again later.
If your service always runs on the same machine as SQL Server, You should be using ServiceInstaller.ServicesDependedOn to tell Windows(SCM) that you depend on 'MSSQLSERVER' (the name of service that runs SQL Server).
From MSDN:
A service can require other services to be running before it can
start. The information from this property is written to a key in the
registry. When the user (or the system, in the case of automatic
startup) tries to run the service, the Service Control Manager (SCM)
verifies that each of the services in the array has already been
started.
ServiceInstaller is the class that is used by InstallUtil when it installs your service. Other installation packages including InstallShield also support this windows functionality. Equivalent SC command.
So your service will only start after SQL Server is already running. But even in this case, it might still be a good idea to offload all potentially long running startup procedures to the background thread. Do as little as possible in OnStart method. Ideally you would just spawn a new initialization thread that would take care of NHibernate session factory initialization. If for some reasons you still want to do this in OnStart, then you should consider retrying NHibernate initialization and calling ServiceBase.RequestAdditionalTime to avoid:
Error 1053: The service did not respond to the start or control
request in a timely fashion.
Ideally your service should not depend on the database availability because it might be running on a remote machine. The service is an 'always on' process that should tolerate intermittent database connectivity issues.
No clue if there are better ways, but in your service startup, check for the system uptime. If this is less then let's say 5 minutes, wait for (5 minutes - Uptime) and after that start the rest of the service as you normally would.
See the following for Calculating server uptime gives "The network path was not found"
This is not a solution however for when your service tries to connect to a SQL which is down, however if this happens you want to handle the exception and actually be notified that the SQL is down. Very unlikely you want the service to keep trying without you yourself beeing aware the SQL is down.
You could use ServiceController class and call its static method GetServices() to get the list of services. It will give an array of services, find the right one and check its status.
See ServiceController on MSDN
Currently I am making sure I can establish a connection to the database needed and running a default query (configurable). If this is successful I proceed to start the service.
What I've found in some cases is that even if the MSSQL service is started it doesn't guarantee that you can connect to it and execute queries against it.

How to determine the most restrictive SQL server security permissions a program can use and still function?

PROBLEM BACKGROUND
Sorry if this is a bit tedious to read, but please bear with me.
I have been tasked to determine the most restrictive security permissions...or rather investigate if more restrictive security settings can be configured for the SQL server login our program uses, yet still function as normal.
Currently the program runs as a Windows service configured to log on using a Windows user account that has been configured in SQL server with trusted auth. The login used has been assigned a db_owner role and the service works fine like that.
So to narrow the permissions for this user I removed the db_owner rights and assigned it to the db_datareader and db_datawriter roles. Unfortunately this causes a problem and when I start up the service I get an error dialogue displaying:
Error 1053: the service did not respond to the start or control request in a timely fashion.
and in the event viewer under the System events are logged:
event 7009 (timeout waiting for..to connenct)
event 7000 (the service did not respond to the start or control )
My problem is the code base is really large and I'm not sure what exactly to look for that would require db_owner permissions (it sets permissions maybe?).
QUESTION
What should I be looking for in a program that executes SQL that would cause it to require db_owner permissions?
In case the first question is too general: is there an easy way/any tools I can use to figure out what a Windows service is trying to do during start-up 'SQL wise' if I get system error events logged:
event 7009 (Timeout (30000 milliseconds) waiting for the ... service to connect)
event 7000 (The service did not respond to the start or control request in a timely fashion).
BTW I tried running profiler with all audit events selected, but still get nothing logged when starting the service.
This is such a broad question without knowing the architecture of your service and how it communicates with SQL Server. Are you using in-line SQL? Stored Procedures?
I think you'd best tackle this issue by starting from the service's code and tracing the execution path from the start and see what is being executed on/against SQL Server.
Alternatively, if you are using stored procedures, you may want to script them all out into a file and search on some common T-SQL commands limited to a db_owner, such as CREATE, DROP, ALTER.

Resources