从一个案例学习并行执行方面的问题分析方法

如果你想做一个并行查询,但是系统还是串行执行,该如何去一步步的分析呢?在一个割接现场,老白就遇到过类似的问题。这虽然是十多年前的一个案例,不过其分析与处理方法还是比较经典的,可以供大家参考。
这个案例刚刚开始的时候,开发商都觉得遇到了灵异事件,问题出现的莫名其妙。不过经过仔细的分析,终于还是把灵异后面的真相找到了。具体案例是这样的,在一个客户的割接现场,有一些大表,都有好几个G,为了加快割接速度,需要通过并行的方式建索引,但是建索引的过程中发现,实际上操作还是串行的。导致索引创建很慢。想要查清为什么不能并行建索引。

    由于这个问题是可以重现的,并且当时是在即将进行割接的系统上进行操作,于是很方便的建立测试环境进行测试。老白首先创建一张测试表:

createtable xuji_test tablespace sysaux as select * from dba_objects ;

alter table xuji_test parallel 20;

select count(*) from xuji_test

执行上述操作的时候,发现SQL确实没有走并行。除了觉得有些奇怪外并没有发现什么异常,于是继续查询一张大
表:

select/*+ full(a) parallel( a ,50) */  * from xxxx a; 

查询执行了10分钟才结束,期间查询V$PX_SESSION发现无并行进程,同样在V$SESSION中也没有看到并行进程处于活跃状态。看样子这个操作也没有走并行。为什么会这样呢?按照常规的分析流程,我们首先查看一下并行执行的相关参数:

SQL> show parameterparallel

NAME TYPE VALUE
———————————— ———– ——————————
fast_start_parallel_rollback string LOW
parallel_adaptive_multi_user boolean TRUE
parallel_automatic_tuning boolean FALSE
parallel_execution_message_size integer 2152
parallel_instance_group string sjzzw31
parallel_max_servers integer 1000
parallel_min_percent integer 0
parallel_min_servers integer 10
parallel_server boolean TRUE
parallel_server_instances integer 2
parallel_threads_per_cpu integer 2

recovery_parallelism integer 0
SQL>

从并行执行相关的参数来看,似乎也没什么问题。下一步怎么办呢?对于并行查询,如果通过表面现象无法定位问题的时候,我们可以通过_px_trace参数来进行跟踪。

SQL> alter session set “_px_trace” = “compilation”,”execution”,”messaging”
2 /

会话已更改。

SQL> select count(*) fromxuji_test;

COUNT(*)
———-
61059

SQL>

    设置了并行执行追踪参数后,一旦执行并行操作,就会生成TRACE文件。我们可以到udump目录下去查看TRACE文件:

kkfdapdml
pgadep:0 pdml mode:0 PQ allowed DML allowed not autonomous => not allowed
kxfplist
Getting instance info for open group
kxfralo
serial – instance group has no open members
~

从这里我们看到了一个问题,选择serial的原因是instance group has no open members,也就是说我们的parallel_instance_group参数不属于instance_groups中指定的GROUP。
这个时候我们再来看看这两个参数:

SQL> show parameterinstance_group

NAME TYPE VALUE
———————————— ———– ——————————
instance_groups string sjzzw3,sjzzw31
parallel_instance_group string sjzzw31

    好像也没什么问题吧。在这里我被忽悠了很久,也没看出来问题出在哪。这种情况下该如何处理呢?找一个正常的系统去对比一下就可以了。割接前的系统上是能跑并行的,刚刚开发商也用并行在老系统上做了一些数据处理。于是我们把老系统的参数文件和新系统做了一个比较。看到了正常的系统的INSTANCE_GROUPS设置,我才恍然大悟:

SQL> show parameterinstance_group

NAME TYPE VALUE
———————————— ———– ——————————
instance_groups string sjzzw1, sjzzw11
parallel_instance_group string sjzzw11

咋一看,这二者之间似乎也没什么不同吧。
不过细心的读者可能发现了,正确的那个instance_groups的两个组之间有一个空格,这就是区别了。
我们通过

createpfile=’/tmp/init.ora’ from spfile生成一个pfile来看看这个参数:

