首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >试图确定哪个进程正在连接到Server中的特定DB

问试图确定哪个进程正在连接到Server中的特定DB
EN

Database Administration用户
提问于 2019-09-05 20:43:20
回答 2查看 788关注 0票数 1

我正试图追踪..。一些东西..。这就是在没有(显然)对连接做任何事情的情况下建立到特定数据库的连接。然而,到目前为止,我还没有运气。

来自此数据库的数据已迁移到同一服务器上的其他数据库,在开发人员确认他们已更改/删除了对此特定数据库的所有访问(包括嵌入但未使用的连接字符串)之后,我们将数据库重命名为类似于DBNAME_Old的内容。但是,这会产生分散的错误。我们将DB重命名为原始名称,错误消失了。但是,在检查了它们的代码之后,devs仍然无法识别可能导致问题的任何其他代码。

我无法访问访问数据库的代码(否则我会亲自搜索)。

接下来,我设置了一个计划作业,试图识别到数据库的任何连接。我可以通过多个方法识别数据库中运行的进程,但是在运行监视时什么也没有显示出来(相对来说,不频繁,因为没有对生产进行猛烈抨击)。

然后,我尝试了几个扩展的事件过程:

代码语言:javascript
复制
-- 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这样的情况。

任何关于识别到特定数据库中的数据的任何连接的建议,或者任何登录,即使数据库中没有数据被触摸,都将在这里得到充分的赞赏,因为我已经在这里达到了我的资源的末尾,而不是连续监视服务器,这将使生产陷入瘫痪。

帮助?

EN

回答 2

Database Administration用户

回答已采纳

发布于 2019-09-06 09:41:16

一种方法是将数据库设置为AUTO_CLOSE并捕获database_started事件,如下例所示。虽然我在本例中包含了一个database_id过滤器,但可能不需要它,因为这将(希望)成为实例上唯一的AUTO_CLOSE数据库。

跟踪中的database_name将反映使用数据库的上下文数据库,例如在跨数据库查询中。

代码语言:javascript
复制
ALTER DATABASE DeprecatedDatabase
    SET AUTO_CLOSE ON;
GO

--get database_id value for the database
SELECT DB_ID(N'DeprecatedDatabase') AS DatabaseID;
GO

--specify above database_id value as session filter
CREATE EVENT SESSION DeprecatedDatabaseUsed ON SERVER 
ADD EVENT sqlserver.database_started(
    ACTION(sqlserver.client_app_name,sqlserver.client_hostname,sqlserver.database_name,sqlserver.server_principal_name)
    WHERE ([database_id]=(40)))
ADD TARGET package0.event_file(SET filename=N'DeprecatedDatabaseUsed',max_file_size=(100))
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
ALTER EVENT SESSION DeprecatedDatabaseUsed ON SERVER
    STATE = START;
GO

注意,AUTO_CLOSE通常是个不好的主意,但在这种情况下,我希望数据库很少被使用,因为它根本不应该被使用。

我要补充的是,应用程序团队应该能够识别数据库重命名后代码中的“分散错误”发生的位置。这将精确地指出使用数据库的位置。

票数 2
EN

Database Administration用户

发布于 2019-09-05 21:03:24

登录触发器怎么样?

您可以将应用程序日志记录的数据插入到表中,然后查询它以跟踪故障应用程序和服务器故障。

票数 1
EN
页面原文内容由Database Administration提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://dba.stackexchange.com/questions/247105

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档