我在我们的生产 sql 服务器上遇到了一个问题,其中临时表对象需要很长时间才能删除(当使用小型同步删除时很明显)。我无法在其他 sql 服务器上重现这一点(同样指定使用相同数量的主轴来提供 tempdb 数据文件(拆分为相同数量的文件(每个物理核心 1 个))。在 SQL 2005 Enterprise (SP2 - 3042) 上。
更新:还有一个因素——看起来最有可能。该服务器上有 >500 个数据库。另一个大于 800 的服务器也运行这些 drop 很慢。那是我唯一拥有很多数据库的其他服务器。
第二次更新:重启有问题的服务器将允许立即执行 create 和 drop 语句。在接下来的几个小时内(在应用程序运行时),测试的性能会下降,直到达到(看起来是)平台期。我有一项在后台运行的工作,每 30 分钟测试一次。我会看看几天后的结果,看看执行时间是否相同。我认为他们会。
第三次更新:虽然没有一个正在执行的语句显示闩锁等待 CPU 资源,但使用 sp_whoisactive 我看到在 delta_interval = 30(秒)运行期间,运行查询 CPU_delta 报告大约 30,000(毫秒?),当我在执行期间观察 perf 时在执行期间似乎有一个核心的 CPU 峰值。这些在 16 个 cpu 盒上,因此当其他流量发生时通过 perfmon 看到可能有点困难,但它似乎在执行 drop 语句期间增加了 cpu 的价值。
在我测试过的大多数服务器上,创建和销毁 20 个具有唯一名称(一列,无行)的小型临时表的时间不到 20 毫秒。在一台服务器上需要> 5 秒。绝大多数 (>95%) 的时间都花在 drop 语句上。
在执行期间,没有显式等待,也没有报告阻塞,并且 perfmon 不显示 I/O 子系统上的任何数据或日志文件负载。
我查看了高峰和低使用时间,当大量表标记为销毁和低时。操作需要 5 秒左右来处理 20 个 drop 语句,无论如何。该问题导致(客户)可察觉的响应速度变慢。
示例代码,我创建了 20 个类似的对象来获得 5 秒的计时。似乎每滴大约 300 毫秒。
PRINT CONVERT(varchar(30),GETDATE(),113)
CREATE TABLE [#Objects1]
(
[Id] uniqueidentifier NOT NULL
)
CREATE TABLE [#Objects12]
(
[Id] uniqueidentifier NOT NULL
)
...
DROP TABLE [#Objects1]
DROP TABLE [#Objects12]
...
PRINT CONVERT(varchar(30),GETDATE(),113)
Run Code Online (Sandbox Code Playgroud)
执行时间始终为 5 到 6 秒
2011 年 11 月 11 日 12:56:52:073 - 开始创建临时表
2011 年 11 月 11 日 12:56:52:090 - 结束临时表创建
2011 年 11 月 11 日 12:56:52:090 - 开始删除临时表
2011 年 11 月 11 日 12:56:57:230 - 完成临时表删除
你也可以运行 USE tempdb; DBCC登录信息;并记录返回的行数。请将脚本的所有输出添加到您的原始问题中。
我最初注意到我有大约 271 个视频博客,所以我缩小并重新增长,看看碎片是否是一个问题。没什么区别。当前 DBCC 日志信息
FileId,FileSize,StartOffset,FSeqNo,Status,Parity,CreateLSN
2,253952,8192,101603,2,64,0
2,262144,262144,101604,2,64,0
2,262144,524288,101605,2,64,85000000038300574
2,262144,786432,101606,2,64,85000000038300574
2,262144,1048576,101578,2,128,86000000001600001
2,262144,1310720,101579,2,128,86000000001600001
2,262144,1572864,101580,2,128,86000000001600001
2,262144,1835008,101581,2,128,86000000001600001
2,262144,2097152,101582,2,128,86000000001600001
2,262144,2359296,101583,2,128,86000000023400002
2,262144,2621440,101584,2,128,86000000023500756
2,327680,2883584,101585,2,128,86000000023500756
2,327680,3211264,101586,2,128,86000000023500756
2,393216,3538944,101587,2,128,86000000023500756
2,393216,3932160,101588,2,128,86000000023500756
2,458752,4325376,101589,2,128,86000000023500756
2,253952,4784128,101590,2,128,86000000023500756
2,270336,5038080,101591,2,128,86000000023500756
2,253952,5308416,101592,2,128,86000000023500756
2,270336,5562368,101593,2,128,86000000023500756
2,253952,5832704,101594,2,128,86000000023500756
2,335872,6086656,101595,2,128,86000000023500756
2,253952,6422528,101596,2,128,86000000023500756
2,401408,6676480,101597,2,128,86000000023500756
2,253952,7077888,101598,2,128,86000000023500756
2,466944,7331840,101599,2,128,86000000023500756
2,253952,7798784,101600,2,128,86000000023500756
2,253952,8052736,101601,2,128,86000000023500756
2,278528,8306688,101602,2,128,86000000023500756
2,133627904,8585216,101607,2,64,101336000000013600462
2,133627904,142213120,101563,0,128,101336000000013600462
2,133627904,275841024,101564,0,128,101336000000013600462
2,133627904,409468928,101565,0,128,101336000000013600462
2,133627904,543096832,101566,0,128,101336000000013600462
2,133627904,676724736,101567,0,128,101336000000013600462
2,133627904,810352640,101568,0,128,101336000000013600462
2,133627904,943980544,101569,0,128,101336000000013600462
2,133627904,1077608448,101570,0,128,101336000000013600462
2,133627904,1211236352,101571,0,128,101336000000013600462
2,133627904,1344864256,101572,0,128,101336000000013600462
2,133627904,1478492160,101573,0,128,101336000000013600462
2,133627904,1612120064,101574,0,128,101336000000013600462
2,133627904,1745747968,101575,2,128,101336000000013600462
2,133627904,1879375872,101576,2,128,101336000000013600462
2,134479872,2013003776,101577,2,128,101336000000013600462
Run Code Online (Sandbox Code Playgroud)
Database Name,physical_name,io_stall_read_ms,num_of_reads,avg_read_stall_ms,io_stall_write_ms,num_of_writes,avg_write_stall_ms,io_stalls,total_io,avg_io_stall_ms
msdb,H:\Microsoft SQL Server\MSSQL.1\MSSQL\DATA\MSDBData.mdf,47691565,817329,58.4,10747142,533509,20.1,58438707,1350838,43.3
tempdb,H:\Microsoft SQL Server\MSSQL.1\MSSQL\DATA\templog.ldf,54457,30177,1.8,145691717,8235651,17.7,145746174,8265828,17.6
model,H:\Microsoft SQL Server\MSSQL.1\MSSQL\DATA\modellog.ldf,547,122,4.4,2273,239,9.5,2820,361,7.8
tempdb,P:\tempdb_data3.mdf,2606066,1112043,2.3,17829023,1919954,9.3,20435089,3031997,6.7
tempdb,P:\tempdb_data2.mdf,2484793,1111808,2.2,17270161,1922735,9.0,19754954,3034543,6.5
tempdb,P:\tempdb_data5.mdf,2514469,1112086,2.3,17066589,1919802,8.9,19581058,3031888,6.5
tempdb,P:\tempdb_data7.mdf,2542070,1112551,2.3,17049649,1920204,8.9,19591719,3032755,6.5
tempdb,P:\tempdb_data6.mdf,2517767,1112237,2.3,17043756,1924983,8.9,19561523,3037220,6.4
tempdb,P:\tempdb_data0.mdf,2476811,1113570,2.2,17084779,1926333,8.9,19561590,3039903,6.4
tempdb,P:\tempdb_data4.mdf,2462179,1111649,2.2,17073336,1920058,8.9,19535515,3031707,6.4
tempdb,P:\tempdb_data1.mdf,2456317,1111859,2.2,16997589,1922438,8.8,19453906,3034297,6.4
model,H:\Microsoft SQL Server\MSSQL.1\MSSQL\DATA\model.mdf,5194,798,6.5,612,240,2.5,5806,1038,5.6
master,H:\Microsoft SQL Server\MSSQL.1\MSSQL\DATA\master.mdf,40640,7326,5.5,2868,1548,1.9,43508,8874,4.9
msdb,H:\Microsoft SQL Server\MSSQL.1\MSSQL\DATA\MSDBLog.ldf,8015,950,8.4,1012107,312084,3.2,1020122,313034,3.3
master,H:\Microsoft SQL Server\MSSQL.1\MSSQL\DATA\mastlog.ldf,640,141,4.5,198283,99134,2.0,198923,99275,2.0
Run Code Online (Sandbox Code Playgroud)
wait_type,wait_time_s,pct,running_pct
PAGEIOLATCH_EX,0.02,100.00,100.00
Run Code Online (Sandbox Code Playgroud)
TokenAndPermUserStore 大小为 2952kb。
SELECT SUM(single_pages_kb + multi_pages_kb) AS "SecurityTokenCacheSize(kb)" FROM sys.dm_os_memory_clerks WHERE name = 'TokenAndPermUserStore'
Run Code Online (Sandbox Code Playgroud)
小智 8
您没有提到 tempdb LUN 使用的 IOPS。您是否在 LUN 设备上看到任何 IO 等待?该 LUN 上还有其他内容吗?另一个系统是否正在使用分割 LUN 的磁盘组/池?
同上主数据库——同样的问题。
另外,您使用的是本地临时表 (#tablename) 还是全局临时表 (##tablename)?如果 global 在您尝试删除它们时,另一个 SPID 是否可以将共享锁保持在全局临时表上?
我的性能问题的答案鲜为人知(尽管我很久以前就看过)与在具有许多数据库的系统上收集 dmv 统计信息相关的问题,其中代码大量使用临时表(或者您可能有很多表) . 在我们最慢的服务器上,sys.dm_db_index_usage_stats 有超过 200k 条记录,服务器返回 10k 条记录仍然存在可测量的滞后。
KB 文章描述了该问题。http://support.microsoft.com/kb/2003031
当 sys.dm_db_index_usage_stats 有大量行时查询性能下降
考虑以下场景:
- 在 Microsoft SQL Server 2005 中,您经常执行涉及删除和重新创建大量表(尤其是 tempdb 数据库中的临时表)的 DDL 操作。
- 在 sys.dm_db_index_usage_stats 动态管理视图 (DMV) 中有大量条目(100,000 或更多)。
此问题在 SQL 2008 中已修复,但只能在 2005 年通过更改代码以减少对临时表的依赖或启用跟踪标志 2330 来缓解。
这个知识库救了我的培根。添加此跟踪标志以启动参数后重新启动已将下降时间减少到 <100 毫秒级别(从 40000 毫秒!),并且我可以期待这些服务器上的其他性能提升!
附加阅读使我得出结论,这是问题所在
感谢所有为这个问题做出贡献的人,我获得了很多非常有用的工具来诊断这个过程中的性能问题。
当 drop-table 等待超过一两秒时,运行Adam Machanic 的 sp_WhoIsActive。这是一个很好的工具,可以找出任何查询运行缓慢的原因。在等待列中,您将看到特定任务的等待时间,如果它卡在等待 CPU(不会出现在 sys.dm_os_wait_stats 中),您也会看到。
另外,如果我没有指出您的构建不受支持,那我就失职了。作为一名顾问,我告诉我的客户,“我不愿意花数小时进行故障排除,结果却发现它已在服务包中得到修复 - 并且最终要为您可以免费修复的某些东西向您收取数千美元的费用。另外,您”无论如何都失去支持了。” 您可以在http://sqlserverbuilds.blogspot.com 上找到最新的 SQL Server 服务包和累积更新。构建3042是方式过时了-支持的版本是SP4。
编辑:2011-11-12 13:00
由于 TokenAndPermStore 看起来是“正常”大小,因此它不太可能成为一个因素。下一个要看的地方可能是spinlock stats。你也可以吗(正如我在聊天中提到的如果您删除显式 drop 语句并让表超出范围,)确定问题是否仍然存在。
编辑:2011-11-12 01:00
当您使用 2005SP2 时,我开始怀疑这是否可能是TokenAndPermUserStore 问题。这将解释为什么通过重新启动实例来缓解问题,以及为什么该问题在具有大量数据库的服务器上普遍存在。
您能否运行以下查询并将输出添加到您的问题中。
SELECT SUM(single_pages_kb + multi_pages_kb) AS "SecurityTokenCacheSize(kb)"
FROM sys.dm_os_memory_clerks
WHERE name = 'TokenAndPermUserStore'
Run Code Online (Sandbox Code Playgroud)
对此的快速修复是创建一个作业来监视缓存的大小并DBCC FREESYSTEMCACHE ('TokenAndPermUserStore')
在超过特定大小时运行。IIRC(我将在明天检查并更新)我已将服务器上的限制设置为 100MB,这会导致问题。SP3 引入了一种机制来控制缓存大小,而无需强力清除它。
原答案:
可能需要一些来回,但我们可以从查看IO和等待统计数据开始吗?(GIST 中的脚本)
修改创建/删除脚本以DBCC SQLPERF("sys.dm_os_wait_stats",CLEAR);
在开始时运行,然后在最后删除后运行等待统计脚本。如果将它们作为 CSV 发布(因此它们可以复制到 Excel),结果可能会更容易阅读。
您还可以运行USE tempdb; DBCC LOGINFO;
并记录返回的行数。
归档时间: |
|
查看次数: |
2797 次 |
最近记录: |