如何判断是否仍在使用SQL Server数据库?


33

我们正在寻求停用一个仍具有几个数据库的SQL Server实例。

如何判断用户或Web应用程序仍在使用它们?

我发现一个论坛线程具有一个T-SQL查询,您可以运行该查询来检索上一个查询日期。看来可行,但是我想知道此信息是否足够有效以删除数据库。是吗?

如果您有其他方法也有帮助。


1
下面有很多精彩的讨论,但也请参阅此博客文章
亚伦·伯特兰

Answers:


29

您将不得不考虑从缓存中清除的内容以及丢失的内容,或使用频率不高的数据库。

与其使数据库失去控制权,要么将它们置于离线状态以防止访问而不会使其掉落,或者使它们处于RESTRICTED_USER模式以限制访问。这样做可以将它们保留在该状态一两个月,以查看是否偶尔使用。

您还可以考虑在该数据库上使用服务器端探查器跟踪过滤。


24
成为DBA的规则#1:如果有必要,请不要进行无法迅速撤消的任何更改。
Gaius

14

这些是我过去使用的方法:

  1. 使数据库脱机/分离
  2. 拒绝用户/登录访问
  3. 探查器跟踪

问题是这样的:您要等多久才能确定没有人会访问数据?对于财务数据,您需要每天,每周,每月,每季度,每半年和每年运行一些项目。但是一年足够吗?我还看到要求将数据保持至少7年的请求,有一次我被告知,即使没有人使用它,一个系统中的数据也需要永远存在。

最好的建议是:无论如何关闭访问,请确保可以立即将其重新打开。我发现这种运送方式效果最好。我只是编写重新编写脚本的脚本,并指示我的团队“如果有人问它在哪里,请运行此脚本”。这给了我们最好的机会,使事情尽快恢复原状。


我已经考虑过,我监视数据库使用的时间是否足够长。您是否仅凭SQL Server的性质做出判断?
jsauni 2011年

是的,在某个时候,您会让所有人都同意拔下插头,并了解如果某个恶意程序失败,则需要迅速将其恢复原状。只要它们可以停电就可以,而且您可以很快将其恢复在线,那么就可以了。但是要让所有人都同意并不容易!
SQLRockstar

13

我同意尼克的建议。如果需要确定,则必须使用Profiler(服务端跟踪),因为某些SQL查询将不会被缓存,或者由于某些原因会清除过程缓存。

我通常会检查虚拟文件统计信息,以查看OS文件级别是否发生任何读取或写入操作。即使数据库处于非活动状态,如果您要进行日志备份,完整备份等,您仍然会看到少量读/写操作……但是,这也会使您对该数据库进行读/写活动。

在删除任何数据库之前,我将确保您在单独的位置至少有2个或3个可读备份(测试它们)。您永远不知道何时需要它们。


8

以下查询显示自上次重新启动以来没有使用过的DB,而无需依赖于保留在缓存中的查询计划,因为它显示了针对索引(和堆)的用户IO。这有点类似于使用虚拟文件统计信息,但是此处使用的DMV从备份中排除了IO活动。无需保持探查器跟踪运行,无需触发器或审计。当然,如果您频繁地重新启动SQL Server(或经常附加/关闭数据库),则可能不是这样的方法:-)

话虽如此,仍然同意即使该查询似乎可以确认可以删除数据库, 一定要进行OFFLINE / detach或拒绝用户访问一段时间,再加上在删除之前进行的所有尽职调查!

select [name] from sys.databases 
where database_id > 4
AND [name] NOT IN 
(select DB_NAME(database_id) 
from sys.dm_db_index_usage_stats
where coalesce(last_user_seek, last_user_scan, last_user_lookup,'1/1/1970') > 
(select login_time from sys.sysprocesses where spid = 1))

如果运行良好,那就太好了。请问您为什么要合并并与login_time进行比较?以及为什么没有包含last_user_update?这是否是一种聪明的尝试,以查看数据库是否正在获取INSERTS,但从未有人在查询它?还是该DMV可能包含所有NULL时间戳?
杰森

2

我在一个有大量孤立和半孤立数据库的地方工作。由于许多任务是季节性的还是年度性的,因此很难确定它们是否真的是孤儿-因此该网站每年仅运行3-4个月(例如,W2表格需要以电子方式提交1/31,因此网站需要处理这些仅从1月中旬到4月底运行)。

所做的事情是以下各项的组合:
*问每个开发人员是否正在使用某个数据库或其他数据库(这些电子邮件将每月发送一次,或者每当备份花费的时间太长时发送)。
*使数据库脱机,看看谁抱怨。
*重命名服务器以查看谁抱怨。

由于尖头的上司只愿意允许“完整的”文档,因此明确禁止创建Wiki,并且裁员会导致符合标准的文档急剧减少。

如果由我决定,则每台服务器都将有一个Wiki页面,其中包含每个数据库的联系人名称(也许还简要说明了该数据库的用途)。Wiki上未记录的任何数据库都是删除的公平游戏。

我们有一个大型金融客户端,直到2009年末仍在使用SQL Server 2000,因此我们必须保持一个SQL Server 2000实例的运行状态,直到该客户端最终移至SQL Server 2005。


2

另两种选择是:

  1. 在数据库上创建触发器,该触发器将通知您(或存储到表)任何活动。
  2. 在数据库上启用审核。

    • 取决于您的数据库版本。

2

下一个解决方案显示实例中特定数据库的临时总计,干净和脏页(以MB为单位)(可在Internet上找到并稍作修改):

SELECT
    (CASE WHEN ([database_id] = 32767) THEN 'Resource Database' ELSE DB_NAME (database_id) END) AS 'Database Name',
    COUNT(*) *8/1024 AS [TotalPages in MB],
    SUM(CASE WHEN ([is_modified] = 1) THEN 0 ELSE 1 END) *8/1024 AS [CleanPages in MB],
    SUM(CASE WHEN ([is_modified] = 1) THEN 1 ELSE 0 END) *8/1024 AS [DirtyPages in MB]
FROM sys.dm_os_buffer_descriptors
GROUP BY database_id
ORDER BY DB_NAME(database_id)

要么

select value [DBid],attribute, last_execution_time ,text
from
sys.dm_exec_query_stats
cross apply
sys.dm_exec_plan_attributes(plan_handle)
cross apply
sys.dm_exec_sql_text(plan_handle)
where  attribute = 'dbid' 
order by last_execution_time desc

要么

select value [DBid],attribute, last_execution_time ,text
from
sys.dm_exec_query_stats
cross apply
sys.dm_exec_plan_attributes(plan_handle)
cross apply
sys.dm_exec_sql_text(plan_handle)
--where dbid=8
where 
      text like '%idAdministrator%' and
      attribute = 'dbid' 
      and value>= 5 -- dbid >=5 for user databases but include resource database which
                     --you can exclude by its numer I don't remember at the moment
order by last_execution_time desc

2
您能否说明这如何解决原始问题?
dezso 2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.