关于SQLServer的tempdb的数据文件暴增问题(1)

问题表现:

tempdb的数据文件暴增,无法收缩。


查看tempdb用在哪里?

监视tempdb磁盘空间:

如何确定 tempdb 中的可用空间量,以及如何确定版本存储区、内部对象和用户对象使用的空间量。

确定 tempdb 中的可用空间量

下面的查询将返回 tempdb 中所有文件的总可用页数和总可用空间量 (MB)。

SELECT SUM(unallocated_extent_page_count) AS [free pages], 

(SUM(unallocated_extent_page_count)*1.0/128) AS [free space in MB]

FROM sys.dm_db_file_space_usage;

确定版本存储区使用的空间量

下面的查询将返回 tempdb 中版本存储区使用的总页数和总空间量 (MB)。

SELECT SUM(version_store_reserved_page_count) AS [version store pages used],

(SUM(version_store_reserved_page_count)*1.0/128) AS [version store space in MB]

FROM sys.dm_db_file_space_usage;

确定运行时间最长的事务

如果版本存储区使用了 tempdb 中的大量空间,则必须确定运行时间最长的事务。使用下面的查询可按顺序(事务的最长运行时间)列出活动事务。

SELECT transaction_id,session_id

FROM sys.dm_tran_active_snapshot_database_transactions 

ORDER BY elapsed_time_seconds DESC;

与联机索引操作无关的长时间运行的事务需要很大的版本存储区。此版本存储区保存自事务启动以来生成的所有版本。联机索引生成事务可能需要较长时间才能完成,但是使用了专用于联机索引操作的单独的版本存储区。因此,这些操作不会防止删除其他事务的版本。有关详细信息,请参阅行版本控制资源的使用情况。

确定内部对象使用的空间量

下面的查询将返回 tempdb 中内部对象使用的总页数和总空间量 (MB)。

SELECT SUM(internal_object_reserved_page_count) AS [internal object pages used],

(SUM(internal_object_reserved_page_count)*1.0/128) AS [internal object space in MB]

FROM sys.dm_db_file_space_usage;

确定用户对象使用的空间量

下面的查询将返回 tempdb 中用户对象使用的总页数和总空间量。

SELECT SUM(user_object_reserved_page_count) AS [user object pages used],

(SUM(user_object_reserved_page_count)*1.0/128) AS [user object space in MB]

FROM sys.dm_db_file_space_usage;

确定总空间量(可用空间和已用空间)

下面的查询将返回 tempdb 中所有文件使用的磁盘空间总量。

SELECT SUM(size)*1.0/128 AS [size in MB]

FROM tempdb.sys.database_files

SQL:

select 

 sm.sysno sosysno

 ,sm.orderdate

 ,replace(replace(replace(replace((ar.ProvinceName + ar.CityName + ar.DistrictName + sm.ReceiveAddress),char(10),''),char(13),''),char(9),''),',','')  address

 ,ar.CityName  city

from master  sm

left join Area  as ar 

 on ar.SysNo = sm.ReceiveAreaSysNo

where 1=1

 and convert(varchar(10),sm.orderdate,111)   between convert(varchar(10),getdate()-1,111)  and convert(varchar(10),getdate()-1,111)

 and sm.ordertype <>5

 and replace(replace(replace(replace((ar.ProvinceName + ar.CityName + ar.DistrictName + sm.ReceiveAddress),char(10),''),char(13),''),char(9),''),',','') is not null

确定问题是行版本控制导致了tempdb的占用。事务持有未释放长达522696秒。

抓到那句SQL。杀掉会话。tempdb空间释放。


SELECT transaction_id,session_id


FROM sys.dm_tran_active_snapshot_database_transactions 


ORDER BY elapsed_time_seconds DESC;

可以进行tempdb的空间收缩了。



PS:查询当前数据库tempdb在 用户对象和 内部对象的使用量:

SELECT top 10 t1.session_id, 

t1.internal_objects_alloc_page_count, t1.user_objects_alloc_page_count,

t1.internal_objects_dealloc_page_count , t1.user_objects_dealloc_page_count,

t3.login_name,t3.status,t3.total_elapsed_time

from sys.dm_db_session_space_usage t1 

inner join sys.dm_exec_sessions as t3 

on t1.session_id = t3.session_id 

where (t1.internal_objects_alloc_page_count>0 

or t1.user_objects_alloc_page_count >0

or t1.internal_objects_dealloc_page_count>0 

or t1.user_objects_dealloc_page_count>0)

order by t1.internal_objects_alloc_page_count desc

internal_objects_alloc_page_count:内部对象使用量

user_objects_alloc_page_count:用户对象使用量

internal_objects_dealloc_page_count:内部对象释放量

user_objects_dealloc_page_count:用户对象释放量



请使用浏览器的分享功能分享到微信等