rac下的TS enq解决方案–适用于rac数据仓库环境

公司里面有一个12nodes的rac环境来跑数据仓库的应用,有一个1TB的临时表空间,有一些应用会跑的很慢,比如多个大表关联,而且有复杂的分组排序的操作会耗费大量的临时表空间,这些应用有事会跑的比较快,有时会跑的莫名其妙的慢,这是为什么呢?

花了点时间看了一下原因,
模块1正常的时候15分钟完成,但是慢的时候会跑1个半小时,原来有些的P0XX进程都在等待”enq: TS – contention”,根据gv$session_wait我们可以通过p2找到tablespace ID,进而可以发现是临时表空间出现了TS enq,然后可以发现是smon进程持有了这enq,这些P0XX的并行进程都在等待smon去释放这个enq,但是smon这时候在做什么呢?
那首先让我们来看一下rac里面的temp空间分配的机制是怎么样的。在rac里面,大家都知道temp表空间对所有节点都是可见的,但是temp空间一旦分配给了某一个节点使用,其他节点对这部分空间将都会看不见。

很典型的情况就像下面这样,每个节点有自己的temp extent

INST_ID TSNAME TOTAL USED FREE  ---------- ------- ----- ---- -----  1 TEMP 6678 0 6678  2 TEMP 83966 0 83966  3 TEMP 8908 0 8908  4 TEMP 1589 0 1589  5 TEMP 10006 0 10006  6 TEMP 12147 0 12147  7 TEMP 99 0 99  8 TEMP 414 0 414  9 TEMP 10913 0 10913  10 TEMP 2347 6 2341  11 TEMP 343 3 340  12 TEMP 16189 0 16189

一旦某个节点上发生了一个大的分组排序的操作,它目前分配到的temp exten将会被耗尽,这时候它会发出一个Cross Instance Call(CIC)来向每个节点请求新的temp extent,这时候smon就启动去回收每个节点的free temp extent,在这个过程中smon会持有TS enq,发起空间请求的节点必须等待smon完成对所有节点的free temp extent回收请求后才会继续下一步动作,smon每次向每个节点回收100 extents的临时空间,在这个12nodes的环境里面最大就是1200 extents,每个extent设置为8M,大致每次回收8GB的空间可以给发起节点使用,但是在一个很大操作面前,8GB的临时空间一下子就能用完。而且在一个多并发的系统里面,同时会有很多个大操作在进行,这个时候对于临时表空间的争用将会非常严重,会严重影响整个系统的执行效率。

下面来看一个实验
首先看一下当前系统个节点临时空间的分配情况

INST_ID TSNAME TOTAL USED FREE  ---------- ------- ----- ----- ---  1 TEMP 6378 0 6378  2 TEMP 82296 0 82296  3 TEMP 8908 0 8908  4 TEMP 1589 0 1589  5 TEMP 10006 0 10006  6 TEMP 12147 0 12147  7 TEMP 99 0 99  8 TEMP 414 0 414  9 TEMP 10913 0 10913  10 TEMP 2347 6 2341  11 TEMP 520 3 517  12 TEMP 16189 0 16189

我们可以看到7节点上当前只分配到了99个extents,

select sum(TOTAL_EXTENTS)*8/1024||'G' from gv$sort_segment;   SUM(TOTAL_EXTENTS)*8/1024||'G'  -----------------------------------------  1185.984375G

当前系统总共分配了1185.984375G的temp空间,总的temp表空间大小是1200G,整个系统里面还有1200-1186=14GB的空闲temp空间可以使用

下面登录到7节点执行一个耗费临时空间的操作

dwdb7> exec big_sort(null);

过了一会可以看到

select sum(TOTAL_EXTENTS)*8/1024||'G' from gv$sort_segment;  SUM(TOTAL_EXTENTS)*8/1024||'G'  -----------------------------------------  1199.9921875G

系统的空闲临时空间已经被用完,这个时候7节点会通过CIC请求smon释放其他节点的空闲temp空间,可以看到节点7现在的等待

