玩命加载中 . . .

Oracle Shared Pool与Processes参数的关系


前言

大家都知道,我们使用ORACLE数据库时,常常会为实例配置一个processes参数,此参数故名思意,就是设置整个数据库系统可以启动多少个进程(包括系统自己的后台进程)

设置不合理的processes参数值,会导致实例无法启动。此参数还有其它许许多多的含义和作用,影响着数据库系统的运行。

比如,ORACLE在哪里为其分配内存,分配多大内存?此内存信息在ORACLE instance级的作用?为什么processes参数是一个静态参数?

通过本文,相信大家能找到一个的答案。下面是通过一些测试,来回答上述问题。

实践

测试环境

OS: SUSE Linux Enterprise Server 10 SP1 (x86_64) Kernel 2.6.16.46-0.12-smp (1)
ORACLE VERSION: Release 11.1.0.6.0

修改processes

SQL> alter system set processes=20000 scope=spfile;

系统已更改。

SQL> shutdown immediate
数据库已经关闭。
已经卸载数据库。
ORACLE 例程已经关闭。


oracle@mmsc101:~> sqlplus / as sysdba

SQL*Plus: Release 11.1.0.6.0 - Production on 星期五 6月 24 11:17:55 2011

Copyright (c) 1982, 2007, Oracle.  All rights reserved.

已连接到空闲例程。

SQL> startup nomount
ORA-27154: post/wait create failed
ORA-27300: OS system dependent operation:semids_per_proc failed with status: 0
ORA-27301: OS failure message: Error 0
ORA-27302: failure occurred at: sskgpwcr2
ORA-27303: additional information: semids = 132, maxprocs = 20000
SQL>

从上面的错误说明,oracle会根据processes参数的值在共享池中分配一定数量的内存,参数值越大,分配的内存也越多。

修改process

修改process为300,重启数据库,查看shared pool 中processes值

SQL> show parameter processes

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
aq_tm_processes                      integer     0
db_writer_processes                  integer     1
gcs_server_processes                 integer     0
global_txn_processes                 integer     1
job_queue_processes                  integer     1000
log_archive_max_processes            integer     4
processes                            integer     300


SQL> select * from v$sgastat where pool='shared pool' and name like '%process%';

