tempdb大量闩锁等待问题分析
背景
客户业务系统升级后,高峰期运行缓慢,在SQL专家云上看到数据库出现严重等待,需要分析原因并紧急处理。现象
登录到SQL专家云中,进入实时可视化页面,在活动会话里面看到有大量资源等待的会话。
![]()
点击一个时间点,进入到该时间点的活动会话原始数据。看到大量会话的等待类型为PAGELATCH_UP,等待资源为“2:1:xxxxxxx” ,SQL语句都和临时表有关。
![]()
![]()
分析
会话等待的资源“2:1:xxxxxxx” 代表ID为 2 的数据库(tempdb)的1号文件(tempdev)的xxxxxxx页。SQL语句创建一个临时表时,相当于在tempdb中创建一张表,SQL Server要为这张表分配存储页面,需要修改SGAM、PFS、GAM系统数据页,为了其他表不会分配到同一个数据页,在修改时使用闩锁,修改完成后释放闩锁。
这种机制对一般的用户数据库不会有问题,因为正常的应用不会折腾着不停地建表、删表。但是tempdb就不同了,经常会有高并发的SQL语句使用临时表。因此在同一个时间点会有很多线程要修改系统页,就会产生大量的PAGELATCH_UP闩锁等待。
解决
最直接的解决办法是增加tempdb数据文件的个数,这样多个线程修改系统页时就被分配到不同的数据文件上,从而降低了闩锁争用。在增加数据文件时有2点重要的注意事项:
文件个数一定要和CPU核数对齐,也就是能被CPU核数整除。例如是40个核,则可以创建4个、8个、10个、20个等。建议最少4个,最多可以和CPU的核数一样多,但一般的服务器CPU核数都在几十个,没有必要创建这么多
- 。每个数据文件的初始大小和增长大小的配置一定要一致,如果不一致,SQL Server将不会平均地使用每个数据文件,而是先使用容量最大的数据文件。
![]()
tempdb的重要性
临时表、表变量、查询语句(ORDER BY、GROUP BY、UNION等)、触发器、索引维护、快照事务隔离级别等很多功能都会用到tempdb,详细参考微软官方文档:https://docs.microsoft.com/zh-cn/sql/relational-databases/databases/tempdb-database?view=sql-server-ver15。
![]()
最佳实践
对tempdb依赖较高的实例,可以为tempdb单独规划一个快速的物理磁盘,例如SSD,让tempdb独享I/O资源,不和用户数据库文件争抢,从而加快tempdb的响应速度。如果服务器有基于磁盘镜像的容灾软件,为tempdb规划单独的磁盘的另一个好处是不用把temdp文件同步到备机。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)