知识大全 PGA自动管理原理深入分析及性能调整
Posted 语句
篇首语:实践是知识的母亲,知识是生活的明灯。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 PGA自动管理原理深入分析及性能调整相关的知识,希望对你有一定的参考价值。
PGA自动管理原理深入分析及性能调整 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
PGA的概念以及所包含的内存结构作为一个复杂的oracle数据库系统来说 每时每刻都要处理不同的用户所提交的SQL语句 获取数据并返回数据给用户 众所周知 解析SQL语句的工作是在oracle实例中的shared pool所完成的 那么对于每个session来说 其执行SQL语句时所传入的绑定变量放在哪里?而且 对于那些需要执行比较复杂SQL的session来说 比如需要进行排序(sort)或hash连接(hash join)时 这时这些session所需要的内存空间又从哪里来?另外 还有与每个session相关的一些管理控制信息又放在哪里?对于诸如此类与每个session相关的一些内存的分配问题 oracle通过引入PGA这个内存组件来进行解决 PGA的相关概念 PGA按照oracle官方文档解释 叫做程序全局区(Program Global Area) 但也有些资料上说还可以理解为进程全局区(Process Global Area) 这两者没有本质的区别 它首先是一个内存区域 其次 该区域中包含了与某个特定服务器进程相关的数据和控制信息 每个进程都具有自己私有的PGA区 这也就意味着 这块区域只能被其所属的进程进入 而不能被其他进程访问 所以在PGA中不需要latch这样的内存结构来保护其中的信息 笼统的来说 PGA里包含了当前进程所使用的有关操作系统资源的信息(比如打开的文件句柄等)以及一些与当前进程相关的一些私有的状态信息 每个PGA区都包含两部分 固定PGA部分(Fixed PGA) 这部分包含一些小的固定尺寸的变量 以及指向变化PGA部分的指针 变化PGA部分(Variable PGA) 这部分是按照堆(Heap)来进行组织的 所以这部分也叫做PGA堆 可以从X$KSMPP视图中看到有关PGA堆的分布信息 PGA堆中所包含的内存结构包括 有关一些固定表的永久性内存 如果session使用的是专用连接方式(dedicated server) 则还含有用户全局区(UGA-User Global Area)子堆 如果session使用的是共享连接方式(shared server) 则UGA位于SGA中 调用全局区(CGA-Call Global Area)子堆 UGA(用户全局区)的相关概念 UGA是包含与某个特定session相关信息的内存区域 比如session的登录信息以及session私有的SQL区域等 每个UGA也包含两个部分 固定UGA部分(Fixed UGA) 这部分包含一些小的固定尺寸的变量 以及指向变化UGA部分的指针 变化UGA部分(Variable UGA) 这部分也是按照堆来进行组织的 可以从X$KSMUP视图中看到有关UGA堆的分布情况 UGA堆的分布与OPEN_CURSORS OPEN_LINKS等参数有关系 所谓的游标(cursor)就是放在这里的 UGA堆中所包含的内存结构包括 私有SQL区域(Private SQL Area) 这部分区域包含绑定变量信息以及运行时的内存结构等数据 每一个发出SQL语句的session都有自己的私有SQL区域 这部分区域又可分成两部分 永久内存区域 这里存放了相同SQL语句多次执行时都需要的一些游标信息 比如绑定变量信息 数据类型转换信息等 这部分内存只有在游标被关闭时才会被释放 运行时区域 这里存放了当SQL语句运行时所使用的一些信息 这部分区域的大小尺寸依赖于所要执行的SQL语句的类型(sort或hash join等)和复杂度以及所要处理的数据行的行数以及行的大小 在处理SQL语句时的第一步就是要创建运行时区域 对于DML(INSERT UPDATE DELETE)语句来说 SQL语句执行完毕就释放该区域 而对于查询语句(SELECT)来说 则是在所有数据行都被获取并传递给用户以后被释放 或者该查询被取消以后也会被释放 Session相关的信息 这部分信息包括 正在使用的包(package)的状态信息 使用alter session这样的命令所启用的跟踪信息 或者所修改的session级别的优化器参数(optimizer_mode) 排序参数(sort_area_size等) 修改的NLS参数等 所打开的dblinks 可使用的角色(roles)等 从上面可以很明显的看出 我们最需要关注的就是私有SQL区域中的运行时区域了 实际上 从 i以后 对这部分区域有了一个新的名称 SQL工作区域(SQL Work Area) SQL工作区域的大小依赖于所要处理的SQL语句的复杂程度而定 如果SQL语句包含诸如group by Hash join等这样的操作 则会需要很大的SQL工作区域 实际上 我们调整PGA也就是调整这块区域 后面还会说到这部分内容 而UGA所处的位置完全由session连接的方式决定 如果session是通过共享服务器(shared server)方式连到数据库的 则毫无疑问 UGA必须能够被所有进程访问 所以这个时候UGA是从SGA中进行分配的 进一步说 如果SGA中设置了large pool 则UGA从large pool里进行分配 否则 如果没有设置large pool 则UGA只能从shared pool里进行分配了 如果session是通过专用服务器(dedicated server)方式连到数据库的 则UGA是从进程的PGA中进行分配的 CGA(调用全局区)的相关概念 CGA也是一块内存区域 但它是动态的 随着调用(call)的开始而创建 在调用过程中一直存在 直到调用结束时被释放 它存放的是在调用过程中所需要的数据 我们知道 调用主要包括解析(parse)调用 执行(executive)调用 获取(fetch)调用以及递归SQL调用和PL/SQL调用 从调用的种类可以看出 实际上在调用过程中所需要的数据 比如SQL AREA PL/SQL AREA和SORT AREA基本都是放在UGA中的 因为这些数据在各个调用之间必须一直存在并可用 而在CGA中只存放了在调用过程中临时需要的数据 比如直接I/O缓存(Direct I/O Buffer)以及堆栈空间等数据结构 因此 没有CGA中的数据结构 调用是无法完成的 注意 CGA不象UGA可以位于SGA中(以共享服务器模式连接) CGA一定是位于PGA中的 如果当前进程正在运行 则每个PGA中只有一个CGA 如果当前进程没有运行 则该进程的PGA中就没有CGA转储PGA就象实例中的其他内存结构一样 oracle同样提供了可以将PGA转储到跟踪文件的方法 方法如下 SQL> alter session set events immediate trace name heapdump level n ;其中的level n决定了将哪些内存堆转储到跟踪文件 Level : PGA汇总信息Level : SGA汇总信息Level : UGA汇总信息Level : 当前调用的汇总信息(CGA)Level : 用户调用的汇总信息(CGA)Level : Large pool的汇总信息(LGA)Level : PGA详细信息Level : SGA详细信息Level : UGA 详细信息Level : 当前调用的详细信息Level : 用户调用的详细信息Level : Large pool的详细信息
举例来说 我们转储PGA的汇总信息 SQL> alter session set events immediate trace name heapdump level ; 到user_dump_dest所定义的目录下 找到跟踪文件并打开 可以看到类似下面的信息 ******************************************************HEAP DUMP heap name= pga heap desc= DB extent sz= x c alt= het= rec= flg= opc= parent= owner= nex= xsz= x cEXTENT addr= Chunk c sz= perm perm alo= EXTENT addr= BC C Chunk bc sz= freeable Fixed Uga EXTENT addr= B C Chunk b sz= perm perm alo= Chunk a f sz= free Chunk ba c sz= freeable kopolal dvoid …………… Chunk e c sz= recreate Alloc environm latch= ds eade sz= ct= Chunk ea bc sz= freeable kpuinit env han
我们可以看到 其中的红色部分就是在PGA中所包含的固定UGA部分 同时 我们可以使用如下的命令将PGA的子堆也给转储出来 其中 以前使用 SQL> alter session set events immediate trace name heapdump_addr level n ; 以后使用 SQL> alter session set events immediate trace name heapdump_addr level addr n ;其中的n表示子堆的地址 而子堆的地址可以在PGA的转储文件中找到 比如上面的例子中 我们可以看到这样的一行 ds eade sz= ct= 这里的ds eade 就是某个子堆的地址 这是个十六进制的数值 于是我们先将其转换为十进制数值 SQL> select to_number( eade xxxxxxxx ) from dual;TO_NUMBER( EADE XXXXXXXX ) 这里的 就是转储PGA子堆的命令中的n 所以我们可以执行(我的测试库为 ) SQL> ALTER SESSION SET EVENTS immediate trace name heapdump_addr level addr ;
PGA自动管理及深入研究 PGA自动管理概述在 i之前 我们主要是通过设置sort_area_size hash_area_size等参数值(通常都叫做*_area_size)来管理PGA的使用 不过严格说来 是对PGA中的UGA中的私有SQL区域进行管理 这块内存区域又有个名称叫做SQL工作区域 但是 这里有个问题 就是这些参数都是针对某个session而言的 也就是说设置的参数值对所有连进来的session都生效 在数据库实际运行过程中 总有些session需要的PGA多 而有些session需要的PGA少 如果都设置一个很小的*_area_size 则会使得某些SQL语句运行时由于需要将临时数据交换到磁盘而导致效率低下 而如果都设置一个很大的值 又有可能一方面浪费空间 另一方面 消耗过多内存可能导致操作系统其他组件所需要的内存短缺 而引起数据库整体性能下降 所以如何设置*_area_size的值一直都是DBA很头疼的一个问题 而从 i起所引入的一个新的特性可以有效的解决这个问题 这个特性就是自动PGA管理 DBA可以根据数据库的负载情况估计所有session大概需要消耗的PGA的内存总和 然后把该值设置为初始化参数pga_aggregate_target的值即可 Oracle会按照每个session的需要为其分配PGA 同时会尽量维持整个PGA的内存总和不超过该参数所定义的值 这样的话 oracle就能尽量避免整个PGA的内存容量异常增长而影响整个数据库的性能 从而 就有效的解决了设置*_area_size所带来的问题 不过遗憾的是 i下的PGA自动管理只对专用连接方式有效 对共享连接方式无效 g以后对两种连接方式都有效 启用PGA自动管理是很容易的 只要设置两个初始化参数即可 首先 设置workarea_size_policy参数 该参数为auto(也是缺省值)时 表示启用PGA自动管理 而设置该参数为manual时 则表示禁用PGA自动管理 仍然沿用 i之前的方式 即使用*_area_size对PGA进行管理 其次 就是设置pga_aggregate_target了 该参数可以动态进行调整 范围是从 MB到 GB – 个字节 PGA自动管理深入 PGA中对性能影响最大的就是SQL工作区了 通常说来 SQL工作区越大则对于SQL语句的执行的效率就高 从而对于用户的响应时间就越少 理想情况下 SQL工作区应该可以容纳SQL执行过程中所涉及到的所有输入数据和控制信息 当然 这只是理想情况 现实往往总是不能尽如人意 很多情况下SQL工作区是不能容纳执行SQL所需要的内存空间的 从而不得不交换到临时表空间里 为了衡量执行SQL所需要的内存与实际分配给该SQL的SQL工作区之间的契合程度 oracle将所分配的SQL工作区大小分成三种类型 optimal尺寸 SQL语句能够完全在所分配的SQL工作区内完成所有的操作 这时的性能最佳 onepass尺寸 SQL语句需要与磁盘上的临时表空间交互一次才能够在所分配的SQL工作区中完成所有的操作 multipass尺寸 由于SQL工作区过小 从而导致SQL语句需要与磁盘上的临时表空间交互多次才能完成所有的操作 这个时候的性能将急剧下降 当系统整体负载不大时 oracle倾向于为每个session的PGA分配optimal尺寸大小的SQL工作区 而随着负载上升 比如连接的session逐渐增多导致同时执行的SQL语句越来越多时 oracle就会倾向于为每个session的PGA分配onepass尺寸大小的SQL工作区 甚至是multipass尺寸的SQL工作区了 那么 PGA自动管理机制在内部到底是如何实现的呢?很遗憾 oracle官方并没有给出说明文档 其实这本身也说明了 PGA自动管理的内部算法会随着版本升级而发生变化 不过 知其然而不知其所以然 总是会让诸如我等之类的技术人员感觉如梗在喉 还好 曾经就有一些专门做oracle优化的公司发布的文档中介绍了PGA内部的实现原理 我想这可能是oracle公司透露给这些公司的 这里就做些简单的介绍 不过记住 这里所描述的PGA自动管理的原理并不一定就是将来版本的原理 只能说是截至到 的PGA自动管理的原理 PGA自动管理是采用名为 循环反馈(feedback loop) 的算法来实现的 如下图所示 上图中 当开始处理一条SQL时 oracle会使用本地内存管理器(local memory manager)对该SQL语句相关的work area profile进行注册 work area profile是一组元数据 描述了该SQL语句所需要的工作区的所有特征 包括该SQL的类型(sort还是hash join等) 该SQL语句的并行度 所需要的内存等信息 它是SQL语句操作与内存管理器之间唯一的接口 当SQL语句执行完毕时 其对应的work area profile就会被删除 而在SQL语句执行期间 为了反映SQL语句当前已经消耗的内存以及是否被交换到临时表空间了等状态信息 oracle会不断更新其对应的work area profile 所以说 SQL语句的work area profile是有生命周期的 始终能够体现其对应SQL语句的工作区状态 因此 我们可以说 在任何时间点 所有当前活动的work area profile就能够基本体现当前所有session对PGA内存的需要以及当前正在使用的PGA内存 通过查询视图v$sql_workarea_active 可以显示所有当前活动的work area profile的相关信息 现在 我们需要引入另外一个后台守护进程(background daemon) 叫做全局内存管理器(global memory manager) 这个进程每隔 秒会启动一次 每次启动时 都会根据当前所有活动的work area profile的数量以及其他相关信息计算出这个时候的SQL工作区的 内存限度(memory bound) 也就是每个工作区最大尽量不能超过多大(不过 注意 严格说来应该是尽量不超过 实际上这个最大值是可以被超过的 后面会用个实例来说明) 然后立即发布这个 内存限度 最后 本地内存管理器关闭 反馈循环 并根据当前的 内存限度 以及当前work area profile 从而计算出当前SQL工作区应该具有的内存大小 并为进程分配该大小的内存以执行SQL语句 这个内存的大小尺寸就叫做 期望尺寸(expect size) 可以从v$sql_workarea_active的expected_size列看到 期望尺寸 的大小 同时 这个 期望尺寸 会定时更新 并据此对SQL工作区进行调整 Oracle内部对这个 期望尺寸 的大小有如下规则的限制 期望尺寸 不能小于最低的内存需求 期望尺寸 不能大于optimal尺寸 如果 内存限度 介于最低的内存需求和optimal尺寸之间 则使用 内存限度 作为 期望尺寸 的大小 但是排序操作除外 因为排序操作算法的限制 对于分配的内存在optimal尺寸和onepass尺寸之间时 排序操作不会随着内存的增加而更快完成 除非能够为排序操作分配optimal尺寸 所以 如果排序操作的 内存限度 介于onepass尺寸和optimal尺寸之间的话 期望尺寸 取onepass尺寸 如果SQL以并行方式运行 则 期望尺寸 为上面三个规则算出的值乘以并行度 非并行模式下 按照通常的说法是 期望尺寸 不能超过min( %*pga_aggregate_target MB) 但实际上 这是在不修改_pga_max_size和_smm_max_size这两个隐藏参数的前提下 可以简单的这么认为 严格说来 应该是不能超过min( %*pga_aggregate_target %*_pga_max_size _smm_max_size) 对于并行的情况 就更加复杂 可以简单认为不超过 %*pga_aggregate_target 下面 我们举例(如下图所示)来说明全局内存管理器是如何计算并应用 内存限度 的 比如
当前系统中有 个活动的work area profile WP 所需要的onepass内存为 MB 而optimal内存为 MB WP 是一个并行度为 的hash join 它需要 MB的onepass内存 以及 MB的optimal的内存 假设pga_aggregate_target设置为 MB 则可以简单的认为全局内存管理器直接将 除以 也就是大约 MB作为 内存限度 的值 于是该 内存限度 限制了分配给WP 的工作区只能为 MB 也就是onepass的大小 因为WP 是一个排序操作 如果给它分配 MB也不能使它在以optimal的方式完成 而对于 MB的 内存限度 WP 可以分到 MB的工作区 因为WP 的并行度为 所以可以分配 MB× 的大小的工作区 如何设置新数据库的PGA值 我们一旦设置了pga_aggregate_target以后 所有的*_area_size就将被忽略 那么 我们该如何来设置该参数的值呢?这依赖于数据库的用途 如果数据库为OLTP(联机事务处理)应用的 则其应用一般都是小的短的进程 所需要的PGA也相应较少 所以该值该值通常为总共分配给oracle实例的 % 另外的 %则给了SGA 如果数据库为OLAP(DSS)(数据仓库或决策分析)应用的 则其应用一般都是很大的 运行时间很长的进程 因此需要的PGA就多 所以通常为PGA分配 %的内存 而如果数据库为混合类型的 则情况比较复杂 一般会先分配 %的初始值 而后随着数据库的应用 而不断对PGA进行监控 并进行相应的调整 比如 对于 GB物理内存的数据库服务器来说 按照oracle推荐的 分配给oracle实例的内存为物理内存的 % 那么对于OLTP应用来说 pga_aggregate_target的值大约就是 MB (( MB× %)× %) 而对于OLAP来说 则该值大约就是 MB ( MB× %)× %) 当然 这里所说的都是对于一个新的数据库来说 初始设置的值 这些值并不一定正确 可能设置过大 也可能设置过小 必须随着系统的不断运行 DBA需要不断监控 从而对其进行调整
PGA监控及调优我们已经大致了解了有关PGA的相关理论知识 现在我们可以开始动手实践来验证上面的理论 并可以开始对PGA的使用进行监控以及调优了 以下测试都是在windows XP oracle 以及专用连接模式下进行的 准备测试用例首先 我们先创建一个测试用例 SQL> create table pga_test as select * from dba_objects;SQL> select count(*) from pga_test; COUNT(*) 然后 引入几个监控PGA的脚本 pga_by_hashvalue sql 这是一个监控SQL语句所使用的SQL工作区的脚本 SELECT b sql_text a operation_type a policy a last_memory_used/( * ) as Used MB a estimated_optimal_size/( * ) as Est Opt MB a estimated_onepass_size/( * ) as Est OnePass MB a last_execution a last_tempseg_sizeFROM v$sql_workarea a v$sql bWHERE a hash_value = b hash_value and a hash_value = &hashvalue/pga_by_session sql 第二个脚本是pga_by_session sql 用来监控session所使用的PGA和UGA的大小 select a name b valuefrom v$statname a v$sesstat bwhere a statistic# = b statistic#and b sid = &sidand a name like %ga % order by a name/ 第三个脚本监控进程所使用的PGA的大小 pga_by_process sql SELECT a pga_used_mem PGA Used a pga_alloc_mem PGA Alloc a pga_max_mem PGA Max FROM v$process a v$session bwhere a addr = b paddr and b sid= &sid/ 单个session对PGA使用情况的监控我们分别创建 个session 第一个session(sess# )执行测试语句 第二个session(sess# )执行pga_by_hashvalue sql脚本 第三个session(sess# )执行pga_by_session sql脚本 第四个session(sess# )执行pga_by_process sql脚本 第五个session(sess# )设置相关参数 以下按照顺序描述整个测试的过程 Sess# SQL> select sid from v$mystat where rownum= ; SID Sess# 查询当前sid为 的session的PGA和UGA各为多少 可以看到 即使不执行任何的SQL 只要session连接了 就会消耗大约 MB的PGA内存 SQL> @pga_by_session sql;NAME VALUE session pga memory session pga memory max session uga memory session uga memory max Sess# 我们将pga_aggregate_target设置为 MB SQL> alter system set pga_aggregate_target= M; Sess# 执行测试语句 SQL> set autotrace traceonly stat;SQL> select a * from pga_test a pga_test b where rownum< order by ; Sess# 找到sess# 中所执行的SQL语句的hash值 SQL> select hash_value from v$sql where sql_text= select a * from pga_test a pga_test b where rownum< order by ;HASH_VALUE Sess# SQL> @d:\\pga_by_hashvalue sql输入 hashvalue 的值: 原值 : and a hash_value = &hashvalue新值 : and a hash_value = SQL_TEXT OPERATION_TYPE POLICY Used MB Est Opt MB Est OnePass MB LAST_EXECUTION LAST_TEMPSEG_SIZE select a * from pga_test a pga_test b where rownum< order by SORT AUTO PASSES 我们可以看到 该SQL语句所分配的工作区为 MB 这个值就是 %*pga_aggregate_target( M* ) 符合前面说到的 期望尺寸 为min( %*pga_aggregate_target MB) Sess# SQL> @ pga_by_session sql;NAME VALUE session pga memory session pga memory max session uga memory session uga memory max
可以看到 为了执行测试语句 为该session分配的PGA为 个字节 其中UGA为 个字节 大约 M 同时可以看出 执行完测试语句以后 oracle就把该session的PGA空间回收了(PGA从 下降到 而UGA从 下降到 ) 顺带提一下 在 i中分配了PGA以后是不会回收的 也就是说session pga memory始终等于session pga memory max 而 i以后的PGA的分配方式发生了改变 从而能够在分配PGA以后还可以再回收一部分内存 结合上面为SQL语句所分配的 M的工作区 可以知道 UGA中的其他空间占用大约 M 而SQL工作区占整个PGA大小大约为 % 从这个方面也可以看出 SQL工作区是PGA中最占空间 也是最重要的部分 Sess# SQL> @d:\\pga_by_process sql输入 sid 的值: 原值 : and b sid= &sid新值 : and b sid= PGA Used PGA Alloc PGA Max
可以看到 这几个视图查出来的PGA的大小基本都是一致的 我们继续测试 从sess# 可以看出 如果要让该SQL语句完全在内存中完成 需要大约 MB的PGA空间 根据 %的原理倒算 可以知道这个时候的pga_aggregate_target应该大于 MB( / ) 于是 我们设置 MB 来看看是不是确实进行optimal了 顺便提醒一下 并不是说你的电脑得有超过 MB的物理内存你才可以设置 M的pga_aggregate_target 事实上pga_aggregate_target是按需分配的 不象SGA 一旦设置就占著内存 不用也得占著 也就是说是PGA是随着对内存需求的增长而不断增长的 我测试的机器上只有 GB的物理内存 但做测试时完全可以将pga_aggregate_target设置 GB 甚至更高的 GB Sess# 我们将pga_aggregate_target设置为 MB SQL> alter system set pga_aggregate_target= M; Sess# SQL> select a * from pga_test a pga_test b where rownum< order by ; Sess# SQL> @d:\\pga_by_hashvalue sql输入 hashvalue 的值: 原值 : and a hash_value = &hashvalue新值 : and a hash_value = SQL_TEXT OPERATION_TYPE POLICY Used MB Est Opt MB Est OnePass MB LAST_EXECUTION LAST_TEMPSEG_SIZE select a * from pga_test a pga_test b where rownum< order by SORT AUTO OPTIMAL我们可以看到 该SQL语句确实完全在内存里完成了(LAST_EXECUTION为 OPTIMAL ) 同时 实际的 期望尺寸 始终会小于optimal( < ) 也符合前面说的第二条规则 我们继续测试 看看SQL工作区的 期望尺寸 是否真的不能超过 MB 为此 需要设置 %*pga_aggregate_target> MB 因此pga_aggregate_target最少要大于 G 我们设置 GB Sess# 我们将pga_aggregate_target设置为 GB SQL> alter system set pga_aggregate_target= G; Sess# 注意 为了能够占用更多的PGA 这时的SQL语句已经把where条件修改了 SQL> select a * from pga_test a pga_test b where rownum< order by ; Sess# 找到该语句的hash值 SQL> select hash_value from v$sql where sql_text= select a * from pga_test a pga_test b where rownum< order by ;HASH_VALUE Sess# SQL> /输入 hashvalue 的值: 原值 : and a hash_value = &hashvalue新值 : and a hash_value = SQL_TEXT OPERATION_TYPE POLICY Used MB Est Opt MB Est OnePass MB LAST_EXECUTION LAST_TEMPSEG_SIZE select a * from pga_test a pga_test b where rownum< order by SORT AUTO PASS 可以看到 optimal尺寸已经超过 MB很多了 但是实际分配的 期望尺寸 却只有 MB左右 而 G* 为 MB 为何该SQL用不了呢?这其实是由两个隐藏参数决定的 分别是_pga_max_size和_smm_max_size 我们来看一下这两个参数的含义和缺省值 Sess# SQL> select ksppinm ksppstvl ksppdesc from x$ksppi x x$ksppcv y where x indx = y indx and ksppinm in ( _pga_max_size _smm_max_size );KSPPINM KSPPSTVL KSPPDESC _pga_max_size Maximum size of the PGA memory for one process_smm_max_size maximum work area size in auto mode (serial)我们可以看到_pga_max_size缺省值为 M( / / ) 而_smm_max_size缺省值为 MB(上面的查询结果中显示的单位是KB) 而每个session的PGA最多只能使用_pga_max_size的一半 也就是 MB 当你修改参数pga_aggregate_target的值时 Oracle系统会根据pga_aggregate_target和_pga_max_size这两个值来自动修改参数_smm_max_size 具体修改的规则是 如果_pga_max_size大于 %*pga_aggregate_target 则_smm_max_size为 %*pga_aggregate_target 如果_pga_max_size小于等于 %*pga_aggregate_target 则_smm_max_size为 %*_pga_max_size 有些资料上说 可以通过修改_pga_max_size来突破这个 MB的限制 真的是这样吗?我们来测试 Sess# 修改参数_pga_max_size为 MB SQL> show parameter pgaNAME TYPE VALUE pga_aggregate_target big integer SQL> alter system set _pga_max_size = M;我们将_pga_max_size的值设置为 M 其一半就是 MB 已经超过 %*pga_aggregate_target(即 MB)了 所以这两者的较小值为 M 如果这时我们在sess# 中再次执行测试语句 应该可以使用超过 MB的SQL工作区了 我们来看测试结果 Sess# SQL> select a * from pga_test a pga_test b where rownum< order by ;Sess# SQL> /输入 hashvalue 的值: 原值 : and a hash_value = &hashvalue新值 : and a hash_value =
SQL_TEXT OPERATION_TYPE POLICY Used MB Est Opt MB Est OnePass MB LAST_EXECUTION LAST_TEMPSEG_SIZE select a * from pga_test a pga_test b where rownum< order by SORT AUTO PASS
我们看到 期望尺寸 仍然是大约 MB 并没有突破 MB的限制 其中的问题就在于参数_smm_max_size 上 我们来看这个时候该参数值是多少 Sess# SQL> select ksppinm ksppstvl ksppdesc from x$ksppi x x$ksppcv y where x indx = y indx and ksppinm in ( _pga_max_size _smm_max_size );KSPPINM KSPPSTVL KSPPDESC _pga_max_size Maximum size of the PGA memory for one process_smm_max_size maximum work area size in auto mode (serial)可以看到参数_smm_max_size的值仍然是 MB 实际上 这也是一个对 期望尺寸 的限制参数 这里可以看到 期望尺寸 不能超过 MB 这时 我们只要简单的执行 Sess# SQL> alter system set pga_aggregate_target= G; SQL> select ksppinm ksppstvl ksppdesc from x$ksppi x x$ksppcv y where x indx = y indx and ksppinm in ( _pga_max_size _smm_max_size );KSPPINM KSPPSTVL KSPPDESC _pga_max_size Maximum size of the PGA memory for one process_smm_max_size maximum work area size in auto mode (serial)我们可以看到 只要设置一下pga_aggregate_target 就会按照前面所说的规则重新计算并设置_smm_max_size的值 该参数修改后的值为 MB 这个时候我们重复上面的测试 Sess# SQL> select a * from pga_test a pga_test b where rownum< order by ;Sess# SQL> /输入 hashvalue 的值: 原值 : and a hash_value = &hashvalue新值 : and a hash_value = SQL_TEXT OPERATION_TYPE POLICY Used MB Est Opt MB Est OnePass MB LAST_EXECUTION LAST_TEMPSEG_SIZE select a * from pga_test a pga_test b where rownum< order by SORT AUTO OPTIMAL这时 我们看到 期望尺寸 为 MB左右 终于超过了 MB 如果我们再次将参数_smm_max_size人为的降低到 MB 则 期望尺寸 又将不能突破 MB了 我们来看试验 Sess# SQL> alter system set _smm_max_size = ;Sess# SQL> select a * from pga_test a pga_test b where rownum< order by ;Sess# SQL> /输入 hashvalue 的值: 原值 : and a hash_value = &hashvalue新值 : and a hash_value = SQL_TEXT OPERATION_TYPE POLICY Used MB Est Opt MB Est OnePass MB LAST_EXECUTION LAST_TEMPSEG_SIZE select a * from pga_test a pga_test b where rownum< order by SORT AUTO PASS 可以看到 结果正如我们所预料的 由此 得出我们重要的结论 就是在非并行方式下 期望尺寸 为min( %*pga_aggregate_target %*_pga_max_size _smm_max_size) 而不是很多资料上所说的不是很严密的min( %*pga_aggregate_target %*_pga_max_size) oracle当然是不推荐我们修改这两个隐藏参数的
多个并发session对PGA使用情况的监控现在我们可以来测试多个session并发时PGA的分配情况 测试并发的方式有很多 可以写一个小程序循环创建多个连接 然后执行上面的测试语句 也可以借助一些工具来完成 为了方便起见 我用了一个最简单的方式 就是写一个SQL文本 再写一个bat文件 该bat文件中执行SQL文本 两个文件准备好以后 将bat文件拷贝 份 然后选中这 份一摸一样的bat文件 按回车键后 windows XP将同时执行这 个bat文件 这样就可以模拟出 个session同时连接并同时执行测试语句的环境了 具体这两个文件的具体内容如下 pga_test sql set autotrace traceonly stat;select a * from pga_test a pga_test b where rownum< order by ; run bat @sqlplus s cost/cost@ora @d:\\test\\pga_test sql我们先将pga_aggregate_target设置为 MB Sess# SQL> alter system set pga_aggregate_target= M; 然后同时运行 个bat文件从而启动 个执行相同SQL测试语句的并发session 我执行下面的语句以显示这时正在执行的 个session所消耗的PGA的总内存 Sess# SQL> select a name sum(b value)/ / as MB from v$statname a v$sesstat b where a statistic# = b statistic# and a name like %ga % and sid in(select sid from v$sql_workarea_active) group by a name;NAME MB session pga memory session pga memory max session uga memory session uga memory max 我们可以看到 session pga memory max显示出大约 MB的PGA内存 很明显 PGA的总容量已经超出了pga_aggregate_target( M)的限制的容量 实际上这也就说明 该参数只是说明 oracle会尽量维护整个PGA内存不超过这个值 如果实在没有办法 也还是会突破该参数限制的 同时 我们可以去查看这个时候该测试SQL语句所分配的工作区变成了多少 同样在Sess# 中 SQL> @d:\\pga_by_hashvalue sql输入 hashvalue 的值: 原值 : and a hash_value = &hashvalue新值 : and a hash_value = SQL_TEXT OPERATION_TYPE POLICY Used MB Est Opt MB Est OnePass MB LAST_EXECUTION LAST_TEMPSEG_SIZE select a * from pga_test a pga_test b where rownum< order by SORT AUTO PASSES 从结果中我们可以看到 该SQL的工作区已经从单个session时的 MB下降到了大约 M 我们可以看到 个session总共至少需要 MB( M* )的SQL工作区 明显的 MB的pga_aggregate_target是肯定不能满足需要的
其他监控并调整PGA的方法我们监控PGA的视图除了上面介绍到的v$sql_workarea_active v$sesstat v$sql_workarea以及v$process以外 还有v$sql_workarea_histogram v$pgastat以及v$sysstat v$sql_workarea_histogram记录了每个范围的SQL工作区内所执行的optimal onepass multipass的次数 如下所示 SQL> select low_optimal_size/ Low (K) (high_optimal_size + )/ High (K) optimal_executions Optimal onepass_executions Pass multipasses_executions > Pass from v$sql_workarea_histogram where total_executions <> ; 结果类似如下所示 我们可以看到整个系统所需要的PGA的内存大小主要集中在什么范围里面 Low (K) High (K) Optimal Pass > Pass 另外 我们可以将上面的查询语句改写一下 以获得optimal onepass multipass执行次数的百分比 很明显 optimal所占的百分比越高越好 如果onepass和multipass占的百分比很高 就不需要增加pga_aggregate_target的值了 或者调整SQL语句以使用更少的PGA区 SQL> select optimal_count Optimal round(optimal_count * / total ) Optimal % onepass_count OnePass round(onepass_count * / total ) Onepass % multipass_count MultiPass round(multipass_count * / total ) Multipass % from ( select sum(total_executions) total sum(optimal_executions) optimal_count sum (onepass_executions) onepass_count sum (multipasses_executions) multipass_count from v$sql_workarea_histogram where total_executions <> ) / Optimal Optimal % OnePass Onepass % MultiPass Multipass % 而v$pgastat则提供了有关PGA使用的整体的概括性的信息 SQL> select * from v$pgastat;NAME VALUE UNIT aggregate PGA target parameter bytesaggregate PGA auto target bytesglobal memory bound bytestotal PGA inuse bytestotal PGA allocated bytesmaximum PGA allocated bytestotal freeable PGA memory bytesPGA memory freed back to OS bytestotal PGA used for auto workareas bytesmaximum PGA used for auto workareas bytestotal PGA used for manual workareas bytesmaximum PGA used for manual workareas bytesover allocation count bytes processed bytesextra bytes read/written bytescache hit percentage percent从结果可以看出 第一行表示pga_aggregate_target设置为 M PGA的一部分被用于无法动态调整的部分 比如UGA中的 session相关的信息 等 而PGA内存的剩下部分则是可以动态调整的 由 aggregate PGA auto target 说明 我们来看第二行的值 就表示可以动态调整的内存数量 该值不能与pga_aggregate_target设置的值差太多 如果该值太小 则oracle没有足够的内存空间来动态调整session的内存工作区 其中的global memory bound表示一个工作区的最大尺寸 并且oracle推荐只要该统计值低于 M时 就应该增加pga_aggregate_target的值 另外 i还提供了两个有用的指标 over allocation count和cache hit percentage 如果在使用SQL工作区过程中 oracle认为pga_aggregate_target过小 则它自己会去多分配需要的内存 则多分配的次数就累加在over allocation count指标里 该值越小越好 最好为 cache hit percentage则表示完全在内存里完成的操作的字节数与所有完成的操作(包括optimal onepass multipass)的字节数的比率 如果所有的操作都是optimal类 则该值为 % 最后 我们可以查询v$sysstat视图 获得optimal onepass multipass执行的总次数 SQL> select * from v$sysstat where name like workarea executions% ;STATISTIC# NAME CLASS VALUE workarea executions optimal workarea executions onepass workarea executions multipass 我们可以计算optimal次数占总次数的比率 比如上例中 /( + + )= % 该比率越大越好 如果发现onepass和multipass较多 则需要增加pga_aggregate_target 或者调整SQL语句以使用更少的PGA区 那么我们如何找到需要调整以使用更少的PGA的SQL语句呢?我们可以将v$sql_workarea中的记录按照estimated_optimal_size字段由大到小的排序 选出排在前几位的hash值 同时还可以选出last_execution值为 n PASSES (这里的n大于或等于 )的hash值 将这些hash值与v$sql关联后找出相应的SQL语句 进行调整 以便使其使用更少的PGA
PGA的自动建议特性那么 如果我们需要调整pga_aggregate_target时 到底我们应该设置多大呢?oracle为了帮助我们确定这个参数的值 引入了一个新的视图 v$pga_target_advice 为了使用该视图 需要将初始化参数statistics_level设置为typical(缺省值)或all SQL> select round(pga_target_for_estimate /( * )) Target (M) estd_pga_cache_hit_percentage Est Cache Hit % round(estd_extra_bytes_rw/( * )) Est ReadWrite (M) estd_overalloc_count Est Over Alloc from v$pga_target_advice /
cha138/Article/program/Oracle/201311/17537相关参考
自动内存管理机制深入剖析-C#分析篇 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 在NETFr
Oracle中并行处理技术原理深入分析1 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 并行处理
oracle管理PPT深入分析 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 如何配置才能使客户
本文提供了十点有关性能方面的计划安排它们能确保你的应用得以完整实施 .应用需要性能调整 应该认识到应用在项目的不同阶段需要性能调整而调整需求是需要必要的资源和时间的你应该为此制定相应的
摘要:着重介绍了厌氧处理技术原理及第一代反应器到第三代反应器的发展过程,分析了新型第三代工艺-ABR反应器的性能特点及发展。随着工业的飞速发展和人口的不断增加,能源,资源和环境等问题日趋严重,近30年
摘要:着重介绍了厌氧处理技术原理及第一代反应器到第三代反应器的发展过程,分析了新型第三代工艺-ABR反应器的性能特点及发展。随着工业的飞速发展和人口的不断增加,能源,资源和环境等问题日趋严重,近30年
摘要:着重介绍了厌氧处理技术原理及第一代反应器到第三代反应器的发展过程,分析了新型第三代工艺-ABR反应器的性能特点及发展。随着工业的飞速发展和人口的不断增加,能源,资源和环境等问题日趋严重,近30年
知识大全 OracleFreelist和HWM原理及性能优化
OracleFreelist和HWM原理及性能优化 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!近
近日,老窝镇农业综合服务中心组织全体技术人员深入各村、组田间地头现场指导玉米中耕管理及病虫害防治技术。截止目前以指导农户1856户,现场指导2016人次;防治面积5861亩次。具体技术措施如下: 1
近日,老窝镇农业综合服务中心组织全体技术人员深入各村、组田间地头现场指导玉米中耕管理及病虫害防治技术。截止目前以指导农户1856户,现场指导2016人次;防治面积5861亩次。具体技术措施如下: 1