Taobao@dwdb7> /   EVENT  ----------------------------------------------------------------  PX Deq Credit: send blkd  PX Deq Credit: send blkd  PX Deq Credit: send blkd  PX Deq Credit: send blkd  PX Deq Credit: send blkd  PX Deq Credit: send blkd  PX Deq Credit: send blkd  PX Deq Credit: send blkd  PX Deq Credit: send blkd  PX Deq Credit: send blkd  PX Deq Credit: send blkd  PX Deq Credit: send blkd  PX Deq Credit: send blkd  PX Deq Credit: send blkd  PX Deq Credit: send blkd  PX Deq Credit: send blkd  enq: TS - contention  enq: TS - contention  enq: TS - contention  enq: TS - contention  enq: TS - contention  enq: TS - contention  enq: TS - contention  enq: TS - contention  enq: TS - contention  enq: TS - contention  enq: TS - contention  enq: TS - contention  enq: TS - contention  enq: TS - contention  enq: TS - contention  enq: TS - contention

再看各节点temp空间的分布

扫描二维码关注公众号,回复: 1258436 查看本文章
Taobao@dwdb9> select INST_ID,TABLESPACE_NAME TSNAME,  TOTAL_EXTENTS TOTAL,USED_EXTENTS USED,FREE_EXTENTS  FREE from gv$sort_segment order by inst_id;   INST_ID TSNAME TOTAL USED FREE  ---------- --------------- ----------  1 TEMP 6278 0 6278  2 TEMP 82196 0 82196  3 TEMP 8808 0 8808  4 TEMP 1489 0 1489  5 TEMP 9906 0 9906  6 TEMP 12047 0 12047  7 TEMP 2992 2992 0  8 TEMP 314 0 314  9 TEMP 10813 0 10813  10 TEMP 2247 3 2244  11 TEMP 420 3 417  12 TEMP 16089 0 16089

smon完成一轮空间回收,节点7继续进行排序操作,但是可以看到所有的其他节点free_extents都少了100

INST_ID TSNAME TOTAL USED FREE  ---------- -------------------------  1 TEMP 6178 0 6178  2 TEMP 82096 0 82096  3 TEMP 8708 0 8708  4 TEMP 1389 0 1389  5 TEMP 9806 0 9806  6 TEMP 11947 0 11947  7 TEMP 3728 3728 0  8 TEMP 214 0 214  9 TEMP 10713 0 10713  10 TEMP 2147 3 2144  11 TEMP 320 3 317  12 TEMP 15989 0 15989

然后节点7用完smon回收的空间后又会碰到空间不够的问题,于是发起CIC请求smon会继续回收,

INST_ID TSNAME TOTAL USED FREE  ---------- ------ -------- -------------  1 TEMP 6078 0 6078  2 TEMP 81996 0 81996  3 TEMP 8608 0 8608  4 TEMP 1289 0 1289  5 TEMP 9706 0 9706  6 TEMP 11847 0 11847  7 TEMP 5192 5192 0  8 TEMP 114 0 114  9 TEMP 10613 0 10613  10 TEMP 2047 3 2044  11 TEMP 220 117 103  12 TEMP 15889 0 15889

周而复始,直到整个操作完成,这中间的回收过程会比较久,而且排序操作会一直等待smon从而影响整个应用模块的时间,而且由于各个节点分配到的temp extent严重贫富不均,如果一个sql刚好分配到了某个temp extent比较少的节点,它将会深受其害。

问题的原因相信大家都看明白了,下面就来看一下解决的方案,Oracle提供了一个命令来释放temp空间

ALTER SESSION SET events ‘immediate trace name drop_segments level tablespace_number+1′;

现在节点1有5478个free temp extent,

 INST_ID TSNAME TOTAL USED FREE  ---------- ---------- -------- ---------- -------  1 TEMP 5478 0 5478

登录到节点1执行两次ALTER SESSION SET events ‘immediate trace name drop_segments level 4′后将会释放出200个extent

INST_ID TSNAME TOTAL USED FREE  ---------- ---------- -------- ---------- -------  1 TEMP 5278 0 5278

这样的话我们就可以自己包装到crontab,定时在每个节点执行这个命令,这样节点间贫富不均的情况将会被修正,各个节点的空闲temp空间将会被及时的返回到temp pool中供需要的节点使用,也就避免了sql会去等待smon回收,基本上相当于每个节点有自己的专属的temp空间的效果,修正了RAC在temp空间管理这块的缺陷。

猜你喜欢

转载自andyniu.iteye.com/blog/1968254