use*_*567 2 sql-server sql-server-2014
我们的应用程序由于以下原因突然停止工作The transaction log for database 'tempdb' is full due to 'ACTIVE_TRANSACTION'.
。现在,它又开始工作了。但我怎样才能知道这个错误出现的确切原因呢?
您可以使用此查询来获取整个服务器中正在运行的查询的列表,包括它们的进程 ID、它们运行了多长时间、它们在哪个数据库中运行、谁运行了它们、等待统计信息、阻塞查询 ID我建议将它放在存储过程中,以便您可以根据需要轻松调用它(即使使用它的默认参数),并且您可以定期使用 SQL 代理作业安排它,以将结果记录到表中。
DECLARE @Database VARCHAR(100) = NULL
DECLARE @EntityName VARCHAR(100) = NULL
DECLARE @ExcludeMyQueries BIT = 0
DECLARE @RunningThreadsOnly BIT = 0
DECLARE @LocksOnly BIT = 0
DECLARE @MinDuration INT = 0
DECLARE @OutputMode INT = 0 -- TODO: Setup formally documented modes, and clean up usage below, can even have different kinds of modes like Verbose, vs EmergenciesOnly, etc
DECLARE @ExecutionDate DATETIME = GETDATE();
SELECT
SP.HostName,
SP.SPID,
ER.request_id AS RequestId,
ER.percent_complete AS PercentComplete,
DATEDIFF(s, start_time, @ExecutionDate) AS Duration,
CAST(((DATEDIFF(s, start_time, @ExecutionDate)) / 3600) AS VARCHAR) + ' hour(s), '
+ CAST((DATEDIFF(s, start_time, @ExecutionDate) % 3600) / 60 AS VARCHAR) + 'min, '
+ CAST((DATEDIFF(s, start_time, @ExecutionDate) % 60) AS VARCHAR) + ' sec' AS RunningTime,
CAST((estimated_completion_time / 3600000) AS VARCHAR) + ' hour(s), '
+ CAST((estimated_completion_time % 3600000) / 60000 AS VARCHAR) + 'min, '
+ CAST((estimated_completion_time % 60000) / 1000 AS VARCHAR) + ' sec' AS EstimatedTimeRemaining,
DATEADD(SECOND, estimated_completion_time/1000, @ExecutionDate) AS EstimatedCompletionDate,
ER.Command,
ER.blocking_session_id AS BlockingSessionId,
LastWaitType,
SP.[DBID],
DB_NAME(SP.[DBID]) AS DbName,
--[TEXT] AS EntityText,
CPU,
ER.plan_handle AS PlanHandle,
ER.query_plan_hash AS QueryPlanHash,
LOGIN_TIME AS LoginTime,
LOGINAME AS LoginName,
SP.[Status],
[PROGRAM_NAME] AS ProgramName,
NT_DOMAIN AS NT_Domain,
NT_USERNAME AS NT_Username,
@@SERVERNAME AS ServerName,
@ExecutionDate AS ExecutionDate
INTO #ExecutingQueries
FROM sys.sysprocesses SP
INNER JOIN sys.dm_exec_requests ER
ON sp.spid = ER.session_id
WHERE --TEXT NOT LIKE N'%spGetRunningQueries%'
--AND
DB_NAME(SP.dbid) NOT IN ('msdb','master','Distribution')
AND
(
@Database IS NULL
OR (@Database IS NOT NULL AND @Database = DB_NAME(SP.[DBID]))
)
AND
(
@ExcludeMyQueries = 0
OR (@ExcludeMyQueries = 1 AND hostname <> HOST_NAME())
)
AND
(
@RunningThreadsOnly = 0
OR (@RunningThreadsOnly = 1 AND SP.[Status] = 'RUNNABLE')
)
AND
(
@LocksOnly = 0
OR (@LocksOnly = 1 AND ER.blocking_session_id <> 0) -- TODO: Show the source running query that IS the blocking session ID (will need to join / union this in somehow?)
)
AND DATEDIFF(s, start_time, @ExecutionDate) >= @MinDuration
-- TODO: Clean this up and DON'T USE SELECT *
IF (@OutputMode = 0) -- Everything mode
BEGIN
SELECT *
FROM #ExecutingQueries
END
ELSE IF (@OutputMode = 1) -- Lightweight mode
BEGIN
SELECT
HostName,
SPID,
RequestId,
RunningTime,
BlockingSessionId,
LastWaitType,
DbName,
LEFT(EntityText, 100) AS EntityText,
PlanHandle,
[Status]
FROM #ExecutingQueries
END
Run Code Online (Sandbox Code Playgroud)
使用此功能,您可以查看运行时间最长的查询(Duration
或RunningTime
列),并通过查看LastWaitType
和/或BlockingSessionId
列了解它们运行这么长时间的原因。
这是我根据 Adam Machanic 的sp_WhoIsActive创建的一个正在进行的工作,我经常使用它来调试 SQL Server 上的问题。