pre*_*mar 3 tempdb sql-server-2014
几天前,我们已经从 2012 年服务器迁移到 2014 年,我们保留了与之前相同的设置,例如我们在 Tempdb 中使用 8 个数据文件以获得更好的性能,并且全部放置在单个驱动器中。
由于这是数据仓库环境,批量加载连续运行,并且 tempdb 驱动器已满。即使数据库中有 98% 的可用空间,它也无法重用空间并导致磁盘已满。
tempdb 中没有足够的空间来保存行版本。需要缩小版本存储以释放 tempdb 中的一些空间。事务(id=239368387 xsn=1273322 spid=126 elapsed_time=1590)已被标记为受害者,如果它访问版本存储,它将被回滚。如果问题仍然存在,可能的原因是临时数据库大小不正确或事务长时间运行。请参阅 BOL 了解如何配置 tempdb 进行版本控制。
问题
SQL Sever 2014 中是否有任何特定的 tempdb 设置可以避免这些问题?
对于 tempdb 性能改进有什么建议,例如启用跟踪标志 -T1118 吗?
2012 年,它只需要 64 GB,现在甚至 450 GB 也不够用。
服务器规范。
SQL Server 检测到 4 个插槽,每个插槽 15 个核心,每个插槽 30 个逻辑处理器,总共 120 个逻辑处理器;使用基于 SQL Server 许可的 120 个逻辑处理器。512 GB 内存。
在对 TempDB 空间进行故障排除之前,最好了解哪些对象正在使用 TempDB。
即使您只遇到版本存储方面的问题,了解哪些对象正在使用 TempDB 会让您更好地了解从哪里开始。
请记住,TempDB 是所有数据库的全局资源,因此这将用于所有数据库。在较高级别上,这些是可以使用 TempDB 的对象:
1. 用户对象
2. 内部对象
这些是 SQL Server 创建的内部对象,用于工作表、哈希联接、排序......
3.版本存储
另外Cursors、Database Mail、DBCC CHECKDB也可以使用TempDB。请参阅这篇文章了解更多详细信息Capacity Planning for tempdb
现在我们知道了 TempDB 的使用方式,我们可以使用 SQL Server 提供的 DMVS 来跟踪 TempDB 空间利用率。
跟踪消耗最多空间的用户对象:
WITH task_space_usage AS (
-- SUM alloc/delloc pages
SELECT session_id,
request_id,
SUM(internal_objects_alloc_page_count) AS alloc_pages,
SUM(internal_objects_dealloc_page_count) AS dealloc_pages
FROM sys.dm_db_task_space_usage WITH (NOLOCK)
WHERE session_id <> @@SPID
GROUP BY session_id, request_id
)
SELECT TSU.session_id,
TSU.alloc_pages * 1.0 / 128 AS [internal object MB space],
TSU.dealloc_pages * 1.0 / 128 AS [internal object dealloc MB space],
EST.text,
-- Extract statement from sql text
ISNULL(
NULLIF(
SUBSTRING(
EST.text,
ERQ.statement_start_offset / 2,
CASE WHEN ERQ.statement_end_offset < ERQ.statement_start_offset
THEN 0
ELSE( ERQ.statement_end_offset - ERQ.statement_start_offset ) / 2 END
), ''
), EST.text
) AS [statement text],
EQP.query_plan
FROM task_space_usage AS TSU
INNER JOIN sys.dm_exec_requests ERQ WITH (NOLOCK)
ON TSU.session_id = ERQ.session_id
AND TSU.request_id = ERQ.request_id
OUTER APPLY sys.dm_exec_sql_text(ERQ.sql_handle) AS EST
OUTER APPLY sys.dm_exec_query_plan(ERQ.plan_handle) AS EQP
WHERE EST.text IS NOT NULL OR EQP.query_plan IS NOT NULL
ORDER BY 3 DESC;
Run Code Online (Sandbox Code Playgroud)
内部对象使用的空间((仅限活动)):
SELECT
t1.session_id,
t1.request_id,
t1.task_alloc,
t1.task_dealloc,
t2.sql_handle,
t2.statement_start_offset,
t2.statement_end_offset,
t2.plan_handle
FROM (SELECT session_id,
request_id,
SUM(internal_objects_alloc_page_count) AS task_alloc,
SUM(internal_objects_dealloc_page_count) AS task_dealloc
FROM sys.dm_db_task_space_usage
GROUP BY session_id, request_id) AS t1,
sys.dm_exec_requests AS t2
WHERE t1.session_id = t2.session_id AND
(t1.request_id = t2.request_id)
ORDER BY t1.task_alloc DESC
Run Code Online (Sandbox Code Playgroud)
版本存储: 您可以找到正在使用版本存储的交易列表。要查看它们占用了多少空间,请参阅最后的文章
SELECT top 2
transaction_id,
transaction_sequence_num,
elapsed_time_seconds
FROM sys.dm_tran_active_snapshot_database_transactions
Run Code Online (Sandbox Code Playgroud)
交易完成后,交易使用的空间将自动清理。如果事务长时间打开,它将阻止版本存储清理,您可能必须通过加入 sys.dm_exec_sessions 或 sys.sysprocesses 来检查原因
您还可以自动收集此空间使用情况以供以后分析。
这只是为了给您提供想法,但它可能不适用于您的版本,因为某些列可能已更改。
查询以收集详细信息:
CREATE PROC sp_sampleTempDbSpaceUsage AS
Instance level tempdb FILE space usage FOR ALL files WITHIN
-- tempdb
INSERT tempdb_space_usage (
scope,
Instance_unallocated_extent_pages,
version_store_pages,
Instance_userobj_alloc_pages,
Instance_internalobj_alloc_pages,
Instance_mixed_extent_alloc_pages)
SELECT
'instance',
SUM(unallocated_extent_page_count),
SUM(version_store_reserved_page_count),
SUM(user_object_reserved_page_count),
SUM(internal_object_reserved_page_count),
SUM(mixed_extent_page_count)
FROM sys.dm_db_file_space_usage
-- 2. tempdb space usage per session
--
INSERT tempdb_space_usage (
scope,
session_id,
Sess_task_userobj_alloc_pages,
Sess_task_userobj_deallocated_pages,
Sess_task_internalobj_alloc_pages,
Sess_task_internalobj_deallocated_pages)
SELECT
'session',
session_id,
user_objects_alloc_page_count,
user_objects_dealloc_page_count,
internal_objects_alloc_page_count,
internal_objects_dealloc_page_count
FROM sys.dm_db_session_space_usage
WHERE session_id > 50
-- 3. tempdb space usage per active task
--
INSERT tempdb_space_usage (
scope,
session_id,
Sess_task_userobj_alloc_pages,
Sess_task_userobj_deallocated_pages,
Sess_task_internalobj_alloc_pages,
Sess_task_internalobj_deallocated_pages,
query_text)
SELECT
'task',
R1.session_id,
R1.user_objects_alloc_page_count,
R1.user_objects_dealloc_page_count,
R1.internal_objects_alloc_page_count,
R1.internal_objects_dealloc_page_count,
R3.text
FROM sys.dm_db_task_space_usage AS R1
LEFT OUTER JOIN
sys.dm_exec_requests AS R2
ON R1.session_id = R2.session_id
OUTER APPLY sys.dm_exec_sql_text(R2.sql_handle) AS R3
WHERE R1.session_id > 50
Run Code Online (Sandbox Code Playgroud)
一旦收集了足够的数据,您可以使用以下查询进行分析:
查询 1:此查询报告 TempDB 中针对收集的所有数据点分配的最大空间
SELECT
CONVERT (float, (MAX(version_store_pages +
Instance_userobj_alloc_pages +
Instance_internalobj_alloc_pages +
Instance_mixed_extent_alloc_pages)))/ 128.0
AS max_tempdb_allocation_MB
FROM tempdb_space_usage
WHERE scope = 'instance'
Run Code Online (Sandbox Code Playgroud)
查询 2:此查询计算收集的所有数据点的最大分配页数和版本存储大小(以兆字节为单位)。如果分配给版本存储的 TempDB 空间量很大,则意味着长时间运行的事务正在生成或消耗版本。
SELECT
MAX(version_store_pages) AS max_version_store_pages_allocated,
MAX(version_store_pages/128.0) AS max_version_store_allocated_space_MB
FROM tempdb_space_usage
WHERE scope = 'instance'
Run Code Online (Sandbox Code Playgroud)
查询 3:此查询显示为内部对象分配最多页面的前五个查询。
SELECT top 5 MAX ((Sess_task_internalobj_alloc_pages) - (Sess_task_internalobj_deallocated_pages))
AS Max_Sess_task_allocated_pages_delta, query_text
FROM tempdb_space_usage
WHERE scope = 'task' and session_id > 50
GROUP BY query_text
ORDER BY Max_Sess_task_allocated_pages_delta DESC
Run Code Online (Sandbox Code Playgroud)
以下是我使用的参考资料,可以进一步帮助您:
以下是必读内容:
归档时间: |
|
查看次数: |
3610 次 |
最近记录: |