• 用户对象:包括用户显示创建的本地/全局临时表、表变量、表值函数、游标、临时存储过程等

  • 版本存储:包括联机索引、多活动结果集、after触发器以及使用快照的隔离级别都会在TEMPDB存储旧的行版本

了解了TEMPDB存储了哪些东西就可以知道它对于整个实例的重要性,尤其是性能上的影响,一些高并发场景很容易凸显问题。

500+的session挂起,这时候业务已经无法正常提供服务了,每个session都在等PAGELATCH_UP(lastwaittype)对应资源是 2:*:2(waitresource)。

SQLServer的 PAGELATCH:PAGEPATCH是同步访问数据库PAGE的Latch,SQL server的BP里每个数据页(8K)都有一个对应的LATCH,要访问某个PAGE必须首先获得这个PAGE的LATCH,PAGELATCH有很多种,如共享的PAGELATCH_SH,独占的PAGELATCH_EX,更新的PAGELATCH_UP。

waitresource 2:*:2 分别表示database_id,file_id,page_id 对应资源是tempdb的某个datafile第二个数据页;了解SQLServer的存储结构可以知道datafile的前几个page是固定的系统page,第二个PAGE既是固定的全局分配映射页(GAM),TEMPDB做统一区分配的时候会用到。

这个场景是因为对临时表操作的并发过高,TEMPDB在系统页上出现严重争抢导致整个实例卡慢从而影响业务,是一个非常典型的场景,解决方法最好从TEMPDB的规划设计入手。

  • TEMPDB的数据文件和正常业务数据库分开存储,配置在不同的物理设备上;日志文件建议和数据文件分开存储,业务数据库的日志文件也建议这样
  • 数据和日志文件的最大空间根据物理设备大小配置到最大值或者不限

  • 启用数据和日志文件的自动增长,配置所有数据文件的增长速度一致、初始大小一致;这里还有一种说法是评估设定好应用所需的TEMPDB稳定空间不做自动增长或者靠监控在业务低峰主动调整,当然如果能做到这一点那是很好的,但这需要应用非常稳定并做过长时间测试能够找准这个稳定空间并做好监控和主动扩容,在实际环境中这基本是很难达到的,所以配置自增长是在实际生产环境中更推荐的做法

  • 如果不是物理设备的空间或性能异常请保证只有一个日志文件
  • 开启Trace Flag 1118缓解SGAM页的争抢 DBCC TRACEON (1118, -1)

最后,现实场景中即使对TEMPDB做好了规划也不排除应用异常使用导致的各种问题,所以合理的监控是必不可少的。 SQLServer针对TEMPDB提供了一些视图信息方便我们监控排查,主要了解sys.dm_db_file_space_usage、sys.dm_db_session_space_usage、sys.dm_db_task_space_usage这三个就可以帮我们做好监控。