This is the second part of a series of blogpost on Oracle database PGA usage. See the first part here. The first part described SGA and PGA usage, their distinction (SGA being static, PGA being variable), the problem (no limitation for PGA allocations outside of sort, hash and bitmap memory), a resolution for Oracle 12 (PGA_AGGREGATE_LIMIT), and some specifics about that (it doesn’t look like a very hard limit).
But this leaves out Oracle version 11.2. In reality, the vast majority of the database that I deal with at the time of writing is at version 11.2, and my guess is that this is not just the databases I deal with, but a general tendency. This could change in the coming time with the desupport of Oracle 11.2, however I suspect the installed base of Oracle version 12 to increase gradually and smoothly instead of in a big bang.
With version 11.2 there’s no PGA_AGGREGATE_LIMIT. This simply means there is no official way to limit the PGA. Full stop. However, there is an undocumented event to limit PGA usage: event 10261. This means that if you want to use this in a production database, you should ask Oracle support to bless the usage of it. On the other hand, Oracle corporation made this event public in an official white paper: Exadata consolidation best practices.
Let’s test event 10261! I’ve got the same table (T2) setup, a description how to set this up, and the anonymous PL/SQL code to allocate PGA using a collection is in the first part. I am using a database version 184.108.40.206 with PSU 4 applied. The reason for choosing this version is that if you run a serious business on Oracle 11.2, THAT should be the version you should be running on!
(disclaimer: everything shown in this blogpost is purely for educational purposes. Do test everything thoroughly before applying this to a production system. Behaviour can or may be different in your specific situation)
The reason for this disclaimer: Bernhard (@bdcbuning_gridit) tweeted that he was warned that when setting it at the instance level, it could crash the instance. I am not sure if this means setting it at runtime, this event is always evaluated at the instance level.
Okay, let’s replicate more or less the test done to Oracle version 220.127.116.11 in the first part. In this database PGA_AGGREGATE_SIZE is set to 500M, now let’s try to set the event to 600M, which means we set the PGA limit to 600M:
This is setting the event on runtime:
SYS@v11204 AS SYSDBA> alter system set events = '10261 trace name context forever, level 600000'; System altered.
This is setting the event in the spfile (which means you need a restart of the instance to activate this event, or the above syntax to set it on runtime):
SYS@v11204 AS SYSDBA> alter system set event = '10261 trace name context forever, level 600000' scope=spfile; System altered.
The level is the amount of memory to which the PGA must be limited, in kilobytes.
Now start the anonymous PL/SQL block to fill up the PGA with a collection, again set to 900M:
TS@v11204 > @pga_filler declare * ERROR at line 1: ORA-10260: limit size (600000) of the PGA heap set by event 10261 exceeded ORA-06512: at line 20
That’s nice! There’s actually a meaningful, describing error message which explains why this PL/SQL block ended!
Let’s look at the actual PGA memory used, as reported by v$pgastat:
SYS@v11204 AS SYSDBA> select value/power(1024,2) from v$pgastat where name = 'maximum PGA allocated'; VALUE/POWER(1024,2) ------------------- 676.078125
This is different than setting PGA_AGGREGATE_LIMIT, however there’s still more memory allocated than set as the limit (600000KB), but lesser (676M in 18.104.22.168 versus 1041M in 22.214.171.124). The outside visibility of the limiting happening is different too: there is NO notice of a process hitting the PGA limit set in the alert.log file nor the process’ trace file(!). Another difference is even SYS is limited, a test with the procedure running as SYS gotten me the ORA-10260 too, PGA_AGGREGATE_LIMIT does not limit SYS.
Event 10261 has got the same description to at least as low as version 126.96.36.199. Here’s a test with with the event 10261 set at version 188.8.131.52 to 600M:
TS@v11203 > @pga_filler declare * ERROR at line 1: ORA-00600: internal error code, arguments: , , [top uga heap], , , , , , , , ,  ORA-06512: at line 20
As has been detailed in the Oracle white paper, prior to version 184.108.40.206, an ORA-600  is signalled when event 10261 is set, and more PGA memory is allocated as has been specified as limit. The amount of total allocated PGA is 677M, so roughly the same as with version 220.127.116.11.
Because this is a genuine ORA-600 (internal error, ‘OERI’), this gives messages in the alert.log file:
Tue Dec 16 10:40:09 2014 Errors in file /u01/app/oracle/diag/rdbms/v11203/v11203/trace/v11203_ora_8963.trc (incident=9279): ORA-00600: internal error code, arguments: , , [top uga heap], , , , , , , , ,  Incident details in: /u01/app/oracle/diag/rdbms/v11203/v11203/incident/incdir_9279/v11203_ora_8963_i9279.trc Use ADRCI or Support Workbench to package the incident. See Note 411.1 at My Oracle Support for error and packaging details.
The process’ trace file in the trace directory only points to the incident file, no further details are available there.
The incident trace file contains a complete diagnostics dump.
The behaviour is identical with Oracle 18.104.22.168.
The limiting of the total amount of PGA memory used must be done using an undocumented event prior to Oracle version 12. The event is 10261. The event is made known in an official white paper. Still I would open a service request with Oracle to ask blessing for setting this. This does not mean this functionality is not needed, I would deem it highly important in almost any environment, even when running a single database: this setting, when done appropriately, protects your system from over allocating memory, which could mean entering the swapping death-spiral. The protection means a process gets an ORA message, and the PGA allocation aborted and deallocated.
With version 22.214.171.124 hitting the limit as set with event 10261 is not published, outside of the process getting the ORA-10260.
With versions prior to 126.96.36.199 (188.8.131.52 and 184.108.40.206 verified) processes do get an ORA-600 , which is also visible in the alert.log, and incidents are created accordingly.
When a limit has been set using event 10261, it still means more memory is allocated than set as limit (approximately 677M when 600M is set), but this is way less than with the PGA_AGGREGATE_LIMIT (1041M when 600M is set) in my specific situation. Test this in your own environment when you start using this.
A very good comment to emphasise on the behaviour of using/setting event 10261 by Alexander Sidorov: this event sets a limit per process, not for the entire instance!! (tested with 220.127.116.11 and 18.104.22.168)