SQLServer · 最佳实践 · TEMPDB的设计

认识TEMPDB

TEMPDB和其他数据库一样以MODEL库为模板创建,是一个全局资源,可供所有连接到实例的用户使用,不同的是它在每次SQL Server启动的时候都会被重新创建,它主要存储三种对象:

  • 用户对象:包括用户显示创建的本地/全局临时表、表变量、表值函数、游标、临时存储过程等
  • 内部对象:tempdb中具体的内部对象一般是不可见的,因为它们的meta信息只存于内存中并没有harden,所以系统视图也查询不到,大体分为work table、work file、sort units三类
  • 版本存储:包括联机索引、多活动结果集、after触发器以及使用快照的隔离级别都会在TEMPDB存储旧的行版本

常见场景

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

比如在生产环境中出现这样的场景——应用频繁的创建和销毁临时表

select * from sys.sysprocesses
where spid>50
and lastwaittype<>'MISCELLANEOUS'
and status<>'sleeping'
and spid<>@@SPID


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的数据文件和正常业务数据库分开存储,配置在不同的物理设备上;日志文件建议和数据文件分开存储,业务数据库的日志文件也建议这样
  • 当实例分配的CPU个数小于8时,数据文件的个数调整到和实例绑定CPU个数一致;当分配的CPU个数大于8且存在系统页的闩锁争抢时按照4的倍数增加文件直到瓶颈不在闩锁上
      --获取实例分配的CPU个数
      USE [master]
      GO
      SELECT COUNT(*) AS CPU_NUM FROM SYS.DM_OS_SCHEDULERS WHERE IS_ONLINE=1 AND CPU_ID<255
      GO
    
  • 数据和日志文件的最大空间根据物理设备大小配置到最大值或者不限
      --不限文件大小
      USE [master]
      GO
      ALTER DATABASE [tempdb] MODIFY FILE ( NAME = N'tempdev', MAXSIZE = UNLIMITED)
      GO
    
  • 尽量避免SHRINKING TEMPDB哪怕只是某个FILE
      USE [tempdb]
      GO
      DBCC SHRINKFILE (TEMPDEV, 'TARGET SIZE IN MB')
    
  • 启用数据和日志文件的自动增长,配置所有数据文件的增长速度一致、初始大小一致;这里还有一种说法是评估设定好应用所需的TEMPDB稳定空间不做自动增长或者靠监控在业务低峰主动调整,当然如果能做到这一点那是很好的,但这需要应用非常稳定并做过长时间测试能够找准这个稳定空间并做好监控和主动扩容,在实际环境中这基本是很难达到的,所以配置自增长是在实际生产环境中更推荐的做法
  • 如果不是物理设备的空间或性能异常请保证只有一个日志文件
  • 开启Trace Flag 1118缓解SGAM页的争抢
    DBCC TRACEON (1118, -1)
  • 如果有这样的场景:PAGELATCH_UP对应资源都是同一个FILE(FILE_ID相同),那么可能是由于数据文件大小非常不均衡使proportional fill algorithm一直在一个文件上分配空间,这种情况可以考虑使用黑科技开启Trace Flag 1117解决,但同时会造成空间消耗,因为这是实例级别的参数不止作用于TEMPDB,所有DB的数据文件都会统一增长
    DBCC TRACEON (1117, -1)

空间监控

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

--分类获取TEMPDB总空间使用
Select
	SUM ( user_object_reserved_page_count)*8 as user_objects_kb,
	SUM ( internal_object_reserved_page_count)*8 as internal_objects_kb,
	SUM ( version_store_reserved_page_count)*8  as version_store_kb,
	SUM ( unallocated_extent_page_count)*8 as freespace_kb
From sys .dm_db_file_space_usage

--获取每个会话对TEMPDB用户对象和内部对象的使用空间
--排查用户对象和内部对象使用空间异常的问题
select

t1.session_id ,

