How to figure out what object is represented by associatedObjectId during blocking? - sql

I got report from another team about blocking in SQL Server. Looking at results of
Exec sp_who2
and query from blog by Glenn Berry
SELECT blocking.session_id AS blocking_session_id
,blocked.session_id AS blocked_session_id
,waitstats.wait_type AS blocking_resource
,waitstats.wait_duration_ms
,waitstats.resource_description
,blocked_cache.text AS blocked_text
,blocking_cache.text AS blocking_text
FROM sys.dm_exec_connections AS blocking
INNER JOIN sys.dm_exec_requests blocked
ON blocking.session_id = blocked.blocking_session_id
CROSS APPLY sys.dm_exec_sql_text(blocked.sql_handle) blocked_cache
CROSS APPLY sys.dm_exec_sql_text(blocking.most_recent_sql_handle) blocking_cache
INNER JOIN sys.dm_os_waiting_tasks waitstats
ON waitstats.session_id = blocked.session_id
I want not able to catch anything being blocked. Running this multiple time I start to notice that something shows up but next time I run query, blcoking is gone.
I created temp table by SELECT INTO
,blocking_cache.text AS blocking_text
INTO #TempBlockingTable
FROM sys.dm_exec_connections AS blocking
After that modified query to be INSERT INTO SELECT. Now I was able to run query as many times as I want without fearing that results would be gone.
I kept running query for about 10 seconds until I finally got some results.
SELECT * FROM #TempBlockingTable
Looking at resource_description column from sys.dm_os_waiting_tasks I found that data is displayed in the following format.
<type-specific-description> id=lock<lock-hex-address> mode=<mode> associatedObjectId=<associated-obj-id>
Microsoft documentation on sys.dm_os_waiting_tasks http://technet.microsoft.com/en-us/library/ms188743.aspx does not have definition for associatedObjectId

Answer actually comes from Aaron Bertrand found it on Google Groups. To Get OBJECT_NAME of associatedObjectId you need to run the following query
SELECT OBJECT_NAME([object_id])
FROM sys.partitions
WHERE partition_id = 456489945132196
This number 456489945132196 represents value of associatedObjectId from resource_description column from sys.dm_os_waiting_tasks

Related

Select Query doesn't show any results and appears to hang

