谈谈死事务的回滚

死事务,一般是事务正在跑的时候,被kill掉了,或者数据库shutdown abort了,那么当数据库再次启动的时候,这些事务就需要做回滚。

可以通过下面的语句查到回滚的事务:

根据上面的语句,我们可以查到事务的undo的segment id(USN或者KTUXEUSN),undo的slot(SLT或者KTUXESLT),和undo的sequence(SEQ或者KTUXESQN)。

根据USN,我们可以查到undo segment:

根据上面的语句,我们可以dump出undo block:

然后根据dump出来的trace file,可以判断object number(objn)或者object id(objd)

此时,我们根据object id,可以在数据库里面找到回滚的object的对象:

此时,如果你select count(*) from 这个表,你会发现在回滚完前,这个很简单的select操作会一直处于”db file sequential read”的等待,而且对应的p1是file file,是undo 表空间的数据文件。

我们继续,要查回滚死事务的时间,可以利用x$ktuxe,注意看其单位时间内减少了多少KTUXESIZ,即减少了多少个undo block。根据这个速度,可以估算回滚速度。注,这个速度只是大概的,有时候往往会非线性的减少。

加快回滚速度,我们需要用到一个参数fast_start_parallel_rollback,这个参数默认是low,即2倍cpu数的并发度,进行并发的回滚。我们可以设置成high,即为4倍cpu数的并发度进行回滚。

而high的时候,有时会用去比较多的资源,特别是cpu资源,会看到很多并发进程ora_pnnn,同时去查v$px_session的话,会发现他们的qcsid是smon的进程。在很高的并发度下,会影响生产的稳定,有时甚至撑爆了process数导致应用无法连接,因此需要特别的注意。我们对fast_start_parallel_rollback进行调整,可以调整成low甚至false。

而并发度如果是high或low,4倍或2倍的cpu数,也会受到另外一些参数的影响,如PARALLEL_MAX_SERVERS,这个才是真正最大的并发度设置。

PARALLEL_MAX_SERVERS这个参数的默认值为PARALLEL_THREADS_PER_CPU * CPU_COUNT * concurrent_parallel_users * 5。PARALLEL_THREADS_PER_CPU 和CPU_COUNT都是初始化参数。concurrent_parallel_users 根据是否启用automatic memory management ,如果禁用automatic memory management 则这个值为1,如果pga自动管理则这个值是2,如果是automatic memory management 启用,则这个值是4。

另外,我们还可以_cleanup_rollback_entries,从默认值100改到400,来加快并发回滚的速度,该参数的意义是number of undo entries to apply per transaction clean。

除了上面说的加快,或者减慢(参数往小了调),我们还可以暂时禁用smon的恢复,用10513的事件:

恢复使用:

那么在什么情况下我们需要加大并发,什么时候需要串行?

在一般情况下,并发的回滚总是比串行的快,我们一般在系统资源可以接受的范围内采用并发回滚,但是,有一个情况例外,就是并发的子进程之间存在资源冲突的情况。

在并发子进程之间需要的资源冲突时,往往此时smon的等待事件是长期处于Wait for stopper event to be increased,而子进程的等待事件是较多出现Wait for a undo record。此时,就是子进程冲突了。并发的回滚速度反而不如串行的回滚速度。

冲突时,我们需要把fast_start_parallel_rollback 改成 false。

相关文章

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据