Basic select deadlocks itself - sql

So, I have been looking into more SQL server management tools using a few of them, and I have been amazed to find simple selects blocking themselves and causing deadlocks. I have done a little research, but I am truly amazed this could happen. Can anyone clarify, or maybe solve, why this happens?
I'm talking about a simple select.
SELECT
ID
FROM
MainTable
WHERE
Name Like 'John Smith'
Using Microsoft SQL Server Managment Studios, if it matters.

In SQL 2000 processes would sometimes report as blocking themselves, but I don't think this applies in later versions of SQL Server.
latch waits reported as blocking
It is definitely possible for a SELECT statement to cause a deadlock, because shared locks are acquired when data is selected, but there would also have to be another process that is trying to update the data.

A parallel execution plan can show as a SPID blocking itself. This is basically just threads waiting for the other tasks in the query to complete. Deadlocking is another matter, caused by different sessions waiting on each other. Deadlocks (and excessive parallelism) can be a symptom of the need for query and index tuning.
If you are running SQL 2008 or later, deadlock information is captured by the system_helath extended event trace by default. Below is a query to extract recent deadlock information from the ring buffer. This will eliminate some of the guesswork.
SELECT
xed.value('#timestamp', 'datetime') as Creation_Date,
xed.query('.') AS Extend_Event
FROM
(
SELECT CAST([target_data] AS XML) AS Target_Data
FROM sys.dm_xe_session_targets AS xt
INNER JOIN sys.dm_xe_sessions AS xs
ON xs.address = xt.event_session_address
WHERE xs.name = N'system_health'
AND xt.target_name = N'ring_buffer'
) AS XML_Data
CROSS APPLY Target_Data.nodes('RingBufferTarget/event[#name="xml_deadlock_report"]') AS XEventData(xed)
ORDER BY Creation_Date DESC;

This simple select cannot deadlock itself, the only possible cause is something else is updating/deleting rows while you are reading.
Try launching SQL Server Profiler and use the:
deadlock
deadlock chain
deadloch graph
events in your template.
The Deadlock graph in particular will help you identify which two processes are causing trhe deadlock and the one chosen as deadlock victim

Related

Is it ok to KILL this DELETE query?

I ran a query to delete around 4 million rows from my database. It ran for about 12 hours before my laptop lost the network connection. At that point, I decided to take a look at the status of the query in the database. I found that it was in the suspended state. Specifically:
Start Time SPID Database Executing SQL Status command wait_type wait_time wait_resource last_wait_type
---------------------------------------------------------------------------------------------------------------------------------------------------
2018/08/15 11:28:39.490 115 RingClone *see below suspended DELETE PAGEIOLATCH_EX 41 5:1:1116111 PAGEIOLATCH_EX
*Here is the sql query in question:
DELETE FROM T_INDEXRAWDATA WHERE INDEXRAWDATAID IN (SELECT INDEXRAWDATAID FROM T_INDEX WHERE OWNERID='1486836020')
After reading this;
https://dba.stackexchange.com/questions/87066/sql-query-in-suspended-state-causing-high-cpu-usage
I realize I probably should have broken this up into smaller pieces to delete them (or even delete them one-by-one). But now I just want to know if it is "safe" for me to KILL this query, as the answer in that post suggests. One thing the selected answer states is that "you may run into data consistency problems" if you KILL a query while it's executing. If it causes some issues with the data I am trying to delete, I'm not that concerned. However, I'm more concerned about this causing some issues with other data, or with the table structure itself.
Is it safe to KILL this query?
If you ran the delete from your laptop over the network and it lost connection with the server, you can either kill the spid or wait when it will disappear by itself. Depending on the ##version of your SQL Server instance, in particular how well it's patched, the latter might require instance restart.
Regarding the consistency issues, you seem to misunderstand it. It is possible only if you had multiple statements run in a single batch without being wrapped with a transaction. As I understand, you had a single statement; if that's the case, don't worry about consistency, SQL Server wouldn't have become what it is now if it would be so easy to corrupt its data.
I would have rewritten the query however, if T_INDEX.INDEXRAWDATAID column has NULLs then you can run into issues. It's better to rewrite it via join, also adding batch splitting:
while 1=1 begin
DELETE top (10000) t
FROM T_INDEXRAWDATA t
inner join T_INDEX i on t.INDEXRAWDATAID = i.INDEXRAWDATAID
WHERE i.OWNERID = '1486836020';
if ##rowcount = 0
break;
checkpoint;
end;
It definitely will not be any slower, but it can boost performance, depending on your schema, data and the state of any indices the tables have.

