【oracle】修改sga、pga、tmpfs的原则和方法

需求场景:

SGA,系统全局区(System Global Area),在oracle11g中,是instance的基本组成部分,我的理解就是实例的结构组成。是用于存储数据库信息的内存区,该信息为数据库进程所共享。它包含Oracle 服务器的数据和控制信息。

PGA,程序全局区(Program Global Area),此区域包含单个服务器进程或单个后台进程的数据和控制信息。我的理解就是对外部用户提供管理和访问接口的监听和会话等进程。即我们通过pga进程链接数据库实例,再通过sga结构体系,来进行对数据database的真实操作。

tmpfs,临时文件系统,是一种基于内存的文件系统,一般是基于RAM运行内存上。闪电般读写速度,可以给一些服务进程提供高效的运行空间,也就是共享内存。

那么这里提到修改sga和pga,什么情况下修改呢?可以理解sga提供实例运行的工作区,它的大小决定了实例运行工作中可以使用的大小。既然是工作区域,我们知道计算机的工作数据一般是在内存中运行,sga也是如此,需要注意的是,如果我们在oracle的spfile文件中配置了sga_target参数的大小并使其生效则sga会直接使用的物理内存来启动instance,如果配置的是memory_target的大小,则使用的shm虚拟文件系统的共享内存空间。当然为了使oracle运行更优化,一般我们都是使用的memory_target参数并使其生效。

也就是说,当sga的大小无法满足实例运行的所需空间时,或是tmpfs分区无法给sga分配足够的内存空间时,我们就需要对sga,tmpfs的大小做些调整,同样一般会顺带着修改一下pga的大小。说到pga,事实上pga有别于sga是一个大的共享区域,它是基于单个服务器进程或单个后台进程的独立的一个区域,最简单理解就是一个会话进程一个pga区域,且当进程终止时,pga的空间会被回收,所以pga总的大小不需要配置太大,一般由其实例的并发连接来决定。且一般pga的大小等于并发执行进程数*(sort_area_size+hash_ara_size+2M)

原则:系统使用内存+SGA+PGA < 0.7*总内存、sga+pga+其它程序内存<tmpfs内存大小

这里我们重点说一下修改sga的大小,我们以一个常见的error做切入点:

ORA00845: MEMORY_TARGET not supported on this system(此系统不被内存目标支持)

出现这个问题,就是memory_target参数配置的sga大小,大于tmpfs共享内存真实可用的空间;

为是什么说是可用的空间,因为tmpfs并不仅仅被分配给oracle使用,一些系统程序或服务,比如java进程也会占用空间,如果我们什么服务都没有启动可能数据库会是正常的,但是突然你发现数据库挂了,重启会报这个错误,很可能就是因为其它程序占用了大量空间,导致sga不够使用。注意上面我们的原则中sga+pga+其它程序内存<tmpfs内存大小,所以sga配置多大,还需要根据业务情况不同分析。

那么当出现这个问题时怎么解决呢?比较稳妥的,两个方向:减小sga大小、增加tmpfs大小

一、减小sga大小配置:

①、关闭数据库通过spfile修改

$ sqlplus / as sysdba
SQL> shutdown immediate;
Database closed.
Database dismounted.
ORACLE instance shut down.
(如果报错,使用shutdown abort关闭数据库)
SQL> create pfile from spfile;
SQL> create pfile='/home/oracle/oxblog.ora' from spfile;
SQL> exit
(查看当前tmpfs大小以作对照)
$ df -lh
tmpfs                 6.2G   68K  6.2G   1% /dev/shm
$ vi /home/oracle/oxblog.ora
(找到下面参数并修改之保存退出)
*.memory_max_target=3g
*.memory_target=3g
$ sqlplus / as sysdba
SQL> create spfile from pfile='/home/oracle/oxblog.ora';
SQL> startup
ORACLE instance started.
Total System Global Area 3206836224 bytes
Fixed Size 2232640 bytes
Variable Size 2717912768 bytes
Database Buffers 469762048 bytes
Redo Buffers 16928768 bytes
Database mounted.
Database opened.
思考

上面启动实例,除了显示有sga全局区域内存的大小,还有database buffers、redo buffers、Fixed Size、Variable Size等;

