Oracle技術嘉年華的一個案例,redo的那些事,連載三
電梯
Oracle技術嘉年華的一個案例,redo的那些事,連載一
Oracle技術嘉年華的一個案例,redo的那些事,連載二
在上一篇中,修改row flag後,logminer已經可以正確的解析日誌了,那麼,這個問題是否可以重現呢?我們來做個測試。
由於沒有9i環境,我們使用11g環境進行測試,測試結果稍微有些偏差,但不影響結論
首先,我們建立varchar2(4000)型別的三條資料,然後,對這三條資料進行修改,將4000位元組全部佔滿,那麼,必然有一條記錄將發生遷移。
SQL*Plus: Release 11.2.0.3.0 Production on Fri Oct 28 08:34:33 2011
Copyright (c) 1982, 2011, Oracle. All rights reserved.
SQL> conn / as sysdba
Connected.
SQL> create table t (a varchar2(4000));
Table created.
SQL> insert into t values ('a');
1 row created.
SQL> insert into t values ('b');
1 row created.
SQL> insert into t values ('c');
1 row created.
SQL>
SQL> commit;
Commit complete.
SQL> select t.rowid from t;
ROWID
------------------
AAADZiAABAAAIDBAAA
AAADZiAABAAAIDBAAB
AAADZiAABAAAIDBAAC
SQL> update t set t.a=lpad('a',4000,'a') where t.a='a';
1 row updated.
SQL> update t set t.a=lpad('b',4000,'b') where t.a='b';
1 row updated.
SQL> update t set t.a=lpad('c',4000,'c') where t.a='c';
1 row updated.
SQL> commit;
Commit complete.
SQL> select t.rowid from t;
ROWID
------------------
AAADZiAABAAAIDBAAA
AAADZiAABAAAIDBAAB
AAADZiAABAAAIDBAAC
應該是AAADZiAABAAAIDBAAC這條記錄發生了遷移,我們看一下資料的物理位置,並將這部分記錄dump出來
SQL> select dbms_rowid.rowid_relative_fno('AAADZiAABAAAIDBAAA') || '.' ||
dbms_rowid.rowid_block_number('AAADZiAABAAAIDBAAA')
from dual 2 3 ;
DBMS_ROWID.ROWID_RELATIVE_FNO('AAADZIAABAAAIDBAAA')||'.'||DBMS_ROWID.ROWID_BLOCK
--------------------------------------------------------------------------------
1.32961
SQL> alter system dump datafile 1 block 32961;
System altered.
對於這條記錄,會在兩次dump中出現,首先是行頭,它沒有資料,但記錄了資料的偏移地址nrid
tab 0, row 2, @0x3c
tl: 9 fb: --H----- lb: 0x2 cc: 0
nrid: 0x004080c2.0
SQL> alter system dump datafile 1 block 32962;
System altered.
真正的資料在這裡,同時,也記錄了行頭的偏移地址hrid
tab 0, row 0, @0xfdc
tl: 4012 fb: ----FL-- lb: 0x1 cc: 1 --row flag是----FL--,也就是0x0c
hrid: 0x004080c1.2col 0: [4000]
63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63
我們對這條記錄做一下修改操作,模擬一下案例發生時的情況:
SQL> select dbms_flashback.get_system_change_number from dual;
GET_SYSTEM_CHANGE_NUMBER
------------------------
278206
SQL> update t set t.a='d' where t.rowid='AAADZiAABAAAIDBAAC';
1 row updated.
SQL> commit;
Commit complete.
SQL> select dbms_flashback.get_system_change_number from dual;
GET_SYSTEM_CHANGE_NUMBER
------------------------
278213
SQL> begin
dbms_logmnr.add_logfile('/u01/app/oracle/oradata/ORAVM/redo01.log');
end;
/
PL/SQL procedure successfully completed.
SQL> begin
dbms_logmnr.start_logmnr(startScn => 278206,endScn => 278213);
end;
/
PL/SQL procedure successfully completed.
SQL> select * from v$logmnr_contents t;
no rows selected
與案例不同的是,在11g中,已經不會出現Unsupported記錄了,直接就不顯示這條記錄了。同樣,我們做一下logfile dump,看看redo log裡到底是怎麼記錄的
SQL> alter system dump logfile '/u01/app/oracle/oradata/ORAVM/redo01.log';
System altered.
CHANGE #1 TYP:0 CLS:22 AFN:3 DBA:0x00c0096c OBJ:4294967295 SCN:0x0000.00043ec4 SEQ:1 OP:5.1 ENC:0 RBL:0
ktudb redo: siz: 4080 spc: 7722 flg: 0x0022 seq: 0x0021 rec: 0x05
xid: 0x0003.00d.000000cd
ktubu redo: slt: 13 rci: 4 opc: 11.1 objn: 13922 objd: 13922 tsn: 0
Undo type: Regular undo Undo type: Last buffer split: No
Tablespace Undo: No
0x00000000
KDO undo record:
KTB Redo
op: 0x03 ver: 0x01
compat bit: 4 (post-11) padding: 1
op: Z
KDO Op code: URP row dependencies Disabled
xtype: XA flags: 0x00000000 bdba: 0x004080c2 hdba: 0x004080c0
itli: 2 ispac: 0 maxfr: 4863
tabn: 0 slot: 0(0x0) flag: 0x0c lock: 0 ckix: 0
ncol: 1 nnew: 1 size: 4001
col 0: [4000]
63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63
......
CHANGE #2 TYP:2 CLS:1 AFN:1 DBA:0x004080c2 OBJ:13922 SCN:0x0000.00043def SEQ:5 OP:11.5 ENC:0 RBL:0
KTB Redo
op: 0x11 ver: 0x01
compat bit: 4 (post-11) padding: 1
op: F xid: 0x0003.00d.000000cd uba: 0x00c0096c.0021.05
Block cleanout record, scn: 0x0000.00043ec2 ver: 0x01 opt: 0x02, entries follow...
itli: 1 flg: 2 scn: 0x0000.00043def
KDO Op code: URP row dependencies Disabled
xtype: XA flags: 0x00000000 bdba: 0x004080c2 hdba: 0x004080c0
itli: 2 ispac: 0 maxfr: 4863
tabn: 0 slot: 0(0x0) flag: 0x0c lock: 2 ckix: 0
ncol: 1 nnew: 1 size: -4001
col 0: [ 1] 64
與案例相同,logminer無法正確解析,但透過logfile dump,可以看到redo檔案中是包含這部分更新的內容的。
11g與9i不同的地方,9i不會記錄OBJ,而11g記錄了OBJ,雖然這個OBJ也不對。但這並不影響我們的結論
按照Oracle文件中的指示,我們需要開啟附加日誌,才可以使logmminer正確的解析,我們來測試一下。
SQL> alter database add supplemental log data;
Database altered.
Logminer過程略過……
SQL> select t.RBABLK,t.RBABYTE,t.DATA_OBJ#,t.ROW_ID,t.OPERATION,t.SQL_REDO,t.INFO from v$logmnr_contents t ;
13159 16 13922 AAADZiAABAAAIDBAAC UPDATE update "UNKNOWN"."OBJ# 13922" set "COL 1" = HEXTORAW('656565') where "COL 1" = HEXTORAW('64') and ROWID = 'AAADZiAABAAAIDBAAC'; Dictionary Mismatch
Logminer確實可以正確的解析了。
最後,我們來看一下,在開啟附加日誌後,Oracle到底多記錄了什麼東西,使logminer可以正確的解析呢?
下面是開啟附加日誌後,OP:5.1部分的內容,請大家注意看紅色部分,這部分內容在未開啟附加日誌的redo log中是找不到的
05 01 20 00 03 00 ff ff fa 00 c0 00 67 43 04 00
00 00 00 00 01 00 ff ff 10 00 14 00 18 00 20 00
1d 00 02 00 01 00 1c 00 8c 00 a4 1c 22 00 00 00
08 00 01 00 cd 00 00 00 2c 00 06 00 62 36 00 00
62 36 00 00 00 00 00 00 00 00 00 00 0b 01 01 05
00 00 cd 00 04 0d 00 00 01 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 80 00 00
00 00 00 00 c2 80 40 00 c0 80 40 00 ff 12 25 01
03 00 00 00 0c 00 00 00 00 00 01 01 fe ff 00 00
00 0c 40 00 00 00 40 00 64 12 02 01 01 04 00 00
01 00 01 00 01 00 00 00 00 10 00 00 00 00 00 00
c1 80 40 00 02 00 00 00
這部分的內容是不是很眼熟?看看下面這段就明白了,紅色這部分內容對應的就是hrid:
tab 0, row 0, @0xfdc
tl: 4012 fb: ----FL-- lb: 0x1 cc: 1 --row flag是----FL--,也就是0x0c
hrid: 0x004080c1.2col 0: [4000]
63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63
沒錯,在開啟附加日誌後,對於行遷移資料,Oracle會將hrid資訊記錄下來,這樣,我們便可以根據hrid找到行頭,同時,可以計算出正確的ROWID資訊。這部分的內容,同時也證明了我們對於eygle大師這個案例為什麼無法使用logminer解析的猜想。[@more@]
Oracle技術嘉年華的一個案例,redo的那些事,連載一
Oracle技術嘉年華的一個案例,redo的那些事,連載二
在上一篇中,修改row flag後,logminer已經可以正確的解析日誌了,那麼,這個問題是否可以重現呢?我們來做個測試。
由於沒有9i環境,我們使用11g環境進行測試,測試結果稍微有些偏差,但不影響結論
首先,我們建立varchar2(4000)型別的三條資料,然後,對這三條資料進行修改,將4000位元組全部佔滿,那麼,必然有一條記錄將發生遷移。
SQL*Plus: Release 11.2.0.3.0 Production on Fri Oct 28 08:34:33 2011
Copyright (c) 1982, 2011, Oracle. All rights reserved.
SQL> conn / as sysdba
Connected.
SQL> create table t (a varchar2(4000));
Table created.
SQL> insert into t values ('a');
1 row created.
SQL> insert into t values ('b');
1 row created.
SQL> insert into t values ('c');
1 row created.
SQL>
SQL> commit;
Commit complete.
SQL> select t.rowid from t;
ROWID
------------------
AAADZiAABAAAIDBAAA
AAADZiAABAAAIDBAAB
AAADZiAABAAAIDBAAC
SQL> update t set t.a=lpad('a',4000,'a') where t.a='a';
1 row updated.
SQL> update t set t.a=lpad('b',4000,'b') where t.a='b';
1 row updated.
SQL> update t set t.a=lpad('c',4000,'c') where t.a='c';
1 row updated.
SQL> commit;
Commit complete.
SQL> select t.rowid from t;
ROWID
------------------
AAADZiAABAAAIDBAAA
AAADZiAABAAAIDBAAB
AAADZiAABAAAIDBAAC
應該是AAADZiAABAAAIDBAAC這條記錄發生了遷移,我們看一下資料的物理位置,並將這部分記錄dump出來
SQL> select dbms_rowid.rowid_relative_fno('AAADZiAABAAAIDBAAA') || '.' ||
dbms_rowid.rowid_block_number('AAADZiAABAAAIDBAAA')
from dual 2 3 ;
DBMS_ROWID.ROWID_RELATIVE_FNO('AAADZIAABAAAIDBAAA')||'.'||DBMS_ROWID.ROWID_BLOCK
--------------------------------------------------------------------------------
1.32961
SQL> alter system dump datafile 1 block 32961;
System altered.
對於這條記錄,會在兩次dump中出現,首先是行頭,它沒有資料,但記錄了資料的偏移地址nrid
tab 0, row 2, @0x3c
tl: 9 fb: --H----- lb: 0x2 cc: 0
nrid: 0x004080c2.0
SQL> alter system dump datafile 1 block 32962;
System altered.
真正的資料在這裡,同時,也記錄了行頭的偏移地址hrid
tab 0, row 0, @0xfdc
tl: 4012 fb: ----FL-- lb: 0x1 cc: 1 --row flag是----FL--,也就是0x0c
hrid: 0x004080c1.2col 0: [4000]
63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63
我們對這條記錄做一下修改操作,模擬一下案例發生時的情況:
SQL> select dbms_flashback.get_system_change_number from dual;
GET_SYSTEM_CHANGE_NUMBER
------------------------
278206
SQL> update t set t.a='d' where t.rowid='AAADZiAABAAAIDBAAC';
1 row updated.
SQL> commit;
Commit complete.
SQL> select dbms_flashback.get_system_change_number from dual;
GET_SYSTEM_CHANGE_NUMBER
------------------------
278213
SQL> begin
dbms_logmnr.add_logfile('/u01/app/oracle/oradata/ORAVM/redo01.log');
end;
/
PL/SQL procedure successfully completed.
SQL> begin
dbms_logmnr.start_logmnr(startScn => 278206,endScn => 278213);
end;
/
PL/SQL procedure successfully completed.
SQL> select * from v$logmnr_contents t;
no rows selected
與案例不同的是,在11g中,已經不會出現Unsupported記錄了,直接就不顯示這條記錄了。同樣,我們做一下logfile dump,看看redo log裡到底是怎麼記錄的
SQL> alter system dump logfile '/u01/app/oracle/oradata/ORAVM/redo01.log';
System altered.
CHANGE #1 TYP:0 CLS:22 AFN:3 DBA:0x00c0096c OBJ:4294967295 SCN:0x0000.00043ec4 SEQ:1 OP:5.1 ENC:0 RBL:0
ktudb redo: siz: 4080 spc: 7722 flg: 0x0022 seq: 0x0021 rec: 0x05
xid: 0x0003.00d.000000cd
ktubu redo: slt: 13 rci: 4 opc: 11.1 objn: 13922 objd: 13922 tsn: 0
Undo type: Regular undo Undo type: Last buffer split: No
Tablespace Undo: No
0x00000000
KDO undo record:
KTB Redo
op: 0x03 ver: 0x01
compat bit: 4 (post-11) padding: 1
op: Z
KDO Op code: URP row dependencies Disabled
xtype: XA flags: 0x00000000 bdba: 0x004080c2 hdba: 0x004080c0
itli: 2 ispac: 0 maxfr: 4863
tabn: 0 slot: 0(0x0) flag: 0x0c lock: 0 ckix: 0
ncol: 1 nnew: 1 size: 4001
col 0: [4000]
63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63
......
CHANGE #2 TYP:2 CLS:1 AFN:1 DBA:0x004080c2 OBJ:13922 SCN:0x0000.00043def SEQ:5 OP:11.5 ENC:0 RBL:0
KTB Redo
op: 0x11 ver: 0x01
compat bit: 4 (post-11) padding: 1
op: F xid: 0x0003.00d.000000cd uba: 0x00c0096c.0021.05
Block cleanout record, scn: 0x0000.00043ec2 ver: 0x01 opt: 0x02, entries follow...
itli: 1 flg: 2 scn: 0x0000.00043def
KDO Op code: URP row dependencies Disabled
xtype: XA flags: 0x00000000 bdba: 0x004080c2 hdba: 0x004080c0
itli: 2 ispac: 0 maxfr: 4863
tabn: 0 slot: 0(0x0) flag: 0x0c lock: 2 ckix: 0
ncol: 1 nnew: 1 size: -4001
col 0: [ 1] 64
與案例相同,logminer無法正確解析,但透過logfile dump,可以看到redo檔案中是包含這部分更新的內容的。
11g與9i不同的地方,9i不會記錄OBJ,而11g記錄了OBJ,雖然這個OBJ也不對。但這並不影響我們的結論
按照Oracle文件中的指示,我們需要開啟附加日誌,才可以使logmminer正確的解析,我們來測試一下。
SQL> alter database add supplemental log data;
Database altered.
Logminer過程略過……
SQL> select t.RBABLK,t.RBABYTE,t.DATA_OBJ#,t.ROW_ID,t.OPERATION,t.SQL_REDO,t.INFO from v$logmnr_contents t ;
13159 16 13922 AAADZiAABAAAIDBAAC UPDATE update "UNKNOWN"."OBJ# 13922" set "COL 1" = HEXTORAW('656565') where "COL 1" = HEXTORAW('64') and ROWID = 'AAADZiAABAAAIDBAAC'; Dictionary Mismatch
Logminer確實可以正確的解析了。
最後,我們來看一下,在開啟附加日誌後,Oracle到底多記錄了什麼東西,使logminer可以正確的解析呢?
下面是開啟附加日誌後,OP:5.1部分的內容,請大家注意看紅色部分,這部分內容在未開啟附加日誌的redo log中是找不到的
05 01 20 00 03 00 ff ff fa 00 c0 00 67 43 04 00
00 00 00 00 01 00 ff ff 10 00 14 00 18 00 20 00
1d 00 02 00 01 00 1c 00 8c 00 a4 1c 22 00 00 00
08 00 01 00 cd 00 00 00 2c 00 06 00 62 36 00 00
62 36 00 00 00 00 00 00 00 00 00 00 0b 01 01 05
00 00 cd 00 04 0d 00 00 01 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 80 00 00
00 00 00 00 c2 80 40 00 c0 80 40 00 ff 12 25 01
03 00 00 00 0c 00 00 00 00 00 01 01 fe ff 00 00
00 0c 40 00 00 00 40 00 64 12 02 01 01 04 00 00
01 00 01 00 01 00 00 00 00 10 00 00 00 00 00 00
c1 80 40 00 02 00 00 00
這部分的內容是不是很眼熟?看看下面這段就明白了,紅色這部分內容對應的就是hrid:
tab 0, row 0, @0xfdc
tl: 4012 fb: ----FL-- lb: 0x1 cc: 1 --row flag是----FL--,也就是0x0c
hrid: 0x004080c1.2col 0: [4000]
63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63
沒錯,在開啟附加日誌後,對於行遷移資料,Oracle會將hrid資訊記錄下來,這樣,我們便可以根據hrid找到行頭,同時,可以計算出正確的ROWID資訊。這部分的內容,同時也證明了我們對於eygle大師這個案例為什麼無法使用logminer解析的猜想。[@more@]
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/19423/viewspace-1056063/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- TechWorld2021技術嘉年華,解鎖“不一樣”的技術盛會
- 2019年仲夏,來一場“可鹽可甜”的技術嘉年華
- 不負每一份對技術的熱愛| 2020 TechWorld技術嘉年華
- 2019TechWorld技術嘉年華,“我們不一樣”
- 乾貨 | TechWorld2021技術嘉年華演講PPT下載
- 倒數計時三天|技術嘉年華的範兒即將拉滿,敬請關注
- SegmentFault 思否技術週刊 -- JavaScript 的那些事JavaScript
- 搞懂分散式技術13:快取的那些事分散式快取
- Android技術總監應該乾的那些事Android
- 與技術來一場邂逅|2020TechWorld綠盟科技技術嘉年華如約盛啟
- 就要技術範!2019TechWorld技術嘉年華•黑客馬拉松完美落幕黑客
- 2021資料技術嘉年華 | OceanBase 技術盛宴ON LINE ,我們不見不散!
- 大咖來襲 | 2019TechWorld技術嘉年華技術大咖首秀
- 那些年的體驗技術部
- 當藝術邂逅技術|2020TechWorld技術嘉年華邀您解鎖新玩法
- 《那些年啊,那些事——一個程式設計師的奮鬥史》——26程式設計師
- 負載均衡的那些事?負載
- 記我第一次做線下技術分享的那些事
- Java開發技術大雜燴(一)之Redis、Jmeter、MySQL的那些事JavaRedisJMeterMySql
- 2019 資料技術嘉年華,資料英雄聚京華 - 誠邀論道
- oracle的redo和undoOracle
- 限時早鳥票 | 2019資料技術嘉年華超豪華盛宴搶先看!
- 《夢幻花園》嘉年華落地深圳 探索三消輕競技模式模式
- 2019TechWorld技術嘉年華·十大議題重磅釋出
- 楠姐技術漫話:圖計算的那些事 | 京東雲技術團隊
- Java 資料庫連線的那些事Java資料庫
- 一個20年技術老兵的2020年度技術總結
- 技術戰疫:下一個10年的技術趨勢
- 一個20年技術老兵的 2020 年度技術總結
- 創新我們是認真的 GBase閃耀資料技術嘉年華
- 那些年啊,那些事——一個程式設計師的奮鬥史 開始預售了程式設計師
- 純享版技術交流盛會 | TechWorld2021綠盟科技技術嘉年華不負熱愛
- 那些年關於HTTPS的事HTTP
- 9012年的嘉年華,能讓暴雪“翻身”嗎?
- 連載三:Oracle升級文件大全Oracle
- 【REDO】Oracle redo advice-sqlOracle RedoSQL
- 【REDO】Oracle redo undo 學習Oracle Redo
- EF中延遲載入的那些事
- 史玉柱熱愛的事業:征途5年嘉年華 探究其中的“變與不變”