POOL         NAME                            BYTES
------------ -------------------------- ----------
shared pool  generic process shared st         456
shared pool  ksb ci process list (each         688
shared pool  process count for each CI         320
shared pool  dia* process descriptor            16
shared pool  ksb cic process list              632
shared pool  Background process state           48
shared pool  process group array             66704
shared pool  ksb process so list               632
shared pool  processes                        2400  --300个进程要在共享池中分配2400字节

已选择9行。

修改process为100,重启数据库,查看shared pool 中processes值

SQL> alter system set processes = 100 scope=spfile;

系统已更改。
重启数据库后
SQL> show parameter processes 

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
aq_tm_processes                      integer     0
db_writer_processes                  integer     1
gcs_server_processes                 integer     0
global_txn_processes                 integer     1
job_queue_processes                  integer     1000
log_archive_max_processes            integer     4
processes                            integer     100
SQL>

SQL> select * from v$sgastat where pool='shared pool' and name like '%process%';

POOL         NAME                            BYTES
------------ -------------------------- ----------
shared pool  generic process shared st         456
shared pool  ksb ci process list (each         688
shared pool  process count for each CI         320
shared pool  dia* process descriptor            16
shared pool  ksb cic process list              632
shared pool  Background process state           48
shared pool  process group array             66704
shared pool  ksb process so list               632
shared pool  processes                         800  --100个进程要在共享池中分配800字节

已选择9行。

从上面两次修改processes参数的值,可以看出每个进程将会在shared pool中分配8字节内存,那此8字节信息是什么呢?

我们查看如下的v$process视图

SQL>  desc v$process;
 名称                                      是否为空? 类型
 ----------------------------------------- -------- ----------------------------
 ADDR                                               RAW(8)
 PID                                                NUMBER
 SPID                                               VARCHAR2(24)
 USERNAME                                           VARCHAR2(15)
 SERIAL#                                            NUMBER
 TERMINAL                                           VARCHAR2(30)
 PROGRAM                                            VARCHAR2(48)
 TRACEID                                            VARCHAR2(255)
 TRACEFILE                                          VARCHAR2(513)
 BACKGROUND                                         VARCHAR2(1)
 LATCHWAIT                                          VARCHAR2(16)
 LATCHSPIN                                          VARCHAR2(16)
 PGA_USED_MEM                                       NUMBER
 PGA_ALLOC_MEM                                      NUMBER
 PGA_FREEABLE_MEM                                   NUMBER
 PGA_MAX_MEM                                        NUMBER


SQL> select addr from v$process;

ADDR
----------------
00000000BF4EB598
00000000BF4EC588
00000000BF4ED578
00000000BF4EE568
00000000BF4EF558
00000000BF4F0548
00000000BF4F1538
00000000BF4F2528
00000000BF4F3518
00000000BF4F4508
00000000BF4F54F8

ADDR
----------------
00000000BF4F64E8
00000000BF4F74D8
00000000BF4F84C8
00000000BF4F94B8
00000000BF4FA4A8
00000000BF4FB498
00000000BF4FC488
00000000BF4FD478
00000000BF4FE468
00000000BF4FF458
00000000BF500448

已选择22行。

SQL>

字段ADDR字段刚好为8字节 ,在共享池中保存process进程的信息很有可能就是其地址信息,知道了其地址,也就知道了PGA在哪里,从PGA里的数据结构就可以知道系统进程号等等之类的东西。PMON进程也是利用此信息,在pmon timer到来之际,通过地址信息检查各数据库服务器进程的状态;

此地址信息也是执行alter system kill session命令的重要纽带。怎样从Shared Pool到PGA,或者说怎样从PGA到Shared Pool?共享池中保存process进程的信息成了关键性的作用。

顺便提一句,在ORACLE 9i之上,共享池划分了很多的subpool,在实例启动时,oracle根据processes参数的值,只会挑选其中一个子池来保留此信息

为什么processes参数是一个静态参数?这跟ORACLE关于此参数的内存申请很有关系,个人猜想,此控制结构的信息是以数组的方式保存的,大家都知道数组结构是不能动态扩大的,不像队列或者线性链表。

db_cache与pga之间走的是数据流;shared pool保存的一些信息,可以看成了对pga的控制流。

刚才查看了64位AIX 6.1操作系统

SQL> show parameter processes

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
aq_tm_processes                      integer     0
db_writer_processes                  integer     2
gcs_server_processes                 integer     0
global_txn_processes                 integer     1
job_queue_processes                  integer     1000
log_archive_max_processes            integer     4
processes                            integer     150
SQL> select * from v$sgastat where pool='shared pool' and name like '%process%';

POOL         NAME                            BYTES
------------ -------------------------- ----------
shared pool  ksb ci process list (each         688
shared pool  generic process shared st          96
shared pool  processes                        1200
shared pool  dia* process descriptor            16
shared pool  ksb process so list               632
shared pool  process count for each CI         320
shared pool  ksb cic process list              632
shared pool  Background process state           48
shared pool  process group array             66448

已选择9行。

AIX5.3

% sqlplus "/ as sysdba"

SQL*Plus: Release 9.2.0.8.0 - Production on Fri Jun 24 12:01:48 2011

Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.


Connected to:
Oracle9i Enterprise Edition Release 9.2.0.8.0 - 64bit Production
JServer Release 9.2.0.6.0 - Production

SQL>
SQL> show parameter processes

NAME                                 TYPE                   VALUE
------------------------------------ ---------------------- ------------------------------
aq_tm_processes                      integer                1
db_writer_processes                  integer                1
job_queue_processes                  integer                20
log_archive_max_processes            integer                2
processes                            integer                1000

SQL> select * from v$sgastat where pool='shared pool' and name like '%process%';

POOL                   NAME                                                      BYTES
---------------------- ---------------------------------------------------- ----------
shared pool            processes                                               1368000

oracle11g数据库,AIX6.1系统,为每个进程在共享池中分配8字节;oracle9i数据库,AIX5.3系统每个进程在共享池中分配1368字节,看来这个分配,跟OS,与ORACLE版本都很有关系的。


文章作者: Gavin Wang
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Gavin Wang !
  目录