暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

关于parallel rollback的一点总结

原创 Roger 2011-10-07
552

关于parallel rollback,不少人写过相关的文章,今天偶然看到了,也简单的总结一下。
说到parallel rollback,那我们首先就要来看看与其有重大关系的一个参数:

fast_start_parallel_rollback

该参数是oracle 8i引入的,详细信息如下表所示:


Version Parameter Type Modifiable

11.1.0.7 fast_start_parallel_rollback STRING ALTER SYSTEM (IMMEDIATE)
11.1.0.6 fast_start_parallel_rollback STRING ALTER SYSTEM (IMMEDIATE)
10.2.0.4 fast_start_parallel_rollback STRING ALTER SYSTEM (IMMEDIATE)
10.2.0.3 fast_start_parallel_rollback STRING ALTER SYSTEM (IMMEDIATE)
10.1.0.5 fast_start_parallel_rollback STRING ALTER SYSTEM (IMMEDIATE)
10.1.0.4 fast_start_parallel_rollback STRING ALTER SYSTEM (IMMEDIATE)
9.2.0.8 fast_start_parallel_rollback STRING ALTER SYSTEM (IMMEDIATE)
9.0.1.4 fast_start_parallel_rollback STRING ALTER SYSTEM (IMMEDIATE)
8.1.7.4 fast_start_parallel_rollback STRING ALTER SYSTEM (IMMEDIATE)


该参数如下3种属性值:

false -- 即是关闭parallel rollback功能
low -- 也是10g的默认值,该值含有是最大的rollback进程为2*cpu_count个
high -- 当设置为该值时,最大的rollback进程为4*cpu_count个

当然其最大值是要受参数parallel_max_servers的影响的,如果是rac环境,那么还跟参数
parallel_threads_per_cpu有关系,这里需要说明一点的是,该参数跟recovery_parallelism不同的,
recovery_parallelism参数是指在进行instance crash recovery时的并行恢复进程个数。

关于并行rollback操作,我们可以通过观察几个试图来进行判断其回滚的时间,如下的几个试图就是
我们需要进行查询的:

v$fast_start_transactions
V$FAST_START_SERVERS



x$ktuxe

下面通过例子来进行说明.


SQL> show parameter rollback

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
_cleanup_rollback_entries integer 100
_corrupted_rollback_segments string
_max_cr_rollbacks integer 0
_offline_rollback_segments string
_rollback_segment_count integer 0
_rollback_segment_initial integer 1
_rollback_stopat integer 0
fast_start_parallel_rollback string LOW #### 10g中的默认值 ####
rollback_segments string
transactions_per_rollback_segment integer 5

SQL> show user
USER is "ROGER"

SQL> select count(*) from ht1;

COUNT(*)
----------
999

SQL> begin
2 for i in 1 .. 1000 loop
3 insert /*+ append */
4 into ht1
5 select * from ht1;
6 commit;
7 end loop;
8 end;
9 /
begin
*
ERROR at line 1:
ORA-01653: unable to extend table ROGER.HT1 by 1024 in tablespace ROGER
ORA-06512: at line 3

SQL> select count(*) from ht1;

COUNT(*)
----------
1022976


++++++ 在当前session执行全表的delete操作,如下:++++++

SQL> delete from ht1;

1022976 rows deleted.

++++++ 时间大约1分钟左右 ++++++


###### 在另一窗口进行如下查询:######

SQL> show user
USER is "SYS"

SQL> set lines 200
SQL> select XIDUSN,XIDSLOT,XIDSQN,NAME,START_UBASQN,START_UBAREC
2 from v$transaction;

XIDUSN XIDSLOT XIDSQN NAME START_UBASQN START_UBAREC
---------- ---------- ---------- ------------------------- ------------ ------------
6 31 234 221 1

SQL> select KTUXEUSN, KTUXESLT, KTUXESQN, KTUXECFL, KTUXESIZ, sysdate
2 from x$ktuxe
3 where KTUXEUSN = 6
4 and KTUXESLT = 31;

