zoukankan      html  css  js  c++  java
  • rebuild online 创建时,会话被Kill修复索引测试

    rebuild online 创建时,会话被Kill修复索引

    1.0实验目的:日常运维经常create index online,但是期间被kill会导致索引再次创建失败,测试解决该问题

    2.0测试流程:
    创建一个测试表,创建一个测试Local索引,记录创建时间(有足够Kill session time)
    查询会话ID
    创建测试分区索引
    kill 会话
    查询视图,该索引状态
    drop 索引尝试
    再次创建索引进行测试
    使用dbms包进行清理

    3.0创建测试表,测试索引创建时间
    #drop table scott.t purge;
    SCOTT > create table scott.t(id int,name varchar2(20)) partition by hash(id) partitions 4;
    set timing on
    declare
    v_id int;
    begin
    for v_id in 1 .. 5000000
    loop
    insert into scott.t values(v_id,'test'||v_id);
    end loop;
    commit;
    end;
    /
    Elapsed: 00:10:27.90
    create index scott.t_p_ind on scott.t(id) local;
    Elapsed: 00:00:20.25

    drop index scott.t_p_ind;

    3.1 kill session script
    SYS > select inst_id,sid,serial#,paddr from gv$session where sid =(select sid from v$mystat where rownum=1);
    INST_ID SID SERIAL# PADDR
    ---------- ---------- ---------- ----------------
    1 41 2799 0000000073A1C4A8
    select '!ps -ef|grep '||pro.spid ||' '|| '!kill -9 '||pro.spid from v$session ses,v$process pro where ses.sid in( 41 ) and ses.paddr=pro.addr

    '!PS-EF|GREP'||PRO.SPID||''||'!KILL-9'||PRO.SPID
    --------------------------------------------------------------------------------
    !ps -ef|grep 3868 !kill -9 3868

    3.2 create index SQL execute
    create index scott.t_p_ind on scott.t(id) online;


    3.3 kill create index session
    !kill -9 3868

    create index scott.t_p_ind on scott.t(id) online
    ERROR at line 1:
    ORA-03113: end-of-file on communication channel
    Process ID: 3868
    Session ID: 41 Serial number: 2799


    3.4查询索引被kill后的状态
    SYS > select owner,index_name,status from dba_indexes where owner='SCOTT' and index_name='T_P_IND';
    OWNER INDEX_NAME STATUS
    --------- ---------------- --------
    SCOTT T_P_IND VALID


    ####创建一个其它列索引,使用hint 是否强制走索引? [failed] 不重要,可忽略
    SYS > create index scott.test_ind on scott.t(name);
    set autotrace on
    select count(name) from scott.t;
    COUNT(*)
    ----------
    5000000
    -----------------------------------------------------------------------------------------------------------
    | Id | Operation | Name | Rows | Cost (%CPU)| Time | Pstart| Pstop |
    -----------------------------------------------------------------------------------------------------------
    | 0 | SELECT STATEMENT | | 1 | 4389 (1)| 00:00:53 | | |
    | 1 | RESULT CACHE | cnrwbkdx2qdpa9s91jr2ka3jzb | | | | | |
    | 2 | SORT AGGREGATE | | 1 | | | | |
    | 3 | PARTITION HASH ALL| | 4759K| 4389 (1)| 00:00:53 | 1 | 4 |
    | 4 | TABLE ACCESS FULL| T | 4759K| 4389 (1)| 00:00:53 | 1 | 4 |
    -----------------------------------------------------------------------------------------------------------

    select /*+ INDEX(TEST_IND) */ count(*) from scott.t;
    -----------------------------------------------------------------------------------------------------------
    | Id | Operation | Name | Rows | Cost (%CPU)| Time | Pstart| Pstop |
    -----------------------------------------------------------------------------------------------------------
    | 0 | SELECT STATEMENT | | 1 | 4389 (1)| 00:00:53 | | |
    | 1 | RESULT CACHE | cnrwbkdx2qdpa9s91jr2ka3jzb | | | | | |
    | 2 | SORT AGGREGATE | | 1 | | | | |
    | 3 | PARTITION HASH ALL| | 4759K| 4389 (1)| 00:00:53 | 1 | 4 |
    | 4 | TABLE ACCESS FULL| T | 4759K| 4389 (1)| 00:00:53 | 1 | 4 |
    -----------------------------------------------------------------------------------------------------------


    SYS > desc scott.t
    Name Type
    --------------------------------------------
    ID NUMBER(38)
    NAME VARCHAR2(20)


    alter table scott.t modify name not null;
    再次重复上述操作,还是全表扫描
    收集统计信息
    analyze table SCOTT.T compute statistics
    *
    ERROR at line 1:
    ORA-08104: this index object 91965 is being online built or rebuilt
    。。。。。。出现之前online创建索引报错的信息,无法收集该索引统计信息

    单独收集索引信息
    Analyze index scott.TEST_IND estimate statistics
    Index analyzed.

    再次重复上述查询
    count(*)还是未走索引,11g Oracle优化器使用的是基于成本的考量,因此我们无法强制改变,hint只是一定范围内的提示,而并非100%指定

    修改上述思路,查询一条记录
    SYS > select count(*) from scott.t t where name LIKE 'test999999';

    COUNT(*)
    ----------
    1
    ------------------------------------------------------------------------------
    | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
    ------------------------------------------------------------------------------
    | 0 | SELECT STATEMENT | | 1 | 12 | 3 (0)| 00:00:01 |
    | 1 | SORT AGGREGATE | | 1 | 12 | | |
    |* 2 | INDEX RANGE SCAN| TEST_IND | 1 | 12 | 3 (0)| 00:00:01 |
    ------------------------------------------------------------------------------

    drop index scott.TEST_IND;
    SYS > select count(*) from scott.t t where name LIKE 'test999999';

    COUNT(*)
    ----------
    1
    -------------------------------------------------------------------------------------------------------------------
    | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |
    -------------------------------------------------------------------------------------------------------------------
    | 0 | SELECT STATEMENT | | 1 | 12 | 4398 (1)| 00:00:53 | | |
    | 1 | RESULT CACHE | 0n8qmskbrjq8sbj8x2d00ugtz4 | | | | | | |
    | 2 | SORT AGGREGATE | | 1 | 12 | | | | |
    | 3 | PARTITION HASH ALL| | 186 | 2232 | 4398 (1)| 00:00:53 | 1 | 4 |
    |* 4 | TABLE ACCESS FULL| T | 186 | 2232 | 4398 (1)| 00:00:53 | 1 | 4 |
    -------------------------------------------------------------------------------------------------------------------
    #####


    回归本次实验目的,测试的是online create index kill 之后,对索引问题的修复
    本次索引虽然状态是好的,但实际索引是有问题的
    SYS > select owner,index_name,status from dba_indexes where owner='SCOTT' and index_name='T_P_IND';
    OWNER INDEX_NAME STATUS
    --------- ---------------- --------
    SCOTT T_P_IND VALID

    SYS > select count(*) from scott.t where id=1;
    COUNT(*)
    ----------
    1
    ----------------------------------------------------------------------------------------------------------------------
    | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |
    ----------------------------------------------------------------------------------------------------------------------
    | 0 | SELECT STATEMENT | | 1 | 13 | 1389 (22)| 00:00:17 | | |
    | 1 | RESULT CACHE | d74bgy2vpgmj18rsc3c4w4dygh | | | | | | |
    | 2 | SORT AGGREGATE | | 1 | 13 | | | | |
    | 3 | PARTITION HASH SINGLE| | 44 | 572 | 1389 (22)| 00:00:17 | 4 | 4 |
    |* 4 | TABLE ACCESS FULL | T | 44 | 572 | 1389 (22)| 00:00:17 | 4 | 4 |
    ----------------------------------------------------------------------------------------------------------------------

    如果索引状态正常,执行计划将走索引,而非table access full 全表扫描,如何解决索引问题?


    3.5drop 索引尝试
    drop index soctt.T_P_IND;
    drop index soctt.T_P_IND
    *
    ERROR at line 1:
    ORA-01418: specified index does not exist

    再次创建索引进行测试

    SYS > create index scott.t_t on scott.t(id);
    create index scott.t_t on scott.t(id)
    *
    ERROR at line 1:
    ORA-01408: such column list already indexed

    对该索引rebuild重建

    alter index scott.t_p_ind rebuild online;
    ERROR at line 1:
    ORA-08104: this index object 91970 is being online built or rebuilt


    查询报错解释说明,该索引正在重建
    SYS > !oerr ora 08104
    08104, 00000, "this index object %s is being online built or rebuilt"
    // *Cause: the index is being created or rebuild or waited for recovering
    // from the online (re)build
    // *Action: wait the online index build or recovery to complete

    MOS (ID 375856.1)
    在运行在线索引重建时,会话被终止或以其他方式异常终止。您现在正在尝试再次运行索引重建并抛出错误:
    已创建dbms_repair.online_index_clean函数以清除联机索引重建。使用dbms_repair.online_index_clean函数来解决此问题。

    参考LOB
    https://blog.csdn.net/haibusuanyun/article/details/50236057


    create /rebuild index online时会修改数据库字典表obj$,并在该索引用户下创建表sys_journal_obj#和ind$、ind_online$表里
    如果服务器进程在语句执行过程中意外终止的话,可能会导致相关在ind$标记位信息及在线日志中间表不能及时处理及清除(清除动作一般有smon进程处理,如果重建过程异常中断,smon会清理重建痕迹,但是如果系统非常繁忙导致smon无法清除,或dml操作频繁,导致smon无法获取相关表上的锁,从而造成无法清理痕迹,当再次重建索引或对表进行dml操作会报本篇提示错误),这将导致对该索引的后续操作因ora-08104错误而无法继续,如果是分区表,索引是global,在添加分区也无法继续。

    4.0解决问题
    4.1表没有tm锁,调用存储过程进行清理
    4.2表存在事务,需等待事务结束
    4.3存在大量的rebuild online被结束,批量操作

    4.1表没有tm锁,调用存储过程进行清理
    --查询字典表中的记录
    select i.obj#, i.flags, u.name, o.name, o.type#
    from sys.obj$ o, sys.user$ u, sys.ind_online$ i
    where (bitand(i.flags, 256) = 256 or bitand(i.flags, 512) = 512)
    and (not ((i.type# = 9) and bitand(i.flags, 8) = 8))
    and o.obj# = i.obj#
    and o.owner# = u.user#;
    OBJ# FLAGS NAME NAME TYPE#
    ---------- ---------- ---------------- -------------------
    91970 256 SCOTT T_P_IND 1

    --调用dbms_repair.online_index_clean
    declare
    a boolean;
    begin
    a := dbms_repair.online_index_clean(91970,dbms_repair.lock_wait);
    end;
    /

    SYS > select owner,index_name,status from dba_indexes where owner='SCOTT' and index_name='T_T';
    no rows selected


    4.2表存在事务,需等待事务结束
    --如果此时,表存在TM 3 dml事务?
    create index scott.t_t on scott.t(id) online;
    *
    ERROR at line 1:
    ORA-03113: end-of-file on communication channel
    Process ID: 4245
    Session ID: 65 Serial number: 115
    --再次查询视图
    OBJ# FLAGS NAME NAME TYPE#
    ---------- ---------- ------------------------------ ------------------------------ ----------
    91974 256 SCOTT T_T 1
    --dml操作

    SYS > delete scott.t where rownum<2;
    1 row deleted.
    --调用dbms_repair.online_index_clean
    declare
    a boolean;
    begin
    a := dbms_repair.online_index_clean(91974,dbms_repair.lock_wait);
    end;
    / --会话hang住


    Alert log
    Sat May 12 10:03:52 2018
    online index (re)build cleanup: objn=91974 maxretry=2000 forever=0

    --
    select object_name,s.sid,s.serial#,s.username,' '||'!kill -9 '||p.spid as"kill"
    from v$locked_object l , dba_objects o , v$session s , v$process p
    where l.object_id=o.object_id and l.session_id=s.sid and s.paddr=p.addr and o.owner='SCOTT' and o.object_name='T';
    OBJECT_NAM SID SERIAL# USERNAME kill
    ---------- ---------- ---------- ---------- --------------------
    T 40 2437 SYS !kill -9 4114
    T 40 2437 SYS !kill -9 4114
    --kill session
    可释放资源


    --4.3存在大量的rebuild online被结束,批量操作

    declare
    isClean boolean;
    begin
    isClean := FALSE;
    while isClean=FALSE loop
    isClean := dbms_repair.online_index_clean(dbms_repair.all_index_id,
    dbms_repair.lock_wait);
    dbms_lock.sleep(2);
    end loop;
    exception
    when others then
    RAISE;
    end;

    --测试创建两个不同用户下的online失效

    create index scott.t_t on scott.t(id) online;
    kill session
    HR > create table hr.t1 as select * from scott.t;
    select distinct sid from v$mystat;
    create index hr.c1 on hr.t1(id) online;
    kill session

    --查询视图记录
    OBJ# FLAGS NAME NAME TYPE#
    ---------- ---------- ----------------- --------------------
    91977 256 SCOTT T_T 1
    91987 256 HR C1 1
    --执行存储过程
    PL/SQL procedure successfully completed.
    --Alert日志记录
    Sat May 12 10:19:29 2018
    online index (re)build cleanup: objn=91977 maxretry=2000 forever=0
    online index (re)build cleanup: objn=91987 maxretry=2000 forever=0

    --重建完毕,如果存在锁资源,相信也无法申请,kill或等待即可

  • 相关阅读:
    QT小技巧
    C#通用类库设置开机自运行禁用任务管理器注册表等操作
    C#通用类库农历类(很全面)
    C#通用类库导出数据(比其他方式快200倍)
    如果你想当程序员!请看!
    C#通用类库汉字转拼音
    C#通用类库加密解密类
    C#制作图片压缩工具
    QT编写图片数据转换工具
    C++面试题 virtual
  • 原文地址:https://www.cnblogs.com/lvcha001/p/9696281.html
Copyright © 2011-2022 走看看