当 TokenAndPermUserStore 缓存的大小在 SQL Server 中增长时,查询需要更长的时间才能完成
本文可帮助你排查在增长大小 TokenAndPermUserStore
时与查询性能相关的问题。 它还提供了各种原因和解决方法。
原始 KB 数: 927396
现象
在 Microsoft SQL Server 中,会出现以下症状:
通常运行快速的查询需要更长的时间才能完成。
SQL Server 进程的 CPU 使用率高于平常。
运行即席查询时,性能会降低。 但是,如果查询
sys.dm_exec_requests
或sys.dm_os_waiting_tasks
动态管理视图,则结果不会指示即席查询正在等待任何资源。缓存的大小
TokenAndPermUserStore
以稳定的速度增长。缓存的大小
TokenAndPermUserStore
为几百兆字节(MB)。在某些情况下,运行
DBCC FREEPROCCACHE
或DBCC FREESYSTEMCACHE
命令可提供临时救济。
原因
性能问题(如 CPU 过高和内存使用率增加)可能是缓存中的 TokenAndPermUserStore
条目过多造成的。 默认情况下,仅当 SQL Server 发出内部内存压力时,才会清除此缓存中的条目。 在具有大量 RAM 的服务器上,内部内存压力可能不会经常触发。 当此缓存增长时,搜索现有条目需要更长的时间才能重复使用。 对此缓存的访问由旋转锁控制。 一次只能有一个线程执行搜索。 此行为最终会导致查询性能下降,并且出现更多的 CPU 使用率。
若要监视缓存的大小 TokenAndPermUserStore
,可以使用类似于以下查询的查询:
SELECT SUM(pages_kb) AS
"CurrentSizeOfTokenCache(kb)"
FROM sys.dm_os_memory_clerks
WHERE name = 'TokenAndPermUserStore'
缓存 TokenAndPermUserStore
维护以下安全令牌类型:
- LoginToken
- 每个服务器级别主体一个登录令牌。
- TokenPerm
- 记录 UserToken 和 SecContextToken 的安全对象的所有权限。
- 此缓存中的每个条目都是特定安全对象的单个权限。 例如,对表 t1 授予用户 u1 的选择权限。
- 此令牌条目不同于访问检查结果(ACR)缓存中的条目。 ACR 条目主要指示用户或登录名是否有权运行整个查询。
- UserToken
- 每个数据库的一个用户令牌用于登录。
- 在数据库级别角色中存储有关成员身份的信息。
- SecContextToken
- 为每个服务器级别主体创建一个 SecContextToken。
- 存储主体的服务器范围安全上下文。
- 包含用户令牌的哈希表缓存。
- 存储有关服务器级别角色成员身份的信息。
- TokenAccessResult
- 存在 TokenAccessResult 条目的不同类。
- Access Check 指示特定数据库中的给定用户是否有权运行涉及多个对象的查询。
- Microsoft SQL Server 2008 之前,ACR 安全缓存存储在单个缓存
TokenAndPermUserStore
中。 - 在 SQL Server 2008 中,ACR 缓存被分隔,ACR 缓存条目在各自的单个用户存储中被跟踪。 这种分离提高了性能,为缓存提供了更好的存储桶计数和配额控制。
TokenAndPermUserStore
目前,也是ACRCacheStores
唯一使用的安全缓存类型。 有关 ACR 缓存的详细信息,请参阅 访问检查缓存服务器配置选项。
可以运行以下查询来获取有关不同缓存及其各个大小的信息:
SELECT type, name, pages_kb
FROM sys.dm_os_memory_clerks
WHERE type = 'USERSTORE_TOKENPERM'
可以运行以下查询来标识在以下项中增长的 TokenAndPermUserStore
令牌类型:
SELECT [name] AS "SOS StoreName",[TokenName],[Class],[SubClass], count(*) AS [Num Entries]
FROM
(SELECT name,
x.value('(//@name)[1]', 'varchar (100)') AS [TokenName],
x.value('(//@class)[1]', 'varchar (100)') AS [Class],
x.value('(//@subclass)[1]', 'varchar (100)') AS [SubClass]
FROM
(SELECT CAST (entry_data as xml),name
FROM sys.dm_os_memory_cache_entries
WHERE type = 'USERSTORE_TOKENPERM')
AS R(x,name)
) a
GROUP BY a.name,a.TokenName,a.Class,a.SubClass
ORDER BY [Num Entries] desc
解决方法
SQL Server 提供了两个可用于配置配额的 TokenAndPermUserStore
跟踪标志(默认情况下,没有配额)。这意味着此缓存中可以有任意数量的条目。
- TF 4618 - 将条目
TokenAndPermUserStore
数限制为 1024。 - TF 4618+TF 4610 - 将条目数限制为
TokenAndPermUserStore
8192。
如果 4618 的条目计数非常低会导致其他性能问题,请使用跟踪标志 4610 和 4618。
跟踪标志 4610 和 4618 记录在联机丛书主题 DBCCC TRACEON - 跟踪标志中。
这些跟踪标志应用于未绑定增长 TokenAndPermUserStore
对服务器而言太大的方案。 这通常发生在两种类型的环境中:
低端或中端硬件
TokenAndPermUserStore
占用了服务器的大量可用内存,并且新条目创建速率更快或快于缓存逐出速率。 这可能会导致内存争用和服务器其他部分(例如 proc 缓存)的缓存失效。具有大量内存的高端计算机(例如,最近的几个支持案例涉及 1 TB 以上的 RAM)。 在这些环境中,缓存存储在遇到任何内存压力之前可能会增大。 这可能会导致长时间的存储桶链或步行性能下降。
作为临时缓解措施,可以使用以下方法定期清除此缓存:
- 从
TokenAndPermUserStore
缓存刷新条目。
注意:
为此,请运行以下命令:
DBCC FREESYSTEMCACHE ('TokenAndPermUserStore')
出现问题时,请观察缓存大小的阈值
TokenAndPermUserStore
。创建执行以下操作的计划SQL Server 代理作业:
检查缓存的大小
TokenAndPermUserStore
。 若要检查大小,请运行以下命令:SELECT SUM(pages_kb) AS "CurrentSizeOfTokenCache(kb)" FROM sys.dm_os_memory_clerks WHERE name = 'TokenAndPermUserStore'
如果缓存大小大于观察到的阈值,请运行以下命令:
DBCC FREESYSTEMCACHE ('TokenAndPermUserStore')