Oracle 里面如何实现只回滚某个事务的一部分内容
本站文章除注明转载外,均为本站原创: 转载自love wife love life —Roger的Oracle/MySQL/PostgreSQL数据恢复博客
本文链接地址: Oracle 里面如何实现只回滚某个事务的一部分内容
昨天凌晨被电话吵醒,某客户的一套11gR2 RAC出现异常,正常启动之后很快就crash掉,并伴随相关ora-00600错误。
通过alert log发现如下信息:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
Wed Dec 25 06:21:05 2013 QMNC started with pid=50, OS id=9481 Completed: ALTER DATABASE OPEN /* db agent *//* {0:5:77} */ Wed Dec 25 06:21:05 2013 Dumping diagnostic data in directory=[cdmp_20131225062105], requested by (instance=2, osid=9294 (SMON)), summary=[incident=180659]. Use ADRCI or Support Workbench to package the incident. See Note 411.1 at My Oracle Support for error and packaging details. ORACLE Instance xxxx2 (pid = 32) - Error 600 encountered while recovering transaction (114, 16) on object 25736. Errors in file /opt/oracle/app/diag/rdbms/xxxx/xxxx2/trace/xxxx2_smon_9294.trc: ORA-00600: internal error code, arguments: [ktubko_1], [], [], [], [], [], [], [], [], [], [], [] Thread 2 advanced to log sequence 153071 (LGWR switch) Current log# 11 seq# 153071 mem# 0: /yx_oradata1/redo11.log 。。。。。。 ORACLE Instance xxxx2 (pid = 32) - Error 600 encountered while recovering transaction (117, 21) on object 25738. Errors in file /opt/oracle/app/diag/rdbms/xxxx/xxxx2/trace/xxxx2_smon_9294.trc: ORA-00600: internal error code, arguments: [ktubko_1], [], [], [], [], [], [], [], [], [], [], [] Dumping diagnostic data in directory=[cdmp_20131225062114], requested by (instance=2, osid=9294 (SMON)), summary=[incident=180662]. Errors in file /opt/oracle/app/diag/rdbms/xxxx/xxxx2/trace/xxxx2_smon_9294.trc (incident=180663): ORA-00600: internal error code, arguments: [ktubko_1], [], [], [], [], [], [], [], [], [], [], [] Incident details in: /opt/oracle/app/diag/rdbms/xxxx/xxxx2/incident/incdir_180663/xxxx2_smon_9294_i180663.trc Wed Dec 25 06:21:27 2013 PMON (ospid: 9220): terminating the instance due to error 474 Wed Dec 25 06:21:27 2013 System state dump requested by (instance=2, osid=9220 (PMON)), summary=[abnormal instance termination]. System State dumped to trace file /opt/oracle/app/diag/rdbms/xxxx/xxxx2/trace/xxxx2_diag_9230.trc Wed Dec 25 06:21:30 2013 ORA-1092 : opitsk aborting process Non critical error ORA-48913 caught while writing to trace file "/opt/oracle/app/diag/rdbms/xxxx/xxxx2/trace/xxxx2_diag_9230.trc" Error message: ORA-48913: Writing into trace file failed, file size limit [5000000] reached Writing to the above trace file is disabled for now on... Wed Dec 25 06:21:31 2013 ORA-1092 : opitsk aborting process Wed Dec 25 06:21:31 2013 License high water mark = 33 Dumping diagnostic data in directory=[cdmp_20131225062127], requested by (instance=2, osid=9220 (PMON)), summary=[abnormal instance termination]. Instance terminated by PMON, pid = 9220 |
从上面的信息我们可以看出,smon进程在对object进行事务rollback时,事务(例如114,16)存在异常,导致smon无法进行正常的工作,进而导致smon进程dead,最后pmon 进程将实例终止掉。
这里我们以最开始的一个事务(114,16) 进行举例分析。
通过查看trace 文件我们发现,该事务信息存在异常,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
*** ACTION NAME:() 2013-12-25 06:21:03.816 Incorrect next uba in kturCurrBackoutOneChg while backing out xid: 0x0072.010.0006fa20 uba: 0x3288715c.1195.20 Undo record: ktubu redo: slt: 16 rci: 31 opc: 10.22 objn: 25736 objd: 605630 tsn: 4 Undo type: Regular undo Undo type: Last buffer split: No Tablespace Undo: No 0x00000000 index undo for leaf key operations KTB Redo op: 0x03 ver: 0x01 compat bit: 4 (post-11) padding: 1 op: Z Dump kdilk : itl=44, kdxlkflg=0x1 sdc=597172224 indexid=0x5402d1e block=0x05403053 (kdxlpu): purge leaf row key :(15): 07 c6 02 16 37 18 4c 21 06 04 c0 1c cf 00 1b Undo block: tsn 0xe rdba: 0x3288715c Dump of buffer cache at level 4 for tsn=14, rdba=847802716 BH (0x833dc08e0) file#: 202 rdba: 0x3288715c (202/553308) class: 244 ba: 0x833a70000 set: 144 pool: 3 bsz: 8192 bsi: 0 sflg: 2 pwc: 0,0 dbwrid: 7 obj: -1 objn: 0 tsn: 14 afn: 202 hint: f hash: [0x9cd25d2b8,0x9cd25d2b8] lru: [0x833dc0b40,0x9d24f9da8] ckptq: [NULL] fileq: [NULL] objq: [0x833dc0b68,0x9a7c8aaf0] objaq: [0x833dc0b78,0x9a7c8aae0] st: SCURRENT md: NULL tch: 1 atm: 1681309554,1681324042 flags: affinity_lock LRBA: [0x0.0.0] LSCN: [0x0.0] HSCN: [0xffff.ffffffff] HSUB: [65535] cr pin refcnt: 0 sh pin refcnt: 0 Data block dump: tsn: 0x4 rdba: 0x5403053 Dump of buffer cache at level 3 for tsn=4, rdba=88092755 BH (0x833b46e18) file#: 21 rdba: 0x05403053 (21/12371) class: 1 ba: 0x830482000 set: 150 pool: 3 bsz: 8192 bsi: 0 sflg: 2 pwc: 0,0 dbwrid: 5 obj: 605630 objn: 25736 tsn: 4 afn: 21 hint: f hash: [0x9d5ee3068,0x9d5ee3068] lru: [0x833b47078,0x9d24fc7a8] ckptq: [NULL] fileq: [NULL] objq: [0x995835320,0x995835320] objaq: [0x995835310,0x995835310] st: XCURRENT md: NULL tch: 1 atm: 1681313677,1681324178 flags: affinity_lock LRBA: [0x0.0.0] LSCN: [0x0.0] HSCN: [0xffff.ffffffff] HSUB: [65535] cr pin refcnt: 0 sh pin refcnt: 0 buffer tsn: 4 rdba: 0x05403053 (21/12371) scn: 0x0c25.0952cb4d seq: 0x02 flg: 0x04 tail: 0xcb4d0602 frmt: 0x02 chkval: 0xb93c type: 0x06=trans data Hex dump of block: st=0, typ_found=1 |
从trace的内容我们可以看出smon 进程rollback时,发现该事务回滚时访问的uba的地址跟需要信息不匹配或者相关信息不正确,即该undo block中的信息可能异常异常。 XID和UBA的结构解释如下:
xid:
0x0072.010.0006fa20
0072 :回滚段编号,转换后为114,说明该事务使用的回滚段是第114号回滚段
010 :事务槽编号(slot),转换后为16,说明对应undo segment header中的transaction table记录中的index是16
0006fa20 :序号(同一个事务可能具有多个SCN,用于区分一个事务中的多个操作)
uba: 0x3288715c.1195.20
3288715c: undo block地址,为16进制,转换为10进制为847802716,即(202/553308)
1195 : sequence number
20 : undo record编号
根据前面的信息判断,Oracle 利用undo block对事务进行rollback时,发现undo block中对应的记录不对,因此抛出ora-00600 [ktubko_1] 错误。我们知道Oracle 中的事务,必须保持其完整性,即一个事务要么成功,要么失败,不能只完成其中的部分操作(如果一个事务涉及到多个操作的 话)。那么能否实现只对事务中的部分操作进行rollback呢? 如果这个case中,能实现部分操作的rollback,那么就可以顺利打开数据库。当然这里我的处理方式是通过100513 event来屏蔽Smon进程的rollback操作,open之后再去维护相关的Index。
我们知道smon 在对一个事务进行回滚时,如果该事务涉及到多个操作,那么如何去保证顺序的回滚呢 ?其实是根据undo chain来的。
当rollback到rci为0时就结束该事务的rollback。 这里我举个测试例子,针对分区表带索引的操作。 当分区表的数据操作时,
那么必然会维护Index,因此同一个操作,在undo record中应该有2个record记录,下面我们来测试下,能否是否只回滚该事务
的部分操作,如下是我的测试例子,生产库不要随便玩~~~~
针对分区表的delete操作,如上述的例子,很简单,由于客户这里遇到的情况是insert,下面我来看下insert的情况。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 |
++++测试delete SQL> create table test_1227 partition by hash(object_id) partitions 5 as select * from dba_objects; Table created. SQL> create unique index pk_test_1227 on test_1227 (object_id) local ; Index created. SQL> select object_id,data_object_id from dba_objects where object_name=upper('test_1227'); OBJECT_ID DATA_OBJECT_ID ---------- -------------- 83503 83503 83504 83504 83505 83505 83506 83506 83507 83507 83502 6 rows selected. SQL> SQL> select object_id,data_object_id from dba_objects where object_name=upper('pk_test_1227'); OBJECT_ID DATA_OBJECT_ID ---------- -------------- 83509 83509 83510 83510 83511 83511 83512 83512 83513 83513 83508 6 rows selected. SQL> select count(1) from test_1227 where object_id<10; COUNT(1) ---------- 8 SQL> select dbms_rowid.rowid_block_number(rowid) blk# from test_1227 2 where object_id < 10; BLK# ---------- 31762 32786 30738 30738 30738 33810 33810 33810 8 rows selected. SQL> select distinct dbms_rowid.rowid_relative_fno(rowid) file# from test_1227; FILE# ---------- 5 SQL> SQL> delete from test_1227 where object_id < 10; 8 rows deleted. SQL> alter system flush buffer_cache; System altered. SQL> select xidusn,xidslot,xidsqn,ubablk,ubafil,ubarec,start_scn from v$transaction; XIDUSN XIDSLOT XIDSQN UBABLK UBAFIL UBAREC START_SCN ---------- ---------- ---------- ---------- ---------- ---------- ---------- 17 22 2800 420 6 15 12379942 SQL> 我们可以看到该事务涉及的undo block为file 6 block 420. +++++session 2 SQL> conn /as sysdba Connected. SQL> oradebug setmypid Statement processed. SQL> alter session set tracefile_identifier=10; Session altered. SQL> alter system dump datafile 6 block 420; System altered. SQL> oradebug tracefile_name /home/ora11g/diag/rdbms/roger/roger/trace/roger_ora_25146_10.trc SQL> 该undo block的信息如下: ******************************************************************************** UNDO BLK: xid: 0x0011.016.00000af0 seq: 0xea4 cnt: 0xf irb: 0xf icl: 0x0 flg: 0x0000 Rec Offset Rec Offset Rec Offset Rec Offset Rec Offset --------------------------------------------------------------------------- 0x01 0x1f60 0x02 0x1ed4 0x03 0x1e6c 0x04 0x1d68 0x05 0x1c90 0x06 0x1bc0 0x07 0x1aec 0x08 0x1a0c 0x09 0x193c 0x0a 0x1868 0x0b 0x1790 0x0c 0x172c 0x0d 0x16c8 0x0e 0x1638 0x0f 0x15a8 ........... ...........省略部分内容 *----------------------------- * Rec #0xd slt: 0x16 objn: 83510(0x00014636) objd: 83510 tblspc: 6(0x00000006) * Layer: 10 (Index) opc: 22 rci 0x0c Undo type: Regular undo Last buffer split: No Temp Object: No Tablespace Undo: No rdba: 0x00000000 *----------------------------- index undo for leaf key operations KTB Redo op: 0x04 ver: 0x01 compat bit: 4 (post-11) padding: 1 op: L itl: xid: 0xffff.000.00000000 uba: 0x00000000.0000.00 flg: C--- lkc: 0 scn: 0x0000.00bce6df Dump kdilk : itl=2, kdxlkflg=0x1 sdc=0 indexid=0x14077ca block=0x014077cc (kdxlre): restore leaf row (clear leaf delete flags) key :(3): 02 c1 0a keydata/bitmap: (6): 01 40 80 12 00 03 *----------------------------- * Rec #0xe slt: 0x16 objn: 83511(0x00014637) objd: 83511 tblspc: 6(0x00000006) * Layer: 10 (Index) opc: 22 rci 0x0d Undo type: Regular undo Last buffer split: No Temp Object: No Tablespace Undo: No rdba: 0x00000000 *----------------------------- index undo for leaf key operations KTB Redo op: 0x04 ver: 0x01 compat bit: 4 (post-11) padding: 1 op: L itl: xid: 0xffff.000.00000000 uba: 0x00000000.0000.00 flg: C--- lkc: 0 scn: 0x0000.00bce6ee Dump kdilk : itl=2, kdxlkflg=0x25 sdc=0 indexid=0x14077fa block=0x014077fc (kdxlre): restore leaf row (clear leaf delete flags) number of keys: 3 key sizes: 3 3 3 key :(9): 02 c1 03 02 c1 06 02 c1 09 keydata/bitmap: (18): 01 40 78 12 00 0d 01 40 78 12 00 06 01 40 78 12 00 0a selflock: (1): 00 bitmap: (1): ff *----------------------------- * Rec #0xf slt: 0x16 objn: 83512(0x00014638) objd: 83512 tblspc: 6(0x00000006) * Layer: 10 (Index) opc: 22 rci 0x0e Undo type: Regular undo Last buffer split: No Temp Object: No Tablespace Undo: No rdba: 0x00000000 *----------------------------- index undo for leaf key operations KTB Redo op: 0x04 ver: 0x01 compat bit: 4 (post-11) padding: 1 op: L itl: xid: 0xffff.000.00000000 uba: 0x00000000.0000.00 flg: C--- lkc: 0 scn: 0x0000.00bce6fd Dump kdilk : itl=2, kdxlkflg=0x25 sdc=0 indexid=0x1408c2a block=0x01408c2c (kdxlre): restore leaf row (clear leaf delete flags) number of keys: 3 key sizes: 3 3 3 key :(9): 02 c1 04 02 c1 05 02 c1 08 keydata/bitmap: (18): 01 40 84 12 00 02 01 40 84 12 00 0f 01 40 84 12 00 05 selflock: (1): 00 bitmap: (1): ff End dump data blocks tsn: 8 file#: 6 minblk 420 maxblk 420 +++++++测试insert --session 1 SQL> insert into test_1227 select * from dba_objects where object_id=5; 1 row created. SQL> select xidusn,xidslot,xidsqn,ubablk,ubafil,ubarec,start_scn from v$transaction; XIDUSN XIDSLOT XIDSQN UBABLK UBAFIL UBAREC START_SCN ---------- ---------- ---------- ---------- ---------- ---------- ---------- 18 15 2763 307 6 52 12381023 SQL> alter system flush buffer_cache; System altered. SQL> ---session 2 SQL> alter session set tracefile_identifier=20; Session altered. SQL> SQL> alter system dump datafile 6 block 307; System altered. SQL> oradebug tracefile_name /home/ora11g/diag/rdbms/roger/roger/trace/roger_ora_25146_20.trc SQL> 此时该undo block的dump如下: tart dump data blocks tsn: 8 file#:6 minblk 307 maxblk 307 Block dump from cache: Dump of buffer cache at level 4 for tsn=8, rdba=25166131 BH (0x24ff9164) file#: 6 rdba: 0x01800133 (6/307) class: 52 ba: 0x24f7e000 set: 3 pool: 3 bsz: 8192 bsi: 0 sflg: 1 pwc: 0,25 dbwrid: 0 obj: -1 objn: 0 tsn: 8 afn: 6 hint: f hash: [0x314b81d8,0x314b81d8] lru: [0x247e4e44,0x21bf7440] lru-flags: on_auxiliary_list ckptq: [NULL] fileq: [NULL] objq: [NULL] objaq: [NULL] st: FREE md: NULL tch: 0 lfb: 33 flags: cr pin refcnt: 0 sh pin refcnt: 0 Block dump from disk: buffer tsn: 8 rdba: 0x01800133 (6/307) scn: 0x0000.00bceb5f seq: 0x02 flg: 0x00 tail: 0xeb5f0202 frmt: 0x02 chkval: 0x0000 type: 0x02=KTU UNDO BLOCK Hex dump of block: st=0, typ_found=1 ......... ......... *----------------------------- * Rec #0x33 slt: 0x0f objn: 83505(0x00014631) objd: 83505 tblspc: 6(0x00000006) * Layer: 11 (Row) opc: 1 rci 0x00 Undo type: Regular undo Begin trans Last buffer split: No Temp Object: No Tablespace Undo: No rdba: 0x00000000Ext idx: 0 flg2: 0 *----------------------------- uba: 0x01800133.0e8e.31 ctl max scn: 0x0000.00bce7df prv tx scn: 0x0000.00bce80b txn start scn: scn: 0x0000.00bceb5f logon user: 86 prev brb: 0 prev bcl: 0 KDO undo record: KTB Redo op: 0x03 ver: 0x01 compat bit: 4 (post-11) padding: 1 op: Z KDO Op code: QMD row dependencies Disabled xtype: XA flags: 0x00000000 bdba: 0x01407939 hdba: 0x01407811 itli: 1 ispac: 0 maxfr: 4858 tabn: 0 lock: 0 nrow: 1 slot[0]: 0 *----------------------------- * Rec #0x34 slt: 0x0f objn: 83511(0x00014637) objd: 83511 tblspc: 6(0x00000006) * Layer: 10 (Index) opc: 22 rci 0x33 Undo type: Regular undo Last buffer split: No Temp Object: No Tablespace Undo: No rdba: 0x00000000 *----------------------------- index undo for leaf key operations KTB Redo op: 0x04 ver: 0x01 compat bit: 4 (post-11) padding: 1 op: L itl: xid: 0x0011.016.00000af0 uba: 0x018001a4.0ea4.0e ---这里的uba不是当前的,是上一次的。 flg: C--- lkc: 0 scn: 0x0000.00bce966 Dump kdilk : itl=2, kdxlkflg=0x1 sdc=0 indexid=0x14077fa block=0x014077fc ----indexid是段头block,后面的block是当前记录所在的block. (kdxlpu): purge leaf row key :(3): 02 c1 06 |
既然我们知道Oracle是根据rci进行回滚的,那么针对该事务,涉及到2个操作,第1个是Rec 0x34是针对index的操作。
第2个操作是Rec 0x33,这是针对该index所在的分区表的操作。 我们知道这是一个完整的事务,那么能否实现只回滚第1个操作,因为后面的
record 可能存在问题或异常,导致smon无法正常完成。 如果能实现只回滚部分事务,那么就可以顺利打开数据库。
实际上要实现这一点,很简单,我们仅仅需要修改rci值即可实现,当然,这样操作,实际上就牺牲了事务的完整性.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
BBED> set dba 0x01800133 DBA 0x01800133 (25166131 6,307) BBED> map /v File: /home/ora11g/cheshi_bbed/undotbs.dbf (6) Block: 307 Dba:0x01800133 ------------------------------------------------------------ Undo Data struct kcbh, 20 bytes @0 ub1 type_kcbh @0 ub1 frmt_kcbh @1 ub1 spare1_kcbh @2 ub1 spare2_kcbh @3 ub4 rdba_kcbh @4 ub4 bas_kcbh @8 ub2 wrp_kcbh @12 ub1 seq_kcbh @14 ub1 flg_kcbh @15 ub2 chkval_kcbh @16 ub2 spare3_kcbh @18 struct ktubh, 120 bytes @20 struct ktubhxid, 8 bytes @20 ub2 ktubhseq @28 ub1 ktubhcnt @30 ub1 ktubhirb @31 ub1 ktubhicl @32 ub1 ktubhflg @33 ub2 ktubhidx[53] @34 ub1 freespace[1272] @140 ub1 undodata[6776] @1412 ub4 tailchk @8188 BBED> d /v offset 1412 count 92 File: /home/ora11g/cheshi_bbed/undotbs.dbf (6) Block: 307 Offsets: 1412 to 1503 Dba:0x01800133 ------------------------------------------------------- 0a001800 20001400 03006765 37460100 l .... .....ge7F.. ++++374601 表示objn 37460100 06000000 00000000 0a160f33 l 7F.............3 ++++374601 表示objd, 06: 表示tblspc,即使表空间编号 0000cb0a 040d0000 00000000 11001600 l .............. ++++11001600 f00a0000 表示XID f00a0000 a4018001 a40e0e00 00800000 l .......... ++++a4018001 a40e0e 表示UBA 66e9bc00 03020100 fa774001 fc774001 l f榧.....鷚@.黽@. ++++fc774001 为该Index block的DBA地址 00000000 0000b7bf 02c1066d l ......房.m ++++02c106为键值的前镜像 <16 bytes per line> BBED> |
对我们来讲关键的地方是:0a160f33 正确的顺序是:330f160a 其中,33表示rci值,0f是slot,16是opcode,0a表示Layer 编号值. 下面我们来试试,能否实现我们的需求:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
BBED> modify /x 00 offset 1443 File: /home/ora11g/cheshi_bbed/undotbs.dbf (6) Block: 307 Offsets: 1443 to 1474 Dba:0x01800133 ------------------------------------------------------------------------ 000000cb 0a040d00 00000000 00110016 00f00a00 00a40180 01a40e0e 00008000 <32 bytes per line> BBED> sum apply Check value for File 6, Block 307: current = 0x0c06, required = 0x0c06 BBED> verify DBVERIFY - Verification starting FILE = /home/ora11g/cheshi_bbed/undotbs.dbf BLOCK = 307 DBVERIFY - Verification complete Total Blocks Examined : 1 Total Blocks Processed (Data) : 0 Total Blocks Failing (Data) : 0 Total Blocks Processed (Index): 0 Total Blocks Failing (Index): 0 Total Blocks Empty : 0 Total Blocks Marked Corrupt : 0 Total Blocks Influx : 0 Message 531 not found; product=RDBMS; facility=BBED ++++将文件copy到ASM磁盘组中,启动数据库. ASMCMD> cp /home/ora11g/cheshi_bbed/undotbs.dbf +DATA1/roger/undotbs.dbf copying /home/ora11g/cheshi_bbed/undotbs.dbf -> +DATA1/roger/undotbs.dbf ASMCMD> ++++启动数据库 SQL> alter database open; Database altered. SQL> conn roger/roger Connected. SQL> @?/rdbms/admin/utlvalid.sql Table created. SQL> analyze table test_1227 validate structure cascade ; analyze table test_1227 validate structure cascade * ERROR at line 1: ORA-01499: table/index cross reference failure - see trace file SQL> set autot off SQL> select /*+full(t) */ * from test_1227 t where object_id=5; OWNER ------------------------------ OBJECT_NAME -------------------------------------------------------------------------------- SUBOBJECT_NAME OBJECT_ID DATA_OBJECT_ID OBJECT_TYPE ------------------------------ ---------- -------------- ------------------- CREATED LAST_DDL_ TIMESTAMP STATUS T G S NAMESPACE --------- --------- ------------------- ------- - - - ---------- EDITION_NAME ------------------------------ SYS CLU$ 5 2 TABLE OWNER ------------------------------ OBJECT_NAME -------------------------------------------------------------------------------- SUBOBJECT_NAME OBJECT_ID DATA_OBJECT_ID OBJECT_TYPE ------------------------------ ---------- -------------- ------------------- CREATED LAST_DDL_ TIMESTAMP STATUS T G S NAMESPACE --------- --------- ------------------- ------- - - - ---------- EDITION_NAME ------------------------------ 05-SEP-10 05-SEP-10 2010-09-05:15:39:54 VALID N N N 1 SQL> set autot on SQL> select * from test_1227 where object_id=5; no rows selected Execution Plan ---------------------------------------------------------- Plan hash value: 141846461 ------------------------------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop | ------------------------------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 97 | 2 (0)| 00:00:01 | | | | 1 | PARTITION HASH SINGLE | | 1 | 97 | 2 (0)| 00:00:01 | 3 | 3 | | 2 | TABLE ACCESS BY LOCAL INDEX ROWID| TEST_1227 | 1 | 97 | 2 (0)| 00:00:01 | 3 | 3 | |* 3 | INDEX UNIQUE SCAN | PK_TEST_1227 | 1 | | 1 (0)| 00:00:01 | 3 | 3 | ------------------------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 3 - access("OBJECT_ID"=5) Statistics ---------------------------------------------------------- 0 recursive calls 0 db block gets 2 consistent gets 0 physical reads 0 redo size 1183 bytes sent via SQL*Net to client 408 bytes received via SQL*Net from client 1 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 0 rows processed |
我们可以看到,顺利打开数据库。 你会发现我们前面最开始insert了一条记录,通过全表扫描能够查询到,如果
走Index就不行。因为Index 中的记录被smon 进程rollback掉了。注意,如果在最开始的操作中,如果没有flush buffer_cache,
那么可能记录没有写到table中去,仍然会查询不到。
如果然而这种情况下,如果你去对表进行校验,会出现错误类似如下。我们正确的做法是,
将Index 进行重建,建议进行drop,然后create。 当然,这里如下你去看trace,会看到类似如下的内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
row not found in index tsn: 6 rdba: 0x014077fa env [0xbfe0cec8]: (scn: 0x0000.00bd49c5 xid: 0x0000.000.00000000 uba: 0x00000000.0000.00 statement num=0 parent xid: 0x0000.000.00000000 st-scn: 0x0000.00000000 h i-scn: 0x0000.00000000 ma-scn: 0x0000.00bd3beb flg: 0x00000060) col 0; len 2; (2): c1 06 Block header dump: 0x01407939 Object id on Block? Y seg/obj: 0x14631 csc: 0x00.bd4044 itc: 2 flg: E typ: 1 - DATA brn: 0 bdba: 0x1407804 ver: 0x01 opc: 0 inc: 0 exflg: 0 Itl Xid Uba Flag Lck Scn/Fsc 0x01 0x0012.00f.00000acb 0x01800133.0e8e.33 C-U- 0 scn 0x0000.00bd3d60 0x02 0x0000.000.00000000 0x00000000.0000.00 ---- 0 fsc 0x0000.00000000 bdba: 0x01407939 data_block_dump,data header at 0x2152a064 =============== tsiz: 0x1f98 hsiz: 0x14 pbl: 0x2152a064 76543210 flag=-------- ntab=1 nrow=1 frre=-1 fsbo=0x14 fseo=0x1f4c avsp=0x1f38 tosp=0x1f38 0xe:pti[0] nrow=1 offs=0 0x12:pri[0] offs=0x1f4c block_row_dump: tab 0, row 0, @0x1f4c tl: 76 fb: --H-FL-- lb: 0x0 cc: 14 col 0: [ 3] 53 59 53 col 1: [ 4] 43 4c 55 24 col 2: *NULL* col 3: [ 2] c1 06 col 4: [ 2] c1 03 col 5: [ 5] 54 41 42 4c 45 col 6: [ 7] 78 6e 09 05 10 28 37 col 7: [ 7] 78 6e 09 05 10 28 37 col 8: [19] 32 30 31 30 2d 30 39 2d 30 35 3a 31 35 3a 33 39 3a 35 34 col 9: [ 5] 56 41 4c 49 44 col 10: [ 1] 4e col 11: [ 1] 4e col 12: [ 1] 4e col 13: [ 2] c1 02 end_of_block_dump kdgDump: tsn=6 tabn=0 Current Row Piece: rdba=0x01407939 slot=0 Head Row Piece: rdba=0x01407939 slot=0 kdgDumpRedo: dump redo on table/index mismatch: table block tsn=6 rdba=0x01407939 index objn=83511 head rowid 0x01407939.0000 ************************************* |
很明显,牺牲事务的完整性之后,这个table和Index的信息不一致了。当然,我们要做的仅仅是重构Index即可。
如果是有针对table的操作,那么可能会丢失数据,需要权衡。
One Response to “Oracle 里面如何实现只回滚某个事务的一部分内容”
牛圣ROGER,顶起
Leave a Reply
You must be logged in to post a comment.