当前位置: 首页 > 编程日记 > 正文

对Oracle中索引叶块分裂而引起延迟情况的测试和分析

在版本10.2.0.4未打上相关one-off补丁的情况下,分别对ASSM和MSSM管理模式表空间进行索引分裂测试,经过测试的结论如下: l  在10gr2版本中MSSM方式是不能避免索引分裂引起交易超时问题; l  10.2.0.4上的one-off补丁因为目前仅存在Linux版本,可以考虑声请补丁后具体测试(因目前没有补丁所以处于未知状态)。 l  合并索引是目前最具可行性的解决方案(alter index coalesce)。 l  最新的11gr2中经测试仍存在该问题。 具体测试过程如下: 1.    自动段管理模式下的索引块分裂
SQL> drop tablespace idx1 including contents and datafiles; Tablespace dropped. SQL> create tablespace idx1 datafile '?/dbs/idx1.dbf' size 500M 2  segment space management AUTO 3  extent management local uniform size 10M; --创建自动段管理的表空间 Tablespace created. SQL> create table idx1(a number) tablespace idx1; Table created. create index idx1_idx on idx1 (a) tablespace idx1 pctfree 0; Index created.         -- 创建实验对象表及索引 SQL> insert into idx1 select rownum from all_objects, all_objects where rownum <= 250000;           -- 插入25万条记录 250000 rows created. SQL> commit; Commit complete. SQL>create table idx2 tablespace idx1 as select * from idx1 where 1=2; Table created. insert into idx2 select * from idx1 where rowid in (select rid from (select rid, rownum rn from (select rowid rid from idx1 where a between 10127 and 243625 order by a)                    --取出后端部分记录,即每250条取一条 ) where mod(rn, 250) = 0 ) / 933 rows created. SQL> commit; Commit complete. SQL> analyze index idx1_idx validate structure; --分析原索引 select blocks,lf_blks,del_lf_rows from index_stats; Index analyzed. SQL> BLOCKS    LF_BLKS DEL_LF_ROWS ---------- ---------- ----------- 1280        499           0               -- 未删除情况下499个叶块 SQL> delete from idx1 where a between 10127 and 243625;                             -- 大量删除 commit; 233499 rows deleted. SQL> SQL> Commit complete. SQL> analyze index idx1_idx validate structure; select blocks,lf_blks,del_lf_rows from index_stats; Index analyzed. SQL> BLOCKS    LF_BLKS DEL_LF_ROWS ---------- ---------- ----------- 1280        499      233499            -- 删除后叶块数量不变 SQL> insert into idx1 select * from idx2;                   -- 令那些empty 不再empty,但每个块中只有一到二条记录,空闲率仍为75-100% commit; 933 rows created. Commit complete. SQL> insert into idx1 select 250000+rownum from all_objects where rownum <= 126;          -- 造成leaf块分裂前提 SQL> select ss.value,sy.name from v$sesstat ss ,v$sysstat sy where ss.statistic#=sy.statistic# and name like '%split%'  and sid=(select distinct sid from v$mystat); VALUE NAME ---------- ---------------------------------------------------------------- 997 leaf node splits 997 leaf node 90-10 splits 0 branch node splits 0 queue splits                 --找出当前会话目前的叶块分裂次数 SQL>insert into idx1 values (251000);                                        -- 此处确实叶块分裂 1 row created. SQL> commit; Commit complete. SQL> select ss.value,sy.name from v$sesstat ss ,v$sysstat sy where ss.statistic#=sy.statistic# and name like '%split%'  and sid=(select distinct sid from v$mystat); VALUE NAME ---------- ---------------------------------------------------------------- 998 leaf node splits 998 leaf node 90-10 splits 0 branch node splits 0 queue splits         -- 可以看到对比之前的查询多了一个叶块分裂 SQL> set linesize 200 pagesize 1500; SQL> select  executions, buffer_gets, disk_reads, cpu_time, elapsed_time, rows_processed, sql_text from v$sql 2  where sql_text like '%insert%idx1%' and sql_text not like '%v$sql%'; EXECUTIONS BUFFER_GETS DISK_READS   CPU_TIME ELAPSED_TIME ROWS_PROCESSED ---------- ----------- ---------- ---------- ------------ -------------- SQL_TEXT -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1        1603          0     271601       271601            933 insert into idx2 select * from idx1 where rowid in (select rid from (select rid, rownum rn from (select rowid rid from idx1 where a between 10127 and 243625 order by a) ) where mod(rn, 250) = 0 ) 1         156          0      82803        82803            126 insert into idx1 select 250000+rownum from all_objects where rownum <= 126 1         177 0       3728         3728              1 insert into idx1 values (251000)     -- 读了那些实际不空的块,较多buffer_get 1        1409          0      40293        40293            933 insert into idx1 select * from idx2 1      240842          0    3478341      3478341         250000 SQL> insert into idx1 values (251001);                                  -- 不分裂的插入 1 row created. SQL> commit; Commit complete. SQL> select  executions, buffer_gets, disk_reads, cpu_time, elapsed_time, rows_processed, sql_text from v$sql 2  where sql_text like '%insert%idx1%' and sql_text not like '%v$sql%'; EXECUTIONS BUFFER_GETS DISK_READS   CPU_TIME ELAPSED_TIME ROWS_PROCESSED ---------- ----------- ---------- ---------- ------------ -------------- SQL_TEXT -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1        1603          0     271601       271601            933 insert into idx2 select * from idx1 where rowid in (select rid from (select rid, rownum rn from (select rowid rid from idx1 where a between 10127 and 243625 order by a) ) where mod(rn, 250) = 0 ) 1         156          0      82803        82803            126 insert into idx1 select 250000+rownum from all_objects where rownum <= 126 1           9          0       1640         1640              1 insert into idx1 values (251001) --不分裂的插入,少量buffer_gets 1         177          0       3728         3728              1 insert into idx1 values (251000) 1        1409          0      40293        40293            933 insert into idx1 select * from idx2 1      240842          0    3478341      3478341         250000 insert into idx1 select rownum from all_objects, all_objects where rownum <= 250000
如演示1所示,在自动段管理模式下大量删除后插入造成许多块为75%-100%空闲率且不完全为空,此后叶块分裂时将引起插入操作的相关前台进程扫描大量“空块“,若这些块不在内存中(引发物理读)且可能需要延迟块清除等原因时,减缓了该扫描操作的速度,造成叶块分裂缓慢,最终导致了其他insert操作被split操作所阻塞,出现enq:tx index contention等待事件。 2.  手动段管理模式下的索引块分裂
SQL> drop tablespace idx1 including contents and datafiles; Tablespace dropped. SQL> create tablespace idx1 datafile '?/dbs/idx1.dbf' size 500M 2  segment space management MANUAL                                      -- MSSM的情况 3  extent management local uniform size 10M; Tablespace created. SQL> create table idx1(a number) tablespace idx1; create index idx1_idx on idx1 (a) tablespace idx1 pctfree 0; Table created. SQL> SQL> insert into idx1 select rownum from all_objects, all_objects where rownum <= 250 Index created. SQL> SQL> 000; commit; create table idx2 tablespace idx1 as select * from idx1 where 1=2; insert into idx2 select * from idx1 where rowid in (select rid from (select rid, rownum rn from (select rowid rid from idx1 where a between 10127 and 243625 order by a) ) where mod(rn, 250) = 0 ) / commit; 250000 rows created. SQL> SQL> Commit complete. SQL> SQL> Table created. SQL> SQL>   2    3    4    5    6    7    8    9 933 rows created. SQL> SQL> Commit complete. SQL> analyze index idx1_idx validate structure; select blocks,lf_blks,del_lf_rows from index_stats; Index analyzed. SQL> BLOCKS    LF_BLKS DEL_LF_ROWS ---------- ---------- ----------- 1280        499           0 SQL> delete from idx1 where a between 10127 and 243625; 233499 rows deleted. SQL> commit; Commit complete. SQL> insert into idx1 select * from idx2; commit; 933 rows created. SQL> SQL> Commit complete. SQL> SQL> insert into idx1 select 250000+rownum from all_objects where rownum <= 126; commit; 126 rows created. SQL> SQL> Commit complete. SQL> SQL> select ss.value,sy.name from v$sesstat ss ,v$sysstat sy where ss.statistic#=sy.statistic# and name like '%split%'  and sid=(select distinct sid from v$mystat); VALUE NAME ---------- ---------------------------------------------------------------- 1496 leaf node splits 1496 leaf node 90-10 splits 0 branch node splits 0 queue splits SQL> insert into idx1 values (251000);                                  -- 确实分裂 1 row created. SQL> commit; Commit complete. SQL> select ss.value,sy.name from v$sesstat ss ,v$sysstat sy where ss.statistic#=sy.statistic# and name like '%split%'  and sid=(select distinct sid from v$mystat); VALUE NAME ---------- ---------------------------------------------------------------- 1497 leaf node splits 1497 leaf node 90-10 splits 0 branch node splits 0 queue splits -- 以上与ASSM时完全一致 SQL> select  executions, buffer_gets, disk_reads, cpu_time, elapsed_time, rows_processed, sql_text from v$sql 2  where sql_text like '%insert%idx1%' and sql_text not like '%v$sql%'; EXECUTIONS BUFFER_GETS DISK_READS   CPU_TIME ELAPSED_TIME ROWS_PROCESSED ---------- ----------- ---------- ---------- ------------ -------------- SQL_TEXT -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1        1553          0     283301       283301            933 insert into idx2 select * from idx1 where rowid in (select rid from (select rid, rownum rn from (select rowid rid from idx1 where a between 10127 and 243625 order by a) ) where mod(rn, 250) = 0 ) 1         153          0      78465        78465            126 insert into idx1 select 250000+rownum from all_objects where rownum <= 126 1        963 0      10422        10422              1              -- ASSM模式下更大量的空块 insert into idx1 values (251000) 1         984          0      35615        35615            933 insert into idx1 select * from idx2 1      238579          0    3468326      3469984         250000 insert into idx1 select rownum from all_objects, all_objects where rownum <= 250000 SQL> insert into idx1 values (251001); 1 row created. SQL> commit; Commit complete. SQL> select  executions, buffer_gets, disk_reads, cpu_time, elapsed_time, rows_processed, sql_text from v$sql 2  where sql_text like '%insert%idx1%' and sql_text not like '%v$sql%'; EXECUTIONS BUFFER_GETS DISK_READS   CPU_TIME ELAPSED_TIME ROWS_PROCESSED ---------- ----------- ---------- ---------- ------------ -------------- SQL_TEXT -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1        1553          0     283301       283301            933 insert into idx2 select * from idx1 where rowid in (select rid from (select rid, rownum rn from (select rowid rid from idx1 where a between 10127 and 243625 order by a) ) where mod(rn, 250) = 0 ) 1         153          0      78465        78465            126 insert into idx1 select 250000+rownum from all_objects where rownum <= 126 1           7 0       1476         1476              1 insert into idx1 values (251001)    --不分裂的情况与ASSM时一致 1         963 0      10422        10422              1 insert into idx1 values (251000) 1         984          0      35615        35615            933 insert into idx1 select * from idx2 1      238579          0    3468326      3469984         250000 insert into idx1 select rownum from all_objects, all_objects where rownum <= 250000 6 rows selected.
如演示2所示,MSSM情况下叶块分裂读取了比ASSM模式下更多的“空块“;MSSM并不能解决大量删除后叶块分裂需要扫描大量非空块的问题,实际上可能更糟糕。从理论上讲MSSM的freelist只能指出那些未达到pctfree和曾经到达pctfree后来删除记录后使用空间下降到pctused的块(doc:A free list is a list of free data blocks that usually includes blocks existing in a number of different extents within the segment. Free lists are composed of blocks in which free space has not yet reached PCTFREE or used space has shrunk below PCTUSED.),换而言之MSSM模式下”空块“会更多。 3.  自动段管理模式下coalesce后的索引块分裂
SQL> drop tablespace idx1 including contents and datafiles; Tablespace dropped. SQL> create tablespace idx1 datafile '?/dbs/idx1.dbf' size 500M 2  segment space management AUTO                                       -- ASSM coalesce情况 3  extent management local uniform size 10M; Tablespace created. SQL> create table idx1(a number) tablespace idx1; create index idx1_idx on idx1 (a) tablespace idx1 pctfree 0; Table created. SQL> SQL> Index created. SQL> SQL> insert into idx1 select rownum from all_objects, all_objects where rownum <= 250000; commit; create table idx2 tablespace idx1 as select * from idx1 where 1=2; insert into idx2 select * from idx1 where rowid in (select rid from (select rid, rownum rn from (select rowid rid from idx1 where a between 10127 and 243625 order by a) ) where mod(rn, 250) = 0 ) / commit; 250000 rows created. SQL> SQL> Commit complete. SQL> SQL> Table created. SQL> SQL>   2    3    4    5    6    7    8    9 933 rows created. SQL> SQL> Commit complete. SQL> SQL> SQL> SQL> SQL> analyze index idx1_idx validate structure; select blocks,lf_blks,del_lf_rows from index_stats; Index analyzed. SQL> BLOCKS    LF_BLKS DEL_LF_ROWS ---------- ---------- ----------- 1280        499           0 SQL> delete from idx1 where a between 10127 and 243625; commit; 233499 rows deleted. SQL> SQL> Commit complete. SQL> alter index idx1_idx coalesce; Index altered. SQL> analyze index idx1_idx validate structure; select blocks,lf_blks,del_lf_rows from index_stats; Index analyzed. SQL> BLOCKS    LF_BLKS DEL_LF_ROWS ---------- ---------- ----------- 1280         33           0 -- coalesc lf块合并了 SQL> insert into idx1 select * from idx2; 933 rows created. SQL> SQL> commit; Commit complete. SQL> SQL> insert into idx1 select 250000+rownum from all_objects where rownum <= 126; commit; 126 rows created. SQL> SQL> Commit complete. SQL> select ss.value,sy.name from v$sesstat ss ,v$sysstat sy where ss.statistic#=sy.statistic# and name like '%split%'  and sid=(select distinct sid from v$mystat); VALUE NAME ---------- ---------------------------------------------------------------- 1999 leaf node splits 1995 leaf node 90-10 splits 0 branch node splits 0 queue splits SQL> insert into idx1 values (251000);                                       -- 确实分裂 1 row created. SQL> commit; Commit complete. SQL> select ss.value,sy.name from v$sesstat ss ,v$sysstat sy where ss.statistic#=sy.statistic# and name like '%split%'  and sid=(select distinct sid from v$mystat); VALUE NAME ---------- ---------------------------------------------------------------- 2000 leaf node splits 1996 leaf node 90-10 splits 0 branch node splits 0 queue splits SQL> select  executions, buffer_gets, disk_reads, cpu_time, elapsed_time, rows_processed, sql_text from v$sql 2  where sql_text like '%insert%idx1%' and sql_text not like '%v$sql%'; EXECUTIONS BUFFER_GETS DISK_READS   CPU_TIME ELAPSED_TIME ROWS_PROCESSED ---------- ----------- ---------- ---------- ------------ -------------- SQL_TEXT -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1        1603          0     268924       268924            933 insert into idx2 select * from idx1 where rowid in (select rid from (select rid, rownum rn from (select rowid rid from idx1 where a between 10127 and 243625 order by a) ) where mod(rn, 250) = 0 ) 1         156          0      78349        78349            126 insert into idx1 select 250000+rownum from all_objects where rownum <= 126 1          23 0       2218         2218              1                             --少量buffer gets insert into idx1 values (251000) 1         191          0      15596        15596            933 insert into idx1 select * from idx2 1      240852          0    3206130      3206130         250000 insert into idx1 select rownum from all_objects, all_objects where rownum <= 250000 SQL> insert into idx1 values (251001); 1 row created. SQL> commit; Commit complete. SQL> select  executions, buffer_gets, disk_reads, cpu_time, elapsed_time, rows_processed, sql_text from v$sql 2  where sql_text like '%insert%idx1%' and sql_text not like '%v$sql%'; EXECUTIONS BUFFER_GETS DISK_READS   CPU_TIME ELAPSED_TIME ROWS_PROCESSED ---------- ----------- ---------- ---------- ------------ -------------- SQL_TEXT -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1        1603          0     268924       268924            933 insert into idx2 select * from idx1 where rowid in (select rid from (select rid, rownum rn from (select rowid rid from idx1 where a between 10127 and 243625 order by a) ) where mod(rn, 250) = 0 ) 1         156          0      78349        78349            126 insert into idx1 select 250000+rownum from all_objects where rownum <= 126 1           9 0       1574         1574              1 insert into idx1 values (251001) 1          23 0       2218         2218              1 insert into idx1 values (251000) 1         191          0      15596        15596            933 insert into idx1 select * from idx2 1      240852          0    3206130      3206130         250000 insert into idx1 select rownum from all_objects, all_objects where rownum <= 250000 6 rows selected.
如演示三所示在删除后进行coalesce操作,合并操作将大量空块分离出了索引结构(move empty out of index structure),之后的叶块分裂仅读取了少量必要的块。 4.  手动段管理模式下coalesce后的索引块分裂
SQL> drop tablespace idx1 including contents and datafiles; Tablespace dropped. SQL> create tablespace idx1 datafile '?/dbs/idx1.dbf' size 500M 2  segment space management MANUAL                               -- mssm情况下 coalesce 3  extent management local uniform size 10M; Tablespace created. SQL> create table idx1(a number) tablespace idx1; create index idx1_idx on idx1 (a) tablespace idx1 pctfree 0; Table created. SQL> SQL> insert into idx1 select rownum from all_objects, all_objects where rownum <= 250 Index created. SQL> SQL> 000; commit; create table idx2 tablespace idx1 as select * from idx1 where 1=2; insert into idx2 select * from idx1 where rowid in (select rid from (select rid, rownum rn from (select rowid rid from idx1 where a between 10127 and 243625 order by a) ) where mod(rn, 250) = 0 ) / commit; 250000 rows created. SQL> SQL> Commit complete. SQL> SQL> Table created. SQL> SQL>   2    3    4    5    6    7    8    9 933 rows created. SQL> SQL> Commit complete. SQL> SQL> SQL> SQL> SQL> analyze index idx1_idx validate structure; select blocks,lf_blks,del_lf_rows from index_stats; Index analyzed. SQL> BLOCKS    LF_BLKS DEL_LF_ROWS ---------- ---------- ----------- 1280        499           0 SQL> delete from idx1 where a between 10127 and 243625; commit; 233499 rows deleted. SQL> SQL> Commit complete. SQL> analyze index idx1_idx validate structure; select blocks,lf_blks,del_lf_rows from index_stats; Index analyzed. SQL> BLOCKS    LF_BLKS DEL_LF_ROWS ---------- ---------- ----------- 1280        499      233499 SQL> alter index idx1_idx coalesce; Index altered. SQL> analyze index idx1_idx validate structure; select blocks,lf_blks,del_lf_rows from index_stats; Index analyzed. SQL> BLOCKS    LF_BLKS DEL_LF_ROWS ---------- ---------- ----------- 1280         33           0 SQL> insert into idx1 select * from idx2; 933 rows created. SQL> SQL> commit; Commit complete. SQL> SQL> insert into idx1 select 250000+rownum from all_objects where rownum <= 126; commit; 126 rows created. SQL> SQL> Commit complete. SQL> select ss.value,sy.name from v$sesstat ss ,v$sysstat sy where ss.statistic#=sy.statistic# and name like '%split%'  and sid=(select distinct sid from v$mystat); VALUE NAME ---------- ---------------------------------------------------------------- 2502 leaf node splits 2494 leaf node 90-10 splits 0 branch node splits 0 queue splits SQL> insert into idx1 values (251000);                       -- 确实分裂 1 row created. SQL> commit; Commit complete. SQL> select ss.value,sy.name from v$sesstat ss ,v$sysstat sy where ss.statistic#=sy.statistic# and name like '%split%'  and sid=(select distinct sid from v$mystat); VALUE NAME ---------- ---------------------------------------------------------------- 2503 leaf node splits 2495 leaf node 90-10 splits 0 branch node splits 0 queue splits SQL> select  executions, buffer_gets, disk_reads, cpu_time, elapsed_time, rows_processed, sql_text from v$sql 2  where sql_text like '%insert%idx1%' and sql_text not like '%v$sql%'; EXECUTIONS BUFFER_GETS DISK_READS   CPU_TIME ELAPSED_TIME ROWS_PROCESSED ---------- ----------- ---------- ---------- ------------ -------------- SQL_TEXT -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1        1553          0     281059       281059            933 insert into idx2 select * from idx1 where rowid in (select rid from (select rid, rownum rn from (select rowid rid from idx1 where a between 10127 and 243625 order by a) ) where mod(rn, 250) = 0 ) 1         153          0      77817        77817            126 insert into idx1 select 250000+rownum from all_objects where rownum <= 126 1          19          0       2010         2010              1                       -- 少量buffer get insert into idx1 values (251000) 1         126          0      15364        15364            933 insert into idx1 select * from idx2 1      238644          0    3229737      3230569         250000 insert into idx1 select rownum from all_objects, all_objects where rownum <= 250000 SQL> insert into idx1 values (251001); 1 row created. SQL> commit; Commit complete. SQL> select  executions, buffer_gets, disk_reads, cpu_time, elapsed_time, rows_processed, sql_text from v$sql 2  where sql_text like '%insert%idx1%' and sql_text not like '%v$sql%'; EXECUTIONS BUFFER_GETS DISK_READS   CPU_TIME ELAPSED_TIME ROWS_PROCESSED ---------- ----------- ---------- ---------- ------------ -------------- SQL_TEXT -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1        1553          0     281059       281059            933 insert into idx2 select * from idx1 where rowid in (select rid from (select rid, rownum rn from (select rowid rid from idx1 where a between 10127 and 243625 order by a) ) where mod(rn, 250) = 0 ) 1         153          0      77817        77817            126 insert into idx1 select 250000+rownum from all_objects where rownum <= 126 1          7 0       1460         1460              1 insert into idx1 values (251001) 1          19 0       2010         2010              1 insert into idx1 values (251000) 1         126          0      15364        15364            933 insert into idx1 select * from idx2 1      238644          0    3229737      3230569         250000 insert into idx1 select rownum from all_objects, all_objects where rownum <= 250000 6 rows selected.
如演示4所示,MSSM模式下合并操作与ASSM情况下大致一样,合并操作可以有效解决该问题。 5.  Coalesce合并操作的锁影响
SQL> create table coal (t1 int); Table created. SQL> create index pk_t1 on coal(t1); Index created. SQL> begin 2    for i in 1..3000 loop 3      insert into coal values(i); 4      commit; 5      end loop; 6      end; 7  / PL/SQL procedure successfully completed. SQL> delete coal where t1>500; 2500 rows deleted. SQL> commit; Commit complete. SQL> analyze index pk_t1 validate structure; Index analyzed.    -- 注意analyze validate操作会block一切dml操作 SQL> select blocks,lf_blks,del_lf_rows from index_stats; BLOCKS    LF_BLKS DEL_LF_ROWS ---------- ---------- ----------- 8          6        2500          -- 删除后的状态 此时另开一个会话,开始dml操作: SQL> update coal set t1=t1+1; 500 rows updated. -- 回到原会话 SQL> alter index pk_T1 coalesce;             -- coalesce 未被阻塞 Index altered. -- 在另一个会话中commit,以便执行validate structure SQL> analyze index pk_t1 validate structure; Index analyzed. SQL> select blocks,lf_blks,del_lf_rows from index_stats; BLOCKS    LF_BLKS DEL_LF_ROWS ---------- ---------- ----------- 8          3         500 -- 显然coalesce的操作没有涉及有dml操作的块 在没有dml操作的情况下: SQL> truncate table coal; Table truncated. SQL> begin 2    for i in 1..3000 loop 3      insert into coal values(i); 4      commit; 5      end loop; 6      end; 7  / PL/SQL procedure successfully completed. SQL> analyze index pk_t1 validate structure; Index analyzed. SQL> select blocks,lf_blks,del_lf_rows from index_stats; BLOCKS    LF_BLKS DEL_LF_ROWS ---------- ---------- ----------- 8          6           0 SQL> delete coal where t1>500; 2500 rows deleted. SQL> commit; Commit complete. SQL> analyze index pk_t1 validate structure; Index analyzed. SQL> select blocks,lf_blks,del_lf_rows from index_stats; BLOCKS    LF_BLKS DEL_LF_ROWS ---------- ---------- ----------- 8          6        2500 SQL> alter index pk_t1 coalesce; Index altered. SQL> analyze index pk_t1 validate structure; Index analyzed. SQL> select blocks,lf_blks,del_lf_rows from index_stats; BLOCKS    LF_BLKS DEL_LF_ROWS ---------- ---------- ----------- 8          1           0 --没有dml时,coalesce 操作涉及了所有块
如演示5所示coalesce会避开dml操作涉及的块,但在coalesec的短暂间歇出现在索引上有事务的块不会太多。且coalesce操作不会降低索引高度。 附件是关于rebuild及coalesce索引操作的详细描述: 6.  Coalesce操作总结 优点: l  是一种快速的操作,对整体性能影响最小(not performance sensitive)。 l  不会锁表,绕过有事务的索引块。 l  可以有效解决现有的问题。 l  不会降低索引高度,引起再次的root split 缺点: l  需要针对个别对象,定期执行合并操作;无法一劳永逸地全局地解决该问题。 7.  Linux 10.2.0.4上相关补丁的技术交流 Metalink bug 8286901 note中叙述了一位用户遇到相同的问题并提交了SR,当时oracle support给出了one-off补丁,但该用户在apply了该补丁后仍未解决问题。 以下为note 原文:
It is similar to bug8286901, but after applied patch8286901, still see enq tx contentiona with high "failed probes on index block reclamation"
Issue encountered by customer and Oracle developer (Stefan Pommerenk).
He describes is thus:
"Space search performed by the index splitter can't find space in neighboring
blocks, and then instead of allocating new space, we go and continue to
search for space elsewhere, which manifests itself in block reads from disk,
block cleanouts, and subsequent blocks written due to aggressive MTTR
setting."
"To clarify: the cleanouts are not the problem per se. The culprit seems to
be that the space search performed by the index splitter can't find space in
neighboring blocks, and then instead of allocating new space, we go and
continue to search for space elsewhere, which manifests itself in block reads
from disk, block cleanouts, and subsequent blocks written due to aggressive
MTTR setting. This action has caused other sessions to get blocked on TX
enqueue contention, blocked on the splitting session. Advice was to set 10224
trace event for the splitter for a short time only in order to get
diagnostics as to why the space search rejected most blocks.
> A secondary symptom are the bitmap level 1 block updates, which may or may
not be related to the space search; I've not seen them before, maybe because
I didn't really pay attention :P , but the symptoms seen in the ASH trace
indicate it's the same problem. Someone in space mgmt has to look at it to
confirm it is the same problem."
与该用户进行了mail私下交流,他的回复:
I still have a case open with Oracle. I believe that this is a bug in the Oracle code. The problem is that it has been difficult to create a reproducible test case for Oracle support. My specific issue was basically put on hold pending the results of another customer’s service request that appeared to have had the same issue, (9034788). Unfortunately they couldn’t reproduce the issue in that case either. I believe that there is a correlation between the enq TX – index contention wait event and a spike in the number of ‘failed probes on index block reclamation. I have specifically asked Oracle to explain why there is a spike in the ‘failed probes on index block reclamation’ during the same time frame as the enq TX index contention wait event, but they have not answered my question. I was hoping that some investigation by Oracle Support into the failed probes metric might get someone on the right track to discovering the bug. That hasn’t happened though. Hi , Thanks for your sharing .  The bug (or specific ktsp behave) is fatal in response time sensitive  OLTP env. I would like to ask my customer to coalesce those index where massive deleted regularly. Thanks for your help again! Yes, I saw that. I have applied patch 8286901 and set the event for version 10.2.0.4, but the problem still occurs periodically. And as I mentioned before, we see a correlation between enq TX waits and the failed probes on index block reclamation. Which is why I still think that it is a bug. I agree that trying to rebuild or coalesce the indexes are simply attempts to workaround the issue and not solve the root cause. Early on when I started on this issue I did do some index dumps and could clearly see that we had lots of blocks with only 1 or 2 records after our mass delete jobs. I have provided Oracle Support with this information as well as oradump files while the problem is occurring, but they don’t seem to be able to find anything wrong so far. If you are interested in seeing if you are experiencing a high ‘failed probes on index block reclamation’ event run the query below. select SS.snap_id, SS.stat_name, TO_CHAR(S.BEGIN_INTERVAL_TIME, ‘DAY’) DAY, S.BEGIN_INTERVAL_TIME, S.END_INTERVAL_TIME, SS.value, SS.value – LAG(SS.VALUE, 1, ss.value) OVER (ORDER BY SS.SNAP_ID) AS DIFF from DBA_HIST_SYSSTAT SS, DBA_HIST_SNAPSHOT S where S.SNAP_ID = SS.SNAP_ID AND SS.stat_NAME = ‘failed probes on index block reclamation’ ORDER BY SS.SNAP_ID ;
  1. 在11gr2上的测试
