Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Here are some notes on "SQL Server 2008 Locking" I took while attending an advanced class on SQL Server taught by Kimberly Tripp (https://sqlskills.com/AboutKimberlyLTripp.asp).
Please note that, although these notes were taken during the class, I might have added some of my own (mis)interpretation :-). Always check your facts on Books Online (I try to provide links when applicable). As with anything else you get from a blog, never use any of this in production before you thoroughly validate it a test environment. Please keep in mind that some of those will be hard to follow without the right pre-requisite knowledge and the right context. Reading the post from top to bottom will help.
You have more locks than you think
- You have a shared database lock every time you connect
- This helps someone from making the database read only while you're on
- One update on one row will give you three additional locks
- Table intent exclusive, page intent exclusive and row exclusive lock
- That's already 4 locks
- Use sp_lock @@spid to figure out what's going on
Row locks
- Shared locks, Update locks, eXclusive locks
- S on S = OK, S on U = OK, S on X = WAIT
- U on S = OK, U on U = WAIT, U on X = WAIT
- X on S = WAIT, X on U = WAIT, X on X = WAIT
Update locks
- Updates locks are there to help with concurrency
- U acquired in the beginning to isolate rows before change
- U does not prevent readers from seeing the data
- U updates to X on the row to do the update
Page and Table Locks
- Shared, Intent Shared, Intent eXclusive, Shared Intent Exclusive, eXclusive
- X on anyting - WAIT, IX on S - WAIT
Not necessarily accurate
- You're running SELECT (*) on a table with a clustered index
- The first row can be updated to be the last row
- You can actually end up count that row twice
- You're not reading anything that's not COMMITTED
- Better concurrency at the trade off of accuracy
WAIT
- If transactions are efficient and short, it's OK
- If you end up in a WAIT, SQL will WAIT
- SQL Server is incredibily patient :-)
- This also causes your transaction log to grow...
- You can write code to look at who is WAITing on what
- You can write code to kill the transaction that's causing you to WAIT
- However, it's best to figure out why that transaction is taking so long
- It could be an application transaction with external dependencies
Workarounds
- SET LOCK_TIMEOUT is an option at the session level, but be careful
- Use DBCC USEROPTIONS to get your session setting
- Use "SELECT * from sys.dm_exec_sessions" to get other session settings
- SELECT ... WITH (READPAST) hint is an option, but it skips entire pages
- With READPAST, make sure you don't care about missing a few rows
Granularity/Escalation
- SQL tries to be as granular as possible
- When there are too many locks, SQL locks higher in the hierarchy
- Escalation: From Row (RID) to Page to Partition to Table (object) to Database
- Lock escalation to a Partition lock is new in SQL Server 2008
- Change with ALTER TABLE table SET (LOCK_ESCALATION={AUTO|TABLE|DISABLE})
- Monitor with SELECT * FROM sys.dm_tran_locks
Hints to control locks
- You can use ROWLOCK, PAGLOCK, TABLOCK, UPDLOCK, XLOCK
- Careful. This can reduce perfromance or increase concurrency.
- You can do "UPDATE table SET @@var=column=<exp>" to avoid a reselect
- Look at ISOLATION LEVEL more than these types of locks
- Books Online - https://msdn.microsoft.com/en-us/library/ms187373.aspx
- Details at https://www.sqlmag.com/articles/index.cfm?articleid=6198&
Isolation Levels
- This is the I in the ACID properties, controlled with locks
- Level 0 - read uncommited
- Level 1 - read commited - This is the default!
- Level 2 - repeatable read
- Level 3 - serializable
- SET TRANSACTION ISOLATION LEVEL <string>
Other ways to separate readers/writers
- Backup/Restore, SQL IS, Replication, SQL AS, Snapshots
- For real-time, mixed, live workloads - only with snapshot isolation
Locks and issues
- Level 0 - Locks: No row locks, locks not honored
- Level 0 - Issue: Dirty reads
- Level 1 - Locks: Reader locks released ASAP. SELECT (*) locks per row.
- Level 1 - Issue: Inconsistent Analysis, Non-repeatable reads (data can change during transaction)
- Level 2 - Locks: Reader locks are left behind. SELECT (*) locks all.
- Level 2 - Issue: Phantoms (new rows can show up)
- Level 3 - Locks: Locks on ranges (table locks if no index)
READ_COMMITED_SNAPSHOT
- Starting in SQL Server 2005, database option for READ_COMMITED_SNAPSHOT
- Level 1, uses versioning instead of locking
- Can be overridden with READCOMMITEDLOCK hint
Isolation with table hints
- Level 0 - READUNCOMMITTED, NOLOCK
- Level 1 - READCOMMITTED
- Level 2 - REPEATABLEREAD, READCOMMITTEDLOCK (with RCS option on)
- Level 3 - SERIALIZABLE, HOLDLOCK
- SELECT...FROM table1 WITH (READUNCOMMITED) JOIN table2 WITH (SERIALIZABLE)
Blocking
- Locking is good. Guarantees consistency. Prevents conflicts.
- Blocking is not good. It happens if there's a transaction taking too long.
- Find the culprit, fix the issue
Tips to minimize blocking
- Keep transactions short
- Keep transactions in one batch, no interactions
- Use indexes to lock only the necessary data
- Consider estimates instead of long running queries
- Consider separate analysis services for long running queries
- Look closely at long running or conflicting transactions
Detecting Blocking
- Look at sp_blocker_pss80 from https://support.microsoft.com/?id=271509
- Tells who's in the head of the chain
- Deadlock events and trace flag 1222
- Performance data collection and extended events
- Use sp_who3 (not in the product, search the web)
- SQL Profiler, Performance Monitor, Extended Events
Deadlocks
- Two or more transactions request mutually desired resources in wrong order
- It's some sort of circular references, many specific cases.
- Classic case: spose moving savings to checking, other spouse moving checking to saving
- Happens only if you lock the same rows in the reverse sequence, at the same time
- SQL will identify those and kill the "least expensive" transaction
- SQL Profiler events, good for quick visual of what was happening
- You can save the XML format with XDL extension, sent to the developer
- Extended events, Trace flags flags to send to SQL log
Deadlock resolution
- You can use SET DEADLOCK_PRIORITY LOW (choose me, choose me)
- Since SQL Server 2005, you can also do SET DEADLOCK_PRIORITY HIGH (don't choose me)
- Can use a RANGE from -10 to 10 instead of LOW (-5), MEDIUM (0), HIGH (5)
- Deadlock victim receives error 1205
- Books online: https://msdn.microsoft.com/en-us/library/ms186736.aspx
- Certain distributed or application deadlock might be impossible to detect by SQL
Deadlock avoidance
- Access resources in the same order
- Minimize blocking
- Change isolation level
Snapshot Isolation
- Introduced in SQL Server 2005
- There is a cost to implementing this (versioning)
- Much better option then leaving transactions waiting around
Extra space needed for versioning
- Older version of the row stored in tempdb as rows are updated
- 14-byte pointer (LSN) to old version added to row in the data page
- Carefull with splitting if you turn this on and data pages are full
- Pointer in the row in the data page does not go away
Statement-level read consistency
- Read committed isolation using row versioning (aka RCSI)
- Database option: ALTER DATABASE SET READ_COMMITTED_SNAPSHOT ON
- Consider using the "WITH ROLLBACK AFTER 5" option
- You can see the database schema modification log
- This turns it on and uses it for all statements
- See https://msdn.microsoft.com/en-us/library/ms345124.aspx
Transaction-level read consistency
- Snapshot isolation
- Database option: ALTER DATABASE SET ALLOW_SNAPSHOT_ISOLATION ON
- Makes it available, but only uses it if requested in transaction
- Session setting: SET TRANSACTION ISOLATION LEVEL SNAPSHOT
- This is per user (session) and tracks it per transaction
- This potentially holds the versions in tempdb for longer
- Different transactions updating same record detected
- See https://msdn.microsoft.com/en-us/library/ms179599.aspx
- Four choices: None (default), Statement, Transaction, Both