前言:下面主要介绍了11G的AMM特性,实现了对SGA,PGA,以及SGA下面的内存如share_pool的自动管理,因为10G的ASMM特性需要手动对SGA,PGA管理,所以11G引出来了AMM管理。
在一个oracle server可以分为两部分,一部分是database,一部分是instance。
Database:datafile,controlfile,redolog file,这三个文件构成了整个oracle的物理结构
Instance:当要访问数据的时候那么就要通过instance来访问了。Instance=内存+后台进程
当oracle作为一个服务在操作系统上面启动的时候,操作系统会给oracle分配一定的内存,同时会运行一些后台进程。
在linux系统下面可以通过ipcs命令来查看分配给oracle的内存。
[root@Database2 ~]# ipcs
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00000000 720910 oracle 640 4096 0
0x00000000 753681 oracle 640 4096 0 --对oracle进行管理的用户可以看到是oracle
0x84bc7544 786450 oracle 640 4096 0
------ Semaphore Arrays --------
key semid owner perms nsems
0x00000000 0 root 600 1
0x00000000 65537 root 600 1
0x6a52b5d4 196610 oracle 640 154
------ Message Queues --------
key msqid owner perms used-bytes messages
[root@Database2 ~]# ipcs -m --这个查看分配给oracle的共享内存
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00000000 720910 oracle 640 4096 0
0x00000000 753681 oracle 640 4096 0
0x84bc7544 786450 oracle 640 4096 0
[root@Database2 ~]# ipcs -s --看oracle内存访问的信号灯
------ Semaphore Arrays --------
key semid owner perms nsems
0x6a52b5d4 196610 oracle 640 154
上面可以看到的ipcs的信息就是在oracle启动的时候linux给其分配的内存。
现在数据库是开启的状态,下面是关闭数据库
[root@Database2 ~]# ps -ef | grep pmon
oracle 2412 1 0 Jun24 ? 00:00:09 ora_pmon_oradb
root 8188 8117 0 07:45 pts/1 00:00:00 grep pmon
[root@Database2 ~]# su - oracle
[oracle@Database2 ~]$ sqlplus / as sysdba
SQL> shutdown immediate;
Database closed.
Database dismounted.
ORACLE instance shut down.
再去查看linux分配给数据库的内存发现没有了。
[root@Database2 ~]# ipcs -m
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
上面可以看到使用ipcs来查看在操作系统层面分配给oracle内存的信息。
[root@Database2 ~]# ps -ef | grep ora_ | grep -v grep --查看oracle启动之后有哪些后台进程
oracle 8251 1 0 07:49 ? 00:00:00 ora_pmon_oradb
oracle 8253 1 0 07:49 ? 00:00:00 ora_psp0_oradb
oracle 8255 1 3 07:49 ? 00:00:04 ora_vktm_oradb
oracle 8259 1 0 07:49 ? 00:00:00 ora_gen0_oradb
.....................................................................................................................................
可以看到格式都是ora开始,中间就是进程的名字,最后跟着实例的名字oradb。
可以看到在数据库启动的时候会获得分配的内存空间,并且会启动相应的后台进程。后台进程实现了数据库的数据文件和内存之间的交互。
SQL> show parameter mem; --在11G之后,就可以通过memory_max_target,memory_target对内存进行管理了。
NAME TYPE VALUE
------------------------------------ -------------------- ------------------------------
hi_shared_memory_address integer 0
memory_max_target big integer 800M
memory_target big integer 800M
shared_memory_address integer 0
memory_max_target:oracle实例可以获得操作系统最大内存的,一般是操作系统physical mem*80%给oracle使用。比如物理内存是8G,最少给memory_max_target分配6G左右。
memory_max_target代表了oracle实例启动以后可以从操作系统上所获得的最大内存。
memory_target:当前实例分配的内存,memory_target<=memory_max_target
memory_max_target big integer 800M
memory_target big integer 800M
上面可以看到可以从操作系统获得到的最大内存是800M,但是实际上oracle当前实例获得了800M。
在11G之后,如果这两个参数是非0的,那么就叫启动了内存的自动管理AMM。
Oracle内存分为两部分,SGA(系统全局区,是一个共享内存,共享给所有访问数据库实例会话的),PGA(程序全局区,通过建立会话以后,给每一个会话分配UGA的独立内存空间)。
OLTP:以事务操作为主,比如银行,存钱,取钱,转账。在这种类型的数据库里面SGA占80%,PGA占20%,PGA这部分的空间大部分用来数据的排序,OLTP类型的数据库一般访问的数据量不会特别大,排序也不会特别多,所以给PGA的内存不会特别多。希望执行的SQL和访问的数据块都可以被共享,所以SGA占80%。
OLAP(DSS):以海量的查询为主,会牵扯到大量表的连接,数据统计分析汇总,在SQL执行的过程当中访问的数据量都比较大,执行的时间都比较长,会涉及到大量的排序工作,因为访问的数据量大,访问的数据块在内存里很难被共享,执行的SQL也很难做到共享,所以SGA 40%+PGA 60%
由于银行等很多系统,白天可能是OLTP系统,到了晚上是OLAP系统,那么手工方式管理SGA和PGA的内存分配就很麻烦了,在11G之前内存是不能自动管理的,必须手动调整PGA和SGA的大小,在11G增加了memory_max_target,memory_target两个参数。
如果将memory_max_target,memory_target这两个参数设置了非0值,那么就叫启动了内存自动管理AMM,那么oracle就会根据业务类型自动的调整SGA,PGA的大小。
在Oracle 11g中禁用 Automatic Memory Management (AMM)特性(关闭了内存自动管理,SGA,PGA就要手动进行分配了(这个就要使用ASMM管理了),这个适合非常有经验的,对数据库业务很熟悉的DBA,如果是新的DBA,对业务不是很熟悉,不建议设为手工管理,使用自动管理)。
SQL> set linesize 1200;
SQL> show parameter mem;
NAME TYPE VALUE
------------------------------------ -------------------- ------------------------------
hi_shared_memory_address integer 0
memory_max_target big integer 800M
memory_target big integer 800M
shared_memory_address integer 0
从上面内存分配原则,2G*80%=1.6G,实际数据库内存大小是800M,可以调整的大一些,在生产环境下要注意一定要先create pfile from spfile,备份一下参数文件。
SQL> alter system set memory_max_target=1024m scope=spfile;
System altered.
SQL> alter system set memory_target=1024m scope=spfile;
System altered.
最好是将memory_max_target和memory_target调整为一样大。
SQL> show parameter mem;
NAME TYPE VALUE
------------------------------------ -------------------- ------------------------------
hi_shared_memory_address integer 0
memory_max_target big integer 1G
memory_target big integer 1G
shared_memory_address integer 0
当将AMM开启了SGA,PGA大小就不需要再去管了,即使设置了sga_target和pga_aggregate_target为0,那也是说明sga_target和pga_aggregate_target为自动管理。最小值大于0而已,SGA,PGA大小都会根据业务类型来调整。
SGA里包括了:share pool,buffer cache,large pool,Java pool,stream pool。这几个缓冲区大小都可以根据SGA自动进行分配,因为启动了AMM管理,最后调整结果如下(SGA,PGA,SGA下面的内存区都自动管理):
SQL> show parameter mem;
NAME TYPE VALUE
------------------------------------ -------------------- ------------------------------
hi_shared_memory_address integer 0
memory_max_target big integer 1104M
memory_target big integer 1104M
shared_memory_address integer 0
SQL> show parameter sga;
NAME TYPE VALUE
------------------------------------ -------------------- ------------------------------
lock_sga boolean FALSE
pre_page_sga boolean FALSE
sga_max_size big integer 1104M
sga_target big integer 0
SQL> show parameter pga;
NAME TYPE VALUE
------------------------------------ -------------------- ------------------------------
pga_aggregate_target big integer 0
SQL> show parameter db_cache_size;
NAME TYPE VALUE
------------------------------------ -------------------- ------------------------------
db_cache_size big integer 0
SQL> show parameter shared_pool_size;
NAME TYPE VALUE
------------------------------------ -------------------- ------------------------------
shared_pool_size big integer 0
SQL> show parameter java_pool_size;
NAME TYPE VALUE
------------------------------------ -------------------- ------------------------------
java_pool_size big integer 0
SQL> show parameter large_pool_size;
NAME TYPE VALUE
------------------------------------ -------------------- ------------------------------
large_pool_size big integer 0
SQL> show parameter streams_pool_size;
NAME TYPE VALUE
------------------------------------ -------------------- ------------------------------
streams_pool_size big integer 0
在启用了内存自动管理,不要手工去设置sga_max_size的值,如果在pfile文件里面有这个值,最好把这个值删除了,这样sga_max_size的值就由oracle去自动分配了。(在参数文件里面如果没有某个参数的值就由oracle去自动分配)