日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 人文社科 > 生活经验 >内容正文

生活经验

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

發(fā)布時(shí)間:2023/11/27 生活经验 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 对Oracle中索引叶块分裂而引起延迟情况的测试和分析 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
在版本10.2.0.4未打上相關(guān)one-off補(bǔ)丁的情況下,分別對(duì)ASSM和MSSM管理模式表空間進(jìn)行索引分裂測(cè)試,經(jīng)過(guò)測(cè)試的結(jié)論如下: l? 在10gr2版本中MSSM方式是不能避免索引分裂引起交易超時(shí)問(wèn)題; l? 10.2.0.4上的one-off補(bǔ)丁因?yàn)槟壳皟H存在Linux版本,可以考慮聲請(qǐng)補(bǔ)丁后具體測(cè)試(因目前沒(méi)有補(bǔ)丁所以處于未知狀態(tài))。 l? 合并索引是目前最具可行性的解決方案(alter index coalesce)。 l? 最新的11gr2中經(jīng)測(cè)試仍存在該問(wèn)題。 具體測(cè)試過(guò)程如下: 1.? ? 自動(dòng)段管理模式下的索引塊分裂
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; --創(chuàng)建自動(dòng)段管理的表空間 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.???????? -- 創(chuàng)建實(shí)驗(yàn)對(duì)象表及索引 SQL> insert into idx1 select rownum from all_objects, all_objects where rownum <= 250000;?????????? -- 插入25萬(wàn)條記錄 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個(gè)葉塊 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??????????? -- 刪除后葉塊數(shù)量不變 SQL> insert into idx1 select * from idx2;?????????????????? -- 令那些empty 不再empty,但每個(gè)塊中只有一到二條記錄,空閑率仍為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???????????????? --找出當(dāng)前會(huì)話(huà)目前的葉塊分裂次數(shù) SQL>insert into idx1 values (251000);??????????????????????????????????????? -- 此處確實(shí)葉塊分裂 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???????? -- 可以看到對(duì)比之前的查詢(xún)多了一個(gè)葉塊分裂 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)???? -- 讀了那些實(shí)際不空的塊,較多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所示,在自動(dòng)段管理模式下大量刪除后插入造成許多塊為75%-100%空閑率且不完全為空,此后葉塊分裂時(shí)將引起插入操作的相關(guān)前臺(tái)進(jìn)程掃描大量“空塊“,若這些塊不在內(nèi)存中(引發(fā)物理讀)且可能需要延遲塊清除等原因時(shí),減緩了該掃描操作的速度,造成葉塊分裂緩慢,最終導(dǎo)致了其他insert操作被split操作所阻塞,出現(xiàn)enq:tx index contention等待事件。 2.? 手動(dòng)段管理模式下的索引塊分裂
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);????????????????????????????????? -- 確實(shí)分裂 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時(shí)完全一致 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時(shí)一致 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并不能解決大量刪除后葉塊分裂需要掃描大量非空塊的問(wèn)題,實(shí)際上可能更糟糕。從理論上講MSSM的freelist只能指出那些未達(dá)到pctfree和曾經(jīng)到達(dá)pctfree后來(lái)刪除記錄后使用空間下降到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模式下”空塊“會(huì)更多。 3.? 自動(dòng)段管理模式下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);?????????????????????????????????????? -- 確實(shí)分裂 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.
如演示三所示在刪除后進(jìn)行coalesce操作,合并操作將大量空塊分離出了索引結(jié)構(gòu)(move empty out of index structure),之后的葉塊分裂僅讀取了少量必要的塊。 4.? 手動(dòng)段管理模式下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);?????????????????????? -- 確實(shí)分裂 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情況下大致一樣,合并操作可以有效解決該問(wèn)題。 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操作會(huì)block一切dml操作 SQL> select blocks,lf_blks,del_lf_rows from index_stats; BLOCKS??? LF_BLKS DEL_LF_ROWS ---------- ---------- ----------- 8????????? 6??????? 2500????????? -- 刪除后的狀態(tài) 此時(shí)另開(kāi)一個(gè)會(huì)話(huà),開(kāi)始dml操作: SQL> update coal set t1=t1+1; 500 rows updated. -- 回到原會(huì)話(huà) SQL> alter index pk_T1 coalesce;???????????? -- coalesce 未被阻塞 Index altered. -- 在另一個(gè)會(huì)話(huà)中commit,以便執(zhí)行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的操作沒(méi)有涉及有dml操作的塊 在沒(méi)有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 --沒(méi)有dml時(shí),coalesce 操作涉及了所有塊
如演示5所示coalesce會(huì)避開(kāi)dml操作涉及的塊,但在coalesec的短暫間歇出現(xiàn)在索引上有事務(wù)的塊不會(huì)太多。且coalesce操作不會(huì)降低索引高度。 附件是關(guān)于rebuild及coalesce索引操作的詳細(xì)描述: 6.? Coalesce操作總結(jié) 優(yōu)點(diǎn): l? 是一種快速的操作,對(duì)整體性能影響最小(not performance sensitive)。 l? 不會(huì)鎖表,繞過(guò)有事務(wù)的索引塊。 l? 可以有效解決現(xiàn)有的問(wèn)題。 l? 不會(huì)降低索引高度,引起再次的root split 缺點(diǎn): l? 需要針對(duì)個(gè)別對(duì)象,定期執(zhí)行合并操作;無(wú)法一勞永逸地全局地解決該問(wèn)題。 7.? Linux 10.2.0.4上相關(guān)補(bǔ)丁的技術(shù)交流 Metalink bug 8286901 note中敘述了一位用戶(hù)遇到相同的問(wèn)題并提交了SR,當(dāng)時(shí)oracle support給出了one-off補(bǔ)丁,但該用戶(hù)在apply了該補(bǔ)丁后仍未解決問(wèn)題。 以下為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."
與該用戶(hù)進(jìn)行了mail私下交流,他的回復(fù):
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上的測(cè)試
--在最新的11gr2中進(jìn)行了測(cè)試,仍可以重現(xiàn)該問(wèn)題(如圖單條insert引起了6675buffer_gets,這是在更大量數(shù)據(jù)的情況下)。
我們可以猜測(cè)Oracle提供的one-off補(bǔ)丁中可能是為葉塊分裂所會(huì)掃描的“空塊”附加了一個(gè)上限,在未達(dá)到上限的情況下掃描仍會(huì)發(fā)生。而在主流的公開(kāi)的發(fā)行版本中Oracle不會(huì)引入該補(bǔ)丁的內(nèi)容。嘗試在沒(méi)有緩存的情況下引起分裂問(wèn)題,分裂引起了大約4000個(gè)塊的物理讀,但該操作仍在0.12秒(有緩存是0.02秒,如圖)內(nèi)完成了(該測(cè)試使用普通ata硬盤(pán),讀取速度在100MB/S: Timing buffered disk reads:? 306 MB in? 3.00 seconds = 101.93 MB/sec);從1月21日的ash視圖中可以看到引起split的260會(huì)話(huà)處于單塊讀等待(db file sequential read)中,且已等待了43950us約等于44ms;這與良好io的經(jīng)驗(yàn)值10ms左右有較大出入;我們可以確信io性能問(wèn)題也是引發(fā)此葉塊分裂延遲如此顯性的一個(gè)重要因素。

具體結(jié)論

綜上所述,在之前討論的幾個(gè)方案中,MSSM方式是不能避免索引分裂引起交易超時(shí)問(wèn)題的;不刪除數(shù)據(jù)的方案在許多對(duì)象上不可行;10.2.0.4上的one-off補(bǔ)丁因?yàn)槟壳皟H存在Linux版本,可以考慮聲請(qǐng)補(bǔ)丁后具體測(cè)試(因目前沒(méi)有補(bǔ)丁所以處于未知狀態(tài))。Coalesce合并索引是目前既有的最具可操作性且無(wú)副作用的解決方案。

轉(zhuǎn)載于:https://www.cnblogs.com/macleanoracle/archive/2010/03/21/2967378.html

總結(jié)

以上是生活随笔為你收集整理的对Oracle中索引叶块分裂而引起延迟情况的测试和分析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。