[20180608]Wrong Results with IOT, Added Column and Secondary Index.txt
[20180608]Wrong Results with IOT, Added Column and Secondary Index.txt
--//連結:
--//我記得ITPUB上也有一位網友遇到類似的問題.
1.環境:
SCOTT@test01p> @ ver1
PORT_STRING VERSION BANNER CON_ID
-------------------- ---------- ---------------------------------------------------------------------------- ------
IBMPC/WIN_NT64-9.1.0 12.1.0.1.0 Oracle Database 12c Enterprise Edition Release 12.1.0.1.0 - 64bit Production 0
2.測試:
create table iot (
x number,
y number,
constraint iot_pk primary key (x,y)
) organization index;
--//建立第二索引:
create index secondary_idx on iot (y);
--//插入測試資料:
insert into iot select rownum,mod(rownum,3) from dual connect by level<=7;
commit;
--//分析表略.
--//增加1列:
alter table iot add z number;
update iot set z=42 where x=1;
commit;
--//檢視IOT表資訊:
SCOTT@test01p> select * from iot;
X Y Z
------- ---------- ----------
1 1 42
2 2
3 0
4 1
5 2
6 0
7 1
7 rows selected.
--//Note that z contains the value 42 in the first row and null in all the other rows.
SCOTT@test01p> select * from iot where y=1;
X Y Z
------- ---------- ----------
1 1 42
4 1
7 1
SCOTT@test01p> @ dpc '' ''
PLAN_TABLE_OUTPUT
-------------------------------------
SQL_ID 2r4bmd68zgj5u, child number 0
-------------------------------------
select * from iot where y=1
Plan hash value: 1517155850
----------------------------------------------------------------------------
| Id | Operation | Name | E-Rows |E-Bytes| Cost (%CPU)| E-Time |
----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 1 (100)| |
|* 1 | INDEX SKIP SCAN | IOT_PK | 2 | 12 | 1 (0)| 00:00:01 |
----------------------------------------------------------------------------
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
1 - SEL$1 / IOT@SEL$1
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("Y"=1)
filter("Y"=1)
--//我的測試是ok的,不過12c使用IOT_Pk 索引.走的是INDEX SKIP SCAN.沒有選擇secondary_idx索引.
--//使用提示/*+index(iot secondary_idx) */看看.
SCOTT@test01p> select /*+index(iot secondary_idx) */ * from iot where y=1;
X Y Z
------- ---------- ----------
1 1 42
4 1 42
7 1 42
--//對比前面可以發現走第2索引出現問題,顯示結果錯誤.
SCOTT@test01p> @ dpc '' ''
PLAN_TABLE_OUTPUT
-------------------------------------
SQL_ID 07mgh5fbhmc5q, child number 0
-------------------------------------
select /*+index(iot secondary_idx) */ * from iot where y=1
Plan hash value: 177722221
------------------------------------------------------------------------------------
| Id | Operation | Name | E-Rows |E-Bytes| Cost (%CPU)| E-Time |
------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 1 (100)| |
|* 1 | INDEX UNIQUE SCAN| IOT_PK | 2 | 12 | 1 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN| SECONDARY_IDX | 2 | | 1 (0)| 00:00:01 |
------------------------------------------------------------------------------------
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
1 - SEL$1 / IOT@SEL$1
2 - SEL$1 / IOT@SEL$1
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("Y"=1)
2 - access("Y"=1)
SCOTT@test01p> select /*+ index (iot secondary_idx) */ * from iot where y=2 ;
X Y Z
------- ---------- ----------
2 2
5 2
--//這個正確.
It seems that the problem is not with the secondary index itself, as we get the correct rows, but something with
accessing the table via the secondary index causes the wrong results.
If we hint the query to access the table directly we get the correct results:
select /*+ index_ffs (iot) */ * from iot where y=1;
SCOTT@test01p> select /*+ index_ffs (iot) */ * from iot where y=1;
X Y Z
------- ---------- ----------
1 1 42
4 1
7 1
SCOTT@test01p> @ dpc '' ''
PLAN_TABLE_OUTPUT
-------------------------------------
SQL_ID 9k5qc6yx1ju0m, child number 0
-------------------------------------
select /*+ index_ffs (iot) */ * from iot where y=1
Plan hash value: 3252171408
--------------------------------------------------------------------------------
| Id | Operation | Name | E-Rows |E-Bytes| Cost (%CPU)| E-Time |
--------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 2 (100)| |
|* 1 | INDEX FAST FULL SCAN| IOT_PK | 2 | 12 | 2 (0)| 00:00:01 |
--------------------------------------------------------------------------------
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
1 - SEL$1 / IOT@SEL$1
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("Y"=1)
3.作者沒有給出為什麼?自己分析看看.
SCOTT@test01p> select dump(rowid,16) c50 ,rowid,dump(x,16) c20 ,dump(y,16)c20 ,x,y from iot where y=1;
C50 ROWID C20 C20 X Y
---------------------------------------------- ----------------- ----------------- ----------------- - --
Typ=208 Len=13: 2,4,2,40,0,f3,2,c1,2,2,c1,2,fe *BAJAAPMCwQICwQL+ Typ=2 Len=2: c1,2 Typ=2 Len=2: c1,2 1 1
Typ=208 Len=13: 2,4,2,40,0,f3,2,c1,5,2,c1,2,fe *BAJAAPMCwQUCwQL+ Typ=2 Len=2: c1,5 Typ=2 Len=2: c1,2 4 1
Typ=208 Len=13: 2,4,2,40,0,f3,2,c1,8,2,c1,2,fe *BAJAAPMCwQgCwQL+ Typ=2 Len=2: c1,8 Typ=2 Len=2: c1,2 7 1
--//以上查詢僅僅掃描secondary_idx就ok,因為主鍵x,y的資訊儲存在rowid中,這種rowid叫邏輯rowid.
SCOTT@test01p> select header_file,header_block from dba_segments where segment_name='IOT_PK';
HEADER_FILE HEADER_BLOCK
----------- ------------
9 242
--//IOT_PK索引的根節點就是dba=9,243.
SCOTT@test01p> @ convrdba.sql 9 243
RDBA16 RDBA
--------- ----------
024000f3 37748979
--//關於IOT的rowid相關資訊參考:http://blog.itpub.net/267265/viewspace-717272/
--//再次總結如下:
1.開頭的2,4,以及結尾fe實在不好猜測,不過好像是固定不變的。
2.中間的2,40,0,f3正好對應的就是IOT的根節點,也就是對應資料IOT的資料塊。
3.2,c1,8,2,c1,2實際上就是主鍵資訊,2中2表示主鍵x的長度,c1,8就是主鍵x的資訊=7,
2,c1,2 中2表示主鍵y的長度,c1,2就是主鍵y的資訊.
--//以前也提過這種情況可能出現儲存在rowid的塊可能不是真實的資料塊,因為iot的本質就是索引,可能索引分裂導致
--//相關資訊不再原來的塊中,這種情況叫物理猜.參考:http://blog.itpub.net/267265/viewspace-723115/
--//現在再來看看select /*+index(iot secondary_idx) */ * from iot where y=1;為什麼錯誤.
SCOTT@test01p> alter system dump datafile 9 block 243 ;
System altered.
Block header dump: 0x024000f3
Object id on Block? Y
seg/obj: 0x1a436 csc: 0x00.1a10c8b itc: 2 flg: E typ: 2 - INDEX
brn: 0 bdba: 0x24000f0 ver: 0x01 opc: 0
inc: 0 exflg: 0
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0000.000.00000000 0x00000000.0000.00 ---- 0 fsc 0x0000.00000000
0x02 0x000a.003.00006526 0x01400b0a.0664.17 --U- 1 fsc 0x0000.01a10c90
Leaf block dump
===============
header address 187256932=0xb295064
kdxcolev 0
KDXCOLEV Flags = - - -
kdxcolok 0
kdxcoopc 0x90: opcode=0: iot flags=I-- is converted=Y
kdxconco 2
kdxcosdc 0
kdxconro 7
kdxcofbo 50=0x32
kdxcofeo 7968=0x1f20
kdxcoavs 7926
kdxlespl 0
kdxlende 0
kdxlenxt 0=0x0
kdxleprv 0=0x0
kdxledsz 0
kdxlebksz 8036
row#0[7968] flag: K------, lock: 2, len=14
col 0; len 2; (2): c1 02
col 1; len 2; (2): c1 02
tl: 6 fb: --H-FL-- lb: 0x0 cc: 1
col 0: [ 2] c1 2b => 對應數字42
row#1[7990] flag: -------, lock: 0, len=8
col 0; len 2; (2): c1 03
col 1; len 2; (2): c1 03
row#2[7998] flag: -------, lock: 0, len=7
col 0; len 2; (2): c1 04
col 1; len 1; (1): 80
row#3[8005] flag: -------, lock: 0, len=8
col 0; len 2; (2): c1 05
col 1; len 2; (2): c1 02
row#4[8013] flag: -------, lock: 0, len=8
col 0; len 2; (2): c1 06
col 1; len 2; (2): c1 03
row#5[8021] flag: -------, lock: 0, len=7
col 0; len 2; (2): c1 07
col 1; len 1; (1): 80
row#6[8028] flag: -------, lock: 0, len=8
col 0; len 2; (2): c1 08
col 1; len 2; (2): c1 02
----- end of leaf block Logical dump -----
--//視乎也沒看出什麼問題.
--//再修改1條看看:
SCOTT@test01p> update iot set z=43 where x=4;
1 row updated.
SCOTT@test01p> commit ;
Commit complete.
SCOTT@test01p> select /*+ index (iot secondary_idx) */ * from iot where y=1 ;
X Y Z
------- ---------- ----------
1 1 42
4 1 43
7 1 43
--//x=7 那行變成z=43.也是錯誤的.看來這個是一個bug.
--//視乎這樣的錯誤重建索引應該也沒有用.
SCOTT@test01p> alter index secondary_idx rebuild ;
Index altered.
SCOTT@test01p> select /*+ index (iot secondary_idx) */ * from iot where y=1 ;
X Y Z
------- ---------- ----------
1 1 42
4 1 43
7 1 43
--//換一種方式也應該一樣.
SCOTT@test01p> alter index secondary_idx update block references;
Index altered.
SCOTT@test01p> select /*+ index (iot secondary_idx) */ * from iot where y=1 ;
X Y Z
------- ---------- ----------
1 1 42
4 1 43
7 1 43
SCOTT@test01p> alter index iot_pk rebuild ;
alter index iot_pk rebuild
*
ERROR at line 1:
ORA-28650: Primary index on an IOT cannot be rebuilt
--//不能這樣操作.
SCOTT@test01p> alter table iot move tablespace users;
Table altered.
SCOTT@test01p> select /*+ index (iot secondary_idx) */ * from iot where y=1 ;
X Y Z
------- ---------- ----------
1 1 42
4 1 43
7 1
--//這樣顯示正確,為什麼實際上這個時候物理猜失敗.另外對應IOT表(實際上是索引),移動表空間其他索引依舊有效.
SCOTT@test01p> select dump(rowid,16) c50 ,rowid,dump(x,16) c20 ,dump(y,16)c20 ,x,y from iot where y=1;
C50 ROWID C20 C20 X Y
---------------------------------------------- ----------------- -------------------- -------------------- ------- ----------
Typ=208 Len=13: 2,4,2,40,0,f3,2,c1,2,2,c1,2,fe *BAJAAPMCwQICwQL+ Typ=2 Len=2: c1,2 Typ=2 Len=2: c1,2 1 1
Typ=208 Len=13: 2,4,2,40,0,f3,2,c1,5,2,c1,2,fe *BAJAAPMCwQUCwQL+ Typ=2 Len=2: c1,5 Typ=2 Len=2: c1,2 4 1
Typ=208 Len=13: 2,4,2,40,0,f3,2,c1,8,2,c1,2,fe *BAJAAPMCwQgCwQL+ Typ=2 Len=2: c1,8 Typ=2 Len=2: c1,2 7 1
--//對比前面2,40,0,f3沒變.
SCOTT@test01p> select header_file,header_block from dba_segments where segment_name='IOT_PK';
HEADER_FILE HEADER_BLOCK
----------- ------------
9 250
--//而實際上現在IOT的根節點是dba=9,251.如果現在rebuild secondary_idx問題應該會再現嗎?
SCOTT@test01p> alter index secondary_idx rebuild ;
Index altered.
SCOTT@test01p> select dump(rowid,16) c50 ,rowid,dump(x,16) c20 ,dump(y,16)c20 ,x,y from iot where y=1;
C50 ROWID C20 C20 X Y
-------------------------------------------------- ----------------- -------------------- -------------------- ------- ----------
Typ=208 Len=13: 2,4,2,40,0,fb,2,c1,2,2,c1,2,fe *BAJAAPsCwQICwQL+ Typ=2 Len=2: c1,2 Typ=2 Len=2: c1,2 1 1
Typ=208 Len=13: 2,4,2,40,0,fb,2,c1,5,2,c1,2,fe *BAJAAPsCwQUCwQL+ Typ=2 Len=2: c1,5 Typ=2 Len=2: c1,2 4 1
Typ=208 Len=13: 2,4,2,40,0,fb,2,c1,8,2,c1,2,fe *BAJAAPsCwQgCwQL+ Typ=2 Len=2: c1,8 Typ=2 Len=2: c1,2 7 1
SCOTT@test01p> @ convrdba.sql 9 251
RDBA16 RDBA
--------- ----------
024000fb 37748987
SCOTT@test01p> select /*+ index (iot secondary_idx) */ * from iot where y=1 ;
X Y Z
------- ---------- ----------
1 1 42
4 1 43
7 1
--//現在顯示正確的.
SCOTT@test01p> alter system dump datafile 9 block 251 ;
System altered.
Block header dump: 0x024000fb
Object id on Block? Y
seg/obj: 0x1a43c csc: 0x00.1a13f09 itc: 2 flg: E typ: 2 - INDEX
brn: 0 bdba: 0x24000f8 ver: 0x01 opc: 0
inc: 0 exflg: 0
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0000.000.00000000 0x00000000.0000.00 ---- 0 fsc 0x0000.00000000
0x02 0xffff.000.00000000 0x00000000.0000.00 C--- 0 scn 0x0000.01a13f09
Leaf block dump
===============
header address 187256932=0xb295064
kdxcolev 0
KDXCOLEV Flags = - - -
kdxcolok 0
kdxcoopc 0x90: opcode=0: iot flags=I-- is converted=Y
kdxconco 2
kdxcosdc 0
kdxconro 7
kdxcofbo 50=0x32
kdxcofeo 7955=0x1f13
kdxcoavs 7905
kdxlespl 0
kdxlende 0
kdxlenxt 0=0x0
kdxleprv 0=0x0
kdxledsz 0
kdxlebksz 8036
row#0[8022] flag: K------, lock: 0, len=14
col 0; len 2; (2): c1 02
col 1; len 2; (2): c1 02
tl: 6 fb: --H-FL-- lb: 0x0 cc: 1
col 0: [ 2] c1 2b
row#1[8011] flag: K------, lock: 0, len=11
col 0; len 2; (2): c1 03
col 1; len 2; (2): c1 03
tl: 3 fb: --H-FL-- lb: 0x0 cc: 0
row#2[8001] flag: K------, lock: 0, len=10
col 0; len 2; (2): c1 04
col 1; len 1; (1): 80
tl: 3 fb: --H-FL-- lb: 0x0 cc: 0
row#3[7987] flag: K------, lock: 0, len=14
col 0; len 2; (2): c1 05
col 1; len 2; (2): c1 02
tl: 6 fb: --H-FL-- lb: 0x0 cc: 1
col 0: [ 2] c1 2c
row#4[7976] flag: K------, lock: 0, len=11
col 0; len 2; (2): c1 06
col 1; len 2; (2): c1 03
tl: 3 fb: --H-FL-- lb: 0x0 cc: 0
row#5[7966] flag: K------, lock: 0, len=10
col 0; len 2; (2): c1 07
col 1; len 1; (1): 80
tl: 3 fb: --H-FL-- lb: 0x0 cc: 0
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
row#6[7955] flag: K------, lock: 0, len=11
col 0; len 2; (2): c1 08
col 1; len 2; (2): c1 02
tl: 3 fb: --H-FL-- lb: 0x0 cc: 0
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //前面tl: 3應該表示長度.
--//注意看下劃線資訊,前面沒有,也許就是這樣導致異常.因為z欄位是增加的欄位,前面的測試並沒有修改索引塊.
4.按照這樣的測試,如果在IOT增加欄位,修改值都有可能出現查詢異常的情況.
--//這個應該在實際的工作引起重視,不過在國內許多應用中在業務表使用IOT的情況很少,^_^.
--//補充說明:可以發現作者建立的iot非常特殊,開始僅僅都是主鍵.然後在增加欄位,估計這種情況很少見.
5.附上convrdba.sql的指令碼:
select
TO_CHAR (dbms_utility.make_data_block_address(&1,&2), 'FM0xxxxxxxx') rdba16,
dbms_utility.make_data_block_address(&&1,&&2) rdba
from dual;
--//連結:
--//我記得ITPUB上也有一位網友遇到類似的問題.
1.環境:
SCOTT@test01p> @ ver1
PORT_STRING VERSION BANNER CON_ID
-------------------- ---------- ---------------------------------------------------------------------------- ------
IBMPC/WIN_NT64-9.1.0 12.1.0.1.0 Oracle Database 12c Enterprise Edition Release 12.1.0.1.0 - 64bit Production 0
2.測試:
create table iot (
x number,
y number,
constraint iot_pk primary key (x,y)
) organization index;
--//建立第二索引:
create index secondary_idx on iot (y);
--//插入測試資料:
insert into iot select rownum,mod(rownum,3) from dual connect by level<=7;
commit;
--//分析表略.
--//增加1列:
alter table iot add z number;
update iot set z=42 where x=1;
commit;
--//檢視IOT表資訊:
SCOTT@test01p> select * from iot;
X Y Z
------- ---------- ----------
1 1 42
2 2
3 0
4 1
5 2
6 0
7 1
7 rows selected.
--//Note that z contains the value 42 in the first row and null in all the other rows.
SCOTT@test01p> select * from iot where y=1;
X Y Z
------- ---------- ----------
1 1 42
4 1
7 1
SCOTT@test01p> @ dpc '' ''
PLAN_TABLE_OUTPUT
-------------------------------------
SQL_ID 2r4bmd68zgj5u, child number 0
-------------------------------------
select * from iot where y=1
Plan hash value: 1517155850
----------------------------------------------------------------------------
| Id | Operation | Name | E-Rows |E-Bytes| Cost (%CPU)| E-Time |
----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 1 (100)| |
|* 1 | INDEX SKIP SCAN | IOT_PK | 2 | 12 | 1 (0)| 00:00:01 |
----------------------------------------------------------------------------
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
1 - SEL$1 / IOT@SEL$1
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("Y"=1)
filter("Y"=1)
--//我的測試是ok的,不過12c使用IOT_Pk 索引.走的是INDEX SKIP SCAN.沒有選擇secondary_idx索引.
--//使用提示/*+index(iot secondary_idx) */看看.
SCOTT@test01p> select /*+index(iot secondary_idx) */ * from iot where y=1;
X Y Z
------- ---------- ----------
1 1 42
4 1 42
7 1 42
--//對比前面可以發現走第2索引出現問題,顯示結果錯誤.
SCOTT@test01p> @ dpc '' ''
PLAN_TABLE_OUTPUT
-------------------------------------
SQL_ID 07mgh5fbhmc5q, child number 0
-------------------------------------
select /*+index(iot secondary_idx) */ * from iot where y=1
Plan hash value: 177722221
------------------------------------------------------------------------------------
| Id | Operation | Name | E-Rows |E-Bytes| Cost (%CPU)| E-Time |
------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 1 (100)| |
|* 1 | INDEX UNIQUE SCAN| IOT_PK | 2 | 12 | 1 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN| SECONDARY_IDX | 2 | | 1 (0)| 00:00:01 |
------------------------------------------------------------------------------------
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
1 - SEL$1 / IOT@SEL$1
2 - SEL$1 / IOT@SEL$1
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("Y"=1)
2 - access("Y"=1)
SCOTT@test01p> select /*+ index (iot secondary_idx) */ * from iot where y=2 ;
X Y Z
------- ---------- ----------
2 2
5 2
--//這個正確.
It seems that the problem is not with the secondary index itself, as we get the correct rows, but something with
accessing the table via the secondary index causes the wrong results.
If we hint the query to access the table directly we get the correct results:
select /*+ index_ffs (iot) */ * from iot where y=1;
SCOTT@test01p> select /*+ index_ffs (iot) */ * from iot where y=1;
X Y Z
------- ---------- ----------
1 1 42
4 1
7 1
SCOTT@test01p> @ dpc '' ''
PLAN_TABLE_OUTPUT
-------------------------------------
SQL_ID 9k5qc6yx1ju0m, child number 0
-------------------------------------
select /*+ index_ffs (iot) */ * from iot where y=1
Plan hash value: 3252171408
--------------------------------------------------------------------------------
| Id | Operation | Name | E-Rows |E-Bytes| Cost (%CPU)| E-Time |
--------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 2 (100)| |
|* 1 | INDEX FAST FULL SCAN| IOT_PK | 2 | 12 | 2 (0)| 00:00:01 |
--------------------------------------------------------------------------------
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
1 - SEL$1 / IOT@SEL$1
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("Y"=1)
3.作者沒有給出為什麼?自己分析看看.
SCOTT@test01p> select dump(rowid,16) c50 ,rowid,dump(x,16) c20 ,dump(y,16)c20 ,x,y from iot where y=1;
C50 ROWID C20 C20 X Y
---------------------------------------------- ----------------- ----------------- ----------------- - --
Typ=208 Len=13: 2,4,2,40,0,f3,2,c1,2,2,c1,2,fe *BAJAAPMCwQICwQL+ Typ=2 Len=2: c1,2 Typ=2 Len=2: c1,2 1 1
Typ=208 Len=13: 2,4,2,40,0,f3,2,c1,5,2,c1,2,fe *BAJAAPMCwQUCwQL+ Typ=2 Len=2: c1,5 Typ=2 Len=2: c1,2 4 1
Typ=208 Len=13: 2,4,2,40,0,f3,2,c1,8,2,c1,2,fe *BAJAAPMCwQgCwQL+ Typ=2 Len=2: c1,8 Typ=2 Len=2: c1,2 7 1
--//以上查詢僅僅掃描secondary_idx就ok,因為主鍵x,y的資訊儲存在rowid中,這種rowid叫邏輯rowid.
SCOTT@test01p> select header_file,header_block from dba_segments where segment_name='IOT_PK';
HEADER_FILE HEADER_BLOCK
----------- ------------
9 242
--//IOT_PK索引的根節點就是dba=9,243.
SCOTT@test01p> @ convrdba.sql 9 243
RDBA16 RDBA
--------- ----------
024000f3 37748979
--//關於IOT的rowid相關資訊參考:http://blog.itpub.net/267265/viewspace-717272/
--//再次總結如下:
1.開頭的2,4,以及結尾fe實在不好猜測,不過好像是固定不變的。
2.中間的2,40,0,f3正好對應的就是IOT的根節點,也就是對應資料IOT的資料塊。
3.2,c1,8,2,c1,2實際上就是主鍵資訊,2中2表示主鍵x的長度,c1,8就是主鍵x的資訊=7,
2,c1,2 中2表示主鍵y的長度,c1,2就是主鍵y的資訊.
--//以前也提過這種情況可能出現儲存在rowid的塊可能不是真實的資料塊,因為iot的本質就是索引,可能索引分裂導致
--//相關資訊不再原來的塊中,這種情況叫物理猜.參考:http://blog.itpub.net/267265/viewspace-723115/
--//現在再來看看select /*+index(iot secondary_idx) */ * from iot where y=1;為什麼錯誤.
SCOTT@test01p> alter system dump datafile 9 block 243 ;
System altered.
Block header dump: 0x024000f3
Object id on Block? Y
seg/obj: 0x1a436 csc: 0x00.1a10c8b itc: 2 flg: E typ: 2 - INDEX
brn: 0 bdba: 0x24000f0 ver: 0x01 opc: 0
inc: 0 exflg: 0
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0000.000.00000000 0x00000000.0000.00 ---- 0 fsc 0x0000.00000000
0x02 0x000a.003.00006526 0x01400b0a.0664.17 --U- 1 fsc 0x0000.01a10c90
Leaf block dump
===============
header address 187256932=0xb295064
kdxcolev 0
KDXCOLEV Flags = - - -
kdxcolok 0
kdxcoopc 0x90: opcode=0: iot flags=I-- is converted=Y
kdxconco 2
kdxcosdc 0
kdxconro 7
kdxcofbo 50=0x32
kdxcofeo 7968=0x1f20
kdxcoavs 7926
kdxlespl 0
kdxlende 0
kdxlenxt 0=0x0
kdxleprv 0=0x0
kdxledsz 0
kdxlebksz 8036
row#0[7968] flag: K------, lock: 2, len=14
col 0; len 2; (2): c1 02
col 1; len 2; (2): c1 02
tl: 6 fb: --H-FL-- lb: 0x0 cc: 1
col 0: [ 2] c1 2b => 對應數字42
row#1[7990] flag: -------, lock: 0, len=8
col 0; len 2; (2): c1 03
col 1; len 2; (2): c1 03
row#2[7998] flag: -------, lock: 0, len=7
col 0; len 2; (2): c1 04
col 1; len 1; (1): 80
row#3[8005] flag: -------, lock: 0, len=8
col 0; len 2; (2): c1 05
col 1; len 2; (2): c1 02
row#4[8013] flag: -------, lock: 0, len=8
col 0; len 2; (2): c1 06
col 1; len 2; (2): c1 03
row#5[8021] flag: -------, lock: 0, len=7
col 0; len 2; (2): c1 07
col 1; len 1; (1): 80
row#6[8028] flag: -------, lock: 0, len=8
col 0; len 2; (2): c1 08
col 1; len 2; (2): c1 02
----- end of leaf block Logical dump -----
--//視乎也沒看出什麼問題.
--//再修改1條看看:
SCOTT@test01p> update iot set z=43 where x=4;
1 row updated.
SCOTT@test01p> commit ;
Commit complete.
SCOTT@test01p> select /*+ index (iot secondary_idx) */ * from iot where y=1 ;
X Y Z
------- ---------- ----------
1 1 42
4 1 43
7 1 43
--//x=7 那行變成z=43.也是錯誤的.看來這個是一個bug.
--//視乎這樣的錯誤重建索引應該也沒有用.
SCOTT@test01p> alter index secondary_idx rebuild ;
Index altered.
SCOTT@test01p> select /*+ index (iot secondary_idx) */ * from iot where y=1 ;
X Y Z
------- ---------- ----------
1 1 42
4 1 43
7 1 43
--//換一種方式也應該一樣.
SCOTT@test01p> alter index secondary_idx update block references;
Index altered.
SCOTT@test01p> select /*+ index (iot secondary_idx) */ * from iot where y=1 ;
X Y Z
------- ---------- ----------
1 1 42
4 1 43
7 1 43
SCOTT@test01p> alter index iot_pk rebuild ;
alter index iot_pk rebuild
*
ERROR at line 1:
ORA-28650: Primary index on an IOT cannot be rebuilt
--//不能這樣操作.
SCOTT@test01p> alter table iot move tablespace users;
Table altered.
SCOTT@test01p> select /*+ index (iot secondary_idx) */ * from iot where y=1 ;
X Y Z
------- ---------- ----------
1 1 42
4 1 43
7 1
--//這樣顯示正確,為什麼實際上這個時候物理猜失敗.另外對應IOT表(實際上是索引),移動表空間其他索引依舊有效.
SCOTT@test01p> select dump(rowid,16) c50 ,rowid,dump(x,16) c20 ,dump(y,16)c20 ,x,y from iot where y=1;
C50 ROWID C20 C20 X Y
---------------------------------------------- ----------------- -------------------- -------------------- ------- ----------
Typ=208 Len=13: 2,4,2,40,0,f3,2,c1,2,2,c1,2,fe *BAJAAPMCwQICwQL+ Typ=2 Len=2: c1,2 Typ=2 Len=2: c1,2 1 1
Typ=208 Len=13: 2,4,2,40,0,f3,2,c1,5,2,c1,2,fe *BAJAAPMCwQUCwQL+ Typ=2 Len=2: c1,5 Typ=2 Len=2: c1,2 4 1
Typ=208 Len=13: 2,4,2,40,0,f3,2,c1,8,2,c1,2,fe *BAJAAPMCwQgCwQL+ Typ=2 Len=2: c1,8 Typ=2 Len=2: c1,2 7 1
--//對比前面2,40,0,f3沒變.
SCOTT@test01p> select header_file,header_block from dba_segments where segment_name='IOT_PK';
HEADER_FILE HEADER_BLOCK
----------- ------------
9 250
--//而實際上現在IOT的根節點是dba=9,251.如果現在rebuild secondary_idx問題應該會再現嗎?
SCOTT@test01p> alter index secondary_idx rebuild ;
Index altered.
SCOTT@test01p> select dump(rowid,16) c50 ,rowid,dump(x,16) c20 ,dump(y,16)c20 ,x,y from iot where y=1;
C50 ROWID C20 C20 X Y
-------------------------------------------------- ----------------- -------------------- -------------------- ------- ----------
Typ=208 Len=13: 2,4,2,40,0,fb,2,c1,2,2,c1,2,fe *BAJAAPsCwQICwQL+ Typ=2 Len=2: c1,2 Typ=2 Len=2: c1,2 1 1
Typ=208 Len=13: 2,4,2,40,0,fb,2,c1,5,2,c1,2,fe *BAJAAPsCwQUCwQL+ Typ=2 Len=2: c1,5 Typ=2 Len=2: c1,2 4 1
Typ=208 Len=13: 2,4,2,40,0,fb,2,c1,8,2,c1,2,fe *BAJAAPsCwQgCwQL+ Typ=2 Len=2: c1,8 Typ=2 Len=2: c1,2 7 1
SCOTT@test01p> @ convrdba.sql 9 251
RDBA16 RDBA
--------- ----------
024000fb 37748987
SCOTT@test01p> select /*+ index (iot secondary_idx) */ * from iot where y=1 ;
X Y Z
------- ---------- ----------
1 1 42
4 1 43
7 1
--//現在顯示正確的.
SCOTT@test01p> alter system dump datafile 9 block 251 ;
System altered.
Block header dump: 0x024000fb
Object id on Block? Y
seg/obj: 0x1a43c csc: 0x00.1a13f09 itc: 2 flg: E typ: 2 - INDEX
brn: 0 bdba: 0x24000f8 ver: 0x01 opc: 0
inc: 0 exflg: 0
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0000.000.00000000 0x00000000.0000.00 ---- 0 fsc 0x0000.00000000
0x02 0xffff.000.00000000 0x00000000.0000.00 C--- 0 scn 0x0000.01a13f09
Leaf block dump
===============
header address 187256932=0xb295064
kdxcolev 0
KDXCOLEV Flags = - - -
kdxcolok 0
kdxcoopc 0x90: opcode=0: iot flags=I-- is converted=Y
kdxconco 2
kdxcosdc 0
kdxconro 7
kdxcofbo 50=0x32
kdxcofeo 7955=0x1f13
kdxcoavs 7905
kdxlespl 0
kdxlende 0
kdxlenxt 0=0x0
kdxleprv 0=0x0
kdxledsz 0
kdxlebksz 8036
row#0[8022] flag: K------, lock: 0, len=14
col 0; len 2; (2): c1 02
col 1; len 2; (2): c1 02
tl: 6 fb: --H-FL-- lb: 0x0 cc: 1
col 0: [ 2] c1 2b
row#1[8011] flag: K------, lock: 0, len=11
col 0; len 2; (2): c1 03
col 1; len 2; (2): c1 03
tl: 3 fb: --H-FL-- lb: 0x0 cc: 0
row#2[8001] flag: K------, lock: 0, len=10
col 0; len 2; (2): c1 04
col 1; len 1; (1): 80
tl: 3 fb: --H-FL-- lb: 0x0 cc: 0
row#3[7987] flag: K------, lock: 0, len=14
col 0; len 2; (2): c1 05
col 1; len 2; (2): c1 02
tl: 6 fb: --H-FL-- lb: 0x0 cc: 1
col 0: [ 2] c1 2c
row#4[7976] flag: K------, lock: 0, len=11
col 0; len 2; (2): c1 06
col 1; len 2; (2): c1 03
tl: 3 fb: --H-FL-- lb: 0x0 cc: 0
row#5[7966] flag: K------, lock: 0, len=10
col 0; len 2; (2): c1 07
col 1; len 1; (1): 80
tl: 3 fb: --H-FL-- lb: 0x0 cc: 0
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
row#6[7955] flag: K------, lock: 0, len=11
col 0; len 2; (2): c1 08
col 1; len 2; (2): c1 02
tl: 3 fb: --H-FL-- lb: 0x0 cc: 0
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //前面tl: 3應該表示長度.
--//注意看下劃線資訊,前面沒有,也許就是這樣導致異常.因為z欄位是增加的欄位,前面的測試並沒有修改索引塊.
4.按照這樣的測試,如果在IOT增加欄位,修改值都有可能出現查詢異常的情況.
--//這個應該在實際的工作引起重視,不過在國內許多應用中在業務表使用IOT的情況很少,^_^.
--//補充說明:可以發現作者建立的iot非常特殊,開始僅僅都是主鍵.然後在增加欄位,估計這種情況很少見.
5.附上convrdba.sql的指令碼:
select
TO_CHAR (dbms_utility.make_data_block_address(&1,&2), 'FM0xxxxxxxx') rdba16,
dbms_utility.make_data_block_address(&&1,&&2) rdba
from dual;
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/267265/viewspace-2155899/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- [20180609]Wrong Results with IOT, Added Column and Secondary Index2.txtIndex
- MySQL 5.7 建立使用者報錯 ERROR 1805 (HY000): Column count of mysql.user is wrongMySqlError
- What is wrong?
- Oracle:On ROWNUM and Limiting ResultsOracleMIT
- iDLHCGP_Numerical_results
- iDLHCG_Numerical_results
- Elasticsearch——Filter search resultsElasticsearchFilter
- 採用secondary的冷備份的方式來新增新的secondary節點
- Numerical Results of adf-mDFP
- js 原生獲取 url地址引數 const query = new URLSearchParams(window.location.search); const added = query.get("added")JS
- Spectrum Entropy Prediction Assisted Channel Selection for Secondary Users
- [20180608]asmcmd顯示檔案的日期時間問題ASM
- secondary logon服務怎麼開啟?Win10系統secondary logon服務的開啟步驟GoWin10
- OGG-01163 Bad column length (32) specified for column in table
- 再見!onActivityResult!你好,Activity Results API!API
- NFS mount results in "vmount: operation not permitted" errorNFSMITError
- 什麼是 Angular library 的 secondary entry points?Angular
- Numerical Results of iFRCGP-I and iFRCGP-II
- Numerical Results of RhDYas CG method and RhLHas CG method
- Hadoop3.2.1 【 HDFS 】原始碼分析 : Secondary Namenode解析Hadoop原始碼
- Index column size too large. The maximum column size is 767 bytes.Index
- [20200904]12c invisible column impdp segment_column_id.txt
- Sorting arrays in NumPy by column
- data too long for column
- CSS column-gapCSS
- CSS column-ruleCSS
- CSS column-widthCSS
- CSS column-spanCSS
- 5.6.7. Renaming a Column
- tomcat新增專案報錯:There are no resources that can be added or removed from the serverTomcatREMServer
- Warning: Permanently added the RSA host key for IP address '13.250.177.223' to the list of known hos
- 1709 - Index column size too large. The maximum column size is 767 bytes.Index
- 揭開OKR (Objectives and Key Results) 的面紗OKRObject
- Results of T2DFP and iT2DFP methods
- [Err] 1709 - Index column size too large. The maximum column size is 767 bytes.Index
- ExtJs的Column佈局JS
- alter table set unused column
- MySQL建立表失敗:Index column size too large. The maximum column size is 767 bytesMySqlIndex