引子:以前一直没太关注oracle并行这个特性。前几天一个兄弟碰到的一个问题,才让我觉得这个东西还是有很多需要注意的地方,有必要仔细熟悉下。其实碰到的问题不复杂:
类似如下的一条语句:insert into xxxx select /+parallel(a) / * from xxx a;数据量大约在75G左右,这位兄弟从上午跑到下午还没跑完,过来问我咋回事,说平常2hrs能跑完的东西跑了好几个小时还撒动静。查看系统性能也比较 正常,cpu,io都不繁忙,平均READ速度在80M/s左右(勉强凑合),但平均写速度只有10M不到。等待事件里面大量的‘ ‘PX Deq Credit: send blkd’,这里能看出并行出了问题,从而最后得知是并行用法有问题,修改之后20分钟完成了该操作。正确的做法应该是:
alter session enable dml parallel;
insert /+parallel(xxxx,4) / into xxxx select /+parallel(a) / * from xxx a;
因为oracle默认并不会打开PDML,对DML语句必须手工启用。 另外不得不说的是,并行不是一个可扩展的特性,只有在数据仓库或作为DBA等少数人的工具在批量数据操作时利于充分利用资源,而在OLTP环境下使用并行 需要非常谨慎。事实上PDML还是有比较多的限制的,例如不支持触发器,引用约束,高级复制和分布式事务等特性,同时也会带来额外的空间占用,PDDL同 样是如此。有关Parallel excution可参考官方文档,在Thomas Kyte的新书《Expert Oracle Database architecture》也有精辟的讲述。
………………………………………………………………………………………………………………
………………………………………………………………………………………………………………
我在其中一个SESSION 执行
sql> create table test3 parallel 4 as select * from test1;
表已创建。
sql> select * from v$mystat where rownum=1;
SID STATISTIC# VALUE
151 0 1
sql>
然后立刻在另一SESSION 乘上一个执行没结束,看下面,这么说是有4个并行的进程在处理了
sql> select * from v$px_session;
SADDR SID SERIAL# QCSID QCSERIAL# QCINST_ID SERVER_GROUP SERVER_SET SERVER# DEGREE REQ_DEGREE
6D31E434 131 16 151 107 1 1 1 1 4 4
6D32421C 136 11 151 107 1 1 1 2 4 4
6D3267AC 138 18 151 107 1 1 1 3 4 4
6D31F6FC 132 11 151 107 1 1 1 4 4 4
6D335BD4 151 107 151
sql> select * from v$mystat where rownum=1;
SID STATISTIC# VALUE
137 0 1
sql>
我加大后
sql> /
SADDR SID SERIAL# QCSID QCSERIAL# QCINST_ID SERVER_GROUP SERVER_SET SERVER# DEGREE REQ_DEGREE
6D31864C 126 10 151 107 1 1 1 1 7 10
6D31F6FC 132 17 151 107 1 1 1 2 7 10
6D32421C 136 15 151 107 1 1 1 3 7 10
6D3267AC 138 22 151 107 1 1 1 4 7 10
6D322F54 135 11 151 107 1 1 1 5 7 10
6D31E434 131 18 151 107 1 1 1 6 7 10
6D327A74 139 5 151 107 1 1 1 7 7 10
6D335BD4 151 107 151
已选择8行。
sql>
奇怪,怎么看只有7个,我那里可是写成
sql> create table test4 parallel 10 as select * from test1;
表已创建。
怎么少了3个?
不过我实际只有一个cpu的机器,这些说明什么问题呢?
BTW
sql> SHOW Parameter parallel_max
NAME TYPE VALUE
parallel_max_servers integer 20
sql>
……………………………………………………………………………………………………………………
……………………………………………………………………………………………………………………
开多少个parallel server也要看当时系统的负载,并行是很耗系统资源的,
这个并行度和你初始化参数有关。cpu_COUNT 、PARALLEL_THREADS_PER_cpu 等等都有关系。如果你建表的时候没有明确指定并行度,那么oracle会自动的根据需要设定并行度。
用Oracle并行查询发挥多cpu的威力
在一个单独的服务器中安装更多的cpu成为目前的一个趋势。使用对称多处理服务器(SMP)的情况下,一个Oracle服务器拥有8个、16个或32个cpu以及几吉比特RAM的SGA都不足为奇。
Oracle跟上了硬件发展的步伐,提供了很多面向多cpu的功能。从Oracle8i开始,Oracle在每个数据库函数中都实现了并行性,包括sql访问(全表检索)、并行数据操作和并行恢复。对于Oracle专业版的挑战是为用户的数据库配置尽可能多的cpu。
在Oracle环境中实现并行性最好的方法之一是使用Oracle并行查询(OPQ)。我将讨论OPQ是如何工作的和怎样用它来提升大的全表检索的响应时间以及调用并行事务回滚等等。
使用OPQ
当在Oracle中进行一次合法的、大型的全表检索时,OPQ能够极大地提高响应时间。通过OPQ,Oracle将表划分成如图A所示的逻辑块。
图 A
由OPQ划分的表
一旦表被划分成块,Oracle启用并行的子查询(有时称为杂务进程),每个子查询同时读取一个大型表中的一块。所有子查询完毕以后,Oracle将结果会传给并行查询调度器,它会重新安排数据,如果需要则进行排序,并且将结果传递给最终用户。OPQ具有无限的伸缩性,因此,以前需要花费几分钟的全表检索现在的响应时间却不到1秒。
OPQ严重依赖于处理器的数量,通过并行运行之所以可以极大地提升全表检索的性能,其前提就是使用了N-1个并行进程(N=Oracle服务器上cpu的数量)。
必须注意非常重要的一点,即Oracle9i能够自动检测外部环境,包括服务器上cpu的数量。在安装时,Oracle9i会检查服务器上cpu的数量,设置一个名为cpu_count的参数,并使用cpu_count作为默认的初始化输入参数。这些初始化参数会影响到Oracle对内部查询的处理。
下面就是Orale在安装时根据cpu_count而设置的一些参数:
fast_start_parallel_rollback
parallel_max_servers
log_buffer
db_block_lru_latches
参数
参数fast_start_parallel_rollback
Oracle并行机制中一个令人兴奋之处是在系统崩溃时调用并行回滚得能力。当Oracle数据库发生少有的崩溃时,Oracle能自动检测未完成的事务并回滚到起始状态。这被称为并行热启动,而Oracle使用基于cpu_count的fast_start_parallel_rollback参数来决定未完成事务的秉性程度。
并行数据操纵语言(DML)恢复能够在Oracle数据库崩溃后极大地加快其重新启动的速度。此参数的默认值是系统cpu数量的两倍,但是一些DBA们认为应该将这个值设置为cpu_count的四倍。
参数parallel_max_servers_parameter
Oracle一个显著的加强是自动决定OPQ并行的程度。由于Oracle清楚服务器中cpu的数量,它会自动分配合适的子进程的数量来提升并行查询的响应时间。当然,会有其它的外部因素,比如表的划分以及磁盘输入/输出子系统的布局等,但是根据cpu_count来设置parallel_max_servers参数将给Oracle一个合理的依据来选择并行的程度。
由于Oracle的并行操作严重依赖服务器上cpu的数量,parallel_max_servers会被设置成服务器上cpu的数量。如果在一台服务器上运行多个实例,则默认值太大了,会导致过度的页面交换和严重的cpu负担。并行的程度还依赖于目标表中分区的数量,因此parallel_max_servers应该设置成足够大以允许Oracle为每个查询选择最佳数量的并行子查询。
参数log_buffer
参数log_buffer定义了供即刻写入redo日志信息的保留RAM的数量,这个参数受cpu_count的影响。Oracle推荐log_buffer最大为cpu_count乘以500KB或128KB。cpu的数量对于log_buffer来说非常重要,因为Oracle会生成多日志写入(LGWR)进程来异步释放redo信息。
log_buffer是Oracle中最易误解的的RAM参数之一,通常存在下面几个配置错误:
log_buffer被设置得太高(例如,大于1MB),这回引起性能问题,因为大容量的结果会使得写入同步进行(例如,日志同步等待事件非常高)。
log_buffer不是db_block_size的倍数。在的Oracle9i中,log_buffer应该是2048字节的倍数。
参数db_block_lru_latches
LRU锁的数量是在Oracle数据库内部用来管理数据库缓冲的,这严重依赖于服务器上cpu的数量。
很多聪明的Oracle9i的DBA使用多冲数据缓冲(例如db_32k_cache_size),他们推荐将这个未公开声明的参数重设置为默认的最大值。db_block_lru_latches参数在Oracle8i中使用得很多,但是在Oracle9i中变成了一个未公开声明的参数,因为Oracle现在根据数据库拥有的cpu数量设置了一个合理的默认值。
db_block_lru_latches默认被设置为服务器上cpu_count的一半(例如服务器上只有一个Oracle数据库)。Oracle推荐db_block_lru_latches千万不要超过cpu_count的两倍或三倍,或db_block_buffers的五十分之一。
如果使用多缓冲池则这种计算方法有一个问题,因为不能控制分配给每个数据缓冲池的锁的数量。如果db_writers参数大于1,则默认值或许显得太小。
加强服务器
Oracle数据库总是在提升性能,根据外部服务器环境检测cpu_count和基本参数设置的能力对于Oracle软件来说是一个重要的加强。
随着更多的Oracle系统转移到SMP上来,当客户要采取增强措施并将众多的数据库转移到拥有32个或64个cpu的巨大服务器上来的时候,这些参数显得愈发重要。
关于10G的parallel参数的说明
parallel_adaptive_multi_user boolean TRUE
说明: 启用或禁用一个自适应算法,旨在提高使用并行执行方式的多用户环境的性能。通过按系统负荷自动降低请求的并行度,
在启动查询时实现此功能。当 PARALLEL_AUTOMATIC_TUNING = TRUE 时,其效果最佳。
值范围: TRUE | FALSE
默认值: 如果 PARALLEL_AUTOMATIC_TUNING = TRUE,则该值为 TRUE; 否则为 FALSE
parallel_automatic_tuning boolean TRUE
说明: 如果设置为 TRUE,Oracle 将为控制并行执行的参数确定默认值。除了设置该参数外,
你还必须为系统中的表设置并行性。
值范围: TRUE | FALSE
默认值: FALSE
parallel_execution_message_size integer 4096
说明: 指定并行执行 (并行查询,PDML,并行恢复和复制) 消息的大小。如果值大于 2048 或 4096,
就需要更大的共享池。如果 PARALLEL_AUTOMATIC_TUNING = TRUE,
将在大存储池之外指定消息缓冲区。
值范围: 2148 - 无穷大。
默认值: 如果 PARALLEL_AUTOMATIC_TUNING 为 FALSE,通常值为 2148; 如果 PARALLEL_AUTOMATIC_TUNING 为 TRUE,则值为 4096 (根据操作系统而定)。
parallel_instance_group string
说明 : 一个群集数据库参数,标识用来大量产生并行执行从属的并行例程组。并行操作只对在其 INSTANCE_GROUPS
参数中指定一个匹配组的例程大量产生并行执行从属。
值范围: 一个代表组名的字符串。
默认值 : 由所有当前活动例程构成的组
parallel_max_servers integer 160
说明: 指定一个例程的并行执行服务器或并行恢复进程的最大数量。如果需要,例程启动时分配的查询服务器的数量将增加到该数量。
值范围: 0 -256
默认值: 由 cpu_COUNT,PARALLEL_AUTOMATIC_TUNING 和 PARALLEL_ADAPTIVE_MULTI_USER 确定
parallel_min_percent integer 0
说明: 指定并行执行要求的线程的最小百分比。设置该参数,可以确保并行执行在没有可用的恰当查询从属进程时,会显示一个错误消息,
并且该查询会因此而不予执行。
值范围: 0 -100
默认值: 0,表示不使用该参数。
parallel_min_servers integer 0
说明: 指定为并行执行启动例程后,Oracle 创建的查询服务器进程的最小数量。
值范围: 0 - PARALLEL_MAX_SERVERS。
默认值: 0
parallel_server boolean TRUE
说明 : 将 PARALLEL_SERVER 设置为 TRUE,可以启用群集数据库选项。
值范围: TRUE | FALSE
默认值 : FALSE
parallel_server_instances integer 2
说明: 当前已配置的例程的数量。它用于确定 SGA 结构的大小,该结构由已配置的例程数量来确定。正确设置该参数将改善 SGA
的内存使用情况。 有几个参数是用该数量计算得到的。
值范围: 任何非零值。
默认值: 1
parallel_threads_per_cpu integer 2
说明: 说明一个 cpu 在并行执行过程中可处理的进程或线程的数量,
并优化并行自适应算法和负载均衡算法。如果计算机在执行一个典型查询时有超负荷的迹象,应减小该数值。
值范围: 任何非零值。
默认值: 根据操作系统而定 (通常为 2)
举例:Parallel Execution for a Session
并行执行会话,有时候为了加快执行速度,充分利用多cpu资源,进行比如并行创建索引的操作.
要使用并行执行某些操作可以使用alter session 语句
ALTER SESSION ENABLE PARALLEL DML|DDL|QUERY
关闭用如下语句
alter session disable parallel DDL|DML|QUERY
强制并行执行:
ALTER SESSION FORCE PARALLEL DML|DDL|QUERY
PARALLEL_MAX_SERVERS参数用于设置系统中允许的最大并行进程数。Oracle的文档对于这个参数的描述如下:
PARALLEL_MAX_SERVERS specifies the maximum number of parallel execution processes and parallel recovery processes for an instance. As demand increases,Oracle increases the number of processes from the number created at instance startup up to this value.
If you set this parameter too low,some queries may not have a parallel execution process available to them during query processing. If you set it too high,memory resource shortages may occur during peak periods,which can degrade performance.
这个参数在9i及更老的版本中是静态参数,修改需要重启。10g以后可以动态修改生效。如果是RAC环境,则各节点应当设置成同样的值。
对于9i
1.如果PARALLEL_AUTOMATIC_TUNING=FALSE
PARALLEL_MAX_SERVERS=5
2.如果PARALLEL_AUTOMATIC_TUNING=TRUE
PARALLEL_MAX_SERVERS=cpu_COUNT x 10
9i中PARALLEL_AUTOMATIC_TUNING默认为FALSE,所以PARALLEL_MAX_SERVERS默认为5
对于10g
1.如果PGA_AGGREGATE_TARGET >0
PARALLEL_MAX_SERVERS=cpu_COUNT x PARALLEL_THREADS_PER_cpu x 10
2.如果PGA_AGGREGATE_TARGET=0
PARALLEL_MAX_SERVERS=cpu_COUNT x PARALLEL_THREADS_PER_cpu x 5
假如一台机器有50颗cpu,安装的是Oracle9i,则PARALLEL_MAX_SERVERS默认值为5,升级到Oracle10g以后,则PARALLEL_MAX_SERVERS默认值会变为1000,这是值得注意的变化,通常需要根据需要来重新设置该参数。
对于OLTP库,不宜设置过大的PARALLEL_MAX_SERVERS,因为并行操作在OLTP中可用的场景不多,一般也就是在创建和调整索引的时候会用到,并行扫描使用direct path read,会导致扫描对象的segment checkpoint,如果当时系统非常繁忙,后果可能非常严重。
原文链接:https://www.f2er.com/oracle/205796.html