web-dev-qa-db-ja.com

メモリの問題:ほとんどすべてのバッファキャッシュを使用するTempdb

今日作業しているサーバーの1つで、バッファキャッシュのほとんどすべてがtempdbでいっぱいになっているのがわかります。その結果、サーバーのメモリが非常に少なくなります。

CPU - enter image description here

Tempdb:

enter image description here

バージョン:

Microsoft SQL Server 2014(SP2-CU13)(KB4456287)-12.0.5590.1(X64)
Aug 1 2018 01:23:36 Copyright(c)Microsoft Corporation Standard Edition(64-bit)on Windows NT 6.3(Build 14393:)(Hypervisor)

4つのデータファイル= 4096 MB 1つのログファイル= 1536MB

私の問題は、TEMPDBが13GBのバッファキャッシュを使用することです。 tempdbでオブジェクトをチェックしました。最大のオブジェクトは、sp_blitz一時テーブルで、それほど大きくありません。

RCSIはどのデータベースでも有効になっていないため、バージョンストアの問題ではありません。

未処理のトランザクションはありません

開いているカーソルはありません。

Tempdbでチェックポイントを実行すると、約30秒かかりますが終了します。

Dbcc dropcleanbuffersを実行すると、バッファキャッシュ内のtempdbの存在が減少し、場合によっては1 GB、場合によっては4 GB、30秒後に13 GBの完全な栄光に戻ります

例えば:

dbcc dropcleanbuffers


DECLARE @total_buffer INT;

SELECT @total_buffer = cntr_value
FROM sys.dm_os_performance_counters 
WHERE RTRIM([object_name]) LIKE '%Buffer Manager'
AND counter_name = 'Database Pages';

;WITH src AS
(
SELECT 
database_id, db_buffer_pages = COUNT_BIG(*)
FROM sys.dm_os_buffer_descriptors
--WHERE database_id BETWEEN 5 AND 32766
GROUP BY database_id
)
SELECT
[db_name] = CASE [database_id] WHEN 32767 
THEN 'Resource DB' 
ELSE DB_NAME([database_id]) END,
db_buffer_pages,
db_buffer_MB = db_buffer_pages / 128,
db_buffer_percent = CONVERT(DECIMAL(6,3), 
db_buffer_pages * 100.0 / @total_buffer)
FROM src
ORDER BY db_buffer_MB DESC; 

直後の結果:

db_name db_buffer_pages db_buffer_MB    db_buffer_percent
tempdb  620627  4848    58.096

30秒後:

db_name db_buffer_pages db_buffer_MB    db_buffer_percent
tempdb  1313835 10264   83.560

ピーク時のtempdbバッファーキャッシュ使用量(its_over_9000.jpeg) enter image description here

Tempdbのオブジェクトを確認します。

use tempdb 

go
SELECT 
    t.NAME AS TableName,
    s.Name AS SchemaName,
    p.rows AS RowCounts,
    SUM(a.total_pages) * 8 AS TotalSpaceKB, 
    SUM(a.used_pages) * 8 AS UsedSpaceKB, 
    (SUM(a.total_pages) - SUM(a.used_pages)) * 8 AS UnusedSpaceKB
FROM sys.tables t
INNER JOIN sys.indexes i ON t.OBJECT_ID = i.object_id
INNER JOIN sys.partitions p ON i.object_id = p.OBJECT_ID AND i.index_id = p.index_id
INNER JOIN sys.allocation_units a ON p.partition_id = a.container_id
LEFT OUTER JOIN sys.schemas s ON t.schema_id = s.schema_id
GROUP BY  t.Name, s.Name, p.Rows
ORDER BY  TotalSpaceKB desc

上位4つの値:

TableName   SchemaName  RowCounts   TotalSpaceKB    UsedSpaceKB UnusedSpaceKB
#A3B2C869   dbo 0   72  16  56
#A52E4149   dbo 0   72  16  56
#A59B10DB   dbo 0   72  16  56
#A68F3514   dbo 0   72  16  56

合計でなんと74のオブジェクト。

空き容量が7965バイトのページ(375 000以上!!!)がたくさんあり、メモリバッファーに1行しかありません。使用されるクエリ:

select * from sys.dm_os_buffer_descriptors
where database_id = 2
order by free_space_in_bytes desc 

例:

file_id page_id page_level  allocation_unit_id  page_type   row_count   free_space_in_bytes
1   109763  0   71635384526569472   INDEX_PAGE  1   7965

ただし、40バイトの空き領域(1M)を使用した場合はさらに多く、以下を参照してください。

さらにフィルタリングする:

select page_type,free_space_in_bytes,  count(*)as counter from sys.dm_os_buffer_descriptors
where database_id = 2
group by page_type, free_space_in_bytes
having count(*) > 500
order by free_space_in_bytes desc 

