SQL server 2008 里面的 SPINLOCK

 

什么是spinlock呢?

 

Spinlock中文可以称为自旋锁。它是一个轻量级的,用户态的同步对象,和critical section类似,但是粒度比前者小多了。它主要用来保护某些特定的内存对象的多线程并发访问。Spinlock是排他性的。一次只能一个线程拥有。

 

Spinlock的设计目标是非常快和高效率。Spinlock内部如何工作呢?它首先试图获得某个对象的锁,如果目标被其它线程占有,就在那里轮询(spin)一定时间。如果还得不到锁,就sleep一小会,然后继续spin。反复这个过程直到得到对象的占有权。

 

SQL server 2008 里面有150多个对象由spinlock提供并发访问保护。 你可以运行如下命令来看看spinlock的统计信息:

 

select * from sys.dm_os_spinlock_stats order by collisions desc

 

 

输出如下:

 

上面输出你可以看到SQL server的对象的spinlock的使用情况。上面是我的测试机的输出,和您的服务器的输出可能很不一样,因为负荷不一样。

 

有时候你想详细了解某个spinlock究竟是如何使用的呢?他的callstack又是如何的呢?一个方法你生成一些mini-dump,然后分析这些mini-dump。另外一个方法是使用xevent。 下面的脚本就是使用xevent来得到某类spinlock的callstack,从而可以获知SQL server内部spinlock的潜在性能瓶颈。

 

 create event session lock_cachestore_spin on server

 add event sqlos.spinlock_backoff (action (package0.callstack)

 where type=141

 )

  add target package0.asynchronous_bucketizer

   (      set filtering_event_name='sqlos.spinlock_backoff',

           source_type=1 ,

          source='package0.callstack'

     )

   with (MAX_MEMORY=32MB )

go

DBCC traceon (3656, -1)

Go

alter event session lock_hash_spin on server state=start

--Wait for 30mins

waitfor delay '00:30:00'

select event_session_address, target_name, execution_count, CAST(target_data as XML)

from sys.dm_xe_session_targets

go

alter event session lock_cachestore_spin on server state=stop

drop event session lock_cachestore_spin on server

go

 

在我服务器上,我得到如下的callstack:

 

<value>XeSosPkg::spinlock_backoff::Publish+b1 

SpinlockBase::Sleep+64 

SpinlockBase::Backoff+7b

Spinlock&lt;141,1,0&gt;::SpinToAcquireOptimistic+b3 

SOS_CacheStore::GetUserData+fb 

OpenSystemTableRowset+d9 

CMEDScanBase::Rowset+202 

CMEDScan::StartSearch+336 

CMEDCatYukonDR::FGetNextDatabase+83 

DBMgr::AreAllDatabasesRecovered+f3 

CheckServerRecovered+78 

CSvrRecCheckTask::ProcessTskPkt+5 

OnDemandTaskContext::ProcessTskPkt+1d2 

SystemTaskContext::ExecuteFunc+13 

SystemTaskEntryPoint+2db 

OnDemandTaskContext::FuncEntryPoint+23 

  </Slot>