其中database buffers、redo buffers的我们很容易理解,我们知道数据库实例包括SGA(系统全局区)和一系列的后台管理、监视进程,其中sga是数据库实例的内存结构,启动实例也就是启动sga,它又包含共享池、数据库高速缓存、重做日志缓存、流池、以及其它可选池(如java池);而后台进程包括系统监控进程(smon)、进程监控(pmon)、数据库写进程(DBWR)、日志写进程(LGWR)、检查点进程(CKPT)等;这里的database buffers和redo buffers就是数据库高速缓存和重做日志缓存,事实上也是实例中sga的组成部分。

而另外两个fixed size、variable size固定的和可变的大小指的是什么呢?

Fixed Size  (实例内存结构中的固定大小,用于记录SGA结构的固定内存)
Variable Size ( 可变的大小,包含shared_pool_size,java_pool_size,large_pool_size 等等还有用于维护所设置各部分SGA结构的内存)

SQL> show sga
Total System Global Area 3206836224 bytes
Fixed Size 2232640 bytes
Variable Size 2717912768 bytes
Database Buffers 469762048 bytes
Redo Buffers 16928768 bytes

②、sql语句直接修改sga;

修改之前可以show parameter sga/mem查看一下是配置的memory_target还是sga_target;

SQL>alter system set memory_target=4g scope=spfile;
SQL>alter system set memory_max_size=4g scope=spfile;
(修改后记得重启数据库使其生效)
SQL>shutdown immediate;
SQL>startup

如果没有spfile文件(可以通过show parameter spfile查看),可以新创建一个spfile文件。

SQL> create pfile='/opt/oracle/init_pfile.ora';(先创建一个pfile文件,默认也有)
SQL> create spfile='+DG_ORA/${ORACLE_SID}/spfile${SID}.ora' from pfile='/opt/oracle/init_pfile.ora';
(上面的过程需要在数据库关闭状态下操作,然后我们使用pfile文件直接启动数据库)
SQL> startup pfile='/opt/oracle/init_pfile.ora';
(启动状态下,我们修改spfile文件的位置到刚刚创建的spfile文件,这样重启数据库才能正常使用spfile文件启动)
SQL> alter system set spfile='+DG_ORA/${ORACLE_SID}/spfile${SID}.ora';
SQL> shutdown immediate;
SQL> startup;

除此之外,也可以通过EM管理修改,或其它形式,有兴趣的可以自己研究一下。

二、修改tmpfs大小:

同样ora00845的error,我们也可以通过修改tmpfs的大小来解决,这是因为默认情况下tmpfs的大小是物理内存RAM的一半,如果直接使用RAM的进程不是很多,RAM有富余,我们是可以适量增加tmpfs的空间大小,从而提升来满足数据库的性能。

想修改tmpfs很简单,我们可以直接修改fstab文件,然后mount -a重新挂载即可生效:

# vi /etc/fstab
tmpfs                   /dev/shm                tmpfs   defaults,size=80%        0 0
(这里在defaults后面添加参数“size=80%”即可)
# mount -a

当然如果直接这样很容易报错,这是因为tmpfs可能会被占用,比如未杀死的ora进程。

所以一般情况下,还是比较喜欢先umount 一下,不行先释放再umount,然后修改;

# umount tmpfs
umount: /dev/shm: device is busy.
 (In some cases useful info about processes that use
 the device is found by lsof(8) or fuser(1))
(注意这里如果系统没有服务需要继续提供业务,可以直接fuser释放,如果有,建议lsof查看进程后逐一杀掉进程)
# fuser -k /dev/shm
# umount tmpfs

三、修改pga大小

和sga一样,上面我们说到pga程序全局区,会话进程,是直接使用RAM的空间,其真实使用大小和并发数有关。

修改还是很简单的,参照sga的方法,直接修改参数pga_aggregate_target初始化配置,当然pga可以直接在线修改并直接生效的

pga的内存大小我们不用给太大,一般情况下,是sga大小的四分之一即可。

SQL>alter system set pga_aggregate_target=512m scope=spfile;
System altered.

当然有关pga,还有一个相当重要的配置,pga的自动管理(workarea):

SQL>alter system set workarea_size_policy=auto scope=both;
System altered.
SQL>show parameter workarea
NAME				     TYPE	 VALUE
------------------------------------ ----------- ------------------------------
workarea_size_policy		     string	 AUTO
System altered.

