oracle parallel 并行 设置 理解
引子:以前一直没太关注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> select * from v$mystat where rownum=1; SID STATISTIC# VALUE 151 0 1 SQL> 然后立刻在另一SESSION 乘上一个执行没结束,看下面,这么说是有4个并行的进程在处理了 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 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 已选择8行。 SQL> 奇怪,怎么看只有7个,我那里可是写成 表已创建。 怎么少了3个? 不过我实际只有一个CPU的机器,这些说明什么问题呢? BTW SQL> SHOW Parameter parallel_max NAME TYPE VALUE parallel_max_servers integer 20 …………………………………………………………………………………………………………………… 这个并行度和你初始化参数有关。CPU_COUNT 、PARALLEL_THREADS_PER_CPU 等等都有关系。如果你建表的时候没有明确指定并行度,那么oracle会自动的根据需要设定并行度。 用Oracle并行查询发挥多CPU的威力 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 参数 让我们进一步看看CPU的数量是如何影响这些参数的。 参数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_automatic_tuning boolean TRUE parallel_execution_message_size integer 4096 parallel_instance_group string parallel_max_servers integer 160 parallel_min_percent integer 0 parallel_min_servers integer 0 parallel_server boolean TRUE parallel_server_instances integer 2 parallel_threads_per_cpu integer 2 举例:Parallel Execution for a Session 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 9i中PARALLEL_AUTOMATIC_TUNING默认为FALSE,所以PARALLEL_MAX_SERVERS默认为5 对于10g 假如一台机器有50颗CPU,安装的是Oracle9i,则PARALLEL_MAX_SERVERS默认值为5,升级到Oracle10g以后,则PARALLEL_MAX_SERVERS默认值会变为1000,这是值得注意的变化,通常需要根据需要来重新设置该参数。 对于OLTP库,不宜设置过大的PARALLEL_MAX_SERVERS,因为并行操作在OLTP中可用的场景不多,一般也就是在创建和调整索引的时候会用到,并行扫描使用direct path read,会导致扫描对象的segment checkpoint,如果当时系统非常繁忙,后果可能非常严重。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- 获取用户名、计算机名和域名
- Oracle自定义函数,判断一个以逗号拼接的字符串是否完全包含
- swift – Cocoapod podspec上的Preprocesor标志
- c# – 使用嵌套类创建类的Javascript JSON
- animation – 在drawRect()Swift中绘制bezier路径的动画
- Cocos2d-x中libcurl库的使用(6)HTTP消息头
- c# – Nhibernate GetById返回null的intInadad的ObjectNotF
- Swift Playground中的NSTimer.scheduledTimerWithTimeInter
- 合并iPhone应用程序中的两个视频文件
- Oracle数据库锁管理及锁分析_超越OCP精通Oracle视频课程培训