我們都知道,在12c之前,對(duì)于PGA內(nèi)存的管理是使用PGA_AGGREGATE_TARGET參數(shù)來(lái)控制的,但這個(gè)參數(shù)也只是一個(gè)參考值,Oracle實(shí)例只是盡量保證總的PGA使用量在這個(gè)值范圍內(nèi),當(dāng)會(huì)話使用的PGA內(nèi)存超過(guò)這個(gè)限制時(shí),Oracle也不能做出什么強(qiáng)制措施來(lái)限制使用內(nèi)存的大小。
我們提供的服務(wù)有:網(wǎng)站設(shè)計(jì)制作、網(wǎng)站設(shè)計(jì)、微信公眾號(hào)開(kāi)發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認(rèn)證、雙牌ssl等。為近千家企事業(yè)單位解決了網(wǎng)站和推廣的問(wèn)題。提供周到的售前咨詢和貼心的售后服務(wù),是有科學(xué)管理、有技術(shù)的雙牌網(wǎng)站制作公司
12.1.0.1版本中引入了新特性:使用PGA_AGGREGATE_LIMIT參數(shù)來(lái)限制Oracle實(shí)例PGA使用內(nèi)存的上限。后臺(tái)進(jìn)程ckpt每三秒檢查一次PGA使用的內(nèi)存總量,如果超過(guò)限制就采取終止會(huì)話的方式來(lái)降低PGA內(nèi)存的使用量,對(duì)于SYS用戶進(jìn)程和后臺(tái)進(jìn)程不包括job隊(duì)列不會(huì)被終止掉。有了這個(gè)限制,不會(huì)造成PGA內(nèi)存瘋漲,導(dǎo)致內(nèi)存耗盡。
官方文檔:http://docs.oracle.com/database/121/TGDBA/tune_pga.htm#TGDBA95344
默認(rèn)地PGA_AGGREGATE_LIMIT參數(shù)為2G或200%的PGA_AGGREGATE_TARGET值或PROCESSES參數(shù)值*3M
測(cè)試數(shù)據(jù)庫(kù)版本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參數(shù)值大小為2G
SQL> show parameter pga NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ pga_aggregate_limit big integer 2G pga_aggregate_target big integer 250M
創(chuàng)建測(cè)試用戶
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.
創(chuàng)建一個(gè)包用于演示占用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.
查看當(dāng)前會(huì)話sid和使用PGA內(nèi)存情況
SQL> select userenv('sid') from dual; USERENV('SID') -------------- 22 --當(dāng)前會(huì)話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 v$statname a, v$mystat 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 --當(dāng)前會(huì)話使用PGA內(nèi)存為3.5MB
執(zhí)行前面創(chuàng)建的包,查看PGA內(nèi)存使用情況
--循環(huán)執(zhí)行200000次查看PGA內(nèi)存使用情況 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 v$statname a, v$mystat 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內(nèi)存,可以算出循環(huán)執(zhí)行200000*5次占用的PGA就會(huì)超過(guò)設(shè)置的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 --報(bào)錯(cuò)ORA-4036超過(guò)了PGA_AGGREGATE_LIMIT設(shè)置的2G
調(diào)整PGA_AGGREGATE_LIMIT為4G后再次執(zhí)行報(bào)錯(cuò)的過(guò)程,就沒(méi)有問(wèn)題了
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限制,設(shè)置pga_aggregate_limit=0即可。
alter system set PGA_AGGREGATE_LIMIT=0;