您现在的位置是:首页 > 编程 > 

索引:Rebuild Online 被坑的知识点

2025-07-29 10:18:28
索引:Rebuild Online 被坑的知识点 背景  最近一直通过rebuild online 做索引碎片整理,因表均为分区表,大部分为本地索引及分区索引,有的表涉及上千个索引分区,于是我就用脚本放在后台执行了。这种情况正常运行了一个月。  突然今天巡检执行日志的时候,索引IDX_T1_ID 的其它分区重建只需要10min左右,但 IDX_T1_ID rebuild partition SYS

索引:Rebuild Online 被坑的知识点

背景

  最近一直通过rebuild online 做索引碎片整理,因表均为分区表,大部分为本地索引及分区索引,有的表涉及上千个索引分区,于是我就用脚本放在后台执行了。这种情况正常运行了一个月。

  突然今天巡检执行日志的时候,索引IDX_T1_ID 的其它分区重建只需要10min左右,但 IDX_T1_ID rebuild partition SYS_P592 分区从凌晨4:29开始到中午12点都还没有结果,意识到执行不正常,查看了下索引涉及到的数据有数据正常入表,数据也可查询,目前看不影响此表的dml操作。

  然后咨询开发有个定时任务4:0发起,差不多有80w左右的数据入表,查看程序日志此任务也一直没有执行结束。庆幸的是此任务仅是备份表数据功能。

排查及处理

  • 1、先对rebuild操作进行kill,观察程序任务是否能正常执行完成
  • 2、1小时后程序日志依然没输出,然后把程序里的SQL拿到备库查一下20min无法反回结果,按历史执行记录0min已完成入表操作,此时判断此任务已异常,于是停掉任务在数据库层kill 掉会话。
  • 、至此分析:任务里的【注1】:插入表任务影响到了rebuild online操作,不知什么原因导致任务里的SQL执行缓慢一直没有结果。
  • 4、rebuild被kill导致无法重新rebuild 报错如下:
代码语言:javascript代码运行次数:0运行复制
SQL> alter index IDX_T1_ID rebuild partition SYS_P592 online tablespace two_ind_dat;
alter index IDX_T1_ID rebuild partition SYS_P592 online tablespace two_ind_dat
*
ERROR at line 1:
ORA-08106: cannot create journal table TWO.SYS_JOURAL_407292
  • 5、查看SYS_JOURAL_407292对象
代码语言:javascript代码运行次数:0运行复制
select object_name,created,status From dba_objects where object_name like 'SYS_JOURAL_%'
  • 6、kill rebuild alert 日志输出
代码语言:javascript代码运行次数:0运行复制
Wed Dec 04 12::9 2024
online index (re)build cleanup: objn=407292 maxretry=2000 forever=0
Wed Dec 04 12:7:19 2024
opiodr aborting process unknown ospid (12508) as a result of ORA-28
Wed Dec 04 12:48:26 2024
  • 7、查看索引状态为:“user_objects.status=VALID”【注2】:查user_objects判断索引是否有效不准,但查询使用到此索引,感觉像是索引无效了导致SQL查询6-7小时无结果,于是计划对索引删除重建(此表仅为后台查询无交易业务需求,因此可删除重建)
  • 8、drop index 索引报错
  • 原因分析:   在执行rebuild index online前长事务,并且并发量比较大,则一旦执行alter index rebuild online,可能因为长事务阻塞,可能导致系统瞬间出现大量的锁,对于压力比较大的系统,这是一个不小的风险。这是需要迅速出导致阻塞的会话kill掉,rebuild index online一旦执行,不可轻易中断,否则可能遇到ORA-08104。   清除动作一般有smon进程处理,如果重建过程异常中断,smon会清理重建痕迹,但是如果系统非常繁忙导致smon无法清除,或dml操作频繁,导致smon无法获取相关表上的锁,从而造成无法清理痕迹,当再次重建索引或对表进行dml操作会报本篇提示错误,这将导致对该索引的后续操作因ora-08104错误而无法继续,如果是分区表,索引是global,在添加分区也无法继续。
代码语言:javascript代码运行次数:0运行复制
SQL> drop index IDX_T1_ID ;
drop index IDX_T1_ID 
           *
ERROR at line 1:
ORA-08104: this index object 407292 is being online built or rebuilt
  • 9、调用dbms__index_clean清理
  • 因为还有其它rebuild 操作,因此选用指定OBJECT_ID ,【注】:执行7次依然报错。
  • 注:加上dbms_repair.lock_wait表示不是立刻清理,需要不断的寻资源锁,直到抢到为止