enter image description here

質問

Dbcc dropcleanbuffersを発行した後、tempdbがすぐにいっぱいになるのはなぜですか?何か不足していますか、何を確認すればよいですか?

UPDATE 30/11/2018

TEMPDBを512 MBの4つのファイルとして設定し、サーバーを再起動すると、バッファーのMBは低くなるようです。ただし、それでも6GBです。

enter image description here

何をすべきか/今すぐ確認する上で他のアイデアは?

追加情報:

トレースステータス

enter image description here

プロファイラーによってキャプチャされた定数実行クエリの例:

exec sp_reset_connection 

SELECT COUNT(*) FROM dbo.SomeTable WHERE Error IS NULL

一部の接続はシリアライズ可能を使用します:

-- network protocol: TCP/IP
set quoted_identifier on
set arithabort off
set numeric_roundabort off
set ansi_warnings on
set ansi_padding on
set ansi_nulls on
set concat_null_yields_null on
set cursor_close_on_commit off
set implicit_transactions off
set language us_english
set dateformat mdy
set datefirst 7
set transaction isolation level serializable 

一部ではありません

-- network protocol: TCP/IP
set quoted_identifier on
set arithabort off
set numeric_roundabort off
set ansi_warnings on
set ansi_padding on
set ansi_nulls on
set concat_null_yields_null on
set cursor_close_on_commit off
set implicit_transactions off
set language us_english
set dateformat mdy
set datefirst 7
set transaction isolation level read committed

Max memは少々低調です。

enter image description here

DBCCページチェック:DBCC TRACEON(3604);

DBCCページ(2、5、474258、3); DBCC TRACEOFF(3604);

bpage = 0x00000016AA16C000          bhash = 0x0000000000000000          bpageno = (5:474258)
bdbid = 2                           breferences = 0                     bcputicks = 0
bsampleCount = 0                    bUse1 = 1952                        bstat = 0x109
blog = 0xcdcdcdcd                   bnext = 0x0000000000000000          

PAGE HEADER:


Page @0x00000016AA16C000

m_pageId = (5:474258)               m_headerVersion = 1                 m_type = 3
m_typeFlagBits = 0x0                m_level = 0                         m_flagBits = 0x8020
m_objId (AllocUnitId.idObj) = -1778255884                                m_indexId (AllocUnitId.idInd) = 255
Metadata: AllocUnitId = 71941054260314112                                Metadata: PartitionId = 0
Metadata: IndexId = -1              Metadata: ObjectId = 0              m_prevPage = (0:0)
m_nextPage = (0:0)                  pminlen = 0                         m_slotCnt = 1
m_freeCnt = 40                      m_freeData = 8150                   m_reservedCnt = 0
m_lsn = (5148:180860:473)           m_xactReserved = 0                  m_xdesId = (0:0)
m_ghostRecCnt = 0                   m_tornBits = 0                      DB Frag ID = 1

Allocation Status

GAM (5:2) = NOT ALLOCATED           SGAM (5:3) = NOT ALLOCATED          PFS (5:469104) = 0x4 100_PCT_FULL
DIFF (5:6) = NOT CHANGED            ML (5:7) = NOT MIN_LOGGED           


Blob row at: Page (5:474258) Slot 0 Length: 8054 Type: 3 (DATA)

Blob Id:2794796220416



000000464FAFA06E:  0044002b  006f0051  00550038  00520058 +.D.Q.o.8.U.X.R.
...

@Craig出力:

enter image description hereenter image description hereenter image description hereenter image description here

3
Randi Vertongen

確かではありませんが、sys.allocation_unitsとsys.partitionsの結合は docs ごとに完全に正しくありません。例えば

select bd.file_id, bd.page_id, p.*
from sys.dm_os_buffer_descriptors bd
left join sys.allocation_units au
 on bd.allocation_unit_id = au.allocation_unit_id
left join sys.partitions p
  on ( au.type in (1,3) and au.container_id = p.hobt_id )
    or
     ( au.type = 2 and au.container_id = p.partition_id )
where database_id = 2

また、Tempdbから いくつかのページを調べる を試して、ページのヘッダーとデータから、それらがどこから来ているかがわかるかどうかを確認することもできます。

このクエリを試して、出力を送信できますか?

SET NOCOUNT ON;

SELECT
(DATEDIFF(n, dtat.transaction_begin_time, GETDATE())) as duration, *
FROM 
sys.dm_tran_active_transactions dtat 
INNER JOIN sys.dm_tran_session_transactions dtst 
ON dtat.transaction_id = dtst.transaction_id
INNER JOIN sys.dm_exec_sessions es 
ON dtst.session_id = es.session_id
WHERE es.session_id > 50 

おかげで、

クレイグ

1
Craig Efrein