--在最新的11gr2中进行了测试,仍可以重现该问题(如图单条insert引起了6675buffer_gets,这是在更大量数据的情况下)。
我们可以猜测Oracle提供的one-off补丁中可能是为叶块分裂所会扫描的“空块”附加了一个上限,在未达到上限的情况下扫描仍会发生。而在主流的公开的发行版本中Oracle不会引入该补丁的内容。尝试在没有缓存的情况下引起分裂问题,分裂引起了大约4000个块的物理读,但该操作仍在0.12秒(有缓存是0.02秒,如图)内完成了(该测试使用普通ata硬盘,读取速度在100MB/S: Timing buffered disk reads:  306 MB in  3.00 seconds = 101.93 MB/sec);从1月21日的ash视图中可以看到引起split的260会话处于单块读等待(db file sequential read)中,且已等待了43950us约等于44ms;这与良好io的经验值10ms左右有较大出入;我们可以确信io性能问题也是引发此叶块分裂延迟如此显性的一个重要因素。

具体结论

综上所述,在之前讨论的几个方案中,MSSM方式是不能避免索引分裂引起交易超时问题的;不删除数据的方案在许多对象上不可行;10.2.0.4上的one-off补丁因为目前仅存在Linux版本,可以考虑声请补丁后具体测试(因目前没有补丁所以处于未知状态)。Coalesce合并索引是目前既有的最具可操作性且无副作用的解决方案。