(t1. internal_objects_alloc_page_count + task_internal_alloc+t1. user_objects_alloc_page_count + task_user_alloc)*8 as [SPACE Allocated FOR ALL Objects (in KB)] ,

(t1. internal_objects_alloc_page_count + task_internal_alloc )*8 AS [SPACE Allocated FOR Internal Objects (in KB)],

(t1. internal_objects_dealloc_page_count + task_internal_dealloc )*8 as [SPACE Deallocated FOR Internal Objects (in KB)],

(t1. user_objects_alloc_page_count + task_user_alloc )*8 as [SPACE Allocated FOR USER Objects (in KB)],

(t1. user_objects_dealloc_page_count + task_user_dealloc )*8 as [SPACE Deallocated FOR USER Objects (in KB)],

DB_NAME( t1.database_id ) AS [ DATABASE NAME ],

t3.HOST_NAME AS [ System NAME ] ,

t3.program_name AS [ Program NAME ] ,

t3.login_name AS [ USER NAME ],

t3.STATUS ,

t3.cpu_time AS [ CPU TIME(IN milisec) ],

t3.total_scheduled_time AS [ Total Scheduled TIME(IN milisec) ],

t3.total_elapsed_time AS [ Elapsed TIME(IN milisec) ],

(t3. memory_usage * 8 ) AS [ Memory USAGE (IN KB) ]

from sys .dm_db_session_space_usage as t1,

( select session_id,

sum(internal_objects_alloc_page_count ) as task_internal_alloc,

sum(internal_objects_dealloc_page_count ) as task_internal_dealloc,

sum(user_objects_alloc_page_count ) as task_user_alloc,

sum(user_objects_dealloc_page_count ) as task_user_dealloc

from sys .dm_db_task_space_usage group by session_id) as t2,

sys.dm_exec_sessions as t3

where t1. session_id = t2 .session_id

and t2. session_id = t3 .session_id

and t1. session_id > 50

order by [SPACE Allocated FOR ALL Objects (in KB)] desc

--获取行版本的信息
--排查行版本使用异常的问题
SELECT session_id,elapsed_time_seconds as elapsed_time,* FROM sys.dm_tran_active_snapshot_database_transactions ORDER BY elapsed_time_seconds DESC
时间: 2024-11-18 16:46:11

SQLServer · 最佳实践 · TEMPDB的设计的相关文章

SQLServer · 最佳实践 · 透明数据加密TDE在SQLServer的应用

title: SQLServer · 最佳实践 · 透明数据加密TDE在SQLServer的应用 author: 石沫 背景 作为云计算的服务提供者,我们在向用户提供优秀的服务能力时会遇到一个合规的问题.在数据库领域,数据是极其敏感和珍贵的,保护好数据,就如保护好企业的生命线.因此,需要采取一些预防措施来帮助保护数据库的安全,如设计一个安全系统.加密机密资产以及在数据库服务器的周围构建防火墙.但是,如果遇到物理介质被盗的情况,恶意破坏方只需还原或附加数据库即可浏览数据,或者遭遇拖库情况.一种解决

SQLServer · 最佳实践 · RDS for SQL Server 2012 权限限制的提升与改善

title: SQLServer · 最佳实践 · RDS for SQL Server 2012 权限限制的提升与改善 author: 石沫 背景 SQL Server 作为一种强大的关系型数据库,能够提供所有场景的应用.在绝大多数云计算公司中,都提供了SQL Server作为服务的云数据库服务,譬如阿里云.但既然是服务,那么服务就需要可管理,可控制,因此,在云计算初期,都对云数据库服务进行了严格的权限控制,好处就是可控可管理,但给用户会带来一些限制,某些限制实际上是可以再细粒度管控.因此,今

SQLServer · 最佳实践 · SQL Server优化案例分享

title: SQLServer · 最佳实践 · SQL Server优化案例分享 author: 石沫 前端时间的视频分享,这里有同学文档总结下来: 请参考:https://yq.aliyun.com/articles/60119

SQLServer · 最佳实践 · 如何将SQL Server 2012降级到2008 R2

