Currently, i have SQL Server 2005 database for which I have admin rights, but do not have sysadmin rights.
There was a particular process which was stopping me to do few things on a table.
Is there a way to kill a user SQL queries, if they were ran through a web client without having sys admin rights. In my case, django website ran the query using pymssql ?
Using "KILL" is role-restricted for a very good reason, and should be used only when you understand what the blocking process is doing. If the KILL statement is used against a SPID executing a long-running transaction, the KILL will initiate a ROLLBACK on the table (which can take quite a while on a large table) to maintain DB consistency. The statement:
SELECT open_tran FROM master.sys.sysprocesses WHERE SPID=<blocking SPID number>
will give you some detail about the process and what it's doing. Alternatively you can try:
DBCC INPUTBUFFER(<spid>)
to find the last statement that was submitted by a SPID (though I think your permissions might not be sufficient). If it's determined that the SPID is sleeping on the block, you'll still need to be promoted to a minimum role of processadmin in order to execute a KILL statement.
Three other recommendations to help you:
Work to implement the use of Locking Hints in code executed against the DB.
If this is a consistent problem, ask your DBA's to evaluate the statement(s) that cause the blocks, and ask their advice.
Getting close to your DBAs never hurts, and a little buttering up (pizza lunch, after-work drinks, etc.) once or twice can really make a difference. They may not grant you the permission promotion you need, but they could create a workaround for you as described here that could solve your problem without changing your role.
Use command for see connections sp_who then use command KILL <SPID>
if you are using ssms then try to close/save the editor window where you sp or query started running
ssms will ask you to commit the transaction just press ok
That's it!
Related
We have a process that was running for 4 hours. Because it was running so long, it was causing other issues in the database, so it was decided to kill the process.
Now, the process is in a suspended state. It also states that it's being blocked by itself after querying sp_who2.
In activity monitor, here's the waitresource information:
objectlock lockPartition=0 objid=xxx subresource=FULL dbid=2 id=lockyyyy mode=X associatedObjectid=xxx
You'll notice that the objid and associatedObjectId are the same value.
Querying the sys.objects table shows NO results for that object id.
Is Sql Server waiting for a lock on an object that doesn't exist anymore? How can I get rid of this process without restarting Sql Server? (our DBA's are not responding to help requests).
Keep in mind, this is a test environment, but it is stopping all development/testing because we are unable to deploy any changes to our database, because one of those changes is affecting one of the objects that the process was accessing.
Edit: more info from activity monitor:
Command = 'KILLED/ROLLBACK'
TASK STATE = 'SUSPENDED'
I have experienced this may times. When you kill a large INSERT/UDPATE/DELETE statement, it can take hours to recover (if it ever does recover) from this state.
run kill <spid> with statusonly.
It will give you a percentage and estimated wait time of the ROLLBACK process.
Sometimes it says 0% or 100% and 0 estimated time. If you are patient, it may recover eventually. If you restart the server, the rollback process will be completed offline, and the database will show IN RECOVERY state and usually will be faster than waiting the server to recover itself.
Be aware that users won't be able to use the database until the recovery process ends, but if the SPID in KILLED/ROLLBACK state is locking other process, it might be an option to restart.
Well, this seems to be lock due to parallel processing inside the tempdb.
You can try kill [processid] if you have the rights to?
Another way is to get more detailed process information with this:
SELECT * FROM sys.sysprocesses WHERE spid = YOURSPID
As the Process runs in DB:2 try this:
SELECT * FROM tempdb.sys.all_objects WHERE object_id = OBJECTID
As I've seen, you have edited your question. If the Spid is in KILLED/ROLLBACK you have to wait until your transaction is rolled back. After that the process will be killed and removed. You can't do anything else, as the transaction security must be given.
We have an SQL Job Agent that runs in the "wee hours" to restore our local database (FooData) from a production backup.
First, the database is set to SINGLE_USER mode and any open processes are killed. Second, the database is restored.
But the 3rd step fails occasionally with Error 6107: "Only User Processes Can Be Killed"
This happens about once or twice a week at seemingly random intervals. Here is the code for step 3 where the failure occasionally occurs:
USE master;
go
exec msdb.dbo.KillSpids FooData;
go
ALTER DATABASE FooData SET MULTI_USER;
go
Does anybody have any ideas what might be occurring to cause this error? I'm thinking there might be some automated process starting up during step 3 or possibly some user trying to log in during that time? I'm not a DBA, so I'm guessing at this point, although I believe that a user should not be able to log in while the DB is in SINGLE_USER mode.
A user probably isn't logged in. The system is probably performing some task. The output of exec sp_who or sp_who2 will show what sessions are open. Any SPID below 50 is a system process, and cannot be killed with KILL. The only way to stop them is to stop the SQL Server service or issue a SHUTDOWN command (which does the same thing).
I found the answer to my problem by changing one line of code which worked like a charm.
As mentioned in the original question, the 'KillSpids" line is used in Step 1 of the job. (Along with SET SINGLE USER) The 'KillSpids' made sense in Step 1 because there may be unwanted processes still active on the database.
The 'KillSpids' line was then added again into Step 3, but it was unnecessary, and was also causing the 6107 error.
I replaced the 'KillSpids' line with the one shown below. Setting the freshly restored database to single user mode takes care of the concern that a user might try to log in before all the job steps have been completed. Here is the updated code:
USE master;
go
ALTER DATABASE [FooData] SET SINGLE_USER WITH ROLLBACK IMMEDIATE
go
ALTER DATABASE FooData SET MULTI_USER;
go
Put differently, should I always set the job owner to sa for a SQL job, even though it defaults to the user who created it?
Any jobs that are owned by a user will cease to run if that user is disabled or deleted. The jobs may also not run if there is an Active Directory problem at run time. Brent Ozar has an article about this on his website:
http://www.brentozar.com/blitz/jobs-owned-by-user-accounts/
You're gonna have to bear with me. Because I'm going by memory.
Looking at some old scripts, I have this code.
select #jobOwnerNameVeryImportantToSetCorrectly = 'someSqlAuthenticatonUser'
Now. In my scenario, I allowed a non 'sa' user to schedule and run the jobs.
Thus why I made the owner a non 'sa' user.
The question I think to answer is, "who runs the jobs". If it is always 'sa', then its not an issue.
But, if you want a non 'sa' account to run it, then how is a less privileged account going to run a job owned by the super-mack-daddy account?
My test would be.
Create a job. Let 'sa' own it.
Create a temp sql-authentication account.
Login to the database as this sql-authentication account.
See if you can run the job.
My memory is saying "the lesser account won't be able to". However, I dealt with jobs on Sql Server 2005. So even if I remember correctly for 2005, it may not be the same for 2008 or 2008R2.
But I remember having issues with this. And thus my variable declaration:
select #jobOwnerNameVeryImportantToSetCorrectly = 'someSqlAuthenticatonUser'
I read Brent Ozar's article as well and am in a similar situation where there are a lot of jobs not owned by SA that are enabled. From what I have researched, I haven't found any compelling reason NOT to change the ownership to 'SA' but two good reasons mentioned above why you should.
You don't have to worry about them not being able to run from this change. The only two things I would be cautious about are:
1) Jobs that you run as SA and
2) If you are coming into an environment, enabling jobs that have been disabled after you've made this change.
Why someone would ever do those two things, IDK but you can always back up msdb and then test these changes in a dev or training server. Just note the jobs that you change in case something unexpected happens.
I'm trying to perform some offline maintenance (dev database restore from live backup) on my dev database, but the 'Take Offline' command via SQL Server Management Studio is performing extremely slowly - on the order of 30 minutes plus now. I am just about at my wits end and I can't seem to find any references online as to what might be causing the speed problem, or how to fix it.
Some sites have suggested that open connections to the database cause this slowdown, but the only application that uses this database is my dev machine's IIS instance, and the service is stopped - there are no more open connections.
What could be causing this slowdown, and what can I do to speed it up?
After some additional searching (new search terms inspired by gbn's answer and u07ch's comment on KMike's answer) I found this, which completed successfully in 2 seconds:
ALTER DATABASE <dbname> SET OFFLINE WITH ROLLBACK IMMEDIATE
(Update)
When this still fails with the following error, you can fix it as inspired by this blog post:
ALTER DATABASE failed because a lock could not be placed on database 'dbname' Try again later.
you can run the following command to find out who is keeping a lock on your database:
EXEC sp_who2
And use whatever SPID you find in the following command:
KILL <SPID>
Then run the ALTER DATABASE command again. It should now work.
There is most likely a connection to the DB from somewhere (a rare example: asynchronous statistic update)
To find connections, use sys.sysprocesses
USE master
SELECT * FROM sys.sysprocesses WHERE dbid = DB_ID('MyDB')
To force disconnections, use ROLLBACK IMMEDIATE
USE master
ALTER DATABASE MyDB SET SINGLE_USER WITH ROLLBACK IMMEDIATE
Do you have any open SQL Server Management Studio windows that are connected to this DB?
Put it in single user mode, and then try again.
In my case, after waiting so much for it to finish I had no patience and simply closed management studio. Before exiting, it showed the success message, db is offline. The files were available to rename.
execute the stored procedure
sp_who2
This will allow you to see if there is any blocking locks.. kill their should fix it.
In SSMS: right-click on SQL server icon, Activity Monitor. Open Processes. Find the processed connected. Right-click on the process, Kill.
In my case I had looked at some tables in the DB prior to executing this action. My user account was holding an active connection to this DB in SSMS. Once I disconnected from the server in SSMS (leaving the 'Take database offline' dialog box open) the operation succeeded.
anytime you run into this type of thing you should always think of your transaction log. The alter db statment with rollback immediate indicates this to be the case. Check this out: http://msdn.microsoft.com/en-us/library/ms189085.aspx
Bone up on checkpoints, etc. You need to decide if the transactions in your log are worth saving or not and then pick the mode to run your db in accordingly. There's really no reason for you to have to wait but also no reason for you to lose data either - you can have both.
Closing the instance of SSMS (SQL Service Manager) from which the request was made solved the problem for me.....
To get around this I stopped the website that was connected to the db in IIS and immediately the 'frozen' 'take db offline' panel became unfrozen.
Also, close any query windows you may have open that are connected to the database in question ;)
I tried all the suggestions below and nothing worked.
EXEC sp_who
Kill < SPID >
ALTER DATABASE SET SINGLE_USER WITH Rollback Immediate
ALTER DATABASE SET OFFLINE WITH ROLLBACK IMMEDIATE
Result: Both the above commands were also stuck.
4 . Right-click the database -> Properties -> Options
Set Database Read-Only to True
Click 'Yes' at the dialog warning SQL Server will close all connections to the database.
Result: The window was stuck on executing.
As a last resort, I restarted the SQL server service from configuration manager and then ran ALTER DATABASE SET OFFLINE WITH ROLLBACK IMMEDIATE. It worked like a charm
In SSMS, set the database to read-only then back. The connections will be closed, which frees up the locks.
In my case there was a website that had open connections to the database. This method was easy enough:
Right-click the database -> Properties -> Options
Set Database Read-Only to True
Click 'Yes' at the dialog warning SQL Server will close all connections to the database.
Re-open Options and turn read-only back off
Now try renaming the database or taking it offline.
For me, I just had to go into the Job Activity Monitor and stop two things that were processing. Then it went offline immediately. In my case though I knew what those 2 processes were and that it was ok to stop them.
In my case, the database was related to an old Sharepoint install. Stopping and disabling related services in the server manager "unhung" the take offline action, which had been running for 40 minutes, and it completed immediately.
You may wish to check if any services are currently utilizing the database.
Next time, from the Take Offline dialog, remember to check the 'Drop All Active Connections' checkbox. I was also on SQL_EXPRESS on local machine with no connections, but this slowdown happened for me unless I checked that checkbox.
SSMS, especially if running it from your own desktop remotely and not directly within the database server, can be a reason for the long delays in detaching a database. For some reason SSMS may not be able to disconnect any existing "connections" to the database.
We found the process was almost instant when we did it directly from the database server itself. And in fact it killed the attempt from my own desktop SSMS session, and it "took over" and detached the database.
Nothing else suggested here worked.
Thanks
In my case i stopped Tomcat server . then immediately the DB went offline .
I've written some code to upgrade a SQL Server database. Before I upgrade the database, I attain an exclusive lock via:
ALTER DATABASE Test SET SINGLE_USER WITH NO_WAIT
However, I'd like to test the database to see if the exclusive lock is possible before I run the above code. The test doesn't have to be 100% perfect, I'd just like to avoid the possibility of a timeout when attempting to gain an exclusive lock.
To that end, I've written the code below:
SELECT
*
FROM
sys.db_tran_locks
WHERE
resource_database_id = DB_ID('Test') AND
request_session_id <> ##SPID
I'm assuming that if there's 1 or more row returned, then the database must be in use. Is this true? Or is it not that simple?
UPDATE Taking #gbn's comments into account, I've decided to force rollback of existing connections using the following statement:
ALTER DATABASE Test SET SINGLE_USER WITH ROLLBACK IMMEDIATE
Before running this code, I'll give the user the an opportunity to opt out. However, I'd like the user to be able to see the list of active connections to the database - so they can make an informed decision. Which leads me onto this question.
Mainly, a DB lock is just to show it is in use. Databases don't really have many exclusive locks situations compared to code/table objects.
Single user mode is not a lock, but the number of connections allowed.
I'd wrap the ALTER DATABASE in a TRY/CATCH block because there is no guarantee the state won't change between check and ALTER DB.
However, I could be wrong or misunderstanding the question... so you'll also have to test for the exclusive lock mode on the database resource in the query above. Your code above will show you any lock, which could be someone having a blank query window open in SSMS...
Edit, based on comment
You can detect who is using it by these:
sys.dm_exec_connections
sys.dm_exec_sessions
sys.dm_exec_requests
To be honest, it's difficult to stop auto stats update or a user taking the single connection. Normally, you'd this which disconnects all other users and not bother waiting...
ALTER DATABASE MYDB SET SINGLE_USER WITH ROLLBACK IMMEDIATE
What if the database becomes busy from the time you determined that it was not in use, until the point where you try to acquire the exclusive lock?