Sql Server 2008 Update query is taking so much time

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.

SQl statement to monitor SQL Server Locks

Which SQL sentence (function or stored procedure) I can use to monitor an SQL Server DeadLock, caused by an UPDATE statement?
try this query to see blocking processes, including the actual SQL query text:
SELECT
r.session_id AS spid
,r.cpu_time,r.reads,r.writes,r.logical_reads
,r.blocking_session_id AS BlockingSPID
,LEFT(OBJECT_NAME(st.objectid, st.dbid),50) AS ShortObjectName
,LEFT(DB_NAME(r.database_id),50) AS DatabaseName
,s.program_name
,s.login_name
,OBJECT_NAME(st.objectid, st.dbid) AS ObjectName
,SUBSTRING(st.text, (r.statement_start_offset/2)+1,( (CASE r.statement_end_offset
WHEN -1 THEN DATALENGTH(st.text)
ELSE r.statement_end_offset
END - r.statement_start_offset
)/2
) + 1
) AS SQLText
FROM sys.dm_exec_requests r
JOIN sys.dm_exec_sessions s ON r.session_id = s.session_id
CROSS APPLY sys.dm_exec_sql_text (sql_handle) st
--WHERE r.session_id!=##SPID --uncomment to not see this query
deadlocks are easily trapped with the profiler:
Try running the run a trace in the profiler (pick the blank template), select the "deadlock graph event", and on the new tab that appears (Events Extraction Settings), save each (check "save deadlock XML events separately") in its own file. Open this file in an xml viewer and it will be easy to tell what is happening. Each process is contained, with an execution stack of procedure/trigger/etc calls, etc. and all locks are in there too.
Look at the "resource list" section of the file, it will show what is being locked and held by each process causing the deadlock. Figure out how to not have one of these locked and the deadlock will be resolved.
Let this trace run until the deadlock happens again, info is only recorded when a deadlock happens, so there isn't much overhead. If it never happens again, good it is solved, if not you have captured all the info.
I think you're better placed to use SQL Profiler to monitor deadlocks - see here. SQL Profiler shows the deadlocks in a diagram to make it easier to determine what caused them.
SELECT * FROM sys.dm_exec_requests WHERE blocking_session_id <> 0
But that will show you requests that are blocking, which is normal for SQL Server and doesn't indicate a deadlock. If SQL Server detects a deadlock it will kill one of the processes to allow the others to continue. So you can't use a function or stored procedure to monitor this as by the time it happens it has already finished.
You can either use the SQL Profiler or Trace Flags

SQL Server 2008 - Query takes forever to finish even though work is actually done

Running the following simple query in SSMS:
UPDATE tblEntityAddress
SET strPostCode= REPLACE(strPostCode,' ','')
The update to the data (at least in memory) is complete in under a minute. I verified this by performing another query with transaction isolation level read uncommitted. The update query, however, continues to run for another 30 minutes. What is the issue here? Is this caused by a delay to write to disk?
TIA
Most probably, you transaction is locked by another transaction which affected tblEntityAddress.
Run sp_lock and see if tblEntityAddress is locked by another process.
In a separate SSMS window, try running the following:
SELECT status, wait_type
FROM sys.dm_exec_requests
WHERE session_id = <SPID>
Just replaced with the SPID associated with your UPDATE query (number in brackets after your login name in the bottom bar).
Run the above a few times in succession and note what the wait_type is. There are numerous types of waits - see what that is (& let use know), it could highlight the cause.
Update:
Quotes from this MS KB article:
IO_COMPLETION
This waittype indicates that the SPID
is waiting for the I/O requests to
complete. When you notice this
waittype for an SPID in the
sysprocesses system table, you must
identify the disk bottlenecks by using
the performance monitor counters,
profiler trace, the
fn_virtualfilestats system
table-valued function, and the
SHOWPLAN option to analyze the query
plans that correspond to the SPID. You
can reduce this waittype by adding
additional I/O bandwidth or balancing
I/O across other drives. You can also
reduce I/O by using indexing, look for
bad query plans, and look for memory
pressure.
Another thing to consider is a slow running trigger.

Why would this SELECT statement lock up on SQL Server?

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.