有问题的系统的参数设置为:

instance_groups=’sjzzw3,sjzzw31′

正确的系统的参数设置为:

instance_groups=’sjzzw1′,’sjzzw11′

这回我们看到的结果更清晰一些了。一个是用单引号引起的我们认为的两个组,一个是每个组用单引号引起来,用逗号分割。第一个的错误之处在于实际上这种设置方法把INSTANCE_GROUPS设置为一个叫做sjzzw3,sjzzw31的组,因为逗号是组成组名的合法字符。
由于设置INSTANCE_GROUPS参数要重启实例,为了解决这个问题,我想出了一个简单的办法,将parallel_instance_group设置为那个带逗号的:

SQL> alter session set”_px_trace”=”compilation”,”execution”,”messaging”;

会话已更改。

SQL> alter session setparallel_instance_group=’sjzzw3,sjzzw31′;

会话已更改。

SQL> select count(*) fromxuji_test;

COUNT(*)
———-
61059

这时再来看TRACE文件:

kkfdapdml
pgadep:0 pdml mode:0 PQ allowed DMLallowed not autonomous => not allowe
d
kxfplist
Getting instance info for open group
kxfrSysInfo
DOP trace — compute default DOPfrom system info

getting 1 sets of 20 threads, client parallel query execution flg=0x30
Height=20, Affinity List Size=0,inst_total=1, coord=1
Insts 1
Threads 20
kxfpg1srv
trying to get slave P000 on instance1
kxfpg1sg
Got It. 1 so far.
kxfpg1srv
trying to get slave P001 on instance1
kxfpg1sg
Got It. 2 so far.
kxfpg1srv
trying to get slave P002 on instance1
kxfpg1sg
Got It. 3 so far.
kxfpg1srv
trying to get slave P003 on instance1
kxfpg1sg
Got It. 4 so far.
kxfpg1srv
trying to get slave P004 on instance1
kxfpg1sg
Got It. 5 so far.
kxfpg1srv
trying to get slave P005 on instance1
kxfpg1sg
Got It. 6 so far.
kxfpg1srv
trying to get slave P006 on instance1
kxfpg1sg
Got It. 7 so far.
kxfpg1srv
trying to get slave P007 on instance1
kxfpg1sg
Got It. 8 so far.
kxfpg1srv
trying to get slave P008 on instance1
kxfpg1sg
Got It. 9 so far.
kxfpg1srv
trying to get slave P009 on instance1

    并行执行又回来了。这充分说明了刚才所说的参数设置问题是确实存在的。这个案例大家主要是掌握并行执行的跟踪和分析方法。除了看参数外,通过_PX_TRACE来跟踪并行操作的执行。另外在某些情况下,找个正常的系统,对比参数设置会有帮助。

这个案例能带给我们什么启示呢?首先就是灵异事件是肯定不存在的,任何灵异事件背后都有我们未知的秘密,都有我们脑子里的知识点未能覆盖或者我们思维未能覆盖的区域。其次是对并行执行的分析方法。通过_px_trace来分析并行执行的问题是一种十分有效的方法。最后我们再来给并行执行平平反。在十多年前,由于服务器的CPU、IO、内存等资源十分紧张,经常因为资源不足而导致性能问题,甚至导致系统HANG死。所以并行执行是被严格禁止的。那时候的很多DBA的著名案例中都有并行执行导致问题的内容。所以导致我们的很多DBA在接受培训的时候都很容易接受了并行执行要严控的思想。实际上并行执行可以更为有效的使用系统资源,获得更好的系统性能。因此对于并行执行我们不能一禁了之,而是要充分利用。也有朋友要说了,如果并发执行很多的应用,使用了并行执行,把系统资源耗尽了怎么办?实际上这个使用也是有条件的,在有控制和管理下使用。如果有一个每秒执行几百次的SQL在做全表扫描,用了并行查询耗尽了系统资源,你是把并行查询禁了还是不让它做全表扫描更好呢?


从一个案例学习并行执行方面的问题分析方法》来自互联网,仅为收藏学习,如侵权请联系删除。本文URL:http://www.bookhoes.com/897.html