我正试图追查......某事......正在与特定数据库建立连接,而(显然)没有对连接做任何事情。但是,到目前为止,我没有运气。
该数据库中的数据已迁移到同一服务器上的其他数据库,在开发人员确认他们已更改/删除对该特定数据库的所有访问权限(包括已嵌入但未使用的连接字符串)后,我们将数据库重命名为类似的东西DBNAME_Old
。然而,这导致产生分散的错误。我们将数据库重命名为原始名称,错误消失了。然而,在检查了他们的代码之后,开发人员仍然无法识别任何其他可能导致问题的代码。
我无法访问访问数据库的代码(或者我自己会搜索它)。
接下来,我设置了一个计划作业,试图识别与数据库建立的任何连接。我可以通过多种方法识别数据库中运行的进程,但在我的监控运行时没有任何显示(相对不频繁,因为没有猛烈的生产)。
然后我尝试了几个扩展事件过程:
-- Attempt 1 -
CREATE EVENT SESSION [DBToMonitorMonitoring] ON SERVER
ADD EVENT sqlserver.connectivity_ring_buffer_recorded(
ACTION(sqlserver.client_app_name,sqlserver.client_connection_id,sqlserver.client_hostname,sqlserver.database_name,sqlserver.nt_username,sqlserver.server_principal_name,sqlserver.session_nt_username,sqlserver.session_server_principal_name,sqlserver.sql_text,sqlserver.username)
WHERE ([sqlserver].[equal_i_sql_unicode_string]([sqlserver].[database_name],N'DBToMonitor') AND [sqlserver].[session_server_principal_name]<>N'[THEDOMAIN\Domain_Login]')),
ADD EVENT sqlserver.login(SET collect_options_text=(1)
ACTION(sqlserver.client_app_name,sqlserver.client_connection_id,sqlserver.client_hostname,sqlserver.database_name,sqlserver.nt_username,sqlserver.server_principal_name,sqlserver.session_nt_username,sqlserver.session_server_principal_name,sqlserver.sql_text,sqlserver.username)
WHERE ([database_name]=N'DBToMonitor' OR [sqlserver].[database_name]=N'DBToMonitor')),
ADD EVENT sqlserver.logout(
ACTION(sqlserver.client_app_name,sqlserver.client_connection_id,sqlserver.client_hostname,sqlserver.database_name,sqlserver.nt_username,sqlserver.server_principal_name,sqlserver.session_nt_username,sqlserver.session_server_principal_name,sqlserver.sql_text,sqlserver.username)
WHERE ([sqlserver].[database_name]=N'DBToMonitor')),
ADD EVENT sqlserver.rpc_starting(SET collect_statement=(1)
ACTION(sqlserver.client_app_name,sqlserver.client_connection_id,sqlserver.client_hostname,sqlserver.database_name,sqlserver.nt_username,sqlserver.server_principal_name,sqlserver.session_nt_username,sqlserver.session_server_principal_name,sqlserver.sql_text,sqlserver.username)
WHERE ([sqlserver].[equal_i_sql_unicode_string]([sqlserver].[database_name],N'DBToMonitor') AND [sqlserver].[session_server_principal_name]<>N'[THEDOMAIN\Domain_Login]')),
ADD EVENT sqlserver.sql_batch_starting(
ACTION(sqlserver.client_app_name,sqlserver.client_connection_id,sqlserver.client_hostname,sqlserver.database_name,sqlserver.nt_username,sqlserver.server_principal_name,sqlserver.session_nt_username,sqlserver.session_server_principal_name,sqlserver.sql_text,sqlserver.username)
WHERE ([sqlserver].[equal_i_sql_unicode_string]([sqlserver].[database_name],N'DBToMonitor') AND [sqlserver].[not_equal_i_sql_unicode_string]([sqlserver].[session_server_principal_name],N'AMERICAS\DTNA_S_SQLService')))
ADD TARGET package0.ring_buffer(SET max_events_limit=(400))
WITH (MAX_MEMORY=4096 KB,EVENT_RETENTION_MODE=ALLOW_SINGLE_EVENT_LOSS,MAX_DISPATCH_LATENCY=30 SECONDS,MAX_EVENT_SIZE=0 KB,MEMORY_PARTITION_MODE=NONE,TRACK_CAUSALITY=ON,STARTUP_STATE=OFF)
GO
-- Attempt 2 - Found on the internet
CREATE EVENT SESSION [DBToMonitor_DB_Usage] ON SERVER
ADD EVENT sqlserver.sql_statement_completed(
ACTION(sqlserver.client_app_name,sqlserver.client_hostname,sqlserver.username)
WHERE ([sqlserver].[database_name]=N'DBToMonitor'))
ADD TARGET package0.event_file(SET filename=N'D:\Traces\DBToMonitor_DB_Usage.xel',metadatafile=N'D:\Traces\DBToMonitorDB_Usage.xem')
WITH (MAX_MEMORY=4096 KB,EVENT_RETENTION_MODE=ALLOW_SINGLE_EVENT_LOSS,MAX_DISPATCH_LATENCY=30 SECONDS,MAX_EVENT_SIZE=0 KB,MEMORY_PARTITION_MODE=NONE,TRACK_CAUSALITY=OFF,STARTUP_STATE=OFF)
GO
尽管第二个可以识别与数据库的直接连接,但它无法识别诸如SELECT TOP 1 * FROM DBToMonitor.dbo.SampleTable
任何有关识别与特定数据库中的数据建立的任何连接,或者即使数据库中没有数据被触及的任何登录的任何建议,都将在这里得到充分的赞赏,因为我已经在这里达到了我的资源的尽头,除了猛击具有持续监控的服务器会使生产陷入瘫痪。
帮助?
一种方法是将数据库设置为
AUTO_CLOSE
并捕获database_started
事件,如下例所示。尽管我database_id
在此示例中包含了一个过滤器,但可能不需要它,因为这将(希望)是AUTO_CLOSE
实例上唯一的数据库。跟踪中的
database_name
将反映使用数据库的上下文数据库,例如在跨数据库查询中。注意
AUTO_CLOSE
通常是一个坏主意,但我希望在这种情况下不经常使用数据库,因为它根本不应该使用。我要补充一点,应用程序团队应该能够识别数据库重命名后代码中出现“分散错误”的位置。这将查明正在使用数据库的位置。
登录触发器呢?
您可以将应用程序登录到服务器的数据插入到表中,然后稍后查询它以跟踪出现故障的应用程序和服务器。