注:本文不是讲解Db2 Activity event monitor,只是一个用法实践。要了解Activity event monitor,请参考 https://www.ibm.com/docs/en/db2/11.5?topic=events-activity-event-monitoring
。
环境
- Red Hat Enterprise Linux release 8.8 (Ootpa)
- Db2 MPP V2 11.5.8
准备
Activity event monitor
在Db2中创建一个Activity event monitor(其table所在的table space跨所有DB member):
create event monitor <XXX> for activities write to table
activity (table IBM_RTMON.activity_<timestamp>)
, activitystmt (table IBM_RTMON.activity_stmt_<timestamp>)
, activitymetrics (table IBM_RTMON.activity_metrics_<timestamp>)
manualstart
其中:
activity
:包含event信息activity_stmt
:包含statement信息activity_metrics
:包含metrics信息,如ROWS_INSERTED
将其激活:
set event monitor <XXX> state 1
Table
创建table T1
和 T2
:
create table bluadmin.t1(c1 int, c2 int);
create table bluadmin.t2(c1 int, c2 int);
向 T1
插入一些数据。
[db2inst1@dashmpp-head-0 - Db2wh ~]$ db2 "select count(*) from bluadmin.t1"
1
---------------------------------
160.
1 record(s) selected.
Workload
假设对 T1
和 T2
的DML操作都属于 SYSDEFAULTUSERWORKLOAD
workload。
Alter workload SYSDEFAULTUSERWORKLOAD
:
alter workload SYSDEFAULTUSERWORKLOAD COLLECT ACTIVITY DATA ON COORDINATOR MEMBER WITH DETAILS
注:默认情况下,workload的activity不会被Activity event monitor收集。
可以查看 syscat.workloads
视图:
[db2inst1@dashmpp-head-0 - Db2wh ~]$ db2 "select workloadid, cast(workloadname as varchar(30)) as workloadname, collectactdata, collectactpartition from syscat.workloads order by workloadid"
WORKLOADID WORKLOADNAME COLLECTACTDATA COLLECTACTPARTITION
----------- ------------------------------ -------------- -------------------
1 SYSDEFAULTUSERWORKLOAD D C
2 SYSDEFAULTADMWORKLOAD D C
3 DSM_WORKLOAD N C
4 CONSOLE_WORKLOAD N C
5 WL_0 D C
6 WL_1 D C
......
对 COLLECTACTDATA
和 COLLECTACTPARTITION
的解释,详见 https://www.ibm.com/docs/en/db2/11.5?topic=views-syscatworkloads
。
问题
清空表 T2
,然后将 T1
的数据插入 T2
:
insert into bluadmin.t2 (select * from bluadmin.t1)
Activity event monitor会产生一个event,并在相应的table里产生一些数据。
先来看看 activity_stmt
表:
select partition_number, stmt_text, *
from ibm_rtmon.activity_stmt_1701671110833
where cast(stmt_text as varchar(100)) like 'insert into t2%';
注意:这里 like
条件不要写成 '%insert into t2%'
,否则把其它无关SQL(比如本条SQL也包含 insert into t2
)也查到了。
说明已经产生event了,然后再根据其信息比如 appl_id
来查找 activity_metrics
表:
select partition_number, rows_inserted, *
from ibm_rtmon.activity_metrics_<timestamp>
where appl_id = '<XXXXXX>'
在结果中只有1条记录,其 partition_number
为0,而 rows_inserted
也是0。
明明插入了160条记录,怎么在Activity event monitor产生的event里, rows_inserted
是0呢?
分析
这是因为,workload SYSDEFAULTUSERWORKLOAD
的 collectactpartition
是 C
,也就是 ON COORDINATOR MEMBER
,所以 activity_metrics
表只产生了coordinator member所对应的那条记录,而在此member上实际并没有插入数据,所以 rows_inserted
是0。
解决方法
把workload SYSDEFAULTUSERWORKLOAD
的 collectactpartition
改为 D
,也就是 ON ALL MEMBERS
:
alter workload SYSDEFAULTUSERWORKLOAD COLLECT ACTIVITY DATA ON ALL MEMBERS WITH DETAILS
然后查看 syscat.workloads
,确认修改成功:
[db2inst1@dashmpp-head-0 - Db2wh ~]$ db2 "select workloadid, cast(workloadname as varchar(30)) as workloadname, collectactdata, collectactpartition from syscat.workloads where workloadid = 1"
WORKLOADID WORKLOADNAME COLLECTACTDATA COLLECTACTPARTITION
----------- ------------------------------ -------------- -------------------
1 SYSDEFAULTUSERWORKLOAD D D
1 record(s) selected.
现在,将 T2
表清空,再重新插入一些数据,这回在 activity_metrics
表里就会产生多条记录:
把各个member的 rows_inserted
值加起来,正好等于插入的数据总数160。
可见,要用 activity_metrics
表收集metrics,需要将对应的workload设置为 COLLECT ACTIVITY DATA ON ALL MEMBERS
,不能是 COLLECT ACTIVITY DATA ON COORDINATOR MEMBER
,否则只能收集到coordinator member上的metric。
其它
对于一条插入语句:
- 若workload指定为
COLLECT ACTIVITY DATA ON COORDINATOR MEMBER
,则activity
、activity_stmt
、activity_metrics
都只产生一条记录。 - 若workload指定为
COLLECT ACTIVITY DATA ON ALL MEMBERS
,则activity
和activity_metrics
会产生多条记录,每个member对应一条记录。而activity_stmt
只产生一条记录。
要收集 rows_inserted
信息,就要把workload指定为 COLLECT ACTIVITY DATA ON ALL MEMBERS
,同时,不能以 partition_number
作为三个table的连接条件。
正确做法是:
- 如果只想要总的信息,则先把
activity_metrics
表里各个member的rows_inserted
信息汇总起来,再和其它表join - 如果要看各个member的详细信息,则收集
activity_metrics
表里各个member的rows_inserted
信息,再和其它表join
总之不要以 partition_number
作为和 activity_stmt
table的连接条件,而只以 appl_id
、 uow_id
、 activity_id
、 activity_secondary_id
作为连接条件。比如:
with m as (select appl_id, uow_id, activity_id, activity_secondary_id, sum(rows_inserted) as rows_inserted
from ibm_rtmon.activity_metrics_<timestamp>
group by appl_id, uow_id, activity_id, activity_secondary_id)
select s.stmt_text, m.rows_inserted
from ibm_rtmon.activity_<timestamp> a
join ibm_rtmon.activity_stmt_<timestamp> s
on a.appl_id = s.appl_id and a.uow_id = s.uow_id and a.activity_id = s.activity_id and a.activity_secondary_id = s.activity_secondary_id
join m
on a.appl_id = m.appl_id and a.uow_id = m.uow_id and a.activity_id = m.activity_id and a.activity_secondary_id = m.activity_secondary_id
运行结果如下:
activity
表的 details_xml
字段
activity
表有一个 details_xml
字段,里面包含了很多信息,比如 rows_inserted
。把workload设置为 COLLECT ACTIVITY DATA ON ALL MEMBERS
,activity
表会为每个member产生一条记录,然后也可以从 details_xml
字段获取 rows_inserted
,每个member上获取的是各自的 rows_inserted
值。例如:
select a.partition_number, s.stmt_text, xml.rows_inserted from ibm_rtmon.activity_<timestamp> a
join ibm_rtmon.activity_stmt_<timestamp> s
on a.appl_id = s.appl_id and a.uow_id = s.uow_id and a.activity_id = s.activity_id and a.activity_secondary_id = s.activity_secondary_id
, XMLTABLE
(
XMLNAMESPACES( default 'http://www.ibm.com/xmlns/prod/db2/mon' ),
'$metrics/activity_metrics' PASSING XMLPARSE( DOCUMENT a.details_xml ) as "metrics" COLUMNS
ROWS_INSERTED BIGINT PATH'rows_inserted'
) as xml
where stmt_text like 'insert into t2%';
可见,各个member上的 rows_inserted
总和也是160。
参考
https://www.ibm.com/docs/en/db2/11.5?topic=views-syscatworkloads
https://www.ibm.com/docs/en/db2/11.5?topic=statements-alter-workload#sdx-synid_alter-collect-activity-data-clause
https://www.ibm.com/docs/en/db2/11.5?topic=events-activity-event-monitoring