KTUXEUSN KTUXESLT KTUXESQN KTUXECFL KTUXESIZ SYSDATE
---------- ---------- ---------- ------------------------ ---------- ---------
6 31 234 NONE 38912 07-OCT-11


++++++ 下面进行rollback time计算 ++++++

SQL> show user
USER is "ROGER"

SQL> set timing on
SQL> rollback;

Rollback complete.

Elapsed: 00:00:46.53

++++++ 该rollback操作花费了46.53秒 ++++++


###### 另外窗口 ######

SQL> alter session set nls_date_format='yyyy-mm-dd hh24:mi:ss';

Session altered.

Elapsed: 00:00:00.04

SQL> select KTUXEUSN, KTUXESLT, KTUXESQN, KTUXECFL, KTUXESIZ, sysdate
2 from x$ktuxe
3 where KTUXEUSN = 6
4 and KTUXESLT = 31;

KTUXEUSN KTUXESLT KTUXESQN KTUXECFL KTUXESIZ SYSDATE
---------- ---------- ---------- ------------ ---------- -------------------
6 31 234 NONE 3616 2011-10-07 06:32:45

Elapsed: 00:00:00.00

SQL> /

KTUXEUSN KTUXESLT KTUXESQN KTUXECFL KTUXESIZ SYSDATE
---------- ---------- ---------- ------------ ---------- -------------------
6 31 234 NONE 2479 2011-10-07 06:32:47

Elapsed: 00:00:00.01

SQL> /

KTUXEUSN KTUXESLT KTUXESQN KTUXECFL KTUXESIZ SYSDATE
---------- ---------- ---------- ------------ ---------- -------------------
6 31 234 NONE 0 2011-10-07 06:32:52

Elapsed: 00:00:00.01

SQL> select 38912/((3616-2479)/2) from dual;

38912/((3616-2479)/2)
---------------------
68.4467898

Elapsed: 00:00:00.01


通过我计算发现,应该是需要68.44s才能完成rollback操作,但是为什么实际上46.53s就完成了呢?


###### 再次进行相同的测试 ######

SQL> delete from ht1;

1022976 rows deleted.

Elapsed: 00:01:31.96

SQL> rollback;

Rollback complete.

Elapsed: 00:00:36.51


###### 另一session窗口 ######

SQL> select XIDUSN,XIDSLOT,XIDSQN,NAME,START_UBASQN,START_UBAREC from v$transaction;

XIDUSN XIDSLOT XIDSQN NAME START_UBASQN START_UBAREC
---------- ---------- ---------- ------------------------- ------------ ------------
2 13 217 207 55

Elapsed: 00:00:00.01

SQL> select KTUXEUSN, KTUXESLT, KTUXESQN, KTUXECFL, KTUXESIZ, sysdate
2 from x$ktuxe
3 where KTUXEUSN = 2
4 and KTUXESLT = 13;

KTUXEUSN KTUXESLT KTUXESQN KTUXECFL KTUXESIZ SYSDATE
---------- ---------- ---------- ------------------------ ---------- -------------------
2 13 217 NONE 38913 2011-10-07 06:55:36

Elapsed: 00:00:00.01

SQL> /

KTUXEUSN KTUXESLT KTUXESQN KTUXECFL KTUXESIZ SYSDATE
---------- ---------- ---------- ------------------------ ---------- -------------------
2 13 217 NONE 32721 2011-10-07 06:55:54

Elapsed: 00:00:00.00

SQL> /

KTUXEUSN KTUXESLT KTUXESQN KTUXECFL KTUXESIZ SYSDATE
---------- ---------- ---------- ------------------------ ---------- -------------------
2 13 217 NONE 29825 2011-10-07 06:55:55

Elapsed: 00:00:00.00

SQL> /

KTUXEUSN KTUXESLT KTUXESQN KTUXECFL KTUXESIZ SYSDATE
---------- ---------- ---------- ------------------------ ---------- -------------------
2 13 217 NONE 29195 2011-10-07 06:55:57