代码语言:javascript代码运行次数:0运行复制
-- 清理全部异常数据
declare
  isClean boolean;
begin
  isClean := FALSE;
  while isClean=FALSE loop
isClean := dbms__index_clean(dbms_repair.all_index_id,dbms_repair.lock_wait);
dbms_lock.sleep(2);
  end loop;
  exception 
when others then 
  RAISE; 
end;
/
-- 指定OBJECT_ID 清理
SQL> DECLARE
  2  RetVal BOOLEA;
    OBJECT_ID BIARY_ITEGER;
  4  WAIT_FOR_LOCK BIARY_ITEGER;
  5  BEGI
  6  OBJECT_ID := 407292;
  7  WAIT_FOR_LOCK := ULL;
  8  RetVal := SYS.DBMS_REPAIR.OLIE_IDEX_CLEA ();
  9  COMMIT;
 10  ED;
 11  /
DECLARE
*
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-00054: resource busy and acquire with OWAIT specified or timeout expired
ORA-06512: at "SYS.DBMS_REPAIR", line 475
ORA-06512: at line 8
  • 10、查看alert 日志数据库一直在清理objn=69888,为另一个任务对像
代码语言:javascript代码运行次数:0运行复制
Wed Dec 04 16:56:09 2024
online index (re)build cleanup: objn=69888 maxretry=2000 forever=0
online index (re)build cleanup: objn=69888 maxretry=2000 forever=0
online index (re)build cleanup: objn=69888 maxretry=2000 forever=0
online index (re)build cleanup: objn=69888 maxretry=2000 forever=0
Wed Dec 04 16:56:28 2024
online index (re)build cleanup: objn=69888 maxretry=2000 forever=0
Wed Dec 04 16:57:16 2024
online index (re)build cleanup: objn=69888 maxretry=2000 forever=0
online index (re)build cleanup: objn=69888 maxretry=2000 forever=0
  • 11、再次查看SYS_JOURAL%对像未发现SYS_JOURAL_407292,然后成功删除索引、重建索引、对表进行信息收集。
  • 12、最后再次执行SQL,10s出结果,任务重新执行0分钟数据补入完成。

【注 1】小测

  • 表准备
代码语言:javascript代码运行次数:0运行复制
create table t1 (
  id          VARCHAR2(11) not null,
  create_date TIMESTAMP(6) not null
);
create index IDX_T1_ID on t1 (id);
  • session1:插入数据不提交,session2:rebuild online索引
  • session1 一直不提交,session2就一直无法完成,符合上面的事故现像
  • session1 :提交,session2:完成
  • 测试小结:索引涉及字段的修改未提交,rebuild online就无法结束。

【注 2】 小测

  • 表准备
代码语言:javascript代码运行次数:0运行复制
create table t1 (
  id          VARCHAR2(11) not null,
  create_date TIMESTAMP(6) not null
)
PARTITIO BY RAGE(create_date)ITERVAL(numtoyminterval(1,'month'))
    (PARTITIO part202401 VALUES LESS THA(TO_DATE('20240201','yyyymmdd')),
     PARTITIO part202402 VALUES LESS THA(TO_DATE('2024001','yyyymmdd'))
    );
  • 数据准备
代码语言:javascript代码运行次数:0运行复制
11:47:21 SQL> select count(*) from t1 partition(SYS_P1741);
  COUT(*)
----------
  44551512
  • 创建索引
代码语言:javascript代码运行次数:0运行复制
11:48:05 SQL> create index IDX_T1_ID on t1 (id);
Index created.
  • 查看执行计划:索引扫描
代码语言:javascript代码运行次数:0运行复制
12:6:05 SQL> set  autotrace trace 
12:6:1 SQL> select * from t1 where id ='1';
no rows selected
Execution Plan
----------------------------------------------------------
Plan hash value: 220901882
----------------------------------------------------------------------------------------------------------------
| Id  | Operation                          | ame      | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
----------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMET                   |           |     1 |    20 |        (0)| 00:00:01 |       |       |
|   1 |  TABLE ACCESS BY GLOBAL IDEX ROWID| T1        |     1 |    20 |        (0)| 00:00:01 | ROWID | ROWID |
|*  2 |   IDEX RAGE SCA                 | IDX_T1_ID |     1 |       |        (0)| 00:00:01 |       |       |
----------------------------------------------------------------------------------------------------------------
  • Truncate 分区,查看索引状态为:VALID
