在使用的数据库中,发现有表的区段数(extents)存在很大的数据的情况,以下是我们正在使用的SQL用于统计数据库表的区段数及空间占用情况的。
SQL1:从sysmaster:sysextents表的分类统计。Sysextents包含了所有表区段的信息。
$ dbaccess sysmaster - << !SQL
Select
dbsname,tabname,count(*),sum(size)
From
sysextents
Group
by 1,2
Order
by 3 desc,4 desc ;
!SQL
返回值
dbsname tabname num_of_extents total_size
iip
crbt_ring 266 305184
SQL2:从sysmaster:systabnames,sysmaster:sysptnext两表通过dbsname,tabname联合查询,然后进行分类统计。Systabnames包含了所有表的信息,sysptnext包含了所有区域信息。
$ dbaccess sysmaster - << !SQL
SELECT
dbsname,tabname,count(*) num_of_extents,sum( pe_size ) total_size
FROM systabnames,sysptnext
WHERE partnum = pe_partnum
AND dbsname[1,3] != "sys"
AND tabname[1,3] != "sys"
GROUP BY 1, 2
ORDER BY 3 desc,4 desc;
!SQL
返回值
dbsname tabname num_of_extents total_size
iip
crbt_ring 266 305184
从两种方法查询的结果都一致,似乎这个值应该是准确的。然而,使用oncheck –pt iip:crbt_ring 命令,我们看到了不一样的结果:
TBLspace Report for iip:dsennew.crbt_ring
Physical Address
5:362909
Creation date 04/02/2008 00:16:26
TBLspace Flags
800901 Page Locking
TBLspace contains VARCHARS
TBLspace use 4 bit bit-maps
Maximum row size
565
Number of special columns
1
Number of keys
0
Number of extents
13
Current serial value
545818
First extent size
64000
Next extent size
6400
Number of pages allocated
166400
Number of pages used
163658
Number of data pages
163617
Number of rows
488914
Partition partnum
5243352
Partition
lockid 5243352
在oncheck的输出中,只查到了13个区段,另外的266-13=253个区段失踪了?!
我们查看下在sysptnext(区域表)中的各extents的区域,
SQL3:从sysmaster:systabnames表中获取表的partnum号。
$ dbaccess
sysmaster - << !SQL
Select * from systabnames where tabname=”crbt_ring”
;
!SQL
返回值
partnum dbsname owner tabname collate
5243116 iip iip
crbt_ring en_US.819
5243316 iip iip
crbt_ring en_US.819
5243352 iip dsennew crbt_ring en_US.819
返回值让我们感到吃惊!!一个database(iip)里竟然有三个同样的表名!!这是不应该出现的情况,如果说这个表是分段表,那么partnum应该是0,这排除了这个表是分段表。而且返回里出现2个不同用户的3个同名表。从partnum来看,oncheck –pt 中的输出是partnum为 5243352 ,即owner为dsennew用户创建的crbt_ring表。那么另两个partnum对应的crbt_ring表哪去了呢?
SQL4:从业务库的systables表中通过partnum取表名。
$ dbaccess
sysmaster - << !SQL
select tabname,owner,partnum,created
from iip:systables
where partnum in ("5243116","5243316","5243352");
!SQL
返回值
tabname owner partnum created
crbt_ringbak iip 5243116 2006-09-21
crbt_ring_bak iip 5243316 2007-08-14
crbt_ring
dsennew 5243352 2008-04-02
我们可以看到从业务库的systables返回跟sysmaster:systabnames中的返回不一致!!!询问用户:crbt_ring这个表进行了重建操作,即先将crbt_ring表改名,然后按照表结构SQL重建该表并导入数据。可为什么会出现systables表的数据更新了,而sysmaster:systabnames表的数据没有得到更新呢??
SQL5:从sysmaster:sysptnext中检查所有crbt_ring表的区域。
$
dbaccess sysmaster - <
select count(*) num_of_extents
from sysptnext
where
pe_partnum="5243352";
!SQL
返回值
num_of_extents
13
当pe_partnum=” 5243116”
时,返回 138
当pe_partnum=” 5243316”
时,返回 115
当pe_partnum为5243352时,返回的正是oncheck里的输出number of extents。且13+138+115 = 266 正好是SQL1,SQL2里的结果。
在SQL1,SQL2中的sysmaster:sysextents,sysmaster:systabnames表的中信息tabname都没有及时更新,而sysmaster:sysptnext仅根据pe_partnum来记录,SQL2中的结果受到systabnames的误导。
从上面的操作,我们分析可知:业务库的systables的准确性比sysmaster库中的系统表高。因此,要统计表的区段数,应该选取高的业务库systables表与系统库中的sysptnext表来通过partnum来联合查询。
SQL6:通过sysmaster:sysptnext表与业务库iip:systables表联合查询区段数。
$ dbaccess sysmaster
- << !SQL
select "iip" dbsname,t.tabname,count(*)
total_extent,sum(pe_size) total_size
from sysmaster:sysptnext p, iip:systables t
where p.pe_partnum = t.partnum
group by 1,2
having count(*) > 99
order by 3 desc,4 desc;
!SQL
结束语:解决方法找到了,但出现问题的原因:业务库systables已经成功更新,为什么sysmaster:systabnames,sysmaster:sysextents表中的记录没有同时更新?