ITPub博客

首页 > Linux操作系统 > Linux操作系统 > 表异常增大的bug

表异常增大的bug

原创 Linux操作系统 作者:yangtingkun 时间:2008-01-15 23:08:52 0 删除 编辑

今天突然发现一个表空间的空间不足,后台开始报错:ORA-1653

 

 

奇怪的是,上周才检查过表空间的容量,这个表空间还有20G左右的空间,怎么这么快就用完了。

检查了是哪个表占用了大量的空间:

SQL> SELECT * FROM                                                  
  2  (   
  3  SELECT SEGMENT_NAME, SUM(BYTES)/1024/1024/1024 G   
  4  FROM DBA_SEGMENTS   
  5  WHERE WNER = 'ZHEJIANG'
  6  GROUP BY SEGMENT_NAME
  7  ORDER BY 2 DESC
  8  )
  9  WHERE ROWNUM < 5;

SEGMENT_NAME                              G
-------------------------------- ----------
ORD_ORDER_RECEIVE                21.3242188
ORD_HIT_COMM                     5.47070313
CAT_LOG_AREA_PRICE                   5.0625
ORD_ORDER_ITEM                   3.19335938

问题对象已经找到,这个表的空间占用了21g,而正常情况下,这个表应该不会超过3G

检查表的数据量是否发生数据量级的增长:

SQL> SELECT COUNT(*) FROM ZHEJIANG.ORD_ORDER_RECEIVE;

  COUNT(*)
----------
   4141294

总共四百万条记录,这个数据量也很正常,再看看表的记录长度:

SQL> SELECT AVG_ROW_LEN FROM DBA_TABLES
  2  WHERE TABLE_NAME = 'ORD_ORDER_RECEIVE'
  3  AND WNER = 'ZHEJIANG';

AVG_ROW_LEN
-----------
        323

这个平均长度也没有问题,如果根据表的大小除以表记录数计算来计算平均长度:

SQL> select 21.3242188*1024*1024*1024/4136937 from dual;

21.3242188*1024*1024*1024/4136937
---------------------------------
                       5534.70009

这个长度就离谱了,计算这个表的最大长度:

SQL> SELECT SUM(DATA_LENGTH) FROM DBA_TAB_COLUMNS
  2  WHERE WNER = 'ZHEJIANG'
  3  AND TABLE_NAME = 'ORD_ORDER_RECEIVE';

SUM(DATA_LENGTH)
----------------
             777

最大长度才777,可是现在这张表的平均大小已经到了5K多,看来表中存在大量没有使用的BLOCK

SQL> SELECT INDEX_NAME,
  2     SUM(S.BYTES)/1024/1024 M
  3  FROM DBA_INDEXES I, DBA_SEGMENTS S
  4  WHERE I.OWNER = 'ZHEJIANG'
  5  AND S.OWNER = 'ZHEJIANG'
  6  AND SEGMENT_TYPE = 'INDEX'
  7  AND SEGMENT_NAME = INDEX_NAME
  8  AND TABLE_NAME = 'ORD_ORDER_RECEIVE'
  9  GROUP BY INDEX_NAME;

INDEX_NAME                              M
------------------------------ ----------
TU_ORD_ORDER_COMB_ITEM_FLAG           224
TU_ORD_ORDER_RECEIVE_PROD_ID          204
IND_ORD_ORDER_REC_REC_DATE            108
PK_ORD_ORDER_RECEIVE                  196
IND_ORD_RECEIVE_BUYERSENDER           340

索引的大小都很正常,看来问题只是出在了表上,下面通过两个DBMS_SPACE来检查表的block使用情况,这里对两个过程进行了简单的封装:

SQL> create or replace procedure p_unused_space(p_object_name in varchar2,
  2     p_object_type in varchar2 default 'TABLE',
  3     p_owner in varchar2 default user,
  4     p_partition_name in varchar2 default '') is
  5     v_total_blocks number;
  6     v_total_bytes number;
  7     v_unused_blocks number;
  8     v_unused_bytes number;
  9     v_last_used_extent_file_id number;
 10     v_last_used_extent_block_id number;
 11     v_last_used_block number;
 12  begin
 13     dbms_space.unused_space(upper(p_owner), upper(p_object_name), upper(p_object_type), v_total_blocks,
 14             v_total_bytes, v_unused_blocks, v_unused_bytes, v_last_used_extent_file_id,
 15             v_last_used_extent_block_id, v_last_used_block, upper(p_partition_name));
 16     dbms_output.put_line('total_blocks is ' || v_total_blocks);
 17     dbms_output.put_line('total_bytes is ' || v_total_bytes);
 18     dbms_output.put_line('unused_blocks is ' || v_unused_blocks);
 19     dbms_output.put_line('unused_bytes is ' || v_unused_bytes);
 20     dbms_output.put_line('last_used_extent_file_id is ' || v_last_used_extent_file_id);
 21     dbms_output.put_line('last_used_extent_block_id is ' || v_last_used_extent_block_id);
 22     dbms_output.put_line('last_used_block is ' || v_last_used_block);
 23  end;
 24  /

