pctfree是用来指定数据块中预留的空闲空间,预防因update操作,使得行变长的首先空间;因此,
对含LOB字段的表(LOB项的加载,就是update操作),要预留的相对要大些,虽然会浪费一些空间,
相比起LOB产生行迁移增加的I/O的开销,要划算得多。
在生产环境下,要对某数据库的所有表进行检测,看哪些表上存在行迁移的数据,需要将这些表重新分配pctfree,来预防行迁移的产生。
在当前生产库下,需要获取每张表的统计信息,查出哪些表存在行迁移数据,计算出行迁移的百分比。
先查一下每张表的原始情况:
select table_name,avg_row_len,blocks,empty_blocks,pct_free from user_tables;
对每张表进行统计分析,获取统计信息:
select 'analyze table '||table_name||' compute statistics;'
筛查有行迁移情况的表:
select table_name,avg_row_len,num_rows,chain_cnt,chain_cnt/num_rows,pctfree from user_tables
where chain_cnt>0;
pctfree = (avg_row_len - init avg_row_len)*100/avg_row_len
alter table &tbname pctfree xx;
alter table &tbname move;
alter index &idx_name rebuild online parallel 2;
ORA-08104: this index object 88214 is being online built or rebuilt
【smon会去消除,但是如果捉急,可以尝试执行如下操作】
SQL> declare
done boolean;
begin
done:=dbms_repair.online_index_clean(88214);
end;
/
ORA-04030: 在尝试分配...字节(...)时进程内存不足【系统自身内存释放、分配不及时,多发生在远程调用】
如果内存的确是足够的,可以尝试重启监听服务程序;或者到本地去执行重建。
6、针对行迁移量少、表大的情况,还可以使用utlchain工具生成chained_rows表:
SQL>@?/rdbms/admin/utlchain
SQL>analyze table &tbname list chained rows;
SQL>select count(1) from chained_rows;
7、如果表中的数据所占的比例并不高,可以不使用move.
根据上面的方法,计算出表合适的pctfree后,进行以下操作。
7.1、把发生行迁移的行复制到一张新表:
create table tb_tmp as select * from tb where rowid in(select head_rowid from chained_rows where table_name='TB')
7.2、把发生行迁移的行删除:
delete tb where rowid in (select head_rowid from chained_rows where table_name='TB');
7.3、把新表中的行insert到原表中:
insert into tb select * from tb_tmp ;
commit;
7.4、将表的pctfree值修改为合适值:
alter table tb pctfree xx;