视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
AuditingSQLServerSQLStatements
2020-11-09 16:29:27 责编:小采
文档

可以看到go是不能用在动态语句里面的。

为了验证SP:Stmt*是不是指的是存储过程里面的语句,我们先创建一个stored procedure,然后再执行它:

create procedure dbo.getRegionName

as

begin

declare @regionName varchar(20) = 'China'

select top 10 * from dbo.region

where regionName = @regionName

declare @regionNamex varchar(20) = 'England'

select top 10 * from dbo.region

where regionName = @regionNamex

end

exec dbo.getRegionName


正是如此 !综上所述, SQL:Batch* , 这里的batch相当于是个scope,一个大的执行空间,里面的所有 SQL 语句都是statement,包括DML,DDL等一系列 T-SQL语句 ;而SP:Stmt*又是存储过程的执行空间,里面所有的 T-SQL语句都是statement。

下面看段c#调用这个stored procedure,看看trace是如何识别的:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.Data.SqlClient;

using System.Data.SqlTypes;

using System.Data;

namespace AccessLenistest4DB

{

 class Program

 {

 static void Main(string[] args)

 {

 SqlConnection ICONN = new SqlConnection(@"data source = (localhost);initial catalog = lenistest4 ;user id = sa; password = sas;");

 SqlCommand icmd = new SqlCommand();

 icmd.Connection = ICONN;

 icmd.CommandType = System.Data.CommandType.StoredProcedure;

 icmd.CommandText = "dbo.getRegionName";

 SqlDataAdapter ida = new SqlDataAdapter(icmd);

 DataSet localds = new DataSet();

 try

 {

 ICONN.Open();

 ida.Fill(localds);

 }

 catch(SqlException se)

 {

 Console.Write(se.ToString());

 }

 }

 }

}


这儿多了个RPC, remote procedure call。其他都一样,所以RPC可以看作是一种命名空间,用阿里区别访问协议。这里要区别的是我们调用的是stored procedure,所以会RPC。所以如果我们是用纯SQL来访问数据库,那会不会有 RPC标示呢:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.Data.SqlClient;

using System.Data.SqlTypes;

using System.Data;

namespace AccessLenistest4DB

{

 class Program

 {

 static void Main(string[] args)

 {

 SqlConnection ICONN = new SqlConnection(@"data source = (localhost);initial catalog = lenistest4 ;user id = sa; password = sas;");

 SqlCommand icmd = new SqlCommand();

 icmd.Connection = ICONN;

 icmd.CommandType = System.Data.CommandType.Text;

 icmd.CommandText = "select * from dbo.region";

 SqlDataAdapter ida = new SqlDataAdapter(icmd);

 DataSet localds = new DataSet();

 try

 {

 ICONN.Open();

 ida.Fill(localds);

 }

 catch(SqlException se)

 {

 Console.Write(se.ToString());

 }

 }

 }

}


并没有RPC。 事实证明 RPC只出现在客户端语言调用存储过程的例子。

Trace的手段 :“破坏分子”的特征被识别了,接下来就是怎么去抓捕的手段问题了。可以有即时的GUI工具,比如SQL Profiler,Extended Event(SSMS自带),也可以用脚本去抓,并放在特定存储里面供稍后分析使用。

SQL Profiler 是即时的GUI工具很好用,可以保存结果,也可以自定义模板,缺点在于你必须开一个额外的窗口去跟踪,有时候数据量太大,还会影响传输,对多太SQL Server做监控就不怎么容易了,一个一个手工去开窗口,是不是很麻烦 ?

这里有Extended Events可以帮我们用脚本的形式去捕捉这些T-SQL语句,这里有个简单的例子:

  1. 通过 Extended Events ,我们可以监控一段时间内的的 SQL Completed 情况,简要介绍下:

1.1 Extended Events 概念:由一系列自动触发的 event 产生性能数据,经过 event engine 的收集,存放到指定的输出文件,以供后续的分析。

1.2 XE 涉及到的动态管理试图 : sys.dm_xe_packages; sys.dm_xe_objects;sys.dm_xe_sessions

1.3 基本用法:

2.3.1 创建一个 Event Session

create event session capture_sql_events

on server

add event sqlserver.sql_statement_completed

(

action(sqlserver.sql_text)

)

add target package0.event_file

(

set filename = 'E:\data_bu\capture_sql_events.xel', metadatafile = 'E:\data_bu\capture_sql_event.xem'

)

go

2.3.2 启用这个 Event session 来收集数据

alter event session capture_sql_events

on server

STATE = start

go

2.3.3 停用这个 Event session

alter event session capture_sql_events

on server

state = stop

go

2.3.4 修改一个 session 来增加或者删除对 Event 的监控

alter event session capture_sql_events on server

add event sqlserver.sql_batch_completed (action(sqlserver.sql_text))

go

2.3.5 查看正在运行的 Event Session

select * from sys.dm_xe_sessions

select * from sys.dm_xe_session_events

2.3.6 查看收集到的统计数据

select top 10 * from dbo.region

go

select * , cast(event_data as xml) as event_data_xml

from sys.fn_xe_file_target_read_file('E:\data_bu\capture_sql_events*.xel',null,null,null)

where event_data like N'%region%'

从结果集我们可以看到,sql_statement_completed这个Event抓到的结果中,包含了Action中我们指定的内容,还包含了其他的一些统计信息:





0





0





0





2





0





6





6





1





0





62





select top 10 * from dbo.region











select top 10 * from dbo.region





我们在Action里面加入对database_name,和plan_handle的捕捉,可以从结果看到又多出来两个元素:

create event session capture_sql_events

on server

add event sqlserver.sql_statement_completed

(

action(sqlserver.sql_text,sqlserver.database_name,sqlserver.plan_handle)

)

add target package0.event_file

(

set filename = 'E:\data_bu\capture_sql_events.xel', metadatafile = 'E:\data_bu\capture_sql_event.xem'

)




0





0





0





2





0





6





6





1





0





62





select top 10 * from dbo.region











06002000448a700f00d62b7a0300000001000000000000000000000000000000000000000000000000000000





lenistest4





select top 10 * from dbo.region





下载本文
显示全文
专题