Elapsed: 00:00:00.01

SQL> /

KTUXEUSN KTUXESLT KTUXESQN KTUXECFL KTUXESIZ SYSDATE
---------- ---------- ---------- ------------------------ ---------- -------------------
2 13 217 NONE 25293 2011-10-07 06:56:00

Elapsed: 00:00:00.00

SQL> /

KTUXEUSN KTUXESLT KTUXESQN KTUXECFL KTUXESIZ SYSDATE
---------- ---------- ---------- ------------------------ ---------- -------------------
2 13 217 NONE 22288 2011-10-07 06:56:02

Elapsed: 00:00:00.00

SQL> /

KTUXEUSN KTUXESLT KTUXESQN KTUXECFL KTUXESIZ SYSDATE
---------- ---------- ---------- ------------------------ ---------- -------------------
2 13 217 NONE 21288 2011-10-07 06:56:04

Elapsed: 00:00:00.00

SQL> /

KTUXEUSN KTUXESLT KTUXESQN KTUXECFL KTUXESIZ SYSDATE
---------- ---------- ---------- ------------------------ ---------- -------------------
2 13 217 NONE 18512 2011-10-07 06:56:05

Elapsed: 00:00:00.01

SQL> /

KTUXEUSN KTUXESLT KTUXESQN KTUXECFL KTUXESIZ SYSDATE
---------- ---------- ---------- ------------------------ ---------- -------------------
2 13 217 NONE 17643 2011-10-07 06:56:07

Elapsed: 00:00:00.00

SQL> /

KTUXEUSN KTUXESLT KTUXESQN KTUXECFL KTUXESIZ SYSDATE
---------- ---------- ---------- ------------------------ ---------- -------------------
2 13 217 NONE 16880 2011-10-07 06:56:08

Elapsed: 00:00:00.00

SQL> select * from v$fast_start_transactions;

no rows selected

Elapsed: 00:00:00.00

SQL> select * from v$fast_start_servers;

no rows selected

Elapsed: 00:00:00.00

SQL> /

no rows selected

Elapsed: 00:00:00.00

根据前面的时间数据,我分别计算出2个值如下1238和1102,然后再根据该值取平均值,如下;

SQL> select 1238+1102 from dual;

1238+1102
----------
2340

SQL> select 2340/2 from dual;

2340/2
----------
1170

SQL> select 38913/1170 from dual;

38913/1170
----------
33.2589744


我们来看看此次的rollback时间,如下:

SQL> show user
USER is "ROGER"

SQL> delete from ht1;

1022976 rows deleted.

Elapsed: 00:01:31.96

SQL> rollback;

Rollback complete.

Elapsed: 00:00:36.51


可以看到,已经非常的接近了,因为前面的时间计算,其实还存在一定的误差,从数学的角度来说,
要想更加精确,需要把时间扩大,进行多次采集然后计算平均值,那样可能就更加接近实际值了。

最后需要做一点补充的是,关于x$ktuxe大家可以参考我以前的一个笔记,简略信息如下:

... ... ...
... ... ...
ktuxc 其实并不神秘,跟一个x$表相关,即如下x$表:

x$ktuxe
[K]ernel [T]ransaction [U]ndo transaction [E]ntry
... ... ...
... ... ...

我们知道,在平常所遇到的数据库故障中,跟undo相关的太多了,基本上ora-4xxx ~都跟undo有着紧密的联系

比如大家所熟知的ora-4193、ora-4000、ora-4194等等。 这里我主要简单的分析下ktuxe的结构,其实关于ktuxe,
还有一个很重要的地方,那就是无法通过v$tranactions查到的死事务,我们可以通过x$ktuxe来获取。

那么ktuxe,ktuxc结构到底多大呢?换句话说,在整个block中,占据了多少个byte呢? 如下:


COMPONEN TYPE DESCRIPTION TYPE_SIZE
-------- -------- -------------------------------- ----------
S EWORD EITHER WORD 4
S EB1 EITHER BYTE 1 1
S EB2 EITHER BYTE 2 2
S EB4 EITHER BYTE 4 4
S UWORD UNSIGNED WORD 4
S UB1 UNSIGNED BYTE 1 1
S UB2 UNSIGNED BYTE 2 2
S UB4 UNSIGNED BYTE 4 4
S SWORD SIGNED WORD 4
S SB1 SIGNED BYTE 1 1
S SB2 SIGNED BYTE 2 2
S SB4 SIGNED BYTE 4 4
S BOOLEAN BOOLEAN 4
S FLOAT FLOAT 4
S DOUBLE DOUBLE 8
S SIZE_T SIZE_T 4
S DSIZE_T DSIZE_T 4
S PTR_T PTR_T 4
K KDBA DATABASE BLOCK ADDRESS 4
K KTNO TABLE NUMBER IN CLUSTER 1
K KSCN SYSTEM COMMIT NUMBER 8
K KXID TRANSACTION ID 8
K KUBA UNDO ADDRESS 8
KCB KCBH BLOCK COMMON HEADER 20
KTB KTBIT TRANSACTION VARIABLE HEADER 24
KTB KTBBH TRANSACTION FIXED HEADER 48
KTB KTBBH_BS TRANSACTION BLOCK BITMAP SEGMENT 8
KDB KDBH DATA HEADER 14
KDB KDBT TABLE DIRECTORY ENTRY 4
KTE KTECT EXTENT CONTROL 44
KTE KTECH EXTENT CONTROL 72
KTE KTETB EXTENT TABLE 8
KTS KTSHC SEGMENT HEADER 8
KTS KTSFS SEGMENT FREE SPACE LIST 20
KTS KTSPHW PAGE TABLE SEGMENT HWM 60
KTS KTSPHC PAGE TABLE SEGMENT HEADER 112
KTS KTSPFHC LEVEL 1 BITMAP BLOCK HEADER 184
KTS KTSPSHC LEVEL 2 BITMAP BLOCK HEADER 96
KTS KTSPTHC LEVEL 3 BITMAP BLOCK HEADER 88
KTU KTUBH UNDO HEADER 16
KTU KTUXE UNDO TRANSACTION ENTRY 40 ==> 跟ktuxc相关
KTU KTUXC UNDO TRANSACTION CONTROL 104 ==> 这里是我们这里需要关注的地方(占据了104个byte)
KDX KDXCO INDEX HEADER 16
KDX KDXLE INDEX LEAF HEADER 32
KDX KDXBR INDEX BRANCH HEADER 24


BBED> p ktuxc

struct ktuxc, 104 bytes @4148 -- 通过bbed我们可以发现,确定是占据了104个byte
struct ktuxcscn, 8 bytes @4148
ub4 kscnbas @4148 0x001564b5 -- scn值
ub2 kscnwrp @4152 0x0000
struct ktuxcuba, 8 bytes @4156 -- UBA值 (有如下3部分组成)
ub4 kubadba @4156 0x00400181 -- dba(转换后为file 1 block 385)
ub2 kubaseq @4160 0x0068
ub1 kubarec @4162 0x0f -- Last Entry in UNDO record map
sb2 ktuxcflg @4164 1 (KTUXCFSK) -- 表示inactive
ub2 ktuxcseq @4166 0x0068
sb2 ktuxcnfb @4168 1
ub4 ktuxcinc @4172 0x00000000
sb2 ktuxcchd @4176 30
sb2 ktuxcctl @4178 22 -- 这里的部分内容 目前我还没搞清楚是啥意思
ub2 ktuxcmgc @4180 0x8002
ub4 ktuxcopt @4188 0x7ffffffe
struct ktuxcfbp[0], 12 bytes @4192
struct ktufbuba, 8 bytes @4192
ub4 kubadba @4192 0x00400181
ub2 kubaseq @4196 0x0068
ub1 kubarec @4198 0x0f
sb2 ktufbext @4200 2
sb2 ktufbspc @4202 4280
struct ktuxcfbp[1], 12 bytes @4204
struct ktufbuba, 8 bytes @4204
ub4 kubadba @4204 0x00000000
ub2 kubaseq @4208 0x0065
ub1 kubarec @4210 0x02
sb2 ktufbext @4212 5
sb2 ktufbspc @4214 7886
struct ktuxcfbp[2], 12 bytes @4216
struct ktufbuba, 8 bytes @4216
ub4 kubadba @4216 0x00000000
ub2 kubaseq @4220 0x003e
ub1 kubarec @4222 0x25
sb2 ktufbext @4224 2
sb2 ktufbspc @4226 464
struct ktuxcfbp[3], 12 bytes @4228
struct ktufbuba, 8 bytes @4228
ub4 kubadba @4228 0x00000000
ub2 kubaseq @4232 0x003e
ub1 kubarec @4234 0x08
sb2 ktufbext @4236 2
sb2 ktufbspc @4238 7130
struct ktuxcfbp[4], 12 bytes @4240
struct ktufbuba, 8 bytes @4240
ub4 kubadba @4240 0x00000000
ub2 kubaseq @4244 0x0000
ub1 kubarec @4246 0x00
sb2 ktufbext @4248 0
sb2 ktufbspc @4250 0



