So I'm trying to monitor the longest living lock in my database. The idea is that if a lock has been held for a certain amount of time, I will receive a warning in my application.
But for the life of I can't find the creation time of the locks.
I have used:
exec msdb..sp_lock
exec msdb..sp_who2
SELECT * FROM sys.dm_tran_locks
select * from sys.syslockinfo
select cmd, * from sys.sysprocesses where blocked > 0
But none of these seem to have the information I need.
Any ideas?
G
A long running transaction makes more sense which you can do by looking at database_transaction_begin_time column in sys.dm_tran_database_transactions
I've never known anyone to try and monitor locks... which is possibly why there is no start date/time information for them...
The Lock:Acquired EventClass in SQL Profiler has StartTime and EndTime. You might want to check that
Related
I have a table name Companies with 372370 records.
And there is only one row which has CustomerNo = 'YP20324'.
I an running following query and its taking so much time I waited 5 minutes and it was still running. I couldn't figure out where is the problem.
UPDATE Companies SET UserDefined3 = 'Unzustellbar 13.08.2012' WHERE CustomerNo = 'YP20324'
You don't have triggers on update on that table?
Do you have a cascade foreign key based on that column?
Are you sure of the performance of your server? try to take a look of the memory, cpu first when you execute the query (for example on a 386 with 640mb i could understand it's slow :p)
And for the locks, you can right click the database and on the report you can see the blocking transactions. Sometimes it helps for concurrent access.
Try adding an index on the field you are using in your WHERE clause:
CREATE INDEX ix_CompaniesCustomerNo ON Companies(CustomerNo);
Also check if there are other active queries which might block the update.
Try this SQL and see what is running:
SELECT TOP 20
R.session_id, R.status, R.start_time, R.command, Q.text
FROM
sys.dm_exec_requests R
CROSS APPLY sys.dm_exec_sql_text(R.sql_handle) Q
WHERE R.status in ('runnable')
ORDER BY R.start_time
More details:
List the queries running on SQL Server
or
http://sqlhint.com/sqlserver/scripts/tsql/list-long-running-queries
Once I found someone shrinking database and blocking all other people.
More likely than not your UPDATE is not doing anything, is just waiting, blocked by some other statement. Use Activity Monitor to investigate what is causing the blocking. Most likely you have another statement that started a transaction and you forgot to close it.
There could be other causes too, eg. database/log growth. Only you can do the investigation. An index on CustomerNo is required, true, but lack of an index is unlikely to explain 5 minutes on 370k records. Blocking is more likely.
There are more advanced tools out there like sp_whoisactive.
5mn is way too long for 370k rows, even without any indexes, someone else is locking your update. use sp_who2 (or activity monitor) and check for BlockedBy Column to find who is locking your update
I would suggest to rebuild your indexes. This should surely help you.
If you do not have index on CustomerNo field you must add one.
In my case, there was a process that was blocking the update;
Run: 'EXEC sp_who;'
Find the process that is blocked by inspecting the 'blk' column; Let's say that we find a process that is blocked by '73';
Inspect the record with column 'spid' = '73' and if it's not important, run 'kill 73';
370k records is nothing for sql erver. You should check indexes on this table. Each index makes update operation longer.
I ran this query in my database :
SELECT
DB_NAME(dbid) as DBName,
COUNT(dbid) as NumberOfConnections,
loginame as LoginName
FROM
sys.sysprocesses
WHERE dbid > 0
GROUP BY dbid, loginame
---------------------------------------------------
SELECT COUNT(dbid) as TotalConnections
FROM sys.sysprocesses
WHERE
dbid > 0
---------------------------------------------------
exec sp_who2 'Active'
I want to know the total number of connections to my database. The sum of first query and amount of second query are equal but the third query returns a different number of rows.
I want to know what the third query returns? I see some of the status' in the result of the third query are sleeping. What does this mean? Is the connection idle, or it is ready in the pool? What does it mean if I have many sleeping connections in my result?
thanks
A status of sleeping means the session is connected but not actively running anything (e.g. the simplest definition, while perhaps not 100% accurate, is that there is nothing for that session_id in sys.dm_exec_requests).
sp_who2 'active' filters out any spid that has a status of sleeping or has a last command of AWAITING COMMAND, LAZY WRITER or CHECKPOINT SLEEP. No I did not memorize what sp_who2 does; I simply looked at the source code:
EXEC master..sp_helptext sp_who2;
Note that sp_who2 is undocumented and unsupported, and sysprocesses is deprecated and currently present only for backward compatibility reasons. You will be better served, I think, with a procedure like Adam Machanic's sp_whoisactive. Or at the very least knowing how to use the more modern DMVs like sys.dm_exec_sessions and sys.dm_exec_requests.
EDIT
I should add the unfortunate disclaimer that the more modern DMVs still don't properly reveal the database(s) involved. But what does it really mean anyway? If you have a query like this:
USE database_A;
GO
SELECT [column] FROM database_B.dbo.[table]
UNION ALL
SELECT [column] FROM database_C.dbo.[table];
What database id do you expect will get reflected in sys.sysprocesses.dbid for that session while this query is running? I'll leave it as an exercise to the reader to determine what actually happens. Long story short, that's not the view/column you want to rely on to know which databases are currently being "touched."
I'm currently running the following statement
select * into adhoc..san_savedi from dps_san..savedi_record
It's taking a painfully long time and I'd like to see how far along it is so I ran this:
select count(*) from adhoc..san_savedi with (nolock)
That didn't return anything in a timely manner so for the heck of it I did this:
select top 1 * from adhoc..san_savedi with (nolock)
Even that seems to run indefinitely. I could understand if there are millions of records that the count(*) could take a long time, but I don't understand why selecting the top 1 record wouldn't come back pretty much immediately considering I specified nolock.
In the name of full disclosure, dps_san is a view that pulls from an odbc connection via linked server. I don't think that'd be affecting why I can't return the top row but just throwing it out there in case I'm wrong.
So I want to know what is keeping that statement from running?
EDIT:
As I mentioned above, yes dps_san..savedi_record is a view. Here's what it does:
select * from DPS_SAN..root.SAVEDI_RECORD
It's nothing more than an alias and does no grouping/sorting/etc so I don't think the problem lies here, but please enlighten me if I'm wrong about that.
SELECT queries with NOLOCK don't actually take no locks, they still need a SCH-S (schema stability) lock on the table (and as it is a heap it will also take a hobt lock).
Additionally before the SELECT can even begin SQL Server must compile a plan for the statement, which also requires it to take a SCH-S lock out on the table.
As your long running transaction creates the table via SELECT ... INTO it holds an incompatible SCH-M lock on it until the statement completes.
You can verify this by looking in sys.dm_os_waiting_tasks whilst while during the period of blocking.
When I tried the following in one connection
BEGIN TRAN
SELECT *
INTO NewT
FROM master..spt_values
/*Remember to rollback/commit this later*/
And then executing (or just simply trying to view the estimated execution plan)
SELECT *
FROM NewT
WITH (NOLOCK)
in a second the reading query was blocked.
SELECT wait_type,
resource_description
FROM sys.dm_os_waiting_tasks
WHERE session_id = <spid_of_waiting_task>
Shows the wait type is indeed SCH_S and the blocking resource SCH-M
wait_type resource_description
---------------- -------------------------------------------------------------------------------------------------------------------------------
LCK_M_SCH_S objectlock lockPartition=0 objid=461960722 subresource=FULL dbid=1 id=lock4a8a540 mode=Sch-M associatedObjectId=461960722
It very well may be that there are no locks... If dps_san..savedi_record is a view, then it may be taking a long time to execute, because it may be accessing tables without using an index, or it may be sorting millions of records, or whatever reason. Then your query, even a simple top or count, will be only as fast as that view can be executed.
A few issues to consider here. Is dps_san..savedi_record a view? If so, it could just be taking a really long time to get your data. The other thing I can think of is that you're trying to create a temp table by using the select into syntax, which is a bad idea. select * into ... syntax will lock the tempdb for duration of the select.
If you are creating the table using that syntax, then there is a workaround. First, create the table by throwing where 1=0 at the end of your initial statement:
select * into ... from ... where 1=0
This will create the table first (which is quick) which allows you to insert into because the table exists now (without penalty of locking tempdb for duration of query).
Find the session_id that is performing the select into:
SELECT r.session_id, r.blocking_session_id, r.wait_type, r.wait_time
FROM sys.dm_exec_requests AS r
CROSS APPLY sys.dm_exec_sql_text(r.plan_handle) AS t
WHERE t.[text] LIKE '%select%into%adhoc..san_savedi%';
This should let you know if another session is blocking the select into or if it has a wait type that is causing a problem.
You can repeat the process in another window for the session that is trying to do the select. I suspect Martin is right and that my earlier comment about schema lock is relevant.
i got this error
timeout value expired. The timeout period elapsed prior to completion
of the operation or the server is not responding
i have a process, which do inserts and update at night, another process
which does query at nights too, (etl or dts) at sql server 2005 so, now we need to do a query to this table, and this doesn't work, i want to run my process again, and this never finish, and noneone can do a query to this table, (another tables could do) users commented me, yesterday they could do, but today, they coulden't is it posible, my process is execute at night has never finished, and it let a begin transaccion open?
how can i to be sure of this? and close it from ssms ?
this is not a problem of permissions we could do queries and inserts/updates yesterday.
it happens only with one table.
Try this:
SELECT TOP 1 * FROM Table (nolock)
Does that return results? If so, sounds like a locking issue..
I have a simple query like this
SELECT * FROM MY_TABLE;
When I run it, SQL Server Management Studio hangs.
Other tables and views are working fine.
What can cause this? I've had locks while running UPDATE statements before, and I know how to approach those. But what could cause a SELECT to lock?
I have run the "All Blocking Transactions" report, and it says there are none.
It is probably not the select that is locking up, but some other process that is editing (udpate/delete/insert) the table that is causing the locks.
You can view which process is blocking by runing exec sp_who2 on your SQL Server.
Alternatively, if you are OK with dirty reads, you can do one of two things
SELECT * FROM Table WITH (NOLOCK)
OR
SET Transaction Isolation Level Read Uncommitted
SELECT * FROM Table
If there's a lot of other activity going on, something else might be causing locks, and your SELECT might be the deadlock victim. if you run the following
SELECT * FROM my_table WITH(nolock)
you're telling the database that you're ok to read dirty (uncomitted) data, and that locks caused by other activity can be safely ignored.
Also, if a query like that causes management studio to hang, your table might use some optimization
Use this:
SELECT * FROM MY_TABLE with (NOLOCK)
Two possibilities:
Its a really massive table, and you're trying to return 500m rows.
Some other process has a lock on the table, preventing your select from going through until that lock is released.
MY_TABLE could be also locked up by some uncommitted transaction -- i.e. script/stored procedure running (or failed while running) in another MSMM window.