oracle12c PGA_AGGREGATE_LIMIT限制PGA使用內存的大小

轉自:https://www.linuxidc.com/Linux/2017-01/139046.htm

我們都知道,在12C之前,對於PGA內存的管理是使用PGA_AGGREGATE_TARGET參數來控制的,但這個參數也只是一個參考值,Oracle實例只是儘量保證總的PGA使用量在這個值範圍內,當會話使用的PGA內存超過這個限制時,Oracle也不能做出什麼強制措施來限制使用內存的大小。
12.1.0.1版本中引入了新特性:使用PGA_AGGREGATE_LIMIT參數來限制Oracle實例PGA使用內存的上限。後臺進程ckpt每三秒檢查一次PGA使用的內存總量,如果超過限制就採取終止會話的方式來降低PGA內存的使用量,對於SYS用戶進程和後臺進程不包括job隊列不會被終止掉。有了這個限制,不會造成PGA內存瘋漲,導致內存耗盡。
官方文檔:http://docs.oracle.com/database/121/TGDBA/tune_pga.htm#TGDBA95344
默認地PGA_AGGREGATE_LIMIT參數爲2G或200%的PGA_AGGREGATE_TARGET值或PROCESSES參數值*3M
測試數據庫版本12.1.0.2

SQL> select * from v$version;

BANNER CON_ID


Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production 0
PL/SQL Release 12.1.0.2.0 - Production 0
CORE 12.1.0.2.0 Production 0
TNS for Linux: Version 12.1.0.2.0 - Production 0
NLSRTL Version 12.1.0.2.0 - Production 0

查看PGA_AGGREGATE_LIMIT參數值大小爲2G
SQL> show parameter pga

NAME TYPE VALUE


pga_aggregate_limit big integer 2G
pga_aggregate_target big integer 250M

創建測試用戶

SQL> alter session set container=pdb_orcl;

Session altered.

SQL> create user zx identified by zx;

User created.

SQL> grant dba to zx;

Grant succeeded.

SQL> conn zx/zx@pdb_orcl
Connected.

創建一個包用於演示佔用PGA
SQL> create or replace package demo_pkg
2 as
3 type array is table of char(2000) index by binary_integer;
4 g_data array;
5 end;
6 /

Package created.

查看當前會話sid和使用PGA內存情況
SQL> select userenv(‘sid’) from dual;

USERENV(‘SID’)

        22

–當前會話sid爲22
SQL> select a.name, to_char(b.value, ‘999,999,999’) bytes,
2 to_char(round(b.value/1024/1024,1), ‘99,999.9’ ) mbytes
3 from vstatnamea,vstatname a, vmystat b
4 where a.statistic# = b.statistic#
5 and a.name like ‘%ga memory%’;

NAME BYTES MBYTES


session uga memory 2,301,312 2.2
session uga memory max 2,424,824 2.3
session pga memory 3,715,176 3.5
session pga memory max 3,715,176 3.5
–當前會話使用PGA內存爲3.5MB

執行前面創建的包,查看PGA內存使用情況
–循環執行200000次查看PGA內存使用情況
SQL> begin
2 for i in 1 … 200000
3 loop
4 demo_pkg.g_data(i) := ‘x’;
5 end loop;
6 end;
7 /

PL/SQL procedure successfully completed.

SQL> select a.name, to_char(b.value, ‘999,999,999’) bytes,
2 to_char(round(b.value/1024/1024,1), ‘99,999.9’ ) mbytes
3 from vstatnamea,vstatname a, vmystat b
4 where a.statistic# = b.statistic#
5 and a.name like ‘%ga memory%’;

NAME BYTES MBYTES


session uga memory 470,213,072 448.4
session uga memory max 470,213,072 448.4
session pga memory 471,773,288 449.9
session pga memory max 471,773,288 449.9
–共使用449MB內存,可以算出循環執行200000*5次佔用的PGA就會超過設置的2G
SQL> begin
2 for i in 1 … 1000000
3 loop
4 demo_pkg.g_data(i) := ‘x’;
5 end loop;
6 end;
7 /
begin
*
ERROR at line 1:
ORA-04036: PGA memory used by the instance exceeds PGA_AGGREGATE_LIMIT
–報錯ORA-4036超過了PGA_AGGREGATE_LIMIT設置的2G

調整PGA_AGGREGATE_LIMIT爲4G後再次執行報錯的過程,就沒有問題了
SQL> conn / as sysdba
Connected.
SQL> alter system set PGA_AGGREGATE_LIMIT=4G;

System altered.

SQL> conn zx/zx@pdb_orcl
Connected.
SQL> begin
2 for i in 1 … 1000000
3 loop
4 demo_pkg.g_data(i) := ‘x’;
5 end loop;
6 end;
7 /

PL/SQL procedure successfully completed.

SQL> show parameter pga

NAME TYPE VALUE


pga_aggregate_limit big integer 4G
pga_aggregate_target big integer 250M

取消PGA限制,設置pga_aggregate_limit=0即可。
alter system set PGA_AGGREGATE_LIMIT=0;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章