目录
一、oracle数据库的整体架构
二、Oracle数据库存储结构
三、实例的整体架构
3.1 程序全局区(Process Global Area)
3.2系统全局区(System Global Area)
3.1.2数据库缓冲区(Database Buffer Cache)
3.1.3日志缓冲区
3.1.4大池
3.1.5 JAVA池
由上图可知,oracle数据库由实例和数据库组成。
Oracle数据库有物理结构和逻辑结构。数据库的物理结构是数据库中的操作系统文件的集合。
数据库的物理结构由数据文件、控制文件和重做日志文件组成。
查看系统的redo log的信息:
SQL> select group#,sequence#,bytes,members,status from v$log;
GROUP# SEQUENCE# BYTES MEMBERS STATUS
---------- ---------- ---------- ---------- ----------------
1 22 52428800 1 INACTIVE
2 23 52428800 1 CURRENT
3 21 52428800 1 INACTIVE
SQL> select member from v$logfile;
MEMBER
/u01/app/oracle/oradata/hnzk/redo03.log
/u01/app/oracle/oradata/hnzk/redo02.log
/u01/app/oracle/oradata/hnzk/redo01.log
除了三个必须的文件外数据库还能有其它非必须的文件如:参数文件、口令文件及归档日志文件。
Oracle实例整体架构图:
实例由内存和后台进程组成,它暂时存在于RAM和CPU中。当关闭运行的实例时,实例将随即消失。数据库由磁盘上的物理文件组成,不管在运行状态还是停止状态,这些文件就一直存在。因此,实例的生命周期就是其在内存中存在的时间,可以启动和停止。一旦创建数据库,数据库将永久存在。通俗的讲数据库就相当于平时安装某个程序所生成的安装目录,而实例就是运行某个程序时所需要的进程及消耗的内存。
Oracle的内存架构包含两部分系统全局区(SGA)和程序全局区(PGA)。
在操作系统提供的共享内存段实现的内存结构称为系统全局区(SGA)。SGA在实例启动时分配,在关闭时释放。在一定范围内,可以在实例运行时通过自动方式或响应DBA的指令,重新调整11g实例中的SGA及其中的组件的大小。
由上图可知SGA至少包含三种数据结构:数据库缓冲区缓存、日志缓冲区及共享池。还可能包括:大池、JAVA池。可以使用show sga,查看sga的状态。
SQL> show sga
Total System Global Area 9160359936 bytes
Fixed Size 2082752 bytes
Variable Size 2701133888 bytes
Database Buffers 6442450944 bytes
Redo Buffers 14692352 bytes
这部分是Oracle内部使用的一个区,Oracle通过这个区找到SGA其他区,类似一个SGA各个组件的索引,不同平台和不同版本下这部分的大小可能不一样。
包括 shared pool、java pool、large pool,管理db_block_buffers 的内存、管理控制文件信息的内存等等,其他管理和控制Oracle 内部结构的内存(这部分通常被称为Overhead),也就有了如下的公式:
Variable Component(Show SGA) = Shared Pool + Large Pool + Java Pool + Overhead + Free Memory(9i 之前的版本)
Overhead的大小受如下初始化参数的影响:db_files, open_cursors ,processes ,具体算法未知。
为db_cache_size、db_keep_cache_size、db_recycle_cache_size、 db_nk_cache_size的总大小,当然这是sga_target为0的情况,也就是手动SGA管理模式下,如果是自动SGA管理(sga_target>0),则这个值根据sga的分配情况自动进行调整。
这部分是实际分配的Redo log buffer的大小,由初始化参数log_buffer根据SGA的最小分配单位granule 向上取整得到。
共享池由许多子结构组成,这些子结构由oracle服务器内部自动管理。在共享池的总体大小范围内,各个结构的大小将因针对实例的活动模式而异。共享池本身的大小可以动态重调。
共享池的大小对性能产生重要影响,它应该足够大,以便缓存所有频繁执行的代码和频繁访问的对象定义,但也不能过大,以至于连仅执行一次的语句也要缓存。如果共享池过小,则性能下降,因为服务器会话将反复抢夺其中的空间来分析语句,此后,这些语句会被其他语句重写,在重新执行时,将不得不再次分析。过大的共享池也会对性能产生不良影响,因为搜索需要的时间过长。如果共享池小于最优容量,则性能将下降。但有一个最小容量,如果低于此限度,则语句将失败。确定最优容量是一个性能调整问题,大多数数据库都需要一个数百MB的共享池。有些应用程序需要1GB以上的共享池,但很少有应用程序能够在共享池小于100 MB时充分运行。
共享池在实例启动时分配。从9i开始,可以随时将其调大或调小。可以采用手动方式重调,也可以根据工作负荷自动调整大小。
手动调整共享池的大小:
1. 显示可以动态重设大小的SGA组件的当前、最大和最小容量
SQL> select COMPONENT,CURRENT_SIZE,MIN_SIZE,MAX_SIZE from v$sga_dynamic_components;
COMPONENT CURRENT_SIZE MIN_SIZE MAX_SIZE
---------------------------------------------------------------- ------------ ---------- ----------
shared pool 104857600 100663296 0
large pool 4194304 4194304 0
java pool 4194304 4194304 0
streams pool 0 0 0
DEFAULT buffer cache 167772160 167772160 0
KEEP buffer cache 0 0 0
RECYCLE buffer cache 0 0 0
DEFAULT 2K buffer cache 0 0 0
DEFAULT 4K buffer cache 0 0 0
DEFAULT 8K buffer cache 0 0 0
DEFAULT 16K buffer cache 0 0 0
DEFAULT 32K buffer cache 0 0 0
ASM Buffer Cache 0 0 0
13 rows selected.
2. 调整SHARED_POOL_SIZE参数
SQL> ALTER SYSTEM SET SHARED_POOL_SIZE = 110M;
System altered.
SQL> select COMPONENT,CURRENT_SIZE,MIN_SIZE,MAX_SIZE from v$sga_dynamic_components;
COMPONENT CURRENT_SIZE MIN_SIZE MAX_SIZE
---------------------------------------------------------------- ------------ ---------- ----------
shared pool 117440512 100663296 0
large pool 4194304 4194304 0
java pool 4194304 4194304 0
streams pool 0 0 0
DEFAULT buffer cache 155189248 155189248 0
KEEP buffer cache 0 0 0
RECYCLE buffer cache 0 0 0
DEFAULT 2K buffer cache 0 0 0
DEFAULT 4K buffer cache 0 0 0
DEFAULT 8K buffer cache 0 0 0
DEFAULT 16K buffer cache 0 0 0
DEFAULT 32K buffer cache 0 0 0
ASM Buffer Cache 0 0 0
13 rows selected.
数据库缓冲区(Database Buffer Cache)是oracle用来执行SQL的工作区域。在更新数据时,用户会话不直接更新磁盘上的数据,而是首先复制到数据库缓冲区缓存。更改应用于数据库缓冲区缓存中这些数据块的副本,块将在缓存中保留一段时间,直至其占有的缓冲区需要缓存另一块为止。在查询数据时,数据也要经过缓存。会话计算出哪些块包含关键的行,并将它们复制到数据库缓冲区缓存。此后,相关行传输到会话的PGA作进一步处理。此后数据块会在数据库缓存区缓存中保留一段时间。
理想状况下,包含频繁访问的数据的所有块将位于数据库缓冲区缓存中,从而最大程度地减少磁盘I/O的需要。如果缓冲区的缓存中存储的块的映像与磁盘上的映像不同,那么这样的缓冲区常称为“脏缓冲区”。脏缓冲区必须写回到数据文件,然后缓冲区又变得干净了。即使再写入磁盘后,此块也仍留在内存中,可能有一段时间,此缓冲区不会被另一个块所重写。
数据库缓冲区缓存的大小会对性能产生至关重要的影响。缓存应足够大,以便能缓存所有频繁访问的块,但也不能太大,以至于它会缓存极少使用的块。如果缓存过小,那么将导致磁盘活动过多,因为频繁访问的块持续从磁盘读取,并由其他块使用和重写,然后再从磁盘读取。数据库缓冲区缓存在实例启动时分配。从数据库9i开始,可以随时将其调大或调小。可以采用手动方式重调,也可以根据工作负荷自动重调大小(如果启用了自动化机制)。(优化的时候会用到)
修改DB_CACHE_SIZE的方法:
1. 查看SGA大小
show parameter sga_max_size
db_cache_size的尺寸受SGA的影响不能大于SGA
2. 查看show parameter shared_pool_size尺寸
一般来说shared_pool_size+db_cache_size=SGA_MAX_SIZE*70%左右,经过计算再修改db_cache_size,就可以看到修改后的效果了。
sql>alter system set db_cache_size=大小M scope=spfile sid='数据库SID';
sql>shutdown immediate
sql>startup
sql>show parameter db_cache_size
日志缓冲区是小型的、用于短期存储将写入到磁盘上的重做日志的变更向量的临时区域。"变更向量"是应用于某些对象的修改,执行DML语句会生成应用于数据的变更向量。有了重做日志,数据库就保证数据永不丢失,每当数据块放生变更时,都会将应用于块的变更向量写到重做日志,如果需要还原数据文件,则通过重做日志,可以将变更向量提取并应用于数据文件备份。
会话服务器进程不将重做记录直接写入到重做日志文件,否则,每当执行DML语句时,会话将不得不等待磁盘I/O操作完成。相反,会话将重做记录写入内存中的日志缓冲区。这样做的速度将远比写入磁盘快。此后,日志缓冲区写出到重做日志文件。写操作由日志写入器后台进程(LGWR)完成。
日志缓冲区在启动实例时分配,如果不重新启动实例,就不能在随后调整其大小。在oracle体系结构中,将日志缓冲区转储到磁盘是基本瓶颈之一。DML的速度不能超过LGER将变更向量转储到联机重做日志文件的速度。如果重做生成是限制数据库性能的因素,唯一的选项是使用RAC,在RAC数据库中,每个实例都有自己的日志缓冲区和自己的LGWR,这是将重做数据并行写入磁盘的唯一方法。
大池是一个可选区域,如果创建了大池,则那些在不创建大池的情况下使用共享池内存的不同进程将自动使用大池。
大池的一个主要用途是供共享的服务器进程使用。在缺少大池的情况下,这些进程将使用共享池中的内存,将导致对共享池的恶性竞争。如果使用的是共享服务器或并行服务器,那么始终应该创建大池。设置大池的大小与性能无关,如果某个进程需要大内存池,而内存不够用,则此进程将失败并发生错误。如果分配的内存超过需要,语句的执行速度并不会因此加快。从9i第2版本开始,用户可以在启动实例后创建大池,并重设其大小。
只有当应用程序需要在数据库中运行java存储程序时,才需要java池。用户可以在启动实例后创建池并重设池的大小,可以完全自动地创建池,并设置池的大小。