今日作業しているサーバーの1つで、バッファキャッシュのほとんどすべてがtempdbでいっぱいになっているのがわかります。その結果、サーバーのメモリが非常に少なくなります。
Tempdb:
バージョン:
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)
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
質問
Dbcc dropcleanbuffersを発行した後、tempdbがすぐにいっぱいになるのはなぜですか?何か不足していますか、何を確認すればよいですか?
UPDATE 30/11/2018
TEMPDBを512 MBの4つのファイルとして設定し、サーバーを再起動すると、バッファーのMBは低くなるようです。ただし、それでも6GBです。
何をすべきか/今すぐ確認する上で他のアイデアは?
追加情報:
トレースステータス
プロファイラーによってキャプチャされた定数実行クエリの例:
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は少々低調です。
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出力:
確かではありませんが、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
おかげで、
クレイグ