20231027_oracle update restart特性解析
1. 问题概述
oracle数据库在执行update操作,一般情况,首先读一致块获取(read-consistent block get),然后读当前块获取(read current block get),将两次获取结果(update查询谓词)进行比较,如果相等则更新,否则(跳过这个记录,并将其忽略,就会有一个不确定的更新。这可能会破坏数据一致性和完整性。)回滚事务后,数据库会重启动更新(修改update执行时间),而且进入select for update模式,再执行update操作(规避再次重启动)。通过测试总结规则如下,
1). 当sess1 update进程阻塞sess2 update时,sess1提交释放锁后,sess2进行read current block get,如果sess2 一致读和当前读谓词不一致,则启动update restart.
2). 当sess1 update进程阻塞sess2 update,sess1 rollback释放锁后,sess2进行read current block get,sess2 一致读和当前读谓词一致,则不启动update restart.
3). 当sess1 update进程阻塞sess2 update,sess1 同值update commit释放锁后,sess2进行read current block get,sess2 一致读和当前读谓词一致(同值变更,所以两次读结果一致),则不启动update restart.
4). sess1阻塞sess2,sess1修改行内容,sess2全表更新无谓词,则不启动update restart.
5). sess1阻塞sess2,sess1修改sess2谓词内容,sess2谓词所有行满足条件,则启动update restart.
6). sess1阻塞sess2,sess1修改sess2谓词内容,sess2谓词受约束影响(可判断谓词结果),则可能不启动update restart.(不同db version可能测试结果不同) . constraint enable noinvalid
7). :new 和 :old列值在触发器中引用时,也会被oracle用于完成重启动检查 <-- oracle 9i&10g编程艺术
8). 触发器中不引用 :new 和 :old值,不启动update restart.
9). 通过 “测试sequence update更新”,每行记录都会使用新的sequence,但通过测试,不能判断update restart前后影响的行数。
10). 触发器 序列观察update restart前后影响哪些行,实际测试结果与我们预期一致
11). 触发器 序列观察update restart前后影响哪些行,100万数据量时,seq增量情况与预期结果一致。
12). oracle update restart使用logmgr观察较为清晰,分为(首次变更>>回滚过程>>锁定行>>重做过程)四个主要步骤。
### 详细测试过程文档下载
https://www.modb.pro/doc/119100
2. 测试脚本
sqlplus / as sysdba su - oracle sqlplus / as sysdba drop user enmo cascade; create user enmo identified by 123456; grant connect,resource to enmo; grant create sequence to enmo; grant create any table to enmo; grant update any table to enmo; grant delete any table to enmo; grant create procedure to enmo; grant create trigger to enmo; grant execute on dbms_flashback to enmo; alter user enmo quota 1024m on users; conn enmo/123456 drop sequence s; drop table t purge; drop table msg1 purge; drop table msg2 purge; create sequence s; create table msg1 ( seq int primary key, sid int, old_id int, old_y int, new_id int, new_y int ); create table msg2 ( seq int primary key, sid int, old_id int, old_y int, new_id int, new_y int ); create table t as select rownum id, 0 y, 0 z from dual connect by level < 5; create or replace procedure log_msg2( p_seq in int, p_sid in int, p_old_id in int, p_old_y in int, p_new_id in int, p_new_y in int ) as pragma autonomous_transaction; begin insert into msg2 (seq, sid, old_id, old_y, new_id, new_y ) values (p_seq, p_sid, p_old_id, p_old_y, p_new_id, p_new_y ); commit; end; / create or replace trigger t_trigger before update on enmo.t for each row declare l_seq number; begin select s.nextval into l_seq from dual; insert into msg1 (seq, sid, old_id, old_y, new_id, new_y ) values (l_seq, userenv('sessionid'), :old.id, :old.y, :new.id, :new.y ); log_msg2 (l_seq, userenv('sessionid'), :old.id, :old.y, :new.id, :new.y ); end; / select * from msg1; select * from msg2; select * from t;
3. 场景一、sess1修改sess2 update谓词且commit
测试过程
session1 | session2 | session3 | |
---|---|---|---|
t1 | sqlplus enmo/123456 update t set y = -1 where id = 3; --说明:update后未提交 | ||
t2 | sql> select decode(msg1.seq,null,‘not visible’), msg2.* from msg2, msg1 where msg2.seq = msg1.seq( ) order by msg2.seq; 2 3 4 decode(msg1 seq sid old_id old_y new_id new_y ----------- ---------- ---------- ---------- ---------- ---------- ---------- not visible 1 40696 3 0 3 -1 sql> | ||
t3 | update t set y = 1 where y = -1 or id = 2 or id = 3; --说明:被session1锁 | ||
t4 | sql> / decode(msg1 seq sid old_id old_y new_id new_y ----------- ---------- ---------- ---------- ---------- ---------- ---------- not visible 1 40696 3 0 3 -1 not visible 2 40700 2 0 2 1 sql> | ||
t5 | sql> update t set y = -1 where id in ( 1,5 ); 2 rows updated. sql> commit; commit complete. sql> select * from t; id y z ---------- ---------- ---------- 1 -1 0 2 0 0 3 0 0 4 0 0 5 -1 0 sql> | ||
t6 | sql>/ decode(msg1 seq sid old_id old_y new_id new_y ----------- ---------- ---------- ---------- ---------- ---------- ---------- not visible 8 40696 3 0 3 -1 not visible 9 40700 2 0 2 1 10 40709 1 0 1 -1 11 40709 5 0 5 -1 sql> | ||
t7 | sql> commit; commit complete. sql> | ||
t8 | sql> / decode(msg1 seq sid old_id old_y new_id new_y ----------- ---------- ---------- ---------- ---------- ---------- ---------- 8 40696 3 0 3 -1 not visible 9 40700 2 0 2 1 10 40709 1 0 1 -1 11 40709 5 0 5 -1 not visible 12 40700 3 0 3 1 not visible 13 40700 1 -1 1 1 not visible 14 40700 2 0 2 1 not visible 15 40700 3 -1 3 1 not visible 16 40700 5 -1 5 1 9 rows selected. sql> | ||
t9 | sql> update t set y = 1 where y = -1 or id = 2 or id = 3; 4 rows updated. sql> commit; commit complete. sql> select * from t; id y z ---------- ---------- ---------- 1 1 0 2 1 0 3 1 0 4 0 0 5 1 0 sql> | ||
t10 | sql> / decode(msg1 seq sid old_id old_y new_id new_y ----------- ---------- ---------- ---------- ---------- ---------- ---------- 8 40696 3 0 3 -1 not visible 9 40700 2 0 2 1 10 40709 1 0 1 -1 11 40709 5 0 5 -1 not visible 12 40700 3 0 3 1 13 40700 1 -1 1 1 14 40700 2 0 2 1 15 40700 3 -1 3 1 16 40700 5 -1 5 1 9 rows selected. sql> |
初始化环境
###后面测试场景使用以下脚本初始化
truncate table t;
truncate table msg1;
truncate table msg2;
insert into t
select rownum id, 0 y, 0 z
from dual connect by level < 6;
commit;
select * from msg1;
select * from msg2;
select * from t;
小结
当sess1 update进程阻塞sess2 update,sess1 commit释放锁后,sess2进行read current block get,如果sess2 一致读和当前读谓词不一致,则启动update restart.
4.场景二、sess1修改sess2 update谓词且rollback
测试过程
session1 | session2 | session3 | |
---|---|---|---|
t1 | sqlplus enmo/123456 update t set y = -1 where id = 3; --说明:update后未提交 | ||
t2 | update t set y = 1 where y = -1 or id = 2 or id = 3; --说明:被session1锁 | ||
t3 | sql> update t set y = -1 where id in ( 1,5 ); 2 rows updated. sql> commit; commit complete. sql> select * from t; id y z ---------- ---------- ---------- 1 -1 0 2 0 0 3 0 0 4 0 0 5 -1 0 sql> | ||
t4 | sql> rollback; rollback complete. sql> | ||
t5 | sql> update t set y = 1 where y = -1 or id = 2 or id = 3; 2 rows updated. sql> commit; commit complete. sql> select * from t; id y z ---------- ---------- ---------- 1 -1 0 2 1 0 3 1 0 4 0 0 5 -1 0 sql> | ||
t6 | sql> / decode(msg1 seq sid old_id old_y new_id new_y ----------- ---------- ---------- ---------- ---------- ---------- ---------- not visible 27 40696 3 0 3 -1 28 40712 2 0 2 1 29 40709 1 0 1 -1 30 40709 5 0 5 -1 31 40712 3 0 3 1 sql> |
初始化环境
小结
当sess1 update进程阻塞sess2 update,sess1 rollback释放锁后,sess2进行read current block get,sess2 一致读和当前读谓词一致,则不启动update restart.
5. 场景三、sess1 修改 sess2 update谓词且commit,但值不变时
测试过程
session1 | session2 | session3 | |
---|---|---|---|
t1 | sqlplus enmo/123456 update t set y = y where id = 3; --说明:update后未提交 | ||
t2 | update t set y = 1 where y = -1 or id = 2 or id = 3; --说明:被session1锁 | ||
t3 | sql> update t set y = -1 where id in ( 1,5 ); 2 rows updated. sql> commit; commit complete. sql> select * from t; id y z ---------- ---------- ---------- 1 -1 0 2 0 0 3 0 0 4 0 0 5 -1 0 sql> | ||
t4 | sql> commit; commit complete. sql> | ||
t5 | sql> update t set y = 1 where y = -1 or id = 2 or id = 3; 2 rows updated. sql> commit; commit complete. sql> select * from t; id y z ---------- ---------- ---------- 1 -1 0 2 1 0 3 1 0 4 0 0 5 -1 0 sql> | ||
t6 | sql> / decode(msg1 seq sid old_id old_y new_id new_y ----------- ---------- ---------- ---------- ---------- ---------- ---------- 37 40696 3 0 3 0 38 40712 2 0 2 1 39 40709 1 0 1 -1 40 40709 5 0 5 -1 41 40712 3 0 3 1 sql> |
初始化环境
小结
当sess1 update进程阻塞sess2 update,sess1 同值update commit释放锁后,sess2进行read current block get,sess2 一致读和当前读谓词一致(同值变更,所以两次读结果一致),则不启动update restart.
6. 场景四、sess1阻塞sess2,sess1修改行内容,sess2全表更新无谓词,无触发器
测试过程
session1 | session2 | session3 | |
---|---|---|---|
t1 | sqlplus enmo/123456 alter trigger t_trigger disable; update t set y = -1 where id = 3; --说明:update后未提交 | ||
t2 | update t set y = 1; --说明:被session1锁 | ||
t3 | sql> insert into t values(6,0,0); 1 row created. sql> commit; commit complete. sql> | ||
t4 | sql> commit; commit complete. sql> | ||
t5 | sql> update t set y = 1; 5 rows updated. sql> commit; commit complete. sql> select * from t; id y z ---------- ---------- ---------- 6 0 0 1 1 0 2 1 0 3 1 0 4 1 0 5 1 0 6 rows selected. sql> |
初始化环境
小结
sess1阻塞sess2,sess1修改行内容,sess2全表更新无谓词,则不启动update restart.
7. 场景五、sess1阻塞sess2,sess1修改sess2谓词内容,sess2谓词所有行满足条件
测试过程
session1 | session2 | session3 | |
---|---|---|---|
t1 | sqlplus enmo/123456 update t set id = id 100 where id = 3;–说明:update后未提交 | ||
t2 | update t set id = id*10 where id is not null; --说明:被session1锁 | ||
t3 | sql> insert into t values(6,0,0); 1 row created. sql> commit; commit complete. sql> | ||
t4 | sql> commit; commit complete. sql> | ||
t5 | sql> update t set id = id*10 where id is not null; 6 rows updated. sql> commit; commit complete. sql> select * from t; id y z ---------- ---------- ---------- 60 0 0 10 0 0 20 0 0 1030 0 0 40 0 0 50 0 0 6 rows selected. sql> |
初始化环境
小结
sess1阻塞sess2,sess1修改sess2谓词内容,sess2谓词所有行满足条件,则启动update restart.
8. 场景六、sess1阻塞sess2,sess1修改sess2谓词内容,sess2谓词受约束影响
测试过程
session1 | session2 | session3 | |
---|---|---|---|
t1 | sqlplus enmo/123456 alter table t modify id not null; update t set id = id 100 where id = 3;–说明:update后未提交 | ||
t2 | update t set id = id*10 where id is not null; --说明:被session1锁 | ||
t3 | sql> insert into t values(6,0,0); 1 row created. sql> commit; commit complete. sql> | ||
t4 | sql> commit; commit complete. sql> | ||
t5 | sql> update t set id = id*10 where id is not null; 5 rows updated. sql> commit; commit complete. sql> select * from t; id y z ---------- ---------- ---------- 6 0 0 10 0 0 20 0 0 1030 0 0 40 0 0 50 0 0 6 rows selected. sql> |
初始化环境
小结
sess1阻塞sess2,sess1修改sess2谓词内容,sess2谓词受约束影响(可判断谓词结果),则可能不启动update restart.(不同db version可能测试结果不同)
9. 场景七、sess1阻塞sess2,sess1修改行内容,sess2全表更新无谓词,有触发器
测试过程
session1 | session2 | session3 | |
---|---|---|---|
t1 | sqlplus enmo/123456 alter trigger t_trigger enable; update t set y = -1 where id = 3; --说明:update后未提交 | ||
t2 | update t set y = 1; --说明:被session1锁 | ||
t3 | sql> insert into t values(6,0,0); 1 row created. sql> commit; commit complete. sql> | ||
t4 | sql> commit; commit complete. sql> | ||
t5 | sql> update t set y = 1; 6 rows updated. sql> commit; commit complete. sql> select * from t; id y z ---------- ---------- ---------- 6 1 0 1 1 0 2 1 0 3 1 0 4 1 0 5 1 0 6 rows selected. sql> | ||
t6 | sql> / decode(msg1 seq sid old_id old_y new_id new_y ----------- ---------- ---------- ---------- ---------- ---------- ---------- 77 40696 3 0 3 -1 not visible 78 40712 1 0 1 1 not visible 79 40712 2 0 2 1 not visible 80 40712 3 0 3 1 81 40712 6 0 6 1 82 40712 1 0 1 1 83 40712 2 0 2 1 84 40712 3 -1 3 1 85 40712 4 0 4 1 86 40712 5 0 5 1 10 rows selected. sql> |
初始化环境
小结
:new 和 :old列值在触发器中引用时,也会被oracle用于完成重启动检查 <-- oracle 9i&10g编程艺术
10. 场景八、触发器中不引用 new 和 old列值
测试过程
session1 | session2 | session3 | |
---|---|---|---|
t1 | sqlplus enmo/123456 create or replace trigger t_trigger before update on enmo.t for each row begin dbms_output.put_line(‘fired’); end; / set serveroutput on sql> update t set y = -1 where id = 3; --说明:update后未提交 fired 1 row updated. sql> | ||
t2 | set serveroutput on update t set y = 1; --说明:被session1锁 | ||
t3 | sql> set serveroutput on sql> insert into t values(6,0,0); 1 row created. sql> commit; commit complete. sql> | ||
t4 | sql> commit; commit complete. sql> | ||
t5 | sql> set serveroutput on update t set y = 1;sql> fired fired fired fired fired 5 rows updated. sql> commit; commit complete. sql> select * from t; id y z ---------- ---------- ---------- 6 0 0 1 1 0 2 1 0 3 1 0 4 1 0 5 1 0 6 rows selected. sql> |
初始化环境
小结
触发器中不引用 :new 和 :old值,不启动update restart.
11. 场景九、sequence update观察重启动前后影响哪些行
测试sequence update更新
sql> drop sequence s;
sequence dropped.
sql> create sequence s;
sequence created.
sql> select s.nextval from dual;
select s.currval from dual;
nextval
----------
1
sql>
currval
----------
1
sql> drop sequence s;
sequence dropped.
sql> create sequence s;
sequence created.
sql> truncate table t;
table truncated.
sql> insert into t
select rownum id, 0 y, 0 z
from dual connect by level < 100;
commit; 2 3
99 rows created.
sql>
sql> commit;
commit complete.
sql> select * from t;
id y z
---------- ---------- ----------
1 0 0
2 0 0
3 0 0
4 0 0
5 0 0
6 0 0
7 0 0
8 0 0
9 0 0
10 0 0
....
90 0 0
91 0 0
92 0 0
93 0 0
94 0 0
95 0 0
96 0 0
97 0 0
98 0 0
99 0 0
99 rows selected.
sql> update t set y = s.nextval where y > -1;
99 rows updated.
sql> commit;
commit complete.
sql> select * from t;
id y z
---------- ---------- ----------
1 1 0
2 2 0
3 3 0
4 4 0
5 5 0
6 6 0
7 7 0
8 8 0
9 9 0
10 10 0
.......
90 90 0
91 91 0
92 92 0
93 93 0
94 94 0
95 95 0
96 96 0
97 97 0
98 98 0
99 99 0
99 rows selected.
sql>
小结
通过 “测试sequence update更新”,每行记录都会使用新的sequence,所以可以通过sequence的增长情况,来判断update restart前后影响的行数。
观察测试过程
session1 | session2 | session3 | |
---|---|---|---|
t1 | alter trigger t_trigger disable; drop sequence s; create sequence s; truncate table t; insert into t select rownum id, 0 y, 0 z from dual connect by level < 10; commit; update t set y = s.nextval where id = 9; sql> select * from t; id y z ---------- ---------- ---------- 1 0 0 2 0 0 3 0 0 4 0 0 5 0 0 6 0 0 7 0 0 8 0 0 9 1 0 9 rows selected. sql> | ||
t2 | update t set y = s.nextval where y > -1; | ||
t3 | insert into t values(10,s.nextval,0); commit; sql> select * from t; id y z ---------- ---------- ---------- 10 11 0 1 0 0 2 0 0 3 0 0 4 0 0 5 0 0 6 0 0 7 0 0 8 0 0 9 0 0 10 rows selected. sql> | ||
t4 | sql> commit; commit complete. sql> select * from t; id y z ---------- ---------- ---------- 10 11 0 1 0 0 2 0 0 3 0 0 4 0 0 5 0 0 6 0 0 7 0 0 8 0 0 9 1 0 10 rows selected. sql> | ||
t5 | sql> select * from t; id y z ---------- ---------- ---------- 10 22 0 1 23 0 2 24 0 3 25 0 4 26 0 5 27 0 6 28 0 7 29 0 8 30 0 9 31 0 10 rows selected. sql> commit; commit complete. sql> |
12. 场景十、触发器 序列观察update restart前后影响哪些行
测试过程
session1 | session2 | session3 | |
---|---|---|---|
t1 | create or replace trigger t_trigger before update on enmo.t for each row begin dbms_output.put_line(‘fired’||s.nextval); end; / drop sequence s; create sequence s; truncate table t; insert into t select rownum id, 0 y, 0 z from dual connect by level < 10; commit; select * from t; sql> set serveroutput on sql> update t set y = 1 where id = 9; fired1 1 row updated. sql> select * from t; id y z ---------- ---------- ---------- 1 0 0 2 0 0 3 0 0 4 0 0 5 0 0 6 0 0 7 0 0 8 0 0 9 1 0 9 rows selected. sql> |
||
t2 | set serveroutput on update t set y = 2 where y > -1; | ||
t3 | sql> set serveroutput on sql> insert into t values(10,3,0); sql> commit; 1 row created. sql> commit complete. sql> select * from t; id y z ---------- ---------- ---------- 10 3 0 1 0 0 2 0 0 3 0 0 4 0 0 5 0 0 6 0 0 7 0 0 8 0 0 9 0 0 10 rows selected. sql> |
||
t4 | sql> commit; commit complete. sql> select * from t; id y z ---------- ---------- ---------- 10 3 0 1 0 0 2 0 0 3 0 0 4 0 0 5 0 0 6 0 0 7 0 0 8 0 0 9 1 0 10 rows selected. sql> | ||
t5 | sql> set serveroutput on sql> update t set y = 2 where y > -1; fired2 fired3 fired4 fired5 fired6 fired7 fired8 fired9 fired10 fired11 fired12 fired13 fired14 fired15 fired16 fired17 fired18 fired19 fired20 10 rows updated. sql> select * from t; id y z ---------- ---------- ---------- 10 2 0 1 2 0 2 2 0 3 2 0 4 2 0 5 2 0 6 2 0 7 2 0 8 2 0 9 2 0 10 rows selected. sql> |
小结
触发器 序列观察update restart前后影响哪些行,实际测试结果与我们预期一致
13. 场景十一、大数据量 update restart测试
测试过程
session1 | session2 | session3 | |
---|---|---|---|
t1 | create or replace trigger t_trigger before update on enmo.t for each row begin dbms_output.put_line(‘fired’||s.nextval); end; / drop sequence s; create sequence s; truncate table t; insert into t select rownum id, 0 y, 0 z from dual connect by level < 1000000; commit; select 1000000-count(1) from ( select dbms_rowid.rowid_object(rowid) object_id, dbms_rowid.rowid_relative_fno(rowid) file_id, dbms_rowid.rowid_block_number(rowid) block_id, dbms_rowid.rowid_row_number(rowid) row_number,tt.* from enmo.t tt ) te where (te.block_id=( select dbms_rowid.rowid_block_number(rowid) from enmo.t where id=999999 ) and te.row_number>=( select dbms_rowid.rowid_row_number(rowid) from enmo.t where id=999999 )) or te.block_id > ( select dbms_rowid.rowid_block_number(rowid) from enmo.t where id=999999 ); 1000000-count(1) ---------------- 988581 sql> sql> set serveroutput on sql> update t set y = 1 where id = 999999; fired1 1 row updated. sql> | ||
t2 | set serveroutput on update t set y = 2 where y > -1; | ||
t3 | sql> set serveroutput on sql> insert into t values(1000000,3,0); sql> commit; 1 row created. sql> | ||
t4 | sql> commit; commit complete. sql> | ||
t5 | sql> set serveroutput on sql> update t set y = 2 where y > -1; … fired1988565 fired1988566 fired1988567 fired1988568 fired1988569 fired1988570 fired1988571 fired1988572 fired1988573 fired1988574 fired1988575 fired1988576 fired1988577 fired1988578 fired1988579 fired1988580 fired1988581 fired1988582 1000000 rows updated. sql> commit; commit complete. sql> |
小结
触发器 序列观察update restart前后影响哪些行,100万数据量时,seq增量情况与预期结果一致。
14. 场景十二、logmgr工具观察update restart
测试过程
session1 | session2 | session3 | session4 | |
---|---|---|---|---|
t1 | su - oracle sqlplus enmo/123456 alter trigger t_trigger disable; truncate table t; insert into t select rownum id, 0 y, 0 z from dual connect by level < 10; commit; | |||
su - oracle sqlplus / as sysdba alter database force logging; sql> select force_logging from v$database; for — yes sql> archive log list; database log mode archive mode automatic archival enabled archive destination /arch/ oldest online log sequence 142 next log sequence to archive 144 current log sequence 144 sql> sql> alter system set “_in_memory_undo”=false; system altered. sql> sql> @log system altered. system altered. group# thread# sequence# bytes members archived status member f_scn n_scn ---------- ---------- ---------- ---------- ---------- ---------- ---------- ------------------------------------------------------------ -------------------- -------------------- 2 1 152 52428800 1 yes inactive /oradata/orcl/redo02.log 1596480 1596485 3 1 153 52428800 1 yes active /oradata/orcl/redo03.log 1596485 1596492 1 1 154 52428800 1 no current /oradata/orcl/redo01.log 1596492 281474976710655 sql> | ||||
update t set y = 1 where id = 9; sql> select * from t; id y z ---------- ---------- ---------- 1 0 0 2 0 0 3 0 0 4 0 0 5 0 0 6 0 0 7 0 0 8 0 0 9 1 0 9 rows selected. sql> | ||||
t2 | su - oracle sqlplus enmo/123456 update t set y = 2 where y > -1; | |||
t3 | su - oracle sqlplus enmo/123456 insert into t values(10,0,0); commit; | |||
t4 | sql> commit; commit complete. sql> | |||
t5 | sql> commit; commit complete. sql> | |||
t6 | sql> alter system switch logfile; system altered. sql> alter system checkpoint; system altered. sql> select * from vlog; group# thread# sequence# bytes members archived status member f_scn n_scn ---------- ---------- ---------- ---------- ---------- ---------- ---------- ------------------------------------------------------------ -------------------- -------------------- 3 1 153 52428800 1 yes inactive /oradata/orcl/redo03.log 1596485 1596492 1 1 154 52428800 1 yes active /oradata/orcl/redo01.log 1596492 1596545 2 1 155 52428800 1 no current /oradata/orcl/redo02.log 1596545 281474976710655 sql> sql> !ls -ltr /arch/1_154_*.dbf -rw-r----- 1 oracle oinstall 13824 oct 12 14:34 /arch/1_154_1148571774.dbf sql> ### logmgr execute dbms_logmnr.add_logfile(logfilename => '/arch/1_163_1148571774.dbf', options => dbms_logmnr.new); execute dbms_logmnr.start_logmnr(options => dbms_logmnr.dict_from_online_catalog); set linesize 300 pagesize 9999 col seg_owner for a10 col seg_name for a20 col table_name for a20 col usr for a10 col sql_redo for a100 col sql_undo for a100 select scn,start_scn,commit_scn,seg_owner, seg_name,sql_redo,sql_undo from vlogmnr_contents; step 6 end the logminer session. execute dbms_logmnr.end_logmnr(); ### check table info select rowid,dbms_rowid.rowid_object(rowid) object_id, dbms_rowid.rowid_relative_fno(rowid) file_id, dbms_rowid.rowid_block_number(rowid) block_id, dbms_rowid.rowid_row_number(rowid) row_number, t.* from enmo.t t; |
小结
oracle update restart使用logmgr观察较为清晰,分为(1.首次变更>>2.回滚过程>>3.锁定行>>4.重做过程)四个主要步骤。
不经一番寒彻骨,怎得梅花扑鼻香。 --唐 · 黄櫱禅师 《上堂开示颂》
最后修改时间:2023-10-13 14:45:22
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【米乐app官网下载的版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。