转载于:https://www.cnblogs.com/macleanoracle/archive/2010/03/21/2967378.html

相关文章:

node.js和npm版本升级及升级过程中遇到的问题和解决方案

Node.js和NPM版本升级1. 安装Node.js1.1 版本检查1.2 下载安装程序1.3 安装2. npm升级2.1 版本检查2.2 升级3. 检查Node.js和npm之间的版本对应关系4. 检查Angular CLI、Angular、Node.js、TypeScript 和 RxJS 兼容性矩阵最初在本地安装Node.js和npm时&#xff0c;是通过Angula…

学习进度(5)

记录时间&#xff1a; 第六周 所花时间&#xff08;包括上课&#xff09; 20h 代码量&#xff08;行&#xff09; 400行 博客量&#xff08;篇&#xff09; 0篇 了解到的知识点 结对开发石家庄地铁软件&#xff0c;迪杰斯特拉算法的应用 转载于:https://www.cnblogs.c…

Windows搭建wnmp

http://www.cnblogs.com/wujuntian/p/7252343.html转载于:https://www.cnblogs.com/xiaobai-y/p/7815945.html

我的名字叫博客

我的部落是一个小部落&#xff0c;人口比较少&#xff0c;资源很贫瘠&#xff0c;但是我的人们很努力&#xff0c;他们都是最强的&#xff01;转载于:https://www.cnblogs.com/cchenry/archive/2009/06/25/1511162.html

