(一)内存结构和进程结构 Oracle数据库的总体结构如下图: 1:Oracle实例(Instance) 在一个服务器中,每一个运行的Oracle数据库都与一个数据库实例相联系,实例是我们 访问数据库的手段。 实例在操作系统中用ORACLE_SID来标识,在Oracle中用参数INSTANCE_NAME来标识, 它们两个的值是相同的。数据库启动时,系统首先在服务器内存中分配系统全局区(SGA), 构成了Oracle的内存结构,然后启动若干个常驻内存的操作系统进程,即组成了Oracle的 进程结构,内存区域和后台进程合称为一个Oracle实例。 数据库与实例之间是1对1/n的关系,在非并行的数据库系统中每个Oracle数据库与一个 实例相对应;在并行的数据库系统中,一个数据库会对应多个实例,同一时间用户只与一个 实例相联系,当某一个实例出现故障时,其他实例自动服务,保证数据库正常运行。在任何 情况下,每个实例都只可以对应一个数据库。 2:Oracle 10g动态内存治理 内存是影响数据库性能的重要因素,Oracle8i使用静态内存治理,Oracle 10g使用动态 内存治理。所谓静态内存治理,就是在数据库系统中,无论是否有用户连接,也无论并发用 量大小,只要数据库服务在运行,就会分配固定大小的内存;动态内存治理答应在数据库服 务运行时对内存的大小进行修改,读取大数据块时使用大内存,小数据块时使用小内存,读 取标准内存块时使用标准内存设置。 按照系统对内存使用方法的不同,Oracle数据库的内存可以分为以下几个部分: •系统全局区:SGA(System Global Area) •程序全局区:PGA(PRograme Global Area) •排序池:(Sort Area) •大池:(Large Pool) •java池:(Java Pool) 2-1:系统全局区SGA(System Global Area) SGA是一组为系统分配的共享的内存结构,可以包含一个数据库实例的数据或控制信 息。假如多个用户连接到同一个数据库实例,在实例的SGA中,数据可以被多个用户共享。 当数据库实例启动时,SGA的内存被自动分配;当数据库实例关闭时,SGA内存被回收。 SGA是占用内存最大的一个区域,同时也是影响数据库性能的重要因素。 SGA的有关信息可以通过下面的语句查询,sga_max_size的大小是不可以动态调整的。 ===================================== SQL> show parameter sga NAME TYPE VALUE ------------------------------------ ----------- -------- lock_sga boolean FALSE pre_page_sga boolean FALSE sga_max_size big integer 164M sga_target big integer 0
SQL> alter system set sga_max_size=100m; alter system set sga_max_size=100m * ERROR at line 1: ORA-02095: specified initialization parameter cannot be modified ======================================
系统全局区按作用不同可以分为: •数据缓冲区 •日志缓冲区 •共享池 2-1-1:数据缓冲区(Database Buffer Cache) 假如每次执行一个操作时,Oracle都必须从磁盘读取所有数据块并在改变它之后 又必须把每一块写入磁盘,显然效率会非常低。数据缓冲区存放需要经常访问的数据, 供所有用户使用。修改数据时,首先从数据文件中取出数据,存储在数据缓冲区中, 修改/插入数据也存储在缓冲区中,commit或DBWR(下面有具体介绍)进程的其他条 件引发时,数据被写入数据文件。 数据缓冲区的大小是可以动态调整的,但是不能超过sga_max_size的限制。 ====================================== SQL> show parameter db_cache_size NAME TYPE VALUE ------------------------------------ ----------- ----------------- db_cache_size big integer 24M
SQL> alter system set db_cache_size=128m; alter system set db_cache_size=128m * ERROR at line 1: ORA-02097: parameter cannot be modified because specified value is invalid ORA-00384: Insufficient memory to grow cache SQL> alter system set db_cache_size=20m; System altered.
SQL> show parameter db_cache_size; NAME TYPE VALUE ------------------------------------ ----------- ----------------- db_cache_size big integer 20M
#此处我仅增加了1M都不行? SQL> alter system set db_cache_size=25m; alter system set db_cache_size=25m * ERROR at line 1: ORA-02097: parameter cannot be modified because specified value is invalid ORA-00384: Insufficient memory to grow cache #修改显示格式,方便查看。 SQL> column name format a40 wrap SQL> column value format a20 wrap
#下面语句可以用来查看内存空间分配情况,注重SGA各区大小总和。 SQL> select name,value from v$parameter where name like '%size' and value <> '0';
#先将java_pool_size调小,然后再修改db_cache_size SQL> show parameter java_pool_size; NAME TYPE VALUE ------------------------------------ ----------- ----- java_pool_size big integer 48M SQL> alter system set java_pool_size=20m; System altered. SQL> alter system set java_pool_size=30m; System altered. #上面说明SGA中各区大小总和不能超过sga_max_size。 ===================================== 数据缓冲区的大小对数据库的存区速度有直接影响,多用户时尤为明显。有些应 用对速度要求很高,一般要求数据缓冲区的命中率在90%以上。 下面给出一种计算数据缓冲区命中率的方法: •使用数据字典v$sysstat ===================================== SQL> select name, value from v$sysstat 2 where name in('session logical reads', 3 'physical reads', 4 'physical reads direct', 5 'physical reads direct (lob)') NAME VALUE ------------------------------- ---------- session logical reads 895243 physical reads 14992 physical reads direct 34 physical reads direct (lob) 0 ====================================== 命中率=1-(14992-34-0)/895243 可以让Oracle给出数据缓冲区大小的建议: ====================================== SQL> alter system set db_cache_advice=on;#打开该功能 System altered. SQL> alter system set db_cache_advice=off;#关闭该功能 System altered. ====================================== 2-1-2:日志缓冲区(Log Buffer Cache) 日志缓冲区用来存储数据库的修改信息。该区对数据库性能的影响很小,有关日 志后面还会有具体的介绍。 查询日志缓冲区大小: SQL> show parameter log_buffer NAME TYPE VALUE ---------- ----------- ------- log_buffer integer 262144 2-1-3:共享池(Share Pool) 共享池是对SQL,PL/SQL程序进行语法分析,编译,执行的内存区域。 它包含三个部分:(都不可单独定义大小,必须通过share pool间接定义)。 •库缓冲区(Library Cache)包含SQL,PL/SQL语句的分析码,执行计划。 •数据字典缓冲区(Data Dictionary Cache)表,列定义,权限。 •用户全局区(Usr Global Area)用户MTS会话信息。 共享池的大小可以动态修改: ====================================== SQL> show parameter shared_pool_size NAME TYPE VALUE ------------------------------------ ----------- ------ __shared_pool_size big integer 80M shared_pool_size big integer 80M
SQL> alter system set shared_pool_size=78m System altered. ====================================== #上面的__shared_pool_size一行希奇? 2-2:程序全局区PGA(Programe Global Area) 程序全局区是包含单个用户或服务器数据和控制信息的内存区域,它是在用户进程连 接到Oracle并创建一个会话时由Oracle自动分配的,不可共享,主要用于用户在编程存 储变量和数组。 如上图: •Stack Space是用来存储用户会话变量和数组的存储区域; •User Session Data是为用户会话使用的附加存储区。 --Session Information --Sort Area --Cursor Information 注重Session information(用户会话信息)在独占服务器中与在共享服务器中所处 的内存区域是不同的。 2-3:排序区,大池,Java池 排序区(Sort Area)为有排序要求的SQL语句提供内存空间。系统使用专用的内存区 域进行数据排序,这部分空间就是排序区。在Oracle数据库中,用户数据的排序可使用 两个区域,一个是内存排序区,一个是磁盘临时段,系统优先使用内存排序区进行排序。 假如内存不够,Orcle自动使用磁盘临时表空间进行排序。为提高数据排序的速度,建议 尽量使用内存排序区,而不要使用临时段。 参数sort_area_size用来设置排序区大小。(好象不能动态修改?) 大池(Large Pool)用于数据库备份工具--恢复治理器(RMAN:Recovery Manager)。 Large Pool的大小由large_pool_size确定,可用下面语句查询和修改: ========================================= SQL> show parameter large_pool_size NAME TYPE VALUE ----------------- ----------- ------- large_pool_size big integer 8M SQL> alter system set large_pool_size=7m; System altered. =========================================
Java池主要用于Java语言开发,一般来说不低于20M。其大小由java_pool_size来 确定,可以动态调整。 2-4:Oracle自动共享内存治理(Automatic Shared Memory(SGA) Management) 在Oracle 8i/9i中数据库治理员必须手动调整SGA各区的各个参数取值,每个区要根据 负荷轻重分别设置,假如设置不当,比如当某个区负荷增大时,没有调整该区内存大小,则 可能出现ORA-4031:unable to allocate ...bytes of shared memory错误。 在Oracle 10g中,将参数STATISTICS_LEVEL设置为TYPICAL/ALL,使用SGA_TARGET指 定SGA区总大小,数据库会根据需要在各个组件之间自动分配内存大小。 下面是系统自动调整的区域: •固定SGA区及其他•共享池•数据缓冲区• Java池•大池。 注重:假如不设置SGA_TARGET,则自动共享内存治理功能被禁止。 ========================================== SQL> show parameter statistics_level NAME TYPE VALUE --------------------- ----------- ------------ statistics_level string TYPICAL
SQL> alter system set statistics_level=all; System altered. #typical和all有什么区别?
SQL> alter system set statistics_level=typical; System altered. SQL> show parameter sga_target NAME TYPE VALUE ------------- ----------- ---------- sga_target big integer 0 SQL> alter system set sga_target=170m; alter system set sga_target=170m * ERROR at line 1: ORA-02097: parameter cannot be modified because specified value is invalid ORA-00823: Specified value of sga_target greater than sga_max_size SQL> alter system set sga_target=20m; System altered. #不过后来又发现sga_target的值变成了140M? 下面是语句执行情况。 SQL> show parameter sga_target NAME TYPE VALUE ------------- ----------- ------- sga_target big integer 140M
SQL> alter system set sga_target=0; System altered. SQL> show parameter sga_target NAME TYPE VALUE ------------------------------------ ----------- ------ sga_target big integer 0 #改为20M SQL> alter system set sga_target=20m; System altered. #显示的是140M SQL> show parameter sga_target NAME TYPE VALUE ------------------------------------ ----------- ------ sga_target big integer 140M #不可缩减? SQL> alter system set sga_target=130m; alter system set sga_target=130m * ERROR at line 1: ORA-02097: parameter cannot be modified because specified value is invalid ORA-00827: could not shrink sga_target to specified value
#不可增加 SQL> alter system set sga_target=141m; alter system set sga_target=141m * ERROR at line 1: ORA-02097: parameter cannot be modified because specified value is invalid ORA-00823: Specified value of sga_target greater than sga_max_size