过程已创建。

SQL> EXEC P_UNUSED_SPACE('ORD_ORDER_RECEIVE', 'TABLE', 'ZHEJIANG')
total_blocks is 1397504
total_bytes is 22896705536
unused_blocks is 0
unused_bytes is 0
last_used_extent_file_id is 31
last_used_extent_block_id is 110981
last_used_block is 128

PL/SQL 过程已成功完成。

SQL> create or replace procedure p_space_usage (p_segment_name in varchar2,
  2      p_segment_type in varchar2 default 'TABLE',
  3     p_segment_owner in varchar2 default user,
  4     p_partition_name in varchar2 default '') as
  5     v_unformatted_blocks number;
  6     v_unformatted_bytes number;
  7     v_fs1_blocks number;
  8     v_fs1_bytes number;
  9     v_fs2_blocks number;
 10     v_fs2_bytes number;
 11     v_fs3_blocks number;
 12     v_fs3_bytes number;
 13     v_fs4_blocks number;
 14     v_fs4_bytes number;
 15     v_full_blocks number;
 16     v_full_bytes number;
 17  begin
 18     dbms_space.space_usage(upper(p_segment_owner), upper(p_segment_name), upper(p_segment_type), v_unformatted_blocks,
 19             v_unformatted_bytes, v_fs1_blocks, v_fs1_bytes, v_fs2_blocks, v_fs2_bytes, v_fs3_blocks, v_fs3_bytes,
 20             v_fs4_blocks, v_fs4_bytes, v_full_blocks, v_full_bytes, upper(p_partition_name));
 21    
 22     dbms_output.put_line('unformatted_blocks is ' || v_unformatted_blocks);
 23     dbms_output.put_line('unformatted_bytes is ' || v_unformatted_bytes);
 24     dbms_output.put_line('fs1_blocks is ' || v_fs1_blocks);
 25     dbms_output.put_line('fs1_bytes is ' || v_fs1_bytes);
 26     dbms_output.put_line('fs2_blocks is ' || v_fs2_blocks);
 27     dbms_output.put_line('fs2_bytes is ' || v_fs2_bytes);
 28     dbms_output.put_line('fs3_blocks is ' || v_fs3_blocks);
 29     dbms_output.put_line('fs3_bytes is ' || v_fs3_bytes);
 30     dbms_output.put_line('fs4_blocks is ' || v_fs4_blocks);
 31     dbms_output.put_line('fs4_bytes is ' || v_fs4_bytes);
 32     dbms_output.put_line('full_blocks is ' || v_full_blocks);
 33     dbms_output.put_line('full_bytes is ' || v_full_bytes);
 34  end;
 35  /

过程已创建。

SQL> EXEC P_SPACE_USAGE('ORD_ORDER_RECEIVE', 'TABLE', 'ZHEJIANG');
unformatted_blocks is 1300462
unformatted_bytes is 21306769408
fs1_blocks is 37
fs1_bytes is 606208
fs2_blocks is 52
fs2_bytes is 851968
fs3_blocks is 22
fs3_bytes is 360448
fs4_blocks is 903
fs4_bytes is 14794752
full_blocks is 94412
full_bytes is 1546846208

PL/SQL 过程已成功完成。

现在问题已经很清晰了,表中没有被格式化的block大小就有20G左右,正式这个导致了问题的产生。

根据上面的信息查询metalink,找到了相关问题的描述:Bug No. 5987262,这篇文档的标题是:TABLESPACE IS ABNORMALLY INCREASED BY UNFORMATTED BLOCKS。这篇文章中描述的情况与当前的问题十分相似,不过这篇文章描述的bug信息被认为是重复的bug,基础bug指向Bug No. 5890312

bug 5890312的文档标题为:HANG OBSERVED WHILE CREATING CTXCAT INDEX,且版本信息为11.1.0.0,怎么看似乎都和当前的问题无关。

开始的时候怀疑Oracle再指向基础bug的时候出现了错误,于是继续查找类似的问题,结果发现类似的问题的基础bug都指向Bug No. 5890312

仔细阅读了一下这个bug的描述,发现这个bug果然没有指错。虽然表现出来的现象和当前问题不一样,但是本质都是一样的,Oracle再分配空间的时候出现了泄漏,造成了大量的unformatted_blocks

这个Bug11g将被解决,而且Oracle提供了针对10.2.0.39.2.0.8的补丁来修正这个bug

短时间内无法停机打补丁,可以先通过ALTER TABLE MOVE来临时解决这个问题。

 

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/4227/viewspace-145632/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
暂无介绍

注册时间:2007-12-29

  • 博文量
    1955
  • 访问量
    10366646