I have a table, dbo.PE, in SQL Server 2017. Yesterday I had over 40,000 records. today when I do this:
Select Top 1000 * From dbo.PE
Nothing happens. No results (not even a No records message). It just sits there and spins and says Executing Query until it is cancelled. Any Idea to what is going on? I tried inserting new data and once again, nothing happens, just sits there and spins until cancelled.
I can access other tables in the database, just not this one. No permissions have been changed.
So, To answer this question, gsharp was correct in that the table was locked. I ran the following statement to kill the session (https://infrastructureland.wordpress.com/2015/01/24/how-to-release-or-remove-lock-on-a-table-sql-server/):
SELECT
OBJECT_NAME(P.object_id) AS TableName,
Resource_type,
request_session_id
FROM sys.dm_tran_locks L
JOIN sys.partitions P ON L.resource_associated_entity_id = p.hobt_id
WHERE OBJECT_NAME(P.object_id) = ‘dbo.PE’
Found out that the session ID was 54 so I executed:
kill 54

How to change query status from suspended to runnable?

I have a query that needs to update 2 million records but there is no space in the disk, so the query is suspended right now. After that, I free up some space, but the query is still in suspended. So how should I change the status to Runnable or is there any way to tell sql server that you have enough space right now, and you can run the query.
After that, I free up some space, but the query is still in suspended.is there any way to tell sql server that you have enough space right now, and you can run the query.
SQLSERVER will change the query status from suspended to runnable automatically,it is not managed by you..
Your job here is to check ,why the query is suspended..Below dmvs can help
select session_id,blocking_session_id,wait_resource,wait_time,
last_wait_type from sys.dm_exec_requests
where session_id=<< your session id>>
There are many reasons why a query gets suspended..some of them include locking/blocking,rollback,getting data from disk..
You will have to check the status as per above dmv and see what is the reason and troubleshoot accordingly..
Below is some sample piece of code which can help you in understanding what suspended means
create table t1
(
id int
)
insert into t1
select row_number() over (order by (select null))
from
sys.objects c
cross join
sys.objects c1
now in one tab of ssms:
run below query
begin tran
update t1
set id=id+1
Open another tab and run below query
select * from t1
Now open another tab and run below query
select session_id,blocking_session_id,wait_resource,wait_time,
last_wait_type,status from sys.dm_exec_requests
where session_id=<< your session id of select >>
or run below query
select session_id,blocking_session_id,wait_resource,wait_time,
last_wait_type,status from sys.dm_exec_requests
where blocking_session_id>0
You can see status as suspended due to blocking,once you clear the blocking(by committing transaction) , you will see sql server automatically resumes suspended query in this case

Filtering on a derived column in UniOLEDB

I am working on a piece of SQL for a IBM U2 Rocket database. It's not a flavour of db platform I'm familiar with.
I do not have direct access to this database: I can only access it by composing statements in the calling code and testing it from there. That makes it kind of awkward to figure out where the problem is when there are syntax errors.
I'm trying to compose a query which has a condiational on a dervied column. As far as I can tell from what I've read about the database, this ought to work:
SELECT a.*
FROM (
SELECT dp.NAME
,dp.Code
,dp.BusinessType + ts.BusinessType AS bType
FROM dataPoints dp
LEFT OUTER JOIN trialSuppliers ts
WHERE ts.AccountStatus = 'A'
) a
WHERE a.bType LIKE '%cho%'
However, it throws this error:
Died in UCI::SQLExecDirect() with SQLSTATE 37000, Native error:0
[IBM][SQL Client][UNIDATA]
If you just run the inner query, it works fine. Trying to use any kind of inner select statement causes it to throw the same error, i.e. this:
SELECT *
FROM (
SELECT dp.NAME
,dp.Code
,dp.BusinessType + ts.BusinessType AS bType
FROM dataPoints dp
LEFT OUTER JOIN trialSuppliers ts
WHERE ts.AccountStatus = 'A'
)
Still fails.
What's the correct syntax to be able to filter my query by the derived column?
Just doing some clean-up, did the last comment resolve the issue?
I am not a UniData user but in its half cousin UniVerse the "from clause" has to be a table. You have to do sub-queries in the where clause. I would do what you want to do adding a couple of I-descriptors in the dictionary. I have often found the limited SQL compliance of the U2 products to be somewhat of a hindrance, but when your metadata is external to and separate from your data you are going to lose a bit of structured query sanity. – Van Amburg Sep 21 '17 at 17:31

How to see the history of executed scripts and their execution time and counts in sql server?

I want to find the execution time and execution count of the script ran in my sql server.
I have added, for example, /* searchThisString */ on every executed script. And then I use the following code to find them out.
SELECT dest.text, deqs.last_execution_time, deqs.execution_count
FROM sys.dm_exec_query_stats AS deqs
CROSS APPLY sys.dm_exec_sql_text(deqs.sql_handle) AS dest
WHERE deqs.last_execution_time > '<time>'
AND dest.text LIKE '%<searchThisString>%';
However, there is one case that this code failed. If a script only consist of 'update' queries, the above code fails to find it out:
For example,
example_script.sql
/*searchThisString*/
update <table> set colA = 'A' where colB = 'B'
Then the above code will fail to find this executed script out.
Update:
I have just found that sys.dm_exec_cached_plans can actually find all the executed scripts. However, it does not have the last_execution_time and execution_count information of the executed scripts.
I have tried to join it with sys.dm_exec_query_stats using the following code (but it does not work either). I think because sys.dm_exec_query_stats does not have this executed query, so it return 'null' for the last_execution_time and 'null' for execution_count when I join them up.
SELECT dest.text, deqs.last_execution_time, deqs.execution_count
FROM sys.dm_exec_cached_plans AS decp
CROSS APPLY sys.dm_exec_sql_text(decp.plan_handle) AS dest
LEFT JOIN sys.dm_exec_query_stats As deqs
ON decp.plan_handle = deqs.plan_handle
WHERE deqs.last_execution_time > '<time>'
AND dest.text LIKE '%<searchThisString>%';
Update2:
Here is the result:
I executed below script repeatedly
/***text***/
update test1 set name ='a'
where name ='test1'
update test1 set name='b'
where name='test2'
and then i executed below script to see stats..
select txt.text,st.execution_count,st.total_worker_time
from sys.dm_exec_query_stats st
cross apply
sys.dm_exec_sql_text(st.sql_handle) txt
I could see output,even though there are only update statements..
Further,you can see from above snip,comments are not captured.I recommend checking for actual scripts instead of comments and further wrap,it up in a stored proc to see entire batch more clearly
I could see no issues with your query with exception of where clause..
Use the SQL Server profiler to see queries executed.
Also see How to see query history in SQL Server Management Studio.

SQL Server 2012 query blocked with LCK_M_IS

I'm struggling to understand how the following two queries could be blocking each other.
Running query (could be almost anything though):
insert bulk [Import].[WorkTable] ...
I'm trying to run the following SELECT query at the same time:
SELECT *
FROM ( SELECT * FROM #indexPart ip
JOIN sys.indexes i (NOLOCK)
ON i.object_id = ip.ObjectId
and i.name = ip.IndexName) i
CROSS
APPLY sys.dm_db_index_physical_Stats(db_id(), i.object_id,i.index_id,NULL,'LIMITED') ps
WHERE i.is_disabled = 0
The second query is blocked by the first query and shows a LCK_M_IS as wait info. Import information is that the temporary table #indexPart contains one record of an index on a completely different table. My expectation is that the cross apply tries to run the stats on that one index which has nothing to do with the other query running.
Thanks
EDIT (NEW):
After several more tests I think I found the culprit but again can't explain it.
Bulk Insert Session has an X lock on table [Import].[WorkTable]
The query above is checking for an Index on table [Import].[AnyOtherTable] BUT is requesting an IS lock on [Import].[WorkTable]. I've verified again and again that the query above (when running the stuff without cross apply) is only returning an index on table [Import].[AnyOtherTable].
Now here comes the magic, changing the CROSS APPLY to an OUTER APPLY runs through just fine without any locking issues.
I hope someone can explain this to me ...
The problem could be at the where clause you used. It should be within the inline table. The following change could make a difference.
FROM ( SELECT * FROM #indexPart ip
JOIN sys.indexes i (NOLOCK)
ON i.object_id = ip.ObjectId
and i.name = ip.IndexName
WHERE i.is_disabled = 0) i
If you do like so, this may reduce the number of records passed onto the cross apply statement.