代码语言:javascript代码运行次数:0运行复制
12:7:20 SQL> alter table t1 truncate partition (SYS_P1741);
Table truncated.
12:7:0 SQL>  col OBJECT_AME for a50
12:7:8 SQL> set line 800 
12:7:4 SQL> select object_name,status from user_objects where object_name='IDX_T1_ID';
OBJECT_AME                                        STATUS
-------------------------------------------------- -------
IDX_T1_ID                                          VALID
  • 查看执行计划:全表扫描
代码语言:javascript代码运行次数:0运行复制
12:8:25 SQL> set autotrace trace 
12:8:4 SQL> select * from t1 where id ='1';
no rows selected
Execution Plan
----------------------------------------------------------
Plan hash value: 58959414
--------------------------------------------------------------------------------------------
| Id  | Operation           | ame | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
--------------------------------------------------------------------------------------------
|   0 | SELECT STATEMET    |      |     1 |    20 |     2   (0)| 00:00:01 |       |       |
|   1 |  PARTITIO RAGE ALL|      |     1 |    20 |     2   (0)| 00:00:01 |     1 |1048575|
|*  2 |   TABLE ACCESS FULL | T1   |     1 |    20 |     2   (0)| 00:00:01 |     1 |1048575|
--------------------------------------------------------------------------------------------
  • 通过user_indexes.status 显示索引为不可用
代码语言:javascript代码运行次数:0运行复制
1:06:40 SQL>  select status from user_indexes where index_name='IDX_T1_ID';
STATUS
--------
UUSABLE
  • 测试小结:判断索引是否可用通过user_indexes.status 状态为准。

【注 】dbms__index_clean

  • dbms__index_clean 的指定OBJECT_ID 的方法,好像也是清理所有rebuild online操作,因生产还有另一个rebuild任务,因此报:ORA-00054: resource busy and acquire with OWAIT specified or timeout expired 。

生产问题复现

  • T1数据量:95188524,执行计划为:IDEX RAGE SCA
  • Session1:进行插入,然后Session2:rebuild online索引
  • 叉掉Session2 界面,模拟当时kill会话,查看索引状态:VALID
  • 再次rebuild online索引报错:ORA-08104
  • 查看SYS_JOURAL%对象
  • 叉掉Session2 的插入界面,模拟当时杀任务
  • 日志输出

注:以下结果是被验证次后,Rebuild Online 和 Insert 执行1小时以上再Kill会话,才会偶尔出现。

  • 执行计划:全表扫描
代码语言:javascript代码运行次数:0运行复制
15:20:04 SQL> select * from t1 where id='1';
no rows selected
Execution Plan
----------------------------------------------------------
Plan hash value: 58959414
--------------------------------------------------------------------------------------------
| Id  | Operation           | ame | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
--------------------------------------------------------------------------------------------
|   0 | SELECT STATEMET    |      |     1 |    20 |     2   (0)| 00:00:01 |       |       |
|   1 |  PARTITIO RAGE ALL|      |     1 |    20 |     2   (0)| 00:00:01 |     1 |1048575|
|*  2 |   TABLE ACCESS FULL | T1   |     1 |    20 |     2   (0)| 00:00:01 |     1 |1048575|
--------------------------------------------------------------------------------------------
  • rebuild 索引后,查询依然:全表扫描
代码语言:javascript代码运行次数:0运行复制
15:26:06 SQL> alter index IDX_T1_ID rebuild;
Index altered.
15::49 SQL> select * from t1 where id='1';
no rows selected
Elapsed: 00:00:24.82
Execution Plan
----------------------------------------------------------
Plan hash value: 58959414
--------------------------------------------------------------------------------------------
| Id  | Operation           | ame | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
--------------------------------------------------------------------------------------------
|   0 | SELECT STATEMET    |      |     1 |    20 |     2   (0)| 00:00:01 |       |       |
|   1 |  PARTITIO RAGE ALL|      |     1 |    20 |     2   (0)| 00:00:01 |     1 |1048575|
|*  2 |   TABLE ACCESS FULL | T1   |     1 |    20 |     2   (0)| 00:00:01 |     1 |1048575|
--------------------------------------------------------------------------------------------
  • 收集统计信息后,查询执行计划:索引扫描