title: SQLServer · 最佳实践 · 如何将SQL Server 2012降级到2008 R2 author: 石沫 迁移须知 使用SQLSERVER 2012的特性在SQL 2008 R2不支持,比如新的分页方式 此迁移操作手册适用于MSSQL2012到MSSQL2008R2的迁移 迁移使用微软提供的脚本生成和导入导出工具 需要在本地将MSSQL2012迁移完成,并且应用改造完成测试通过方可上RDS 迁移到MSSQL2008R2 RDS通过备份还原的方式进行 迁移步骤 安装200

SQLServer · 最佳实践 · SQL Server 2012 使用OFFSET分页遇到的问题

title: SQLServer · 最佳实践 · SQL Server 2012 使用OFFSET分页遇到的问题 author: 石沫 1. 背景 最近有一个客户遇到一个奇怪的问题,以前使用ROW_NUMBER来分页结果是正确的,但是替换为SQL SERVER 2012的OFFSET...FETCH NEXT来分页出现了问题,因此,这里简单分析一下原因,更深层次的原因还没有确切的结论,但可以提供解决办法. 在升级数据库后并且应用新功能时,这个问题可能会困扰一些同学. 2. 现象 为了复现在这个

SQLServer · 最佳实践 · 开发基于.NET CORE的LINUX版本的数据库应用

title: SQLServer · 最佳实践 · 开发基于.NET CORE的LINUX版本的数据库应用 author: 石沫 背景 最近有客户在基于.NET CORE的LINUX版本连接数据库的应用程序,在开发中,会遇到一些问题,客户会错误地将原因定位到我们的SQL SERVER,陆续收到一些工单,因此,我们需要有计划增强这个方面的能力,同事正确引导用户使用SQL SERVER. 部署环境 1. 服务器版本:ubuntu 14.04 2. .NET CORE 版本:1.0 3. 安装过程 3

SQLServer · 最佳实践 · 数据库实现大容量插入的几种方式

背景 很多用户在使用阿里云云数据库SQL Server时,为了加快插入速度,都尝试使用大容量插入的方式,大家都知道,对于完整恢复模式下的数据库,大容量导入执行的所有行插入操作都会完整地记录在事务日志中.如果使用完整恢复模式,大型数据导入会导致填充事务日志的速度很快.相反,对于简单恢复模式或大容量日志恢复模式,大容量导入操作的按最小方式记录日志减少了大容量导入操作填满日志空间的可能性.另外,按最小方式记录日志的效率也比按完整方式记录日志高 . 但实际上,当大容量导入与数据库镜像共存时,会出现镜像

《Greenplum5.0 最佳实践》 模式设计 (三)

模式设计 最佳实践 Greenplum 是基于大规模并行处理(MPP)和shared-nothing架构的分析型数据库.其不同于高度规范化的事务型SMP数据库. 使用非规范化数据库模式,例如具有大事实表和小维度的星型或者雪花模式,处理MPP分析型任务时,Greenplum数据库表现优异. 数据类型 (Data Types) 使用类型一致 在做关联操作的两个表,其两个关联字段的数据类型尽量保持一致.如果数据类型不一致,Greenplum 数据库必然后动态的转化一个字段的数据类型,这样就可以实现不同

SQLServer · 最佳实践 · 透明数据加密在SQLServer的应用

背景 作为云计算的服务提供者,我们在向用户提供优秀的服务能力时会遇到一个合规的问题.在数据库领域,数据是极其敏感和珍贵的,保护好数据,就如保护好企业的生命线.因此,需要采取一些预防措施来帮助保护数据库的安全,如设计一个安全系统.加密机密资产以及在数据库服务器的周围构建防火墙.但是,如果遇到物理介质被盗的情况,恶意破坏方只需还原或附加数据库即可浏览数据,或者遭遇拖库情况.一种解决方案是加密数据库中的敏感数据,并通过证书保护用于加密数据的密钥.这可以防止任何没有密钥的人使用这些数据,但这种保护必须事