SQL Server 2005のインスタンスがあり、tempdb
を使用していないオブジェクトを保持しているようです。データベースの合計容量は24 GBであり、使用中は明らかに8 GBを下回ることはできません。さまざまな理由で、インスタンスを再起動してtempdb
をリセットする権限を取得するのに苦労しています。
exec sp_msforeachdb 'dbcc opentran (?)'
を使用して各データベースでdbcc opentran
を実行すると、どのデータベースにも開いているトランザクションがないことがわかります。
一方、クエリを実行すると
select log_reuse_wait_desc from sys.databases where name = 'tempdb'
ACTIVE_TRANSACTION
が返ってきます。
sys.dm_exec_requests
からクエリを実行すると、現在のリクエストと通常のバックグラウンドシステムタスク以外のアクティブなリクエストが返されません。
sys.dm_db_task_space_usage
からクエリを実行すると、セッションのリストが表示され、他のすべての列(database_idを除く)が0になります。
オブジェクトは、次のような名前の通常のtempdb
オブジェクトのように見えます。
#0AF29B96
#0B5CAFEA
#0BE6BFCF
#0C50D423
2つの質問があります。最初に、なぜこれらのオブジェクトがまだ存在するのかについて私が見ているはずの別の場所がありますか?次に、それらを削除しても安全ですか?
編集-2013年4月10日午後2時 @Shawn Meltonから提供されたリンクに基づいて、次の2つのクエリを実行しました。
SELECT SUM(unallocated_extent_page_count) AS [free pages],
(SUM(unallocated_extent_page_count)*1.0/128) AS [free space in MB],
SUM(internal_object_reserved_page_count) AS [internal object pages used],
(SUM(internal_object_reserved_page_count)*1.0/128) AS [internal object space in MB],
SUM(user_object_reserved_page_count) AS [user object pages used],
(SUM(user_object_reserved_page_count)*1.0/128) AS [user object space in MB]
FROM sys.dm_db_file_space_usage;
SELECT SUM(size)*1.0/128 AS [size in MB]
FROM tempdb.sys.database_files
次の出力の場合:
free pages free space in MB internal object pages used internal object space in MB user object pages used user object space in MB
------------ ----------------- -------------------------- ---------------------------- ---------------------- -----------------------
1829424 14292.375000 320 2.500000 80 0.625000
size in MB
-------------
22490.062500
@MrDennyがサービスブローカーを提案したので、sys.dm_broker_queue_monitors
に問い合わせました。
MSDBにある2行と2つの非アクティブキューを取得しました。次に、このDMのBOLで最初のクエリ例を使用しました。
SELECT t1.name AS [Service_Name], t3.name AS [Schema_Name], t2.name AS [Queue_Name],
CASE WHEN t4.state IS NULL THEN 'Not available'
ELSE t4.state
END AS [Queue_State],
CASE WHEN t4.tasks_waiting IS NULL THEN '--'
ELSE CONVERT(VARCHAR, t4.tasks_waiting)
END AS tasks_waiting,
CASE WHEN t4.last_activated_time IS NULL THEN '--'
ELSE CONVERT(varchar, t4.last_activated_time)
END AS last_activated_time ,
CASE WHEN t4.last_empty_rowset_time IS NULL THEN '--'
ELSE CONVERT(varchar,t4.last_empty_rowset_time)
END AS last_empty_rowset_time,
(
SELECT COUNT(*)
FROM sys.transmission_queue t6
WHERE (t6.from_service_name = t1.name)
) AS [Tran_Message_Count]
FROM sys.services t1
INNER JOIN sys.service_queues t2
ON ( t1.service_queue_id = t2.object_id )
INNER JOIN sys.schemas t3
ON ( t2.schema_id = t3.schema_id )
LEFT OUTER JOIN sys.dm_broker_queue_monitors t4
ON ( t2.object_id = t4.queue_id AND t4.database_id = DB_ID() )
INNER JOIN sys.databases t5
ON ( t5.database_id = DB_ID() )
そして、以下を取り戻しました。
Service_Name Schema_Name Queue_Name Queue_State tasks_waiting last_activated_time last_empty_rowset_time Tran_Message_Count
------------------------------------------------------------------------- ------------ ----------------------------- --------------- -------------- -------------------- ----------------------- -------------------
InternalMailService dbo InternalMailQueue INACTIVE 0 Apr 7 2013 8:10AM Apr 7 2013 8:10AM 0
ExternalMailService dbo ExternalMailQueue INACTIVE 0 Apr 7 2013 8:10AM Apr 7 2013 8:10AM 0
http://schemas.Microsoft.com/SQL/Notifications/QueryNotificationService dbo QueryNotificationErrorsQueue Not available -- -- -- 0
http://schemas.Microsoft.com/SQL/Notifications/EventNotificationService dbo EventNotificationErrorsQueue Not available -- -- -- 0
http://schemas.Microsoft.com/SQL/ServiceBroker/ServiceBroker dbo ServiceBrokerQueue Not available -- -- -- 0
これはデータベースメールを提案したので、タスクがなく、メッセージ数が0であるにもかかわらず、二重チェックをするつもりでした。 DatabaseMailがオンになって使用されていますが、未送信のメッセージはありません。
ようやくインスタンスを再開するための承認を得ることができました。もちろん、これによりtempdbがクリアされました。皆様のご協力に感謝いたします。うまくいけば、これは二度と起こらないでしょう。
以下は、これらのオブジェクトが何であるかを行数とともに確認するのに役立つコードです。
SELECT OBJECT_NAME(id), rowcnt
FROM tempdb..sysindexes
WHERE OBJECT_NAME(id) LIKE '#%'
ORDER BY rowcnt DESC
SELECT
SUM (user_object_reserved_page_count)*8 as usr_obj_kb,
SUM (internal_object_reserved_page_count)*8 as internal_obj_kb,
SUM (version_store_reserved_page_count)*8 as version_store_kb,
SUM (unallocated_extent_page_count)*8 as freespace_kb,
SUM (mixed_extent_page_count)*8 as mixedextent_kb,
SUM (User_object_reserved_page_count +
internal_object_reserved_page_count +
version_store_reserved_page_count +
unallocated_extent_page_count +
mixed_extent_page_count) * 8 as total_space
FROM sys.dm_db_file_space_usage
以下のコードはtempdbを圧縮するのに役立ちます
USE [tempdb]
GO
DBCC FREEPROCCACHE -- this will free up all cache plans
GO
USE [tempdb]
GO
DBCC SHRINKFILE (N'tempdev' , 10000) -- will shrink the mdf file to 10GB, you can specify log file as well
GO
Tempdbには、オブジェクトの割り当てと割り当て解除がスムーズに行われていないトランザクションがいくつか開いている可能性があります。 tempdbの内部で何が行われているかを確認するには、 here を参照してください。
絶対に必要でない限り、tempdbを縮小しないでください。
sQLを再起動すると、tempdbは常に元の状態にリセットされるため、症状のみを原因として修正されていません。