當 TokenAndPermUserStore 快取的大小成長時,查詢需要較長的時間才能完成 SQL Server

本文可協助您在大小 TokenAndPermUserStore 成長時,針對查詢效能的相關問題進行疑難解答。 它也提供各種原因和因應措施。

原始 KB 編號: 927396

徵狀

在 Microsoft SQL Server 中,您會遇到下列徵兆:

  • 通常快速執行的查詢需要較長的時間才能完成。

  • SQL Server進程的CPU使用量大於平常。

  • 當您執行臨機操作查詢時,效能會降低。 不過,如果您查詢 sys.dm_exec_requestssys.dm_os_waiting_tasks 動態管理檢視,結果不會指出臨機操作查詢正在等候任何資源。

  • 快取的 TokenAndPermUserStore 大小會以穩定的速度成長。

  • 快取的 TokenAndPermUserStore 大小是數百 MB (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 的選取許可權。
    • 此令牌專案與存取檢查結果 (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 造成其他效能考慮,請同時使用追蹤旗標 4610 和 4618。

追蹤旗標 4610 和 4618 記載於在線叢書主題 DBCCC TRACEON - 追蹤旗標中。

這些追蹤旗標應該用於未系結成長 TokenAndPermUserStore 對伺服器而言太大的情況。 這通常會在兩種環境中發生:

  • 低階或中端硬體佔用 TokenAndPermUserStore 伺服器的大量可用記憶體,而且新專案的建立速率會比快取收回的速度更快或快。 這可能會導致記憶體爭用,以及伺服器 (的其他部分更頻繁的快取失效,例如程式快取) 。

  • 例如,具有大量記憶體 (的高階計算機,數個最近的支援案例牽涉到超過 1 TB 的 RAM) 。 在這些環境中,快取存放區可能會在遇到任何記憶體壓力之前變得很大。 這可能會導致長貯體鏈結或步調的效能降低。

作為暫時的緩和措施,您可以使用下列方法定期清除此快取:

  • 從快取排 TokenAndPermUserStore 清專案。

附註:

  1. 若要執行此動作,請執行下列命令:

    DBCC FREESYSTEMCACHE ('TokenAndPermUserStore')

  2. 觀察問題開始出現時快 TokenAndPermUserStore 取大小的臨界值。

  3. 建立執行下列動作的排程 SQL Server Agent 作業:

    • 檢查快取的 TokenAndPermUserStore 大小。 若要檢查大小,請執行下列命令:

      SELECT SUM(pages_kb) AS 
       "CurrentSizeOfTokenCache(kb)" 
       FROM sys.dm_os_memory_clerks 
       WHERE name = 'TokenAndPermUserStore'
      
    • 如果快取大小大於觀察到的臨界值,請執行下列命令:

      DBCC FREESYSTEMCACHE ('TokenAndPermUserStore')