在对很多项目Oracle的内存分配过程中,我一直认为PGA_AGGREGATE_TARGET为pga的最大值,然而这个参数非常有误导性,在查阅Oracle DOC之后发现,这个参数只是一个目标值,比如内存总大小为16G,PGA_AGGREGATE_TARGET为2G,在实际生产环境中pga的使用可以超过设定的大小2G,无法对pga最大值限定大小。
备注:SGA有最大大小限制sga_max_size
然而到了12C中可使用PGA_AGGREGATE_LIMIT参数来限制Oracle实例PGA使用内存的上限,如果超过限制就采取终止会话的方式来降低PGA内存的使用量。
1、创建一个包用于演示占用PGA
SQL> create or replace package demo_pkg
as
type array is table of char(2000) index by binary_integer;
g_data array;
end;
/
2、查看pga初始化参数
SQL> show parameter pga
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
pga_aggregate_limit big integer 0
pga_aggregate_target big integer 300M
此时pga target分配了300M,并且不限制pga最大大小
3、查看当前pga使用内存情况
SQL> select a.name, to_char(b.value, '999,999,999') bytes,
to_char(round(b.value/1024/1024,1), '99,999.9' ) mbytes
from v$statname a, v$mystat b
where a.statistic# = b.statistic#
and a.name like '%ga memory%';
NAME BYTES MBYTES
------------------------------ ------------ ---------
session uga memory 2,426,376 2.3
session uga memory max 2,491,864 2.4
session pga memory 3,836,088 3.7
session pga memory max 4,098,232 3.9
当前pga使用了3.7M
4、执行测试包,查看pga使用情况
SQL>begin
for i in 1 .. 200000
loop
demo_pkg.g_data(i) := 'x';
end loop;
end;
/
备注:上述为循环执行20000次
SQL> select a.name, to_char(b.value, '999,999,999') bytes,
to_char(round(b.value/1024/1024,1), '99,999.9' ) mbytes
from v$statname a, v$mystat b
where a.statistic# = b.statistic#
and a.name like '%ga memory%';
NAME BYTES MBYTES
------------------------------ ------------ ---------
session uga memory 470,141,768 448.4
session uga memory max 470,141,768 448.4
session pga memory 472,484,024 450.6
session pga memory max 472,484,024 450.6
此时pga使用了450M,已超过初始化参数pga_aggregate_target分配的300M
5、设定pga使用最大大小
SQL> alter system set pga_aggregate_limit=600m;
SQL> show parameter pga
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
pga_aggregate_limit big integer 600M
pga_aggregate_target big integer 300M
6、再次执行包测试
SQL>begin
for i in 1 .. 400000
loop
demo_pkg.g_data(i) := 'x';
end loop;
end;
/
备注:上述为循环执行40000次,是第一次执行次数的两倍
此时已无法正常执行,提示报错
ORA-04036: PGA memory used by the instance exceeds PGA_AGGREGATE_LIMIT
7、查看当前会话sid
SQL> select userenv('sid') from dual;
ERROR:
ORA-03114: not connected to ORACLE
由于上述测试pga使用大小已超过PGA_AGGREGATE_LIMIT,Oracle会终止当前会话
8、打开新会话查询pga使用情况
NAME BYTES MBYTES
------------------------------ ------------ ---------
session uga memory 2,098,912 2.0
session uga memory max 2,098,912 2.0
session pga memory 3,442,872 3.3
session pga memory max 3,639,480 3.5
被终止会话之后,pga的使用量已恢复为测试前的大小
1、PGA_AGGREGATE_LIMIT参数很好的限定了pga使用,防止其过量使用从而耗尽内存。
2、在生产环境中,如果使用ASMM,PGA_AGGREGATE_LIMIT会根据PGA_AGGREGATE_TARGET设定值自动进行调整。
3、如果PGA_AGGREGATE_TARGET未超过2G,那么PGA_AGGREGATE_LIMIT初始化大小为2G。如果PGA_AGGREGATE_TARGET超过2G,那么PGA_AGGREGATE_LIMIT是PGA_AGGREGATE_TARGET的2倍。
4、在12C之前可通过调整processes参数间接的限定pga使用