实例15 判断某一年是否为闰年

package wjf; import java.util.Scanner; public class wjf1{public static void main(String[] args){ //主方法Scanner scannew Scanner(System.in); System.out.println("请输入一个年份"); //向控制台输出一个提示信息long year;try{yearsc…

前端开发知识总结思维导图

前端开发扮演的一个角色&#xff1a; 前端开发知识点总结&#xff1a; 转载于:https://www.cnblogs.com/zhaodagang8/p/7821427.html

Angular应用提高打包速度

当Angular应用功能不断增加时&#xff0c;其打包速度会变慢&#xff0c;可以尝试使用以下方法缩短打包时间。 打开node_modules/webpack/lib/optimize/ModuleConcatenationPlugin.js文件&#xff0c;注释以下代码片段&#xff1a; for (let i 0; i < newModule.dependencie…

iCup,USB加热饮品方案

词条&#xff1a; iCup USB加热杯 USB电器 猛料&#xff1a; 其实看用的macbook作为例子&#xff0c;就知道这个设计很有一段时间啦&#xff0c;用i打头来为苹果打造各种莫名其妙的周边产品也是前几年的潮流&#xff0c;iCup出自Onur Karaalioglu的设计&#xff0c;将USB作为加…

Angular 文件上传与下载

Angular文件上传与下载文件上传方式1 使用NG ZORRO中的组件。文件下载方式1 直接下载方式2 通过HTTP请求后端数据的方式进行下载文件上传 方式1 使用NG ZORRO中的组件。 文件下载 方式1 直接下载 已知明确的下载链接&#xff0c;可以直接进行下载。 <a href"downlo…

包装类接受string 会自动将数字类型string转换成对应得包装类型

转载于:https://www.cnblogs.com/classmethond/p/10663229.html

tensorflow常用函数解析

一、tf.transpose函数的用法 tf.transpose(input, [dimension_1, dimenaion_2,..,dimension_n]):这个函数主要适用于交换输入张量的不同维度用的&#xff0c;如果输入张量是二维&#xff0c;就相当是转置。dimension_n是整数&#xff0c;如果张量是三维&#xff0c;就是用0,1,2…

FLASH处理图像的移动、缩放、旋转、颜色变换的类推荐。

这3个都是比较好的外部类&#xff0c;帮助操作图像的。 教程也比较详细。 看了以后发现&#xff0c;需要把图形学的书翻出来再补补课鸟... http://www.adobe.com/devnet/flash/articles/matrix_transformations_print.html http://blog.joa-ebert.com/imageprocessing-library/…

机器学习——XGBoost大杀器,XGBoost模型原理,XGBoost参数含义

0.随机森林的思考 随机森林的决策树是分别采样建立的&#xff0c;各个决策树之间是相对独立的。那么&#xff0c;在我们得到了第k-1棵决策树之后&#xff0c;能否通过现有的样本和决策树的信息&#xff0c; 对第m颗树的建立产生有益的影响呢&#xff1f;在随机森林建立之后&…

使用存储过程更新数据库!成功了但是返回值为 -1 的变态问题的解决办法!

今天遇到个表态的问题&#xff01;使用带事务的存储过程执行sql语句&#xff0c;看数据库里面插入更新都正常&#xff01; 但是返回值一直为-1&#xff01; 头那个大哦&#xff01;先贴2个存储过程吧&#xff01;看大侠们能否找到问题的存在 USE [My_DB] GO/****** Object: St…

poj2289二分图多重匹配

题意&#xff1a;给你一张二分图&#xff0c;求右边点到汇点的最小容量&#xff08;保证流量为n&#xff09;是多少 题解:二分答案&#xff0c;每次重新建边跑最大流&#xff0c;看是不是为n就好了 #include<map> #include<set> #include<cmath> #include<…

Express应用配置端口

Express应用设置端口方法1 静态修改--直接修改代码中配置的默认端口号方法2 动态修改--修改代码逻辑使其获取启动命令中的端口号参数相关文章在Express应用创建成功后&#xff0c;应用会自动配置一个端口号&#xff0c;比如3000&#xff0c;有时会遇到端口号被占用的情况&#…

Oracle中PL/SQL的循环语句

PL/SQL的三种形式的循环&#xff1a;1.LOOP&#xff08;无条件循环&#xff09;&#xff1a;loopstatements;end loop;2.WHILE&#xff08;有条件循环&#xff09;&#xff1a;while condition loopstatements;end loop;3.FOR&#xff08;固定次数循环&#xff09;&#xff1a;…

处理器调度算法

1. P117页,练习15&#xff1a;最高响应比 HRRF&#xff1a; 作业 提交时刻 运行时刻 开始时刻 完成时刻 周转时间/min 带权周转时间/min 1 10:00 2:00 10:00 12:00 120 120/120 2 10:10 1:00 12:25 13:25 195 195/60 3 10:25 0:25 12:00 12:25 120 …

bzoj4516

后缀自动机 留个板子 upd:大概懂了 每次新加入的npRight集合肯定只有最后一个位置&#xff0c;那么求所有长得不一样的子串贡献就是Max-Min1,因为Right集合只有这一个位置&#xff0c;所以这Max-Min1个子串只出现在最后一个位置。 #include<bits/stdc.h> using namespace…

npm : 无法加载文件 D:\...\nodejs\npm.ps1,因为在此系统上禁止运行脚本

问题&#xff1a; 在VSCode终端使用npm命令时&#xff0c;出现如下报错信息&#xff1a; npm : 无法加载文件 D:\ProgramFiles\nodejs\npm.ps1&#xff0c;因为在此系统上禁止运行脚本。有关详细信息&#xff0c;请参阅 https:/go.microsoft.com/fwlink/?Link ID135170 中的 …

Mybatis注解学习记录

Mybatis注解使用1. SQL语句映射1.1 Select注解&#xff1a;实现查询功能1.1.1 用法1.2 Insert注解&#xff1a;实现新增功能1.2.1 用法1.3 Update注解&#xff1a;实现更新功能1.3.1 用法1.4 Delete注解&#xff1a;实现删除功能1.4.1 用法2. 结果集映射2.1 Results注解&#x…

路由和交换机工作原理

路由器与交换机的工作原理 计算机网络往往由许多种不同类型的网络互连连接而成。如果几个计算机网络只是在物理上连接在一起&#xff0c;它们之间并不能进行通信&#xff0c;那么这种“互连”并没有什么实际意义。因此通常在谈到“互连”时&#xff0c;就已经暗示这些相互连接的…

嵌套选项卡自动播放

HTML <div class"box" id"box"><ul class"top" id"top"><li class"fl">专题</li><li class"fl">视频</li></ul><div class"clearFix" id"cont"…

Facebook 与 Google 正在主导在线身份验证市场

OpenID 公司 JanRain 的一项研究发现&#xff0c;用户在第三方网站进行身份验证时&#xff0c;最喜欢使用 Google 和 Facebook 的身份验证服务。Facebook 的验证服务 在媒体&#xff0c; 零售&#xff0c;技术等领域略微领先&#xff0c;而 JanRain 的17万份客户数据显示&#…

WIN2K/XP/2003 + APACHE + ASP + PHP + MYSQL 的简易实现

至目前总算完成了WIN2K/XP/2003 APACHE ASP PHP MYSQL这样一个建站项目&#xff0c;回过头来仔细想想也并不复杂。只是经过了反复的安装、卸载、研究、测试带找资料。真正的步骤却也没什么难的&#xff0c;但如果让你从头研究可能也是一件很头痛的事情了&#xff01;所以打…

.net 去除特殊字符

str Regex.Replace(str, "<script[^>]*?>.*?</script>", "", RegexOptions.IgnoreCase); //str为需要校验的字符 str Regex.Replace(str, "[~#$%^&\*()_\{}\|<>\/\\\[\]]", "", RegexOptions.IgnoreCase…

为TypeScript项目生成API文档

为TypeScript项目生成文档 使用typedoc为TypeScript项目生成API文档。 1. 使用typedoc生成HTML文档 需要安装 typedoc。 npm i typedoc可以通过命令行参数指定配置信息&#xff0c;也可以通过加载配置文件的方式加载配置信息。 本项目中使用加载配置文件typedoc.json的方式…

DropBox免费扩容到10G了

好久没有写博客了,郑重推荐下Dropbox这款同步软件,很多人有多台电脑,比如公司和家里一些文档需要同步更新,用U盘拷贝来拷贝去,不胜其烦.自然而然就想到用同步软件,而这方面DropBox从速度来说,当然是首屈一指的. 先说明DropBox的优点: 使用简单,去官网http://www.dropbox.com下…

子网划分实例与讲解

子网划分 分为两种&#xff1a;◆ 给定网络地址&#xff0c;划分子网。◆不给定网络地址&#xff0c;根据主机数量&#xff0c;自由确定网络地址&#xff0c;进而划分子网。【实例1】给定网络地址&#xff0c;划分子网。我们单位有计算机100台左右&#xff0c;原来都是在192.16…

使用Docsify搭建Markdown文件服务器

使用docsify快速生成文档网站1. 概述2. 安装 docsify-cli 工具3. 初始化项目4. 本地预览5. 多页文档6. 定制导航栏6.1 在index.html中添加导航栏6.2 添加导航栏配置文件6.3 下拉导航栏7. 封面设置7.1 设置封面参数7.2 自定义封面背景7.3 将封面设置为首页配置项elrepomaxLevell…