观察一下Oracle对kill process的反应(对比上一篇中Teradata的反应):
1. 用sys和scott分别打开两个会话。used_ublk列就是在事务中使用的undo block数。
sys@ORA10G> select
saddr,username,sid,serial#,paddr,status from v$session where
username is not null;
SADDR USERNAME SID SERIAL# PADDR STATUS
-------- ---------- ---------- ---------- -------- --------
2632A004
SCOTT 141 10 2625132C
INACTIVE
2632C594
SYS 143 8
2624DDBC ACTIVE
sys@ORA10G> select
used_ublk from v$transaction;
未选定行
scott@ORA10G> select
count(*) from test;
COUNT(*)
----------
2931144
scott@ORA10G> select
count(*) from test2;
COUNT(*)
----------
0
2. 在scott中执行一个insert操作,同时在sys中反复查看v$session和v$transaction。
scott@ORA10G> insert
into test2 select * from test;
(执行中。。。)
sys@ORA10G> select
used_ublk from v$transaction;
USED_UBLK
----------
190
sys@ORA10G> select
saddr,username,sid,serial#,paddr,status from v$session where
username is not null;
SADDR USERNAME SID SERIAL# PADDR STATUS
-------- ---------- ---------- ---------- -------- --------
2632A004
SCOTT 141 10 2625132C
ACTIVE
2632C594
SYS 143 8
2624DDBC ACTIVE
sys@ORA10G> select
used_ublk from v$transaction;
USED_UBLK
----------
2
211
不等scott执行完就手动kill掉该sqlplus进程,然后在sys中反复查看v$session和v$transaction。可以看到scott的session还是保持在ACTIVE状态,并且used_ublk也在持续增加,这说明Oracle还在继续执行insert操作,还在不断的申请新的undo
block:
sys@ORA10G> select
used_ublk from v$transaction;
USED_UBLK
----------
586
sys@ORA10G> select
saddr,username,sid,serial#,paddr,status from v$session where
username is not null;
SADDR USERNAME SID SERIAL# PADDR STATUS
-------- ---------- ---------- ---------- -------- --------
2632A004
SCOTT 141 10 2625132C
ACTIVE
2632C594
SYS 143 8
2624DDBC ACTIVE
sys@ORA10G> select
used_ublk from v$transaction;
USED_UBLK
----------
2
611
过了一段时间之后,会发现used_ublk开始慢慢减小了,这说明Oracle已经发现insert操作对应的process被kill了,正在做rollback操作。注意此时scott的session虽然还在,但是其serial#列却变化了:
sys@ORA10G> select
used_ublk from v$transaction;
USED_UBLK
----------
202
sys@ORA10G> select
saddr,username,sid,serial#,paddr,status from v$session where
username is not null;
SADDR USERNAME SID SERIAL# PADDR STATUS
-------- ---------- ---------- ---------- -------- --------
2632A004
SCOTT 141 11 2625132C
ACTIVE
2632C594
SYS 143 8
2624DDBC ACTIVE
sys@ORA10G> select
used_ublk from v$transaction;
USED_UBLK
----------
54
最后,回滚完成了,scott的session也消失了:
sys@ORA10G> select
saddr,username,sid,serial#,paddr,status from v$session where
username is not null;
SADDR USERNAME SID SERIAL# PADDR STATUS
-------- ---------- ---------- ---------- -------- --------
2632C594
SYS 143 8
2624DDBC ACTIVE
sys@ORA10G> select
used_ublk from v$transaction;
未选定行
sys@ORA10G> select
count(*) from scott.test2;
COUNT(*)
----------
0
结论:恩,看来Oracle也是会先等待insert执行完之后才开始rollback,因为Oracle不知道OS上的process已经被kill了,只有当执行完insert操作,要将结果反馈给scott时,才会发现process已经没了,这时Oracle才会终止这个session,并通知PMON进程去rollback该session中未提交的事务。