如何检查SQL Server 2016数据库是否仍在使用?
我需要检查SQL Server 2016数据库是否仍在使用,思路是通过日志验证是否存在插入、删除、查询等数据操作。但遇到了几个问题:
- 查看
Management -> SQL Server Logs仅找到13个文件,信息不足; - 执行以下查询仅返回当前连接的信息:
SELECT conn.session_id, sson.host_name, sson.login_name, sqltxt.text, sson.login_time, sson.status, sson.database_id FROM sys.dm_exec_connections conn INNER JOIN sys.dm_exec_sessions sson ON conn.session_id = sson.session_id CROSS APPLY sys.dm_exec_sql_text(most_recent_sql_handle) AS sqltxt ORDER BY conn.session_id
- 执行
SELECT * FROM fn_dblog(NULL,NULL)后,多数Begin_Transaction和End_Transaction字段无数据,感觉遗漏了信息。
请问我是否操作有误?有没有更好的方法?
可行的检查方法
实时监控目标数据库的会话活动
你之前的查询仅关联了sys.dm_exec_connections,会漏掉无活跃连接的休眠会话。调整查询,过滤目标数据库并排除自身会话,能看到所有关联该库的会话及最后执行的SQL:SELECT s.session_id, s.host_name, s.login_name, DB_NAME(s.database_id) AS database_name, t.text AS last_executed_sql, s.login_time, s.status, s.program_name FROM sys.dm_exec_sessions s CROSS APPLY sys.dm_exec_sql_text(s.most_recent_sql_handle) t WHERE s.database_id = DB_ID('目标数据库名') -- 替换为你的数据库名称 AND s.session_id <> @@SPID -- 排除当前查询的会话 ORDER BY s.session_id;查看数据库对象的访问统计
使用sys.dm_db_index_usage_stats可以追踪数据库表/索引的最近读写时间,直接反映数据库是否被使用:SELECT OBJECT_NAME(object_id) AS object_name, last_user_seek, last_user_scan, last_user_lookup, last_user_update FROM sys.dm_db_index_usage_stats WHERE database_id = DB_ID('目标数据库名');注意:SQL Server重启后,这些统计数据会重置,若服务器刚重启,需观察一段时间再查看。
过滤事务日志中的有效操作
fn_dblog返回的原始日志中,自动提交的单语句操作不会生成显式的Begin_Transaction/End_Transaction记录。可以过滤出数据修改类操作,更直观看到数据库的变更:SELECT Operation, Context, TransactionID, BeginTime, Description FROM fn_dblog(NULL, NULL) WHERE Operation IN ('LOP_INSERT_ROWS', 'LOP_DELETE_ROWS', 'LOP_MODIFY_ROW') ORDER BY BeginTime DESC;另外,如果数据库采用简单恢复模式,事务日志会自动截断,旧的操作记录会被覆盖,这也会导致你看不到历史数据。
长期监控用Extended Events(轻量级)
若需要持续监控数据库活动,Extended Events是比SQL Server Profiler性能影响更小的工具。可以创建事件会话,捕获sql_statement_completed事件,记录所有针对目标数据库执行的SQL语句。检查数据库连接数性能计数器
通过性能计数器查看数据库的连接历史,判断是否有过访问:SELECT cntr_value AS current_connection_count, instance_name AS database_name FROM sys.dm_os_performance_counters WHERE object_name LIKE '%Databases%' AND counter_name = 'User Connections' AND instance_name = '目标数据库名';
内容的提问来源于stack exchange,提问作者Kenzo_Gilead

