取消一个数据库活动
在我们生产系统中,可能存在一些正在运行的大 SQL,这些活动消耗了太多的资源。如果我们想停止这些正在执行的活动,可以调用 WLM_CANCEL_ACTIVITY() 存储过程,如果想捕获一个活动的详细信息可以调用 WLM_CAPTURE_ACTIVITY_IN_PROGRESS() 存储过程,如果想收集和重置一个工作负载对象的统计信息可以调用 WLM_COLLECT_STATS()。这些存储过程的具体信息如下:
WLM_CANCEL_ACTIVITY ( application_handle , uow_id , activity_id ) .
可以使用这个存储过程来取消一个正在运行或者正在排队的活动。对某个特定的活动来说,我们可以使用应用程序句柄、工作单元标识和活动标识来唯一标识。使用这个存储过程,我们可以取消任何类型的活动。当这个存储过程执行后,被取消的特定活动将收到 SQL4725N 的错误信息。
WLM_CAPTURE_ACTIVITY_IN_PROGRESS ( application_handle , uow_id , activity_id ) .
我们可以使用这个存储过程捕获特定活动的详细信息,并发送给活动事件监控器。这个存储过程会立即发送信息,而不是等待该活动完成再发送。
WLM_COLLECT_STATS ( ) .
使用这个存储过程可以用来收集和重置工作负载对象统计信息。所有跟踪收集的服务类、工作负载、阈值队列和工作动作集统计信息,都会发送给活动统计信息事件监控器(如果存在)并重置。如果没有活动统计信息事件监控器,那么统计信息将只重置,而不收集。
以上存储过程调用中需要的应用程序句柄( application_handle )、工作单元标识( uow_id )、活动标识( activity_id ),可以通过调用表函数 WLM_GET_WORKLOAD_OCCURRENCE_ACTIVITIES 来获得。
我们继续在窗口 1 用 ADMINISTRATOR 用户连接示例数据库 DB2TEST1,在窗口 2 用 RHETTE 用户连接示例数据库 DB2TEST1,并在窗口 2 中执行一个大的查询,具体如清单 23 所示:
清单23 . 在窗口 2 中执行一个大的查询
C:> db2 connect to db2test1 user rhette using passw0rd
数据库连接信息
数据库服务器 = DB2 / NT 9.5.0
SQL 授权标识 = DB2ADMIN
本地数据库别名 = DB2TEST1
C:> db2 select count ( * ) from rhette.project , rhette.project , rhette.projec
t , rhette.project , rhette.project , rhette.project
在窗口 2 中的大型查询完成之前,在窗口 1 中调用表函数 WLM_GET_WORKLOAD_OCCURRENCE_ACTIVITIES,来获得窗口 2 中正在进行的大型查询的应用程序句柄( application_handle )、工作单元标识( uow_id )、活动标识( activity_id )信息,在获得这些信息后,如果还想查看更详细的信息,可以根据应用程序句柄通过 LIST APPLICATIONS SHOW DETAIL 来查看。具体如清单 24 所示:
清单 24 . 在窗口 1 中调用表函数 WLM_GET_WORKLOAD_OCCURRENCE_ACTIVITIES
C:> db2 - tvf get_wkld_activities.txt
SELECT T.APPLICATION_HANDLE , T.UOW_ID , T.ACTIVITY_ID , T.ACTIVITY_TYPE ,
T.ACTIVITY_TYPE , T.ACTIVITY_STATE , T.LOCAL_START_TIME FROM
TABLE( WLM_GET_WORKLOAD_OCCURRENCE_ACTIVITIES ( CAST ( NULL AS BIGINT ) , -2 ) ) T
ORDER BY T.LOCAL_START_TIME
APPLICATION
_HANDLE UOW_ID ACTIVITY_ID ACTIVITY_TYPE ACTIVITY_STATE
LOCAL_START_TIME
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
80 7 1 READ_DML EXECUTING
2008-01-02-17.01.25.306889
81 10 1 READ_DML EXECUTING
2008-01-02-17.01.32.253342
2 条记录已选择。
接下来我们来看一下如何取消窗口 2 中正在进行的大型查询,在窗口 1 中调用 WLM_CANCEL_ACTIVITY 存储过程,输入参数使用在清单 24 中获得的应用程序句柄( application_handle )、工作单元标识( uow_id )、活动标识( activity_id ),具体如清单 25 所示:
清单25 . 在窗口 1 中调用 WLM_CANCEL_ACTIVITY 存储过程取消特定活动
C:> db2 call WLM_CANCEL_ACTIVITY( 80 , 7 , 1 )
返回状态 = 0
此时窗口 2 中正在执行的大型查询会收到“ SQL4725N 已取消该活动。 SQLSTATE = 57014 ”的相关信息,具体如清单 26 所示:
清单 26 . 在窗口 2 中获得特定活动取消的相关信息
C:> db2 select count ( * ) from rhette.project , rhette.project , rhette.projec
t , rhette.project , rhette.project , rhette.project
1
- - - - - - - - - - - - - - - - -
SQL4725N 已取消该活动。 SQLSTATE = 57014
工作类( WORK CLASS )和工作操作( WORK ACTION )
除了使用工作所在的数据库连接属性标识数据库活动以外,你还可以通过创建可选的工作类,通过基于工作的类型来标识数据库活动。这些类型属性可以是 READ , WRITE , DML , DDL , LOAD , CALL ,ALL。工作类型属性具体的介绍如下:
READ
此属性对应的活动包括以下语句:
所有的 SELECT 或者 SELECT INTO 语句,并且语句中不包含 DELETE , INSERT , MERGE , UPDATE 语句;
所有的 VALUES INTO 语句;
所有的 XQuery 语句。
WRITE
此属性对应的活动包括以下语句:
所有的 UPDATE 语句;
所有的 DELETE 语句;
所有的 INSERT 语句;
所有的 MERGE 语句;
所有的包含 DELETE, INSERT, UPDATE 的SELECT 语句;
所有的 XQuery 语句。
CALL
此属性对应的活动包括所有的 CALL 语句。如果想让工作类包含一个 CALL 语句 ,其工作类型可以是 CALL 或者 ALL。
DML
所有在 READ 和 WRITE 中出现的语句都是 DML 语句。
DDL
此属性对应的活动包括以下语句:
所有的 ALTER 语句;
所有的 CREATE 语句;
所有的 COMMENT 语句;
所有的 DECLARE GLOBAL TEMPORARY TABLE 语句;
所有的 DROP 语句;
所有的 FLUSH PACKAGE CACHE 语句;
所有的 GRANT 语句;
所有的 REFRESH TABLE 语句;
所有的 RENAME 语句;
所有的 REVOKE 语句;
所有的 SET INTEGRITY 语句;
LOAD
此属性对应的活动包括所有的 LOAD 操作。
ALL
此属性对应的活动可以是以上属性中出现任意一个活动。
工作操作( WORK ACTION )是一个用来控制某一种类型工作所对应数据库活动的方法。简单的说就是,当数据库活动满足已经定义好的工作类( WORK CLASS )所涉及的范围时,就会触发相应的工作操作( WORK ACTION )。
下面我们在窗口 1 中,发出 CREATE WORK CLASS SET 命令,创建工作类集 myquery,其下包含三个工作类,分别是针对小型查询的 smallquery,针对中型查询的 mediumquery 以及针对大型查询的 largequery,工作类型都是 DML,具体如清单 27 所示:
清单 27 . 在窗口 1 中创建工作类集
C:> db2 connect to db2test1 user administrator using passw0rd
数据库连接信息
数据库服务器 = DB2 / NT 9.5.0
SQL 授权标识 = ADMINIST . . .
本地数据库别名 = DB2TEST1
C:> db2 - tvf crtWorkClassSet.sql
drop work class set myquery
DB21034E 该命令被当作 SQL 语句来处理,因为它是无效的“命令行处理器”命令。在
SQL 处理期间,它返回:
SQL0204N " MYQUERY " 是一个未定义的名称。 SQLSTATE = 42704
create work class set myquery (
work class smallQuery work type dml
for timeroncost from 1 to 1000 ,
work class mediumQuery work type dml
for timeroncost from 1000 to 100000 ,
work class largeQuery work type dml
for timeroncost from 100000 tounbounded )
DB20000I SQL命令成功完成。
命令成功完成,这样我们就创建了一个工作类集和三个工作类。工作类 smallQuery 包含的范围是:当一个特定的 DML 活动,其估计成本大于 1 timeron 且小于等于 1000 timerons。需要注意的是,成本是由 CPU 成本(以指令数计)和 I/O(以寻道数和页的转换数计)的组合得出的。成本的单位是 timeron。timeron 不直接等于任何实际的所用时间,只是给出粗略估计的资源(成本)。工作类 mediumQuery 包含的范围是:当一个特定的 DML 活动,其估计成本大于 1000 timeron 且小于等于 100000 timerons。工作类 largeQuery 包含的范围是:当一个特定的 DML 活动,其估计成本大于 100000 timeron ,没有上限。
下面我们继续在窗口 1 中创建相应的工作动作集以及工作动作。发出 CREATE WORK ACTION SET 命令,创建工作动作集 MYWORKACTION,并创建面向工作类 smallQuery 的工作动作 smallQueryAction ,面向工作类 mediumQuery 的工作动作 mediumQueryAction,面向工作类 largeQuery 的工作动作 largeQueryAction,具体如清单 28 所示:
清单 28 . 在窗口 1 中创建工作动作集
C:> db2 - tvf crtWorkActionSet.sql
alter work action set MYWORKACTION
alter smallQueryAction disable
alter mediumQueryAction disable
alter largeQueryAction disable
DB20000I SQL命令成功完成。
drop work action set MYWORKACTION
DB20000I SQL命令成功完成。
create work action set MYWORKACTION for database using work class set MYQUERY
( work action smallQueryAction on work class smallQuery
count activity,
work action mediumQueryAction on work class mediumQuery
collect activity data with details and values ,
work action largeQueryAction on work class largeQuery
when concurrentdbcoordactivities > 1 and queuedactivities > 1 stop execution )
DB20000I SQL命令成功完成。
命令成功完成。这样我们就创建了 1 个工作动作集和 3 个工作动作。
工作动作集 MYWORKACTION 对应的工作类集 MYQUERY。工作动作 smallQueryAction 对应的工作类是 smallQuery,且指定了 count activity 选项,含义是指定工作类 smallQuery 所对应的数据库活动,只要其任何一个在运行,则这个工作类的计数器就会累积增长。
工作动作 mediumQueryAction 对应的工作类是 mediumQuery,且指定了 collect activity data with details and values 选项,collect activity data 的含义是当工作类 mediumQuery 相关的每一个活动完成后,都将其数据发送给相关合适的事件监控器;with details 的含义是当相关的活动完成后,还要把相关的语句和编译环境发送给相关的时间监控器;and values 的含义是那些活动相关的输入数据值也发送给相关的事件监控器。
工作动作 largeQueryAction 对应的工作类是 largeQuery,且指定了 when concurrentdbcoordactivities > 1 and queuedactivities > 1 stop execution 选项,含义是当并发的数据库协调器活动( database coordinator activities )大于 1 时,数据库管理器将对活动进行排队,对后来的数据库协调器活动(比如一个查询)放入排队队列。并且当排队的活动也大于1时,数据库活动将不允许执行。
下面我们继续在窗口 2 中用 RHETTE 用户连接示例数据库 DB2TEST1,并执行两个查询,在窗口 3 中用 RHETTE 用户连接示例数据库 DB2TEST1 ,也执行两个相同的查询,然后在窗口 2 中通过调用表函数 WLM_GET_WORK_ACTION_SET_STATS ,查看工作动作集的状态,具体如清单 29 所示:
清单 29. 在窗口 2 中执行两个查询
C:> db2 connect to db2test1 user rhette using passw0rd
数据库连接信息
数据库服务器 = DB2 / NT 9.5.0
SQL 授权标识 = RHETTE
本地数据库别名 = DB2TEST1
C:> db2 select count ( * ) from project , project , project
1
- - - - - - - - - - - - - - - - - - - - - -
8000
1 条记录已选择。
C:> db2 select count ( * ) from project , project , project , project , project
1
- - - - - - - - - - - - - - - - - - - - - -
3200000
1 条记录已选择。
清单 30. 在窗口 3 中执行两个查询
C:> db2 connect to db2test1 user rhette using passw0rd
数据库连接信息
数据库服务器 = DB2 / NT 9.5.0
SQL 授权标识 = RHETTE
本地数据库别名 = DB2TEST1
C:> db2 select count ( * ) from project , project , project
1
- - - - - - - - - - - - - - - - - - - - - -
8000
1 条记录已选择。
C:> db2 select count ( * ) from project , project , project , project , project , project
1
- - - - - - - - - - - - - - - - - - - - - -
64000000
1 条记录已选择。
清单 31. 在窗口 2 中查看工作动作集的状态
C:> db2 select substr( work_action_set_name , 1 , 18 ) as work_action_set_name ,
substr ( char ( dbpartitionnum ) , 1 , 4 ) as part ,
substr ( work_class_name , 1 , 15 ) as work_class_name , last_reset ,
substr ( char ( act_total ) , 1 , 14 ) as total_wlo_acts from
table ( WLM_GET_WORK_ACTION_SET_STATS ( cast ( null as varchar ( 128 ) ) , -2 ) )
as wasstats order by work_action_set_name , work_class_name , part
WORK_ACTION_SET_NAME PART WORK_CLASS_NAME LAST_RESET TOTAL_WLO_ACTS
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MYWORKACTION 0 * 2008-01-03-14.26.15.293798 0
MYWORKACTION 0 LARGEQUERY 2008-01-03-14.26.15.293791 1
MYWORKACTION 0 MEDIUMQUERY 2008-01-03-14.26.15.293754 1
MYWORKACTION 0 SMALLQUERY 2008-01-03-14.26.15.293717 3
4 条记录已选择。
命令成功完成。
接下来我们看一下如果同时在三个窗口执行同样的大型 SQL,会出现什么样的状况。首先在窗口 1 中执行一个大型查询 SQL,同时在窗口 2、3 也同时执行同样的大型 sql,在窗口 3 会报“ SQL4712N 已超过阈值 =‘SQL080103142608430’。原因码 = ‘6’。 SQLSTATE = 5U026”错误。窗口 1 和窗口 2 最终将查询出结果集来。具体如清单 30 所示:
清单 32. 在窗口 1 中执行大型查询
C:> db2 connect to db2test1 user rhette using passw0rd
数据库连接信息
数据库服务器 = DB2 / NT 9.5.0
SQL 授权标识 = RHETTE
本地数据库别名 = DB2TEST1
C:> db2 select count ( * ) from project , project , project , project , project , project
1
- - - - - - - - - - - - - - - - - - - - - -
64000000
1 条记录已选择。
清单 33. 在窗口 2 中执行大型查询
C:> db2 select count ( * ) from project , project , project , project , project , project
1
- - - - - - - - - - - - - - - - - - - - - -
64000000
1 条记录已选择。
清单 34. 在窗口 3 中执行大型查询
C:> db2 select count ( * ) from project , project , project , project , project ,
project
SQL4712N 已超过阈值 " SQL080103142608430 "。原因码 = " 6 "。 SQLSTATE = 5U026
总结工作负载管理( WLM )
通过上面的讲述和具体的例子,我们可以发现使用 DB2 V9.5 工作负载管理( WLM )可以更好地控制系统资源,增加了可预测性和稳定性。我们可以定义一个混合的工作负载来满足复杂的场景需求。针对越来越复杂的数据库活动,我们可以预定义一组工作负载,并使用相应的服务类、阈值、工作类和工作动作来标识数据库活动并将它们隔离在自己的执行环境中,并给其分配达到我们设定目标所需要的适当资源。在环境或服务类中,您可以显式管理系统资源,以便较重要的资源可供较高优先级的工作使用,并可以控制或消除与较低优先级工作的争用情况。
当我们的生产系统在高峰期时,增加的数据库活动会影响数据库的性能,通过使用工作负载管理( WLM ),我们可以预先确定适当的资源分配、活动的优先级划分和排队选项来高效地处理工作,从而可以平滑高峰工作负载。在您定义这些指示后,数据服务器使用它们来分配资源和划分工作的优先级。例如,您可以使工作远离流氓查询的影响,这些查询使用过量的数据库资源,因此会对系统上运行的其他查询带来负面影响并可能会影响整个数据库。通过使用阈值,您可以使用许多不同特征(如执行时间或系统临时表空间使用量)来定义系统内可接受的查询行为,并定义对不按要求执行的任何查询要执行哪些操作。这些操作包括收集关于查询的详细信息的功能以及自动取消查询的功能。
另外,通过使用 DB2 V9.5 新增的许多表函数,我们可以动态的监视数据库活动,可以让我们清楚哪个工作当前正在系统上运行、它在分区上的分布情况以及是否有特定的活动可能导致数据服务器上发生资源争用情况。 |