代码语言:javascript代码运行次数:0运行复制
15:4:19 SQL> exec dbms_stats.gather_table_stats(ownname=>'SYS',tabname=> 'T1');
PL/SQL procedure successfully completed.
Elapsed: 00:01:51.92
16:08:04 SQL> select * from t1 where id='1';
no rows selected
Elapsed: 00:00:22.27
Execution Plan
----------------------------------------------------------
Plan hash value: 220901882
----------------------------------------------------------------------------------------------------------------
| Id  | Operation                          | ame      | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
----------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMET                   |           |   18 |  4209 |    27   (0)| 00:00:01 |       |       |
|   1 |  TABLE ACCESS BY GLOBAL IDEX ROWID| T1        |   18 |  4209 |    27   (0)| 00:00:01 | ROWID | ROWID |
|*  2 |   IDEX RAGE SCA                 | IDX_T1_ID |   18 |       |     4   (0)| 00:00:01 |       |       |
----------------------------------------------------------------------------------------------------------------

总结:rebuild online 注意事项

  • 此次事件的原因分析,应该是表信息过期导致Insert异常缓慢,从而使rebuild online一直未结束。
  • 避开数据库维护任务,示例:《记录一起索引rebuild与收集统计信息的事故》
  • 避开大事务操作,可参考此事件;
  • 关注索引状态:user_indexes.status;
  • 异常中断后残留信息一般是smon进程清理,如清理不了可用dbms__index_clean清理;
  • 随时关注临时表,查看临时表情况:
代码语言:javascript代码运行次数:0运行复制
SELECT _name tablespace,
       _total,
       SUM(A.used_blocks * D.block_size) / 1024 / 1024 mb_used,
       _total - SUM(A.used_blocks * D.block_size) / 1024 / 1024 mb_free
FROM v$sort_segment A,
       (SELECT , C.block_size, SUM(C.bytes) / 1024 / 1024 mb_total
          FROM v$tablespace B, v$tempfile C
         WHERE # = #
         GROUP BY , C.block_size) D
WHERE _name = 
GROUP by _name, _total;
  • 根据如下SQL查看rebuild online 进度
代码语言:javascript代码运行次数:0运行复制
col opname format a2
col target format a2
col perwork format a12
set linesize 1200
select sid
      ,opname
      ,target
      ,sofar
      ,totalwork
      ,trunc(sofar/totalwork*100,2)||'%' as perwork
from v$session_longops where sofar!=totalwork and sid=12;

       SID OPAME                        TARGET        SOFAR  TOTALWORK PERWORK
---------- --------------------- ------------------ ---------- ---------- --------
       827 Index Fast Full Scan      IDX_T1_ID         27914     157907 17.67%

#感谢您对电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格的认可,转载请说明来源于"电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格

本文地址:http://www.dnpztj.cn/biancheng/1187351.html

相关标签:无
上传时间: 2025-07-22 14:00:44
留言与评论(共有 20 条评论)
本站网友 马石庄
2分钟前 发表
对表进行信息收集
本站网友 海口婚纱摄影
3分钟前 发表
从而使rebuild online一直未结束
本站网友 免费刷ip
21分钟前 发表
06
本站网友 深圳歌唱培训
18分钟前 发表
05 SQL> create index IDX_T1_ID on t1 (id); Index created.查看执行计划:索引扫描代码语言:javascript代码运行次数:0运行复制12
本站网友 超级扫描器
13分钟前 发表
因此报:ORA-00054
本站网友 郑州搜房网
23分钟前 发表
created
本站网友 顶象
20分钟前 发表
00
本站网友 色吧论坛
26分钟前 发表
56
本站网友 过午不食减肥法
26分钟前 发表
00
本站网友 一路好走
15分钟前 发表
对表进行信息收集
本站网友 胰腺炎的治疗
18分钟前 发表
  突然今天巡检执行日志的时候
本站网友 氧氟沙星说明书
16分钟前 发表
objn=407292 maxretry=2000 forever=0 Wed Dec 04 12
本站网友 干细胞除皱
0秒前 发表
created
本站网友 南充社区
19分钟前 发表
totalwork      
本站网友 无限极传销
8分钟前 发表
C.block_size) D WHERE _name = GROUP by _name
本站网友 面部光子嫩肤
23分钟前 发表
v$tempfile C WHERE # = # GROUP BY
本站网友 生病吃什么
7分钟前 发表
smon会清理重建痕迹
本站网友 丽景千贺
24分钟前 发表
19 2024 opiodr aborting process unknown ospid (12508) as a result of ORA-28 Wed Dec 04 12
本站网友 黄芩的功效
9分钟前 发表
00