当 TokenAndPermUserStore 缓存的大小以SQL Server

本文可帮助你排查与查询性能相关的问题(当 的大小 TokenAndPermUserStore 增大时)。 它还提供了各种原因和解决方法。

原始 KB 编号: 927396

症状

在 Microsoft SQL Server中,遇到以下症状:

  • 通常快速运行的查询需要更长的时间才能完成。

  • SQL Server进程的 CPU 使用率高于平时。

  • 运行即席查询时,性能会降低。 但是,如果查询 sys.dm_exec_requestssys.dm_os_waiting_tasks 动态管理视图,结果并不指示即席查询正在等待任何资源。

  • 缓存的大小 TokenAndPermUserStore 以稳定的速度增长。

  • 缓存的大小 TokenAndPermUserStore 为数百兆字节 (MB) 。

  • 在某些情况下,运行 DBCC FREEPROCCACHEDBCC 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 的 select 权限。
    • 此令牌条目不同于访问检查结果 (ACR) 缓存中的条目。 ACR 条目主要指示用户或登录名是否有权运行整个查询。
  • UserToken
    • 每个数据库一个用户令牌用于登录名。
    • 存储有关数据库级别角色的成员身份的信息。
  • SecContextToken
    • 每个服务器级别主体创建一个 SecContextToken。
    • 存储主体的服务器范围安全上下文。
    • 包含用户令牌的哈希表缓存。
    • 存储有关服务器级别角色的成员身份的信息。
  • TokenAccessResult
    • 存在不同类别的 TokenAccessResult 条目。
    • 访问检查指示特定数据库中的给定用户是否有权运行涉及多个对象的查询。
    • 在 Microsoft SQL Server 2008 之前,ACR 安全缓存存储在单个缓存TokenAndPermUserStore中。
    • 在 2008 SQL Server中,ACR 缓存被分离,ACR 缓存条目在各自的用户存储中被跟踪。 这种分离提高了性能,并为缓存提供了更好的存储桶计数和配额控制。
    • 目前, TokenAndPermUserStoreACRCacheStores 是唯一使用的安全缓存类型。 有关 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 导致其他性能问题,请同时使用 traceflags 4610 和 4618。

跟踪标志 4610 和 4618 记录在联机丛书主题 DBCCC TRACEON - 跟踪标志中。

这些跟踪标志应用于服务器的无限增长 TokenAndPermUserStore 对服务器来说太大的情况。 这通常发生在两种类型的环境中:

  • 低端或中端硬件 TokenAndPermUserStore 占用大量服务器可用内存,并且新条目创建速率更快或快于缓存逐出率。 这可能会导致服务器其他部分的内存争用和更频繁的缓存失效, (例如,proc 缓存) 。

  • 例如,具有大量内存的高端计算机 (最近的几个支持案例涉及超过 1 TB 的 RAM) 。 在这些环境中,缓存存储在遇到任何内存压力之前可能会变大。 这可能会导致长存储桶链或步进的性能下降。

作为临时缓解措施,可以通过使用以下方法定期清除此缓存:

  • 从缓存中 TokenAndPermUserStore 刷新条目。

注意:

  1. 为此,请运行下列命令:

    DBCC FREESYSTEMCACHE ('TokenAndPermUserStore')

  2. 当问题开始出现时, TokenAndPermUserStore 观察缓存大小的阈值。

  3. 创建计划SQL Server 代理作业,该作业执行以下操作:

    • 检查缓存的大小 TokenAndPermUserStore 。 若要检查大小,请运行以下命令:

      SELECT SUM(pages_kb) AS 
       "CurrentSizeOfTokenCache(kb)" 
       FROM sys.dm_os_memory_clerks 
       WHERE name = 'TokenAndPermUserStore'
      
    • 如果缓存大小大于观察到的阈值,请运行以下命令:

      DBCC FREESYSTEMCACHE ('TokenAndPermUserStore')