3/12/2007

DB2脚本收集

感谢高卫明高老的建议, 我们做这样一个专题出来। 便于大家检索।

贴出来的最好是测试好的脚本, 可以是伪码, 或者近似能够运行的脚本।

4 comments:

Yonghang Wang 说...

Question:
今天在整理数据库实体的时候,发现有些分区表空间使用的不是很均匀,如果按照表一个一个查,是很费时间的,能不能有更好的机制,把哪些空间使用不均匀的表找出来呢?

Answer:

要找表空间中哪些表不均匀的问题在DB2里的确只能用select语句对每个表去查一遍,至今好像没有发现更好的办法。但用select语句其实也并不麻烦,编写一个脚本跑一遍就出来了,count还是挺快的,这事我以前就做过,还把select count出来的结果插入到一个记录表中,最后去查看这个记录表,可以找出节点间分布最不均匀的前10个表

by Yunyi

对,这个几乎一定要通过脚本来解决,DB2没有提供直接的机制来搞定这样的需求.

系统表里runstats的信息对这个要求没有帮助.

所以必须"一个一个的查".

丢个伪码脚本在这里(因为手边没环境无法测试...)


create table session.datainfo(tabname varchar(128), node int, count bigint);

db2 -x "select tabshema||'.'||tabname from syscat.tables where ..." | while read tabname
do
col=`db2 -x describe table syscat.tables | head -1 | awk '{print $1}'`
db2 "insert into session.datainfo select '$tabname', dbpartitionnum($col) as node, count(*) from $tabname group by $tabname, dbpartitionnum(kcol) order by 1,2"
done

--查找数据差别大于10%的表
with d1(tabname,min,max) as (select tabname, min(count),max(count) from session.datainfo group by tabname)
with d2(tabname,diff) as (select tabname, (d1.max - d1.min)*100/d1.max from d1 order by 2 desc)
select * from d2 where diff > 10;

Yonghang Wang 说...

注意上述脚本适用于所有节点都存在数据的情况.

如果某个节点没有数据,那么这个节点会被dbpartitionnum函数忽略掉,而不是显示row数目为0.

可以考虑通过和tablespace的map做外联结来搞定这个事情.不过就过份复杂了.

我们可以考虑简单的情况,对上述的临时表进行解析,我们统计差异时统计到的分区个数包括到最终结果里来,这样我们在分析输出结果的时候看到分区数目不对也就知道是怎么回事了--前提是在多数情况下分区组并不多,DBA应该很熟悉每个表空间大概分布在多少个分区上.

--查找数据差别大于10%的表
with d1(tabname,min,max,nodecnt) as (select tabname, min(count),max(count),count(*) from session.datainfo group by tabname)
with d2(tabname,diff,nodecnt) as (select tabname, (d1.max - d1.min)*100/d1.max, nodecnt from d1 order by 2 desc)
select * from d2 where diff > 10;

匿名 说...

提供一个简单实用的脚本,在日常工作中会经常检查正在运行的SQL语句有那些,状态是怎样的,一般需要两步:
1、list application
2、get snapshot for applcation agentid

为了方便快速的完成上面2步,我编写了下面这个脚本,把所有SQL语句一次列举出来,我觉得挺实用的:)

--------------------
db2 list applications global|awk '{if (NR>4 && $3>0) print $3}' | while read i
do

echo $i
db2 get snapshot for application agentid $i global |awk '{if (flag==1) {print $0;flag=0} if ($0=="Dynamic SQL statement text:") flag=1}'

done

-------------------

PS:运行上面脚本前必须把MONITOR SWITCHES (STATEMENT=ON)

Yonghang Wang 说...

呵呵,谢谢xinduo:)