有关pga的自动管理,可以理解为pga为工作区域自动动态分配的模式。

具体里面的原理有机会再做深入的研究,一般情况下都是开启自动管理的。

SQL> set lines 256
SQL> set pages 42
SQL> select * from V$pgastat;
NAME VALUE UNIT(监控自动PGA内存管理的性能)
---------------------------------------------------------------- ---------- ------------
aggregate PGA target parameter 1879048192 bytes
aggregate PGA auto target 935414784 bytes
global memory bound 187904000 bytes
total PGA inuse 839706624 bytes
total PGA allocated 1096290304 bytes
maximum PGA allocated 3659153408 bytes
total freeable PGA memory 103677952 bytes
process count 926
max processes count 1021
PGA memory freed back to OS 1.0837E+14 bytes
total PGA used for auto workareas 0 bytes
maximum PGA used for auto workareas 1787164672 bytes
total PGA used for manual workareas 0 bytes
maximum PGA used for manual workareas 541696 bytes
over allocation count 0
bytes processed 1.6627E+14 bytes
extra bytes read/written 3.1528E+13 bytes
cache hit percentage 84.06 percent
recompute count (total) 6534322
19 rows selected.
扩展·思考

上面我们对sga做了简单的修改,事实上sga系统全局区,上面也提到,除了sga自身的大小外,它还包含很多区域,数据高速缓存,重做日志缓存等,还有几个内存池子,那么既然它们独立开,自然也能分别针对这些区域做些文章,下面收集几个常见的配置:

①、共享池Shared Pool

SQL>show parameter shared_pool_size(查看大小)
SQL>select (sum(pins-reloads))/sum(pins) "Library cache" from v$librarycache;
Library cache
-------------
 .998181718
(这个是查看共享池library命中率,如果其低于90%就要考虑增加共享池子的大小)
SQL> select (sum(gets-getmisses-usage-fixed))/sum(gets) "Data dictionary cache" from v$rowcache;

Data dictionary cache
---------------------
 .994140417
(这个是查看数据字典缓冲区的命中率,低于90%也需要考虑增加共享池大小)
ALTER SYSTEM SET SHARED_POOL_SIZE =64M; (修改共享池的大小)

②、缓冲区数据高速缓存DatabaseBufferCache

SQL>show parameter db_cache_size(查看缓冲区大小)
SQL> select name,value from v$sysstat where name in ('db block gets','consistent gets','physical reads','parse time cpu','parse time elapsed','parse count (hard)');
NAME VALUE
---------------------------------------------------------------- ----------
db block gets 20585
consistent gets 231118
physical reads 12634
parse time cpu 232
parse time elapsed 243
parse count (hard) 1433
6 rows selected.

计算出来数据缓冲区的使用命中率=1-(physicalreads/(dbblock gets+consistent gets)),这个命中率应该在90%以上,否则需要增加数据缓冲区的大小。

③、日志缓冲区redo buffers

查看日志缓冲区的使用情况:

SQL> select name,value from v$sysstat where name in ('redo entries','redo log space requests');
NAME VALUE
---------------------------------------------------------------- ----------
redo entries 14718
redo log space requests 0

查询出的结果可以计算出日志缓冲区的申请失败率:

申请失败率=requests/entries,申请失败率应该接近于0,否则说明日志缓冲区开设太小,需要增加ORACLE数据库的日志缓冲区。

④、大型池:

可以减轻共享池的负担,可以为备份、恢复等操作来使用,不使用LRU算法来管理。

其大小由数据库的'共享模式/db模式'如果是共享模式的话,要分配的大一些。

指定Large Pool的大小:

SQL>ALTER SYSTEM SET LARGE_POOL_SIZE=64M;

(今天的分享就到这里,如果您有高见或好的分享,记得留言哦!)


原创文章,转载请注明:转自于公牛博客

本文链接地址:【oracle】修改sga、pga、tmpfs的原则和方法

标签:
3
祝福我们的祖国繁荣昌盛
  • 请尽情挥洒您的笔墨!

    欢迎来到公牛博客更多分享更多精彩记录美丽点亮生活

    公牛博客·统计碑运行:3057 D
    博文:215 P
    评论:452 S