high US enqueue
前两天在一个生产库上出现了大量的US enqueue. 该系统版本为10203,采AUM管理模式。
因为事情发生在美国的白天,所以只能通过一些statspack中的信息去追溯根本原因。
第一感觉觉得可能是online undo segment时产生的US enqueue,这个问题在9205的数据库特别繁忙时频频出现。
因为AUM的管理方式是当系统不是很忙时会offline一些undo segments,而当不够用时,再将其online,不过当系统特别繁忙时在online或者resize时就会出现问题,可以通过10511来解决这个问题,详细信息可以参考我的另外一片文章:10511 event
但奇怪的地方在于当时该数据库并不是特别繁忙,并不是在波峰时段。当查看stats$undostat时,一个参数吸引了我的注意力:UNXPSTEALCNT
我们来看看UNXPSTEALCNT的解释:
UNXPBLKREUCNT: Number of unexpired undo blocks reused by transactions
一般来说该参数都应该等于0,但是这个参数在那段时间是大于0的。因为只有当undo tablespace不够存放undo_retention时间段内的数据的时候,才会发生unexpired undo extents stealing。再去查看stats$rollstat,发现但是RSSIZE和undo tablespace大小是一样的,这就说明当时undo tablespace确实不够用了。
那么为什么在系统不是很繁忙的时候会出现undo不够用的情况呢,如果说不够用,那在波峰时段应该问题更加严重才对。
查看stats$undostat.tuned_undoretention参数发现了问题所在。从10.2版本开始,oracle默认采用自动调整undo retention的方法,根据你undo tablespace的大小以及系统的繁忙程度(v$undostat中信息)自动调整undo_retention参数,所以在10g的数据库上你会经常发现undo tablespace永远是满的,因为当你undo tablespace有空闲空间时,系统自动调大undo_retention来保留更多的undo blocks。这一方法有利于时间长的查询,但是对于典型的OLTP系统来说不太适用,因为OLTP上不太可能跑如此长时间的查询,而且在很繁忙的OLTP上还会导致上面所遇到的问题。oracle真是吃力不讨好。
出问题前一天,数据库做维护被重启过,因为刚起来数据库很空闲,所以v$undostat.tuned_autoretention很大,undo tablespace被撑满,虽然tuned_autoretention一直在降,但是还是没有赶上系统warm up的速度,导致数据库出现了问题。
该功能可以通过_undo_autotune参数被disable,disable后v$undostat不在更新。
_undo_autotune : enable auto tuning of undo_retention
该参数可以在线修改:
alter system set “_undo_autotune” = false;