This article has been rewritten and is now part of a 4-part series about cursor sharing.
Monday, April 29, 2024
Thursday, April 11, 2024
Configuring Shared Global Area (SGA) in a Multitenant Database with a PeopleSoft Pluggable Database (PDB)
I have been working on a PeopleSoft Financials application that we have converted from a stand-alone database to be the only pluggable database (PDB) in an Oracle 19c container database (CDB). We have been getting shared pool errors in the PDB that lead to ORA-4031 errors in the PeopleSoft application.
I have written a longer version of this article on my Oracle blog, but here are the main points.
SGA Management with a Parse Intensive System (PeopleSoft).
PeopleSoft systems dynamically generate lots of non-shareable SQL code. This leads to lots of parse and consumes more shared pool. ASMM can respond by shrinking the buffer cache and growing the shared pool. However, this can lead to more physical I/O and degrade performance and it is not beneficial for the database to cache dynamic SQL statements that are not going to be executed again. Other parse-intensive systems can also exhibit this behaviour.
In PeopleSoft, I normally set DB_CACHE_SIZE and SHARED_POOL_SIZE to minimum values to stop ASMM shuffling too far in either direction. With a large SGA, moving memory between these pools can become a performance problem in its own right.
We removed SHARED_POOL_SIZE, DB_CACHE_SIZE and SGA_MIN_SIZE settings from the PDB. The only SGA parameters set at PDB level are SGA_TARGET and INMEMORY_SIZE.
SHARED_POOL_SIZE and DB_CACHE_SIZE are set as I usually would for PeopleSoft, but at CDB level to guarantee a minimum buffer cache size.
This is straightforward when there is only one PDB in the CDB. I have yet to see what happens when I have another active PDB with a non-PeopleSoft system and a different kind of workload that puts less stress on the shared pool and more on the buffer cache.
Initialisation Parameters
- SGA_TARGET "specifies the total size of all SGA components". Use this parameter to control the memory usage of each PDB. The setting at CDB must be at least the sum of the settings for each PDB.
- Recommendations:
- Use only this parameter at PDB level to manage the memory consumption of the PDB.
- In a CDB with only a single PDB, set SGA_TARGET to the same value at CDB and PDB levels.
- Therefore, where there are multiple PDBs, SGA_TARGET at CDB level should be set to the sum of the setting for each PDB. However, I haven't tested this yet.
- There is no recommendation to reserve SGA for use by the CDB only, nor in my experience is there any need so to do.
- SHARED_POOL_SIZE sets the minimum amount of shared memory reserved to the shared pool. It can optionally be set in a PDB.
- Recommendation: However, do not set SHARED_POOL_SIZE at PDB level. It can be set at CDB level.
- DB_CACHE_SIZE sets the minimum amount of shared memory reserved to the buffer cache. It can optionally be set in a PDB.
- Recommendation: However, do not set DB_CACHE_SIZE at PDB level. It can be set at CDB level.
- SGA_MIN_SIZE has no effect at CDB level. It can be set at PDB level at up to half of the manageable SGA
- Recommendation: However, do not set SGA_MIN_SIZE.
- INMEMORY_SIZE: If you are using in-memory query, this must be set at CDB level in order to reserve memory for the in-memory store. The parameter defaults to 0, in which case in-memory query is not available. The in-memory pool is not managed by Automatic Shared Memory Management (ASMM), but it does count toward the total SGA used in SGA_TARGET.
- Recommendation: Therefore it must also be set in the PDB where in-memory is being used, otherwise we found(contrary to the documetntation) that the parameter defaults to 0, and in-memory query will be disabled in that PDB.
Oracle Notes
- A-04031 on Multitenant Database with Excessive Amounts of KGLH0 and / or SQLA Memory and Parameter SHARED_POOL_SIZE or SGA_MIN_SIZE Set at the PDB Level (Doc ID 2590172.1) – December 2022, Updated April 2023
- This one says “Remove the PDB-level SHARED_POOL_SIZE and/or SGA_MIN_SIZE initialization parameters. The only SGA memory sizing parameter that Oracle recommends setting at the PDB level is SGA_TARGET.”
- About memory configuration parameter on each PDBs (Doc ID 2655314.1) – Nov 2023
- “As a best practice, please do not to set SHARED_POOL_SIZE and DB_CACHE_SIZE on each PDBs and please manage automatically by setting SGA_TARGET.”
- "This best practice is confirmed by development in Bug 30692720"
- Bug 30692720 discusses how the parameters are validated. Eg. "Sum(PDB sga size) > CDB sga size"
- Bug 34079542: "Unset sga_min_size parameter in PDB."
Monday, March 11, 2024
PSFT_PLAN: A Sample Oracle Database Resource Manager Plan for PeopleSoft
- If you never run out of CPU, then you have probably bought/rented/allocated/licensed too many CPUs.
- If you do run out of CPU, then you should use the database resource manager to prioritise the processes that are most important to the business.
- If you don't enable the resource manager, you will have less visibility of when you do run out of CPU.
- See also Go-Faster Blog: More Bang for your Buck in the Cloud with Resource Manager
Resource Plan Design Goals
Consumer Groups
| Priority Level | Consumer Group | %CPU Guarantee | Comment |
|---|---|---|---|
| 1 | SYS _GROUP | 100% | Oracle system processes. Defined automatically. |
| 2 | PSFT _GROUP | 100% |
Any process that connects to the database as either SYSADM (the default
PeopleSoft owner ID) or PS has higher priority than other processes unless other rules apply. The online application (other than ad hoc query) falls into this category so that the online user experience is safeguarded before other PeopleSoft processes. This includes remote call Cobol processes, but not remote call Application Engine that should be run in the component processor. |
| 4 | BATCH _GROUP | 100% | Process scheduler processes, and processes run by the process schedulers |
| 5 | NVISION _GROUP | 100% | nVision (NVSRUN) and nVision report book (RPTBOOK) processes |
| 6 | PSQUERY _ONLINE _GROUP | 90% | Ad hoc queries are allocated to one of three consumer groups with the same priority, but different CPU guarantees, comprising:
|
| PSQUERY _BATCH _GROUP | 9% |
| |
| NVSRUN _GROUP | 1% |
| |
| 8 | LOW _GROUP | 1% | Other low-priority processes |
| LOW _LIMITED _GROUP | 1% | Other low-priority processes, but whose maximum query time is limited. | |
| OTHER _GROUPS | 1% | All other processes. Defined automatically. |
Consumer Group Mapping Priority
| Priority | Mapping Attribute | Comment |
|---|---|---|
| 2 | Module, Action | The PIA instrumentation sets attributes MODULE to the component name and ACTION to the page name. Specific component pages are allocated to specific consumer groups |
| 3 | Module | Specific scheduled processes are allocated by name to specific consumer groups. PeopleSoft instrumentation puts this name in the MODULE attribute. |
| 4 | Client Program | Batch and query processes are identified by program name and allocated to certain consumer groups. |
| 5 | Oracle User | Anything that connects to the database as either SYSADM or PS is allocated to the PSFT_GROUP. So other mapping rules must take precedence over this mapping. |
Required PeopleSoft Configuration
- Enable PeopleSoft instrumentation: Set EnableAEMonitoring=1 in ALL PeopleSoft application server and process scheduler domains so that PeopleSoft processes set MODULE and ACTION information in the session attributes (using DBMS_APPLICATION_INFO).
See also:
- PeopleTools PeopleBooks: Administration Tools -> Data Management -> Administering PeopleSoft Databases on Oracle -> Monitoring PeopleSoft MODULE and ACTION Information, Press Enter to collapse
- PeopleSoft DBA Blog: Undocumented (until PeopleTools 8.55) Application Engine Parameter: EnableAEMonitoring
- PeopleSoft DBA Blog: PeopleTools 8.50 uses DBMS_APPLICATION_INFO to Identify Database Sessions
- Go-Faster Blog: One of my Favourite Database Things: DBMS_APPLICATION_INFO
- Install instrumentation trigger for PeopleSoft (psftapi.sql). Not all PeopleSoft processes are instrumented. COBOL, SQR, and nVision do not set MODULE or ACTION. When a PeopleSoft process is started by the process scheduler, the first thing it does is set its own status to 7, meaning that it is processing. This script creates a database trigger that fires on that DML and sets the session attributes MODULE to the name of the process and ACTION to the process instance number. Application Engine processes may then subsequently update these values again.
Consumer Group Mappings
| Mapping Priority | Attribute | Value | Consumer Group Priority |
Consumer Group |
|---|---|---|---|---|
| 2 | MODULE_ACTION | QUERY_MANAGER.QUERY_VIEWER | 6 | PSQUERY_ONLINE_GROUP |
| 3 | MODULE | RPTBOOK NVSRUN | 5 | NVISION_GROUP |
| PSQRYSRV% | 6 | PSQUERY_ONLINE_GROUP | ||
| PSAE.PSQUERY.% | 6 | PSQUERY_BATCH_GROUP | ||
| 4 | CLIENT_PROGRAM | PSRUNRMT | 2 | PSFT_GROUP |
| psae% PSAESRV% PSDSTSRV% PSMSTPRC% PSRUN@% PSSQR% pssqr% sqr% | 4 | BATCH_GROUP | ||
| PSQRYSRV% | 6 | PSQUERY_ONLINE_GROUP | ||
| PSNVSSRV% | 6 | NVSRUN_GROUP | ||
| SQL Developer sqlplus% Toad% | 8 | LOW_GROUP / LOW_LIMITED_GROUP | ||
| 5 | ORACLE_USER | PS SYSADM | 2 | PSFT_GROUP |
Resource Plan Script
- psft_resource_plan_simple.sql creates the resource plan. This is intended to be a starting point to which either unwanted parts can be removed, or additional requirements can be added
- resource_plan_report.sql reports on all the resource plan metadata.
Other Options
There are other resource manager options that are either not illustrated in the sample plan, or that are commented out. They may be worth considering in some situations.
- PeopleSoft does not use parallel query by default, but if you do use it, you may well want to limit which processes use how much parallelism. Consumer groups can specify a limit to the parallel query degree.
- If you use the resource plan to restrict the degree of parallelism, and you also plan to vary the number of CPUs in a cloud environment, then I suggest creating a resource plan for each number of CPUs and switch between the plans by changing the setting of the RESOURCE_MANAGER_PLAN parameter.
DBMS_RESOURCE_MANAGER.CREATE_PLAN_DIRECTIVE(
'PSFT_PLAN', 'NVISION_GROUP', 'nVision Reports.'
,mgmt_p5 => 100
,parallel_degree_limit_p1=>2
);
- A parallel query may queue waiting to obtain sufficient parallel query server processes. A timeout can be specified to limit that wait and to determine the behaviour when the timeout is reached. The query can either be cancelled raising error ORA-07454, or run at a reduced parallelism).
DBMS_RESOURCE_MANAGER.CREATE_PLAN_DIRECTIVE(
'PSFT_PLAN', 'PSQUERY_ONLINE_GROUP'
,mgmt_p6 => 90
,parallel_queue_timeout=>900
,pq_timeout_action=>'RUN'
);
- A consumer group can restrict queries that run for a long time, or that are expected to run for a long time based on their optimizer cost. They can be switched to the CANCEL_SQL group after a number of seconds and they will terminate with ORA-00040: active time limit exceeded - call aborted:. This has only specified for the LOW_LIMITED_GROUP, and the PSQUERY_BATCH_GROUP for scheduled queries because the message is captured by the process scheduler and logged. It has not been specified for PSQUERY_ONLINE_GROUP because this error is not handled well by the online application. Just the Oracle error message will be displayed to the user without further explanation, which is neither friendly nor helpful. Instead, there are PeopleSoft configuration options to limit query runtime.
DBMS_RESOURCE_MANAGER.CREATE_PLAN_DIRECTIVE(
'PSFT_PLAN', 'PSQUERY_BATCH_GROUP'
,mgmt_p6 => 1
,switch_group => 'CANCEL_SQL'
,switch_time => 14400
,switch_estimate => TRUE
,switch_for_call => TRUE
);
- Sometimes customers may have different priorities at different times that cannot be satisfied by a single resource plan. In this case, different resource plans can be activated at different times by different scheduler windows.
Other Online Resources
- Oracle White Paper: Using Oracle Database ResourceManager
- Documentation: Oracle Resource Manager Enhancements in Oracle Database 10g
- Documentation: Oracle Resource Manager Enhancements in Oracle Database 12c Release 1 (12.1)
Tuesday, February 20, 2024
What PS/Query is that?
Sometimes, performance analysis will turn up a problem SQL query that is probably a PS/Query. However, I need to know which PS/Query it is should I wish to alter it or talk to the user who wrote it.
Is it a PS/Query?
It is quite easy to spot SQL queries that are generated from queries defined in the PS/Query tool. These are typical characteristics:
- Single character row source aliases (eg. A, B, D)
- The same row source with a suffix 1 (eg. D1) for query security records.
- Effective date/sequence subqueries are always correlated back to the same table.
- Order by column position number rather than column names or aliases.
SELECT A.EMPLID, A.ATTENDANCE, A.COURSE, B.DESCR, D.NAME, A.SESSION_NBR,
TO_CHAR(A.STATUS_DT,'YYYY-MM-DD'),B.COURSE
FROM PS_TRAINING A, PS_COURSE_TBL B, PS_PERSONAL_DTA_VW D, PS_PERS_SRCH_QRY D1
WHERE D.EMPLID = D1.EMPLID
AND D1.ROWSECCLASS = 'HCDPALL'
AND ( A.COURSE = :1
AND A.ATTENDANCE IN ('S','W')
AND A.COURSE = B.COURSE
AND A.EMPLID = D.EMPLID )
The text of a PS/Query is not stored in the database. Instead, as with other objects in PeopleSoft, it is held as various rows in PeopleTools tables. The PSQRY% tables are used to generate the SQL on demand. We can query these tables to identify the query.
REM findqry.sql
SELECT a.oprid, a.qryname
FROM psqryrecord a
, psqryrecord b
, psqryrecord d
WHERE a.oprid = b.oprid
AND a.qryname = b.qryname
AND a.oprid = d.oprid
AND a.qryname = d.qryname
AND a.corrname = 'A'
AND a.recname = 'TRAINING'
AND b.corrname = 'B'
AND b.recname = 'COURSE_TBL'
AND d.corrname = 'D'
AND d.recname = 'PERSONAL_DTA_VW'
/
OPRID QRYNAME
------------------------------ ------------------------------
TRN002__SESSION_ROSTER
TRN003__COURSE_WAITING_LIST
Writing the query on PSQRYRECORD to find queries, which always is slightly different each time, is quite boring. So I have written a script that will dynamically generate the SQL to identify a PS/Query.
Start with a SQL_ID
SQL_ID c3h6vf2w5fxgp
--------------------
SELECT …
FROM PSTREELEAF B, PSTREENODE C, PS_OPER_UNIT_TBL A, PS_PRODUCT_TBL G
…
UNION SELECT …
FROM PSTREENODE D,PS_TREE_NODE_TBL E, PSTREELEAF F
…
--------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
--------------------------------------------------------------------------------------------------------------------------
| * 7 | INDEX STORAGE FAST FULL SCAN | PSBPSTREELEAF | 426K| 19M| | 1178 (1)| 00:00:01 |
| 10 | TABLE ACCESS BY INDEX ROWID BATCHED| PS_PRODUCT_TBL | 1 | 41 | | 3 (0)| 00:00:01 |
| * 11 | INDEX RANGE SCAN | PS_PRODUCT_TBL | 1 | | | 2 (0)| 00:00:01 |
| * 14 | INDEX RANGE SCAN (MIN/MAX) | PS_PRODUCT_TBL | 1 | 21 | | 2 (0)| 00:00:01 |
| * 15 | TABLE ACCESS STORAGE FULL | PSTREENODE | 135K| 5709K| | 663 (1)| 00:00:01 |
| * 17 | INDEX STORAGE FAST FULL SCAN | PS_OPER_UNIT_TBL | 1791 | 35820 | | 4 (0)| 00:00:01 |
| * 20 | INDEX RANGE SCAN (MIN/MAX) | PS_PSTREENODE | 1 | 33 | | 3 (0)| 00:00:01 |
| * 23 | INDEX RANGE SCAN (MIN/MAX) | PSAPSTREELEAF | 1 | 32 | | 3 (0)| 00:00:01 |
| * 26 | INDEX RANGE SCAN (MIN/MAX) | PS_OPER_UNIT_TBL | 1 | 20 | | 2 (0)| 00:00:01 |
| 33 | TABLE ACCESS INMEMORY FULL | PS_TREE_NODE_TBL | 35897 | 1647K| | 6 (0)| 00:00:01 |
| * 35 | TABLE ACCESS STORAGE FULL | PSTREENODE | 167K| 9670K| | 663 (1)| 00:00:01 |
|- * 36 | INDEX RANGE SCAN | PS_PSTREELEAF | 1 | 39 | | 1267 (1)| 00:00:01 |
| 37 | INDEX STORAGE FAST FULL SCAN | PS_PSTREELEAF | 480K| 17M| | 1267 (1)| 00:00:01 |
| * 40 | INDEX RANGE SCAN (MIN/MAX) | PS_PSTREENODE | 1 | 33 | | 3 (0)| 00:00:01 |
| * 43 | INDEX RANGE SCAN (MIN/MAX) | PS_TREE_NODE_TBL | 1 | 28 | | 2 (0)| 00:00:01 |
--------------------------------------------------------------------------------------------------------------------------
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
…
7 - SEL$1 / B@SEL$1
10 - SEL$1 / G@SEL$1
11 - SEL$1 / G@SEL$1
…
15 - SEL$1 / C@SEL$1
17 - SEL$1 / A@SEL$1
…
33 - SEL$6 / E@SEL$6
35 - SEL$6 / D@SEL$6
36 - SEL$6 / F@SEL$6
37 - SEL$6 / F@SEL$6
…
I use this query on DBA_HIST_SQL_PLAN to extract the tables that have single-character row source aliases that correspond to PeopleSoft records, and put them into PLAN_TABLE. I use this table because it is delivered by Oracle as a global temporary table, so it is always there and I can make use of it even if I only have read-only access.
INSERT INTO plan_table (object_name, object_alias)
with p as ( --plan lines with single letter aliases
SELECT DISTINCT object_owner, object_type, object_name, regexp_substr(object_alias,'[[:alpha:]]',2,1) object_alias
from dba_hist_sql_plan p
, ps.psdbowner d
where p.sql_id = '&&sql_id' --put SQL ID here--
and p.object_name IS NOT NULL
and p.object_owner = d.ownerid
and regexp_like(object_alias,'"[[:alpha:]]"') --single character aliases
), r as ( --PeopleSoft table records and the table name
select r.recname, DECODE(r.sqltablename,' ','PS_'||r.recname,r.sqltablename) sqltablename
from psrecdefn r
where r.rectype = 0 --PeopleSoft table records
)
select r.recname, object_alias --referenced table
from p, r
where p.object_type like 'TABLE%'
and p.object_name = r.sqltablename
union --a query plan may reference an index and not the table
select r.recname, object_alias --table for referenced index
from p, r
, all_indexes i
where p.object_type like 'INDEX%'
and i.index_name = p.object_name
and i.owner = p.object_owner
and i.table_name = r.sqltablename
order by 2,1
/
I now have a list of records and row source aliases aliases
RECNAME O
--------------- -
OPER_UNIT_TBL A
PSTREELEAF B
PSTREENODE C
PSTREENODE D
TREE_NODE_TBL E
PSTREELEAF F
PRODUCT_TBL G
Next, I can run this anonymous PL/SQL block to dynamically build the SQL query on PSQRYRECORD (one reference for every table) and execute it to find the matching PS/Queries
DECLARE
l_sep1 VARCHAR2(20);
l_sep2 VARCHAR2(20);
l_counter INTEGER := 0;
l_sql CLOB := 'SELECT r1.oprid, r1.qryname';
l_where CLOB;
TYPE t_query IS RECORD (oprid VARCHAR2(30), qryname VARCHAR2(30));
TYPE a_query IS TABLE OF t_query INDEX BY PLS_INTEGER;
l_query a_query;
BEGIN
FOR i IN(
SELECT *
FROM plan_table
ORDER BY object_alias
) LOOP
l_counter := l_counter + 1;
dbms_output.put_line(i.object_alias||':'||i.object_name);
IF l_counter = 1 THEN
l_sep1 := ' FROM ';
l_sep2 := ' WHERE ';
ELSE
l_sep1 := ' ,';
l_sep2 := ' AND ';
l_where := l_where||' AND r1.oprid = r'||l_counter||'.oprid AND r1.qryname = r'||l_counter||'.qryname';
END IF;
l_sql := l_sql||l_sep1||'psqryrecord r'||l_counter;
l_where := l_where||l_sep2||'r'||l_counter||'.corrname = '''||i.object_alias||''' AND r'||l_counter||'.recname = '''||i.object_name||'''';
END LOOP;
l_sql := l_sql||l_where||' ORDER BY 1,2';
dbms_output.put_line(l_sql);
EXECUTE IMMEDIATE l_sql BULK COLLECT INTO l_query;
FOR indx IN 1 .. l_query.COUNT
LOOP
DBMS_OUTPUT.put_line (indx||':'||l_query(indx).oprid||'.'||l_query(indx).qryname);
END LOOP;
END;
/
The seven records found in my execution plan become a query of PSQRYRECORD 7 times, one for each record, joined on operator ID and query name.
SELECT r1.oprid, r1.qryname
FROM psqryrecord r1 ,psqryrecord r2 ,psqryrecord r3 ,psqryrecord r4 ,psqryrecord r5 ,psqryrecord r6 ,psqryrecord r7
WHERE r1.corrname = 'A' AND r1.recname = 'OPER_UNIT_TBL'
AND r1.oprid = r2.oprid AND r1.qryname = r2.qryname AND r2.corrname = 'B' AND r2.recname = 'PSTREELEAF'
AND r1.oprid = r3.oprid AND r1.qryname = r3.qryname AND r3.corrname = 'C' AND r3.recname = 'PSTREENODE'
AND r1.oprid = r4.oprid AND r1.qryname = r4.qryname AND r4.corrname = 'D' AND r4.recname = 'PSTREENODE'
AND r1.oprid = r5.oprid AND r1.qryname = r5.qryname AND r5.corrname = 'E' AND r5.recname = 'TREE_NODE_TBL'
AND r1.oprid = r6.oprid AND r1.qryname = r6.qryname AND r6.corrname = 'F' AND r6.recname = 'PSTREELEAF'
AND r1.oprid = r7.oprid AND r1.qryname = r7.qryname AND r7.corrname = 'G' AND r7.recname = 'PRODUCT_TBL'
ORDER BY 1,2
NB. You can only open public queries (where OPRID is a single space) or your own private queries. In the Query Manager, you cannot see a private query owned by another user.
…
3: .PS_TREE_PRODUCT
4: .QUERY_PRODUCT_TREE
5: .RM_TREE_PRODUCT
6:XXXXXX.PS_TREE_PRODUCT_XX
…
The new findqry.sql script is available on Github.
Thursday, January 25, 2024
Reducing the Operating System Priority of PeopleSoft Processes
I wrote about controlling the operating system priority of processes in PeopleSoft Tuxedo domains in Chapters 13 of 14 of PeopleSoft for the Oracle DBA, but I think it is worth a note here.
On Linux and Unix systems, the nice command can be used to lower the operating system scheduling priority of a process (or a privileged can increase the priority). When a server has no free CPU, processes with a lower priority get less time on the CPU. However, when there is free CPU available, the scheduling priority does not affect the amount of CPU that the process can utilise.
On Unix, the priority of a Tuxedo server process can be adjusted using the -n server command line option in the configuration. The parameters to this option are simply passed through to the nice(2) function. Hence, this option does not work on Windows.
PSPRCSRV SRVGRP=BASE
SRVID=101
MIN=1
MAX=1
RQADDR="SCHEDQ"
REPLYQ=Y
CLOPT="-n 4 -sInitiateRequest -- -C psprcs.cfg -CD HR88 -PS PSUNX -A start -S PSPRCSRV"
The operating system priority of a process is inherited from its parent. Therefore, lowering the priority of the Process Scheduler running under Tuxedo will also lower the priority of the batch processes that it spawns. - Therefore Stand-alone Application Engine processes (psae) and Cobol processes inherit the priority of the process scheduler server process (PSPRCSRV).
- However, if the Application Engine server process (PSAESRV) is used, its priority can be set directly.
- If the process scheduler is co-resident with the application server, then it could be run at a lower priority to ensure the online users get preferential allocation of CPU, and that online performance does not suffer excessively at the hands of the batch.
- A system might have two websites: one for self-service and the other for the 'back-office' users. You could configure separate application servers for each site, and run the self-service application server is run at a lower priority.
In PeopleSoft, I prefer to create additional variables in the configuration file (psprcs.cfg).
[Process Scheduler]
;=========================================================================
; General settings for the Process Scheduler
;=========================================================================
PrcsServerName=PSUNX
;-------------------------------------------------------------------------
;Reduce priority of Process Scheduler server process, set to 0 if not needed
Niceness=4
…From PeopleTools 8.4, the Application Engine server process is configured by default. The priority of the AE server processes can then be controlled independently of the process scheduler by creating a separate variable in the PSAESRV section of the configuration file. However, it is generally better to use standalone PSAE, unless you have many short-lived application engine processes, as in CRM (see Application Engine in Process Scheduler: PSAESRV Server Process -v- Standalone PSAE executable). [PSAESRV]
;=========================================================================
; Settings for Application Engine Tuxedo Server
;=========================================================================
;-------------------------------------------------------------------------
;Reduce priority of application engine server process, set to 0 if not needed
Niceness=5
…{APPENG}
#
# PeopleSoft Application Engine Server
#
PSAESRV SRVGRP=AESRV
SRVID=1
MIN={$PSAESRV\Max Instances}
MAX={$PSAESRV\Max Instances}
REPLYQ=Y
CLOPT="-n {$PSAESRV\Niceness} -- -C {CFGFILE} -CD {$Startup\DBName} -S PSAESRV"
{APPENG}
…
PSPRCSRV SRVGRP=BASE
SRVID=101
MIN=1
MAX=1
RQADDR="SCHEDQ"
REPLYQ=Y
CLOPT="-n {$Process Scheduler\Niceness} -sInitiateRequest -- -C {CFGFILE} -CD {$Startup\DBName} -PS {$Process Scheduler\PrcsServerName} -A start -S PSPRCSRV"
When the domain is configured in psadmin, the variables are resolved in the Tuxedo configuration file (psprcsrv.ubb). The -n option can be seen in the server command-line options (CLOPT).#
# PeopleSoft Application Engine Server
#
PSAESRV SRVGRP=AESRV
SRVID=1
MIN=1
MAX=1
REPLYQ=Y
CLOPT="-n 5 -- -C psprcs.cfg -CD HR88 -S PSAESRV"
…
PSPRCSRV SRVGRP=BASE
SRVID=101
MIN=1
MAX=1
RQADDR="SCHEDQ"
REPLYQ=Y
CLOPT="-n 4 -sInitiateRequest -- -C psprcs.cfg -CD HR88 -PS PSUNX -A start -S PSPRCSRV"