我们正打算停用尚有几个数据库的SQL Server实例。

如何确定用户或Web应用程序仍在使用它们?

我找到了一个论坛主题,其中包含一个T-SQL查询,您可以运行该查询来检索上一个查询日期。看来可行,但是我想知道此信息是否足够有效以删除数据库。是吗?

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

评论

下面有很多精彩的讨论,但也请参阅此博客文章。

#1 楼

您将需要考虑从缓存中清除的项目以及丢失的项目,或者使用频率不高的数据库。阻止访问而不丢弃它们,或者在RESTRICTED_USER模式下限制访问。这样做可以将它们保持一两个月的状态,以检查是否偶尔使用。

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

评论


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

– Gaius
2011年4月4日上午9:13

#2 楼

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


使数据库脱机/分离
拒绝用户/登录访问
Profiler跟踪

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

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

评论


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

– jsauni
2011年4月5日在8:17

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

– SQLRockstar
2011年4月5日在12:11

#3 楼

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

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

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

#4 楼

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

评论


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

–詹森
18-10-12在17:02

#5 楼

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

做的是以下各项的结合: br /> *使数据库脱机并查看谁抱怨。
*重命名服务器以查看谁抱怨。

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

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

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

#6 楼

另两种选择是:在数据库上创建触发器,该触发器将通知您(或存储到表)任何活动。

对数据库启用审计。


取决于您的数据库版本。




#7 楼

下一个解决方案显示实例中特定数据库的临时总计,干净和脏页(以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


评论


您能否说明这如何解决原始问题?

– dezso
2012年11月6日在21:43