从上面信息,我们可以发现最后一次使用的undo block是 file 1 block 385。下面来看看ktuxe的情况

下面我们来看看x$ktuxe的结构:


SQL> desc x$ktuxe

Name Null? Type
------------------ -------- ----------------------------
ADDR RAW(4)
INDX NUMBER
INST_ID NUMBER
KTUXEUSN NUMBER -- undo seq number
KTUXESLT NUMBER -- slot 即为事务槽号
KTUXESQN NUMBER -- sequence号
KTUXERDBF NUMBER -- 文件号 即为file id
KTUXERDBB NUMBER -- block 号
KTUXESCNB NUMBER -- SCN base for prepare/commit
KTUXESCNW NUMBER -- SCN wrap for prepare/commit
KTUXESTA VARCHAR2(16) -- 事务状态 (我所知道的应该是有3种 action,inaction,dead)
KTUXECFL VARCHAR2(24) -- 事务标志
KTUXEUEL NUMBER -- 这里根据我猜测,应该是指用于存放事务的一个列表
KTUXEDDBF NUMBER -- file id
KTUXEDDBB NUMBER -- block number
KTUXEPUSN NUMBER -- parent usn number
KTUXEPSLT NUMBER -- parent solt number
KTUXEPSQN NUMBER -- parent seq#
KTUXESIZ NUMBER -- 用于该事务有多少个undo block(单位是block)


这里我只想说明一点的是,注意KTUXESIZ的单位是block,而不是byte。
本文的重点不是来讲述这个x$表的用途,而是想详细说明parallel rollback 的一些东西,
这里有点要说明的是,rollback分为两种,如下:

1. parallel rollback 即并行回滚
2. Serial rollback 即串行回滚

当初始化参数fast_start_parallel_rollback设置为false以后,即为串行回滚,否则为并行回滚。
我们知道并行回滚是oracle 8i引入的一个特性,那么必然就有它的优势,但是我google了一下,
找到了老白的帖子,说某些情况下并行恢复会非常的慢,但是没有说具体是那些情况下,这点较为
遗憾。

我这里由于是单表所以模拟的时候并没有发现parallel rollback进程,虽然说参数是默认值。
总的来说,不管是使用并行回滚还是串行回滚,我们都可以通过上面的方法来进行估算具体的回滚时间。

通过所掌握的知识来看,我猜测可能在如下的情况下parallel rollback可能会更慢:

1. 相关的操作正常情况下走index,而如果是parallel,那么将走全表扫描,所以会更慢;
2. 存在相关争用的情况下。

另外,在某些情况下我们还可以同调整_cleanup_rollback_entries来加快恢复进度。


「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论