在 DB2 V9.5 中,新引入的工作负载管理功能( WLM )可以帮助您标识、管理和监视数据服务器的工作负载。本文将重点介绍 DB2 V9.5 关于工作负载管理(WLM)的阈值(THRESHOLD)设置相关的概念,并结合实际的例子帮助大家理解和提高。
阈值( THRESHOLD )
可以通过创建阈值的方式对服务类所使用的资源进行控制,阈值可以根据不同的类型进行创建。阈值提供一种方法,用来控制每种工作能够使用的资源数量。在工作负载管理( WLM )解决方案中,你可以使用阈值来防止系统过载或者资源被滥用现象的发生。通过阈值,你可以直接对特定的资源设置限定,当超过限定时,就会触发特定的动作。
支持的动作有:
STOP EXECUTION:停止违反阈值的相关动作
CONTINUE:继续执行
收集违反阈值的相关动作信息
不管违反阈值的特定动作被停止还是继续执行,你都可以收集该动作的详细信息。当特定动作完成后,其相关信息会被活动的 ACTIVITIES 事件监控器收集到。
每个阈值都有一个应用范围。阈值的作用域定义其可以操作的数据库对象。只有在该阈值范围内发生的动作才会受其影响。阈值的作用域可以是:
数据库(Database)
服务父类(Service superclass )
服务子类(Service subclass )
工作动作(Work action )
工作负载(Workload )
阈值即可以是 predictive ,也可以是 reactive,也就是说,我们可以定义阈值是前触发还是后触发
前触发阈值是在相应的工作开始之前进行检查。数据服务器通过 SQL 编译器得到使用资源的估计值,检查前触发阈值是否会被触发。
后触发阈值是在相应的工作开始之后进行检查的。通过对控制资源的大体运行时间使用估计,来评估是否达到了后触发阈值的边界。运行时间使用估计不是连续获得的,而是在每个(特定工作生命周期中)预先选择的检查点进行获取。
需要注意的是,阈值不是适合所有的语句,比如,阈值不能应用在 COMMIT, ROLLBACK, AVEPOINT 以及 ROLLBACK to SAVEPOINT 等。
你可以使用 CREATE THRESHOLD 创建阈值,使用 ALTER THRESHOLD 修改阈值,还可以使用 DROP THRESHOLD 删除阈值。如果想查询你定义的阈值,可以查询 SYSCAT.THRESHOLDS 系统视图。
下面我们继续在窗口 1 中来创建一个阈值,来限制包含大的查询的服务类,阈值的范围是整个数据库,阈值的边界是当 ESTIMATEDSQLCOST 大于 100000,ESTIMATEDSQLCOST 能够返回优化器分配给 DML 语句相关活动成本的估计值,具体如清单 17 所示:
清单 17 . 在窗口 1 中创建一个阈值,限制包含大查询的服务类
C:\> db2 connect to db2test1 user administrator using passw0rd
数据库连接信息
数据库服务器 = DB2 / NT 9.5.0
SQL 授权标识 = ADMINIST . . .
本地数据库别名 = DB2TEST1
C:\> db2 -tvf createthreshold.sql
ALTER THRESHOLD LargeQuery DISABLE
DB21034E 该命令被当作 SQL 语句来处理,因为它是无效的“命令行处理器”命令。在
SQL 处理期间,它返回:
SQL0204N " LARGEQUERY " 是一个未定义的名称。 SQLSTATE = 42704
DROP THRESHOLD LargeQuery
DB21034E 该命令被当作 SQL 语句来处理,因为它是无效的“命令行处理器”命令。在
SQL 处理期间,它返回:
SQL0204N " LARGEQUERY " 是一个未定义的名称。 SQLSTATE = 42704
CREATE THRESHOLD LargeQuery FOR service class SUPER_CLASS ACTIVITIES
ENFORCEMENT DATABASE WHEN ESTIMATEDSQLCOST > 100000 STOP EXECUTION
DB20000I SQL命令成功完成。
继续在窗口 2 中执行一个大的查询(此时我们的用户是 RHETTE,如果执行查询,该查询会属于 SUPER_CLASS 服务类),这时我们会收到“ SQL4712N 已超过阈值 ‘ LARGEQUERY ’。原因码 = ‘7’。 SQLSTATE = 5U026”的错误信息,这是因为我们执行的查询超过了我们预先定义的边界,具体如清单 18 所示:
清单18 . 在窗口 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 , project , project ,
project
SQL4712N 已超过阈值 " LARGEQUERY "。原因码 = " 7 "。 SQLSTATE = 5U026
接下来我们创建一个新的阈值,用来限制同一条 SQL,并发执行数大于 1,我们继续在窗口 1 中发出 CREATE THRESHOLD 语句,创建新的阈值 MYCUNCURRENT,阈值范围是整个数据库,阈值的边界 CONCURRENTDBCOORDACTIVITIES 大于 1。CONCURRENTDBCOORDACTIVITIES 用来表示某个特定动作的并发执行数。具体如清单 19 所示:
清单 19 . 在窗口 1 中创建一个阈值,限制并发执行数
C:\>db2 -tvf crtThresCurrency.sql
ALTER THRESHOLD MYCUNCURRENT DISABLE
DB21034E 该命令被当作 SQL 语句来处理,因为它是无效的“命令行处理器”命令。在
SQL 处理期间,它返回:
SQL0204N " MYCUNCURRENT " 是一个未定义的名称。 SQLSTATE = 42704
DROP THRESHOLD MYCUNCURRENT
DB21034E 该命令被当作 SQL 语句来处理,因为它是无效的“命令行处理器”命令。在
SQL 处理期间,它返回:
SQL0204N " MYCUNCURRENT " 是一个未定义的名称。 SQLSTATE = 42704
CREATE THRESHOLD MYCUNCURRENT FOR SERVICE CLASS subclass_db2admin
UNDER super_class ACTIVITIES ENFORCEMENT DATABASE WHEN CONCURRENTDBCOORDACTIVITIES > 1
STOP EXECUTION
DB20000I SQL命令成功完成。
命令成功完成。我们继续在窗口 2 中用 DB2ADMIN 用户连上示例数据库 DB2TEST1,具体如清单 20 所示:
清单20 . 在窗口 2 中执行一个简单查询
C:\> db2 connect reset
DB20000I SQL命令成功完成。
C:\> db2 connect to db2test1 user db2admin using passw0rd
数据库连接信息
数据库服务器 = DB2 / NT 9.5.0
SQL 授权标识 = DB2ADMIN
本地数据库别名 = DB2TEST1
命令成功完成。我们继续在窗口 3 中用 DB2ADMIN 用户连上示例数据库 DB2TEST1,基本上同时在窗口 2 和窗口 3 执行一个同样的查询,会发现窗口 2 执行成功,窗口3执行失败,报“ SQL4712N 已超过阈值 ‘MYCUNCURRENT’。原因码 = ‘6"。 ’SQLSTATE = 5U026”错误,这是由于在窗口2执行完这条语句后,几乎同时在窗口 3 执行(此时窗口 2 中的查询还没完成),并发数为 2,超过了我们预定义的阈值边界。具体如清单 21 所示:
清单 21-1 . 在窗口 2 中执行一个简单查询
C:\> db2 select count ( * ) from rhette.project , rhette.project , rhette.project ,
rhette.project , rhette.project
1
- - - - - - - - - - - - - - - - - - - - - -
3200000
1 条记录已选择。
清单 21-2 . 在窗口 3 中执行同一个简单查询
C:\> db2 select count ( * ) from rhette.project , rhette.project , rhette.project ,
rhette.project , rhette.project
SQL4712N 已超过阈值 " MYCUNCURRENT "。原因码 = " 6 "。 SQLSTATE = 5U026
从上面两个例子我们可以看到,WHEN 后可以跟不同的阈值谓词( threshold-predicate ),阈值谓词用来指定阈值的条件,可以是以下选项:
TOTALDBPARTITIONCONNECTIONS > integer-value
这个条件定义了在一个数据库分区上可以同时运行的协调器( coordinator )连接的数量上限。条件值可以是任何正整数,包括零(如果违反,则会报 SQLSTATE 42820 )。零的意思是所有新的协调器连接将被阻止连接。所有当前运行或当前队列中的连接都将继续,不会被阻止。这个条件的定义域( definition domain )必须是数据库( DATABASE ),而且其执行范围( enforcement scope )必须是分区( PARTITION ),如果违反了,将报 SQLSTATE 5U037 错误,阈值无法创建,因为它违反了限制。
TOTALSCPARTITIONCONNECTIONS > integer-value
这个条件定义了在一个数据库分区上特定的服务父类中可以同时运行的协调器( coordinator )连接的数量上限。条件值可以是任何正整数,包括零(如果违反,则会报 SQLSTATE 42820 )。零的意思是新的连接将被阻止加入服务类中。所有当前运行或当前队列中的连接都将继续,不会被阻止。这个条件的定义域( definition domain )必须是服务父类( SERVICE SUPERCLASS ),而且其执行范围( enforcement scope )必须是分区( PARTITION ),如果违反了,将报 SQLSTATE 5U037 错误,阈值无法创建,因为它违反了限制。
AND QUEUEDCONNECTIONS > integer-value or AND QUEUEDCONNECTIONS UNBOUNDED
当允许的协调器连接最大值被超过时,用指定的队列大小(缓存这些连接)。条件值可以是任何正整数,包括零(如果违反,则会报 SQLSTATE 42820)。零的意思是没有协调器连接将被放入队列中。指定 UNBOUNDED,意味着将把所有超过协调器连接最大值的连接放入到队列中,并且 threshold-exceeded-actions 不会被执行。默认值是零。
CONNECTIONIDLETIME > integer-value (DAY | DAYS | HOUR | HOURS | MINUTE | MINUTES )
这个条件定义了数据库管理器允许一个连接保持空闲状态的时间上限。条件值可以是任何非零的正整数(如果违反,则会报 SQLSTATE 42820 )。使用一个合法的持续时间关键字,为 integer-value 指定适当的时间单位。这个条件的定义域( definition domain )必须是数据库( DATABASE )或服务父类( SERVICE SUPERCLASS ),而且其执行范围( enforcement scope )必须是数据库( DATABASE ),如果违反了,将报 SQLSTATE 5U037 错误,阈值无法创建,因为它违反了限制。这个条件将在协调器数据库分区上作为逻辑条件被强制执行。
因为这个阈值的最小粒度是五分钟,指定的值将围绕着五分钟的非零倍数。万一指定的值不是五分钟的非零倍数(超过或小于),那么将自动选择一个最接近五分钟非零倍数的整数值。这个阈值的最大值是 2 147 483 400 秒。任何指定的值(使用天、小时、分钟或者秒),如果其换算成秒的值大于 2 147 483 400 秒,则其将被截断为 2 147 483 400 秒。修改 DB2CHECKCLIENTINTERVAL 注册表变量引起检查频率变低可能会影响这个阈值的粒度。
CONCURRENTWORKLOADOCCURRENCES > integer-value
这个条件定义在每个数据库分区上运行的并发工作负载的数量上限。这个条件值可以被设成任何非零整数值(如果违反,则会报 SQLSTATE 42820 )。条件的定义域( definition domain )必须是 WORKLOAD,如果违反了,将报 SQLSTATE 5U037 错误,阈值无法创建,因为它违反了限制。
CONCURRENTWORKLOADACTIVITIES > integer-value
这个条件定义了每个数据库分区上工作负载的并发协调器活动和嵌套活动的数量上限。这个条件值可以是任何非零正整数值(如果违反,则会报 SQLSTATE 42820 )。条件的执行范围( enforcement scope )必须是 WORKLOAD OCCURRENCE,如果违反了,将报 SQLSTATE 5U037 错误,阈值无法创建,因为它违反了限制。
CONCURRENTDBCOORDACTIVITIES > integer-value
这个条件定义在所有的数据库分区上指定的作用域中可以并发运行的数据库协调器活动( database coordinator activities )的数量上限。条件值可以是任何正整数,包括零(如果违反,则会报 SQLSTATE 42820 )。零的意思是任何新的数据库协调器活动将被阻止执行。所有当前运行或当前队列中的数据库协调器活动都将继续,不会被阻止。这个条件的定义域( definition domain )必须是数据库( DATABASE ),工作动作( WORK ACTION ),服务父类( SERVICE SUPERCLASS ),或者服务子类( SERVICE SUBCLASS ),而且其执行范围( enforcement scope )必须是数据库( DATABASE ),如果违反了,将报 SQLSTATE 5U037 错误,阈值无法创建,因为它违反了限制。
AND QUEUEDACTIVITIES > integer-value or AND QUEUEDACTIVITIES UNBOUNDED
当允许的数据库协调器活动( database coordinator activities )最大值被超过时,用指定的队列大小(缓存这些数据库协调器活动)。条件值可以是任何正整数,包括零(如果违反,则会报 SQLSTATE 42820 )。零的意思是没有数据库协调器活动将被放入队列中。指定 UNBOUNDED,意味着将把所有超过数据库协调器活动最大值的活动放入到队列中,并且 threshold-exceeded-actions 不会被执行。默认值是零。
ESTIMATEDSQLCOST > bigint-value
这个条件定义了一个活动的优化器分配成本的上限。条件值可以是任何非零正整数(如果违反,则会报 SQLSTATE 42820)。这个条件的定义域( definition domain )必须是数据库( DATABASE ),工作动作( WORK ACTION ),服务父类( SERVICE SUPERCLASS ),或者服务子类( SERVICE SUBCLASS ),而且其执行范围( enforcement scope )必须是数据库( DATABASE ),如果违反了,将报 SQLSTATE 5U037 错误,阈值无法创建,因为它违反了限制。这个条件在协调器数据库分区上是被强制执行的。被这个条件跟踪的活动有:
DML协调器活动
那些被用户逻辑调用的嵌套DML活动。因此,那些可以被数据库管理器初始化的DML活动(比如,实用程序,存储过程,嵌入式 SQL 等)都不会被这个条件跟踪(除非他们的开支是被包含在他们的调用者评估上的,也就是间接被跟踪)。
SQLROWSRETURNED > integer-value
这个条件定义了返回给(应用服务器上的)应用客户端的行数上限。条件值可以是任何非零正整数(如果违反,则会报 SQLSTATE 42820 )。这个条件的定义域( definition domain )必须是数据库( DATABASE ),工作动作( WORK ACTION ),服务父类( SERVICE SUPERCLASS ),或者服务子类( SERVICE SUBCLASS ),而且其执行范围( enforcement scope )必须是数据库( DATABASE ),如果违反了,将报 SQLSTATE 5U037 错误,阈值无法创建,因为它违反了限制。这个条件在协调器数据库分区上是被强制执行的。被这个条件跟踪的活动有:
DML 协调器活动;
那些源自用户逻辑嵌套 DML 活动。因此,那些可以被数据库管理器初始化的 DML 活动(比如,实用程序,存储过程,嵌入式 SQL 等)都不会被这个条件跟踪。
在一个存储过程内部的返回结果集被分别视同为独立的活动。没有存储过程返回行数的集合限制。
ACTIVITYTOTALTIME > integer-value ( DAY | DAYS | HOUR | HOURS | MINUTE | MINUTES )
这个条件定义数据库管理器允许一个特定的活动执行的总时间上限,包括这个活动排队的时间。条件值可以是任何非零正整数(如果违反,则会报 SQLSTATE 42820 )。使用一个合法的持续时间关键字,为 integer-value 指定适当的时间单位。这个条件的定义域( definition domain )必须是数据库( DATABASE )或服务父类( SERVICE SUPERCLASS ),而且其执行范围( enforcement scope )必须是数据库( DATABASE ),如果违反了,将报 SQLSTATE 5U037 错误,阈值无法创建,因为它违反了限制。这个条件将在协调器数据库分区上作为逻辑条件被强制执行。
因为这个阈值的最小粒度是五分钟,指定的值将围绕着五分钟的非零倍数。万一指定的值不是五分钟的非零倍数(超过或小于),那么将自动选择一个最接近五分钟非零倍数的整数值。这个阈值的最大值是 2 147 483 400 秒。任何指定的值(使用天、小时、分钟或者秒),如果其换算成秒的值大于 2 147 483 400 秒,则其将被截断为 2 147 483 400 秒。修改 DB2CHECKCLIENTINTERVAL 注册表变量引起检查频率变低可能会影响这个阈值的粒度。
SQLTEMPSPACE > integer-value ( K | M | G )
这个条件定义在任何一个数据库分区上系统临时表空间的上限大小。条件值可以是任何非零正整数(如果违反,则会报 SQLSTATE 42820 )。
如果指定了 integer-value K (大小或小写) , 则最大值是 integer-value 乘以 1024;如果指定了 integer-value M (大小或小写) , 则最大值是 integer-value 乘以 1 048 576;如果指定了 integer-value G (大小或小写) , 则最大值是 integer-value 乘以 1 073 741 824。
这个条件的定义域( definition domain )必须是数据库( DATABASE )或服务父类( SERVICE SUPERCLASS ),而且其执行范围( enforcement scope )必须是分区( PARTITION ),如果违反了,将报 SQLSTATE 5U037 错误,阈值无法创建,因为它违反了限制。这个条件将在协调器数据库分区上作为逻辑条件被强制执行。以下活动将被这个条件跟踪:
DML 协调器活动和相应的子代理工作( subsection execution );
那些源自用户逻辑嵌套 DML 活动和他们相应的子代理工作( subsection execution )。因此,那些可以被数据库管理器初始化的 DML 活动(比如,实用程序,存储过程,嵌入式 SQL 等)都不会被这个条件跟踪。
最后,我们继续在窗口 1 删除刚才定义的两个阈值 MYCUNCURRENT 和 LargeQuery,同样的,在删除之前,需要先把阈值变成不可用。具体如清单 22 所示:
清单22 . 在窗口 1 中删除阈值
C:\> db2 - tvf dropThresholds.sql
ALTER THRESHOLD MYCUNCURRENT DISABLE
DB20000I SQL命令成功完成。
DROP THRESHOLD MYCUNCURRENT
DB20000I SQL命令成功完成。
ALTER THRESHOLD LargeQuery DISABLE
DB20000I SQL命令成功完成。
DROP THRESHOLD LargeQuery
DB20000I SQL命令成功完成。
命令成功完成,这样我们就删除了刚才我们定义的两个阈值。