You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQL Server 2016中log_reuse_wait_desc显示ACTIVE_TRANSACTION但DBCC OPENTRAN无结果

排查SQL Server中log_reuse_wait_desc显示ACTIVE_TRANSACTION但DBCC OPENTRAN无结果的问题

遇到这种情况确实挺头疼的——明明log_reuse_wait_desc显示有活跃事务,但DBCC OPENTRAN却找不到任何结果。结合你提到的数据库有定期爬取的全文目录,大概率是系统后台事务在搞鬼,毕竟DBCC OPENTRAN只专注于用户发起的长时间运行事务,像全文索引爬取这类系统级后台任务的事务,它通常不会展示出来。下面给你一套具体的排查和验证步骤:

1. 用DMV捕获所有活跃事务(包括系统/后台事务)

直接用动态管理视图(DMV)关联查询,能抓到DBCC OPENTRAN遗漏的事务:

SELECT 
    t.transaction_id,
    t.name AS transaction_name,
    t.transaction_begin_time,
    s.session_id,
    s.login_name,
    s.host_name,
    s.program_name,
    st.text AS active_sql_text
FROM sys.dm_tran_active_transactions t
JOIN sys.dm_tran_session_transactions stt ON t.transaction_id = stt.transaction_id
JOIN sys.dm_exec_sessions s ON stt.session_id = s.session_id
LEFT JOIN sys.dm_exec_requests r ON s.session_id = r.session_id
CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) st
ORDER BY t.transaction_begin_time DESC;

重点关注:

  • program_name列中带有Full-text相关字样的会话(比如SQL Server Full-text Filter Daemon Launcher)
  • 事务开始时间较早的记录,这类往往是长时间持有的后台事务

2. 直接检查全文索引的爬取状态

既然你提到有定期爬取的全文目录,直接验证它是否在运行:

SELECT 
    fc.catalog_name,
    t.table_name,
    fi.crawl_type,
    fi.crawl_start_date,
    fi.crawl_end_date,
    fi.crawl_status
FROM sys.fulltext_catalogs fc
JOIN sys.fulltext_indexes fi ON fc.fulltext_catalog_id = fi.fulltext_catalog_id
JOIN sys.tables t ON fi.object_id = t.object_id
WHERE fi.crawl_status IN (0, 1); -- 0=正在爬取,1=暂停未完成

如果返回结果中crawl_status为0,说明当前正有全文爬取在运行,这个后台任务会持有事务,正是导致log_reuse_wait_desc显示ACTIVE_TRANSACTION的原因。

3. 定位阻止数据库脱机的会话

如果数据库无法脱机,用下面的查询找到阻塞源:

SELECT 
    r.blocking_session_id,
    r.session_id,
    r.command,
    r.resource_type,
    r.resource_description,
    st.text AS sql_text
FROM sys.dm_exec_requests r
CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) st
WHERE r.database_id = DB_ID('AdventureWorks')
AND r.blocking_session_id != 0;

或者用经典的sp_who2快速查看:

EXEC sp_who2;

查看结果中BlkBy列不为0的会话,就能找到阻止数据库脱机的源头。

4. 验证全文爬取是否是事务持有源

如果前面的查询找到了全文相关的会话,用下面的语句确认它关联的事务:

SELECT 
    t.transaction_id,
    t.transaction_begin_time,
    s.program_name,
    s.login_name
FROM sys.dm_tran_active_transactions t
JOIN sys.dm_tran_session_transactions stt ON t.transaction_id = stt.transaction_id
JOIN sys.dm_exec_sessions s ON stt.session_id = s.session_id
WHERE s.program_name LIKE '%Full-text%';

后续处理建议

  • 如果确认是全文爬取导致的,可以等待爬取完成(再次执行步骤2的查询,看crawl_end_date是否更新),或者手动暂停爬取:
ALTER FULLTEXT CATALOG [你的全文目录名称] STOP POPULATION;
  • 暂停后再次查询sys.databases的log_reuse_wait_desc,确认是否变回NOTHING,之后尝试脱机数据库。
  • 长期来看,可以调整全文爬取的调度时间,避开数据库维护窗口;或者改用增量爬取代替全量爬取,减少事务持有的时长。

内容的提问来源于stack exchange,提问作者d-_-b

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 04:10:08