ORACLE 体系结构
.Oracle 体系结构图:
.1.ORACLE 实例
.1.1. Oracle 实例
Oracle实例包括内存结构和后台进程
System Global Area(SGA) 和Background Process 称为数据库实例文件。
.2. Oracle 数据库
一系列物理文件的集合(数据文件,控制文件,联机日志,参数文件等)
数据文件(datafiles):数据文件包含数据库中的实际数据,是数据库操作中数据的最终存储位置。
控制文件(controlfile):包含维护数据库和验证数据库完整性的信息,它是二进制文件。
重做日志文件(redo file):重做日志文件包含数据库发生变化的记录,在发生故障时用于数据恢复。
参数文件(parameter file):参数文件中定义了数据库实例的特性。在参数文件中包含为SGA中内存结构分配空间的参数,如分配数据库高速缓冲区的大小等,参数文件是正文文件,可以使用操作系统文本编辑器查看,如在WINDOWS操作系统中使用记事本工具。
密码文件(password file):密码文件授予用户启动和关闭数据库实例,在刚安装数据库时,Oracle的默认用户名和密码就存储在密码文件中,Oracle可以藉此判断用户的操作权限。
归档日志文件:归档日志文件是日志文件的脱机备份,在发生故障时,数据恢复时可能使用该文件。
初始化参数文件:nitSID.ora或init.ora文件,因为版本的不一样,其位置也可能会不一样。在8i中,通常位于$Oracle_HOME/admin//Pfile下,初始化文件记载了许多数据库的启动参数,如内存,控制文件,进程数等,在数据库启动的时候加载(Nomount时加载),初始化文件记录了很多重要参数,对数据库的性能影响很大,如果不是很了解,不要轻易乱改写,否则会引起数据库性能下降。
.3.Oracle 内存结构
System Global Area(SGA) 是一块巨大的共享内存区域,它被看做是oracle数据库的一个大缓冲池,这里的数据都可以被oracle的各个进程共用。(语句:select * fromv$sga)
.3.1.共享池(Shared pool)
共享池是SGA中最关键的内存片段,特别是在性能和可伸缩性上。一个太小的共享池会扼杀性能,使系统停止,太大的共享池也会有同样的效果,将会消耗大量的CPU来管理这个共享池。不正确的使用共享池只会带来灾难。
Oracle引入共享池的目的就是共享SQL或PL/SQL代码,即把解析得到的SQL代码的结果在这里缓存,其中PL/SQL代码不仅在这里缓存,同时在这里共享。共享池由两部分组成,即库高速缓存和数据字典高速缓存。
.3.1.1.SQL语句缓冲(Library Cache)
当一个用户提交一个SQL语句,Oracle会将这句SQL进行分析(parse),这个过程类似于编译,会耗费相对较多的时间。在分析完这个SQL,Oracle会把他的分析结果给保存在Shared pool的Library Cache中,当数据库第二次执行该SQL时,Oracle自动跳过这个分析过程,从而减少了系统运行的时间。这也是为什么第一次运行的SQL比第二次运行的SQL要慢一点的原因。Oracle采用一种LRU(least recently used)最近最少使用算法管理库高速缓冲。
.3.1.2.数据字典缓冲区(Data Dictionary Cache)
数据字典缓存区是与数据字典相关的一段缓冲区。在数据字典高速缓冲区中存储了数据文件、表、索引、列、用户、权限信息和其它一些数据库对象的定义。在SQL语句的解析阶段,数据库服务器需要这些信息来解析用户名和用户的访问权限。如果Oracle缓存了这些信息,无疑提高了查询地相应时间。
.3.2.块缓冲区高速缓存(DatabaseBuffer Cache)
这些缓冲是对应所有数据文件中的一些被使用到的数据块。让他们能够在内存中进行操作。在这个级别里没有系统文件,,户数据文件,临时数据文件,回滚段文件之分。也就是任何文件的数据块都有可能被缓冲。数据库的任何修改都在该缓冲里完成,并由DBWR进程将修改后的数据写入磁盘。
这个缓冲区的块基本上在两个不同的列表中管理。一个是块的“脏”表(Dirty List),需要用数据库块的书写器(DBWR)来写入,另外一个是不脏的块的列表(Free List),一般的情况下,是使用最近最少使用 (Least RecentlyUsed,LRU)算法来管理。块缓冲区高速缓存又可以细分为以下三个部分(Default pool,Keeppool,Recycle pool)。如果不是人为设置初始化参数(Init.ora),Oracle将默认为Default pool。由于操作系统寻址能力的限制,不通过特殊设置,在32位的系统上,块缓冲区高速缓存最大可以达到1.7G,在64位系统上,块缓冲区高速缓存最大可以达到10G。
.3.3.重做日志缓冲区(Redo logbuffer)
重做日志文件的缓冲区,对数据库的任何修改都按顺序被记录在该缓冲,然后由LGWR进程将它写入磁盘。这些修改信息可能是DML语句,如(Insert,Update,Delete),或DDL语句,如(Create,Alter,Drop等)。 重做日志缓冲区的存在是因为内存到内存的操作比较内存到硬盘的速度快很多,所以重作日志缓冲区可以加快数据库的操作速度,但是考虑的数据库的一致性与可恢复性,数据在重做日志缓冲区中的滞留时间不会很长。所以重作日志缓冲区一般都很小,大于3M之后的重作日志缓冲区已经没有太大的实际意义。
.3.4.Java程序缓冲区(Java Pool)
Java的程序区,Oracle8I 以后,Oracle 在内核中加入了对Java的支持。该程序缓冲区就是为Java 程序保留的。如果不用Java程序没有必要改变该缓冲区的默认大小。它用于编译java语音编写的指令。
.3.5.大池(Large Pool)
大池是SGA的一段可选内存区,只在共享服务器环境中配置大池(large pool)。在共享服务器环境下,Oracle在共享池中分配额外的空间用于存储用户进程和服务器进程之间的会话信息,但是用户进程区域UGA(可理解为PGA在共享服务器中的另一个称呼)的大部分将在大池中分配,这样就减轻了共享池的负担。在大规模输入、输出及备份过程中也需要大池作为缓存空间。
.3.6.流池(Streaming pool)
流池也称为流内存,它是为oracle流专用的内存池,流(stream)是oracle数据库中的一个数据共享,其大小可以通过参数stream_pool_size,动态调整。
.3.7.闪回缓冲(flashback buffer)
闪回缓冲可用于恢复错误的DML操作,闪回查询功能。
.3.8.排序池(sort extent pool)
用于记录临时段中区间(临时表空间)的使用情况,临时表空间不存放永久数据,不需要备份恢复。典型用途是用于磁盘排序操作。引发排序的操作主要有CREATE INDEX、ANALYZE、DISTINCT、ORDER BY、GROUPBY、UNION、INTERSECT、MINUS、Sort-Merge Join等。
临时表空间原理:执行排序操作时,oracle优先在内存中完成。如果内存中无法容纳,则oracle将使用临时表空间做为临时空间进行排序。使用临时表空间的排序在oracle中被称为磁盘排序(Sort Disk),磁盘排序的性能远远低于内存排序(Sort Memory)。如果一个数据库系统的磁盘排序过多,则需要考虑优化SQL。
注:内存使用在oracle 9i之前受sort_area_size参数影响,从9i开始受pga_aggregate_target参数影响。数据库的排序信息可以通过动态性能视图v$sysstat查询得到:
selectname, value from v$sysstat where name like ‘sort%’
排序使用临时表空间的方式和永久表空间不同,当第一个使用临时表空间的排序操作开始后,临时段被创建,区间(Extent)被分配到这个临时段中供排序操作使用。当排序完成后,这个临时段不会被删除,oracle会将这个临时段中的区间标记为Free,其他排序操作可以继续使用这个临时段。临时段在数据库中是一次分配,循环使用。
在SGA中存在一块内存区域用于记录临时段中区间的使用情况,成为排序池---SortExtent Pool(SEP)。SEP的访问通过SEP Latch控制。通过v$Latch视图查看Latch的分配和使用情况:
selectaddr, latch#, name, gets, misses, sleeps from v$latch where latch#=138
SEP的信息还可以通过视图 v$temp_extent_pool查询:
selecttablespace_name, extents_cached, extents_used, blocks_cached, blocks_used,bytes_cached, bytes_used fromv$temp_extent_pool
.4.后台进程(Background process)
后台进程是Oracle的程序,用来管理数据库的读写,恢复和监视等工作。Server Process主要是通过他和user process进行联系和沟通,并由他和user process进行数据的交换。在Unix机器上,Oracle后台进程相对于操作系统进程,也就是说,一个Oracle后台进程将启动一个操作系统进程;在Windows机器上, Oracle后台进程相对于操作系统线程,打开任务管理器,我们只能看到一个Oracle.EXE的进程,但是通过另外的工具,就可以看到包含在这里进程中的线程。例如:ps -ef | grep ora_ ps –ef |grep ora_ | grep XCLUAT
.4.1.SMON(系统监护进程)
系统监控进程的主要作用就是数据库实例恢复。当数据库发生故障时,如操作系统重启,此时实例SGA中的所有没有写到磁盘的信息都将丢失。当数据库重新启动后,系统监控进程自动恢复实例。实例恢复包括如下三个步骤。
前滚所有没有写入数据文件而记录在重做日志文件中的数据。此时,系统监控进程读取重做日志文件,把用户更改的数据重新写入数据块。
打开数据库,此时或许系统监控进程的前滚操作还没有完成,Oracle这样做的目的就是方便用户及时登录,以免前滚时间太长,影响用户的行为,这样用户就可以操作那些没有被事务恢复琐住的数据。
回滚未提交的事物。除此之外,系统监控进程执行某些空间维护的作用。combine,coalesces,adjacent 数据文件中的自由空间。回收数据文件中的临时段。
.4.2.PMON(进程监控)
进程监控负责服务器进程的管理和维护工作,在进程失败或连接异常发生时该进程负责一些清理工作。回滚没有提交的事务。释放所持有的当前的表或行琐。
释放进程占用的SGA资源。监视其它Oracle的后台进程,在必要时重启这些后台进程。向OracleTNS监听器注册刚启动的实例。如果监听器在运行,就与这个监听器通信并传递如服务名和实例的负载等参数,如果监听器没有启动,进程监控(PMON)会定期地尝试连接监听器来注册实例。
.4.3.DBWR(数据文件写入进程)
脏数据的概念,脏数据就是用户更改了的但没有提交的数据库中的数据,因为在数据库的数据文件与数据库高速缓存中的数据不一致,说称为脏数据,这种脏数据必须在特定的条件下写到数据文件中,这就是数据库写进程的作用。
数据库写进程负责把数据库高速缓冲区中的脏数据写到数据文件中。或许读者会问,为什么不立即提交脏数据呢,这样就不需要复杂的数据库写进程来管理。其实,Oracle这样设计的思路很简单,就是减少I/O次数,但脏数据量达到一定程度或者某种其它条件满足时,就提交一次脏数据。因为磁盘的输入、输出会花费系统时间,使得Oracle系统的效率不高。
当以下事件发生时,会触发数据库写进程把脏数据写到数据库的数据文件中。
1.发生检查点事件。
2.脏数据量达到了门限值。
3.数据库缓冲区没有足够的缓存为其它事务提供足够的空间。
4.表空间处于热备份状态。
5.表空间被置为离线状态。
6.表空间被置为只读状态。
7.删除表或者截断表。
8.超时。
.4.4.LGWR(日志文件写入进程)
将重做日志缓冲区的数据写入重做日志文件,LGWR是一个必须和前台用户进程通信的进程。当数据被修改的时候,系统会产生一个重做日志并记录在重做日志缓冲区内。提交的时候,LGWR必须将被修改的数据的重做日志缓冲区内数据写入日志数据文件,然后再通知前台进程提交成功,并由前台进程通知用户。
.4.5.ARCH(归档日志进程)
归档日志进程是可选进程,该进程并不再实例启动是自动启动。它的作用是把写满的重做日志文件的数据写到一个归档日志中,这个归档日志用作介质故障时的数据库恢复。
.4.6.CKPT(checkpoint process)
首先介绍检验点,检验点是一个事件,当数据库写进程把SGA中所有被修改了的数据库高速缓冲中的数据写到数据文件上时产生,这些被修改的数据包括提交的和未提交的数据。由于引入了校验点,使得所有的校验点的所有变化了的数据都写到数据文件中,在实例恢复时,就不必恢复校验点之前的重做日志中的数据,加快了系统恢复的效率。
校验点进程并不是用于建立校验点,只是在校验点发生时,会触发这个进程进行一系列工作。这些工作包括如下几点:
校验点进程要将校验点号码写入相关的数据文件的文件头中。
校验点进程把校验点号码、SCN(System Change Number)系统改变号、重做日志序列号、归档日志名字等都写入控制文件。
.5.会话进程
会话指一个明确的数据库。用户和数据库服务器建立连接的方式。
.5.1.服务器进程(Server Process)
专用服务进程(Dedicated Server Process)
一个服务进程对应一个用户进程
共享服务进程(MultiTreaded Server Process)
一个服务进程对应多个用户进程,轮流为用户进程服务
.5.2.用户进程(User Process)
在客户端,将用户的SQL语句传递给服务进程。
.5.3.PGA(Process Global Area)进程全局区
PGA中存储了服务器进程或单独的后台进程的数据信息和控制信息。它随着服务器进程的创建而被分配内存,随着进程的终止而释放内存。PGA与SGA不同,它不是一个共享区域,而是服务器进程专有的区域。在专有服务器(与共享服务器相对的概念)配置中包括如下的组件:
排序区:对某些的SQL语句执行结果进行排序。
会话信息:包含本次会话的用户权限和性能统计信息。
游标状态:标明当前会话执行的SQL语句的处理阶段。
堆栈区:包含其它的会话变量。
.5.4.UGA(User Global Area)用户全局区
在共享服务器模式下有一个重要的概念即UGA(用户全局区),它就是用户的会话状态,这部分内存会话总可以访问,UGA存储在每个共享服务器都可以访问SGA中,这样任何服务器都可以使用用户会话的数据和其它信息。而在专有服务器模式下,用户会话状态不需要共享,用户进程与服务器进程是一一对应的关系,所以UGA总是在PGA中分配。
.6.Oracle 逻辑机构
.6.1.表空间(tablespace)
表空间是数据库中的基本逻辑结构,一系列数据文件的集合。一个表空间可以包含多个数据文件,但是一个数据文件只能属于一个表空间。
.6.1.1.系统表空间
主要存放数据字典和内部系统表基表
查看数据数据字典的SQL
select * from dict
查看内部系统表的SQL
select * from v$fixed_view_definition
DBA对系统的系统表中的数据字典必须有一个很深刻的了解,他们必须准备一些基础的SQL语句,通过这些SQL可以立即了解系统的状况和数据库的状态,这些基本的SQL包括
系统的剩余空间
系统的SGA
状态系统的等待
用户的权限
当前的用户锁
缓冲区的使用状况等
在成为DBA 的道路上我们不建议你过分的依赖于OEM/Quest 等优秀的数据库管理工具,因为他们不利于你对数据数据字典的理解,SQL语句可以完成几乎全部的数据库管理工作。
大量的读少量的写是该表空间的一个显著的特点。
.6.1.2.临时表空间
临时表空间顾名思义是用来存放临时数据的,例如排序操作的临时空间,他的空间会在下次系统启动的时候全部被释放。
.6.1.3.回滚段表空间
.6.1.3.1回滚段在系统中的作用
当数据库进行更新插入删除等操作的时候,新的数据被更新到原来的数据文件,而旧的数据(Before Image)就被放到回滚段中,如果数据需要回滚,那么可以从回滚段将数据再复制到数据文件中。来完成数据的回滚。在系统恢复的时候,回滚段可以用来回滚没有被commit 的数据,解决系统的一至性。
回滚段在什么情况下都是大量的写,一般是少量读,因此建议把回滚段单独出来放在一个单独的设备(如单独的磁盘或RAID),以减少磁盘的IO争用。
.6.1.3.2回滚段的工作方式
一个回滚表空间可以被划分成多个回滚段.
一个回滚段可以保存多个会话的数据.
回滚段是一个圆形的数据模型
假设回滚段由4 个区间组成,他们的使用顺序就是区间1à区间2à区间3à区间4à区间1。也就是说,区间是可以循环使用的,当区间4到区间1的时候,区间1里面的会话还没有结束, 区间4用完后就不能再用区间1,这时系统必须分配区间5,来继续为其他会话服务服务。
例:我们分析一个Update 语句的完成
①. 用户提交一个Update 语句
②. Server Process 检查内存缓冲.
如果没有该数据块的缓冲,则从磁盘读入
i. 如果没有内存的有效空间,DBWR被启动将未写入磁盘的脏缓冲写入磁盘
ii. 如果有有效空间,则读入
③. 在缓冲内更新数据
i. 申请一个回滚段入口,将旧数据写如回滚段
ii. 加锁并更新数据
iii. 并在同时将修改记录在Redo log buffer中
.6.2.段(Segment)
段是对象在数据库中占用的空间,虽然段和数据库对象是一一对应的,但段是从数据库存储的角度来看的。一个段只能属于一个表空间,当然一个表空间可以有多个段。
表空间和数据文件是物理存储上的一对多的关系,表空间和段是逻辑存储上的一对多的关系,段不直接和数据文件发生关系。一个段可以属于多个数据文件,关于段可以指定扩展到哪个数据文件上面。
段基本可以分为以下四种
数据段(Data Segment)
索引段(Index Segment)
回滚段(Rollback Segment)
临时段(Temporary Segment)
.6.3.区间(Extent)
在一个段中可以存在多个区间,区间是为数据一次性预留的一个较大的存储空间,直到那个区间被用满,数据库会继续申请一个新的预留存储空间,即新的区间,一直到段的最大区间数(Max Extent)或没有可用的磁盘空间可以申请。理论上一个段可以无穷个区间,但是多个区间对Oracle却是有性能影响的,Oracle建议把数据分布在尽量少的区间上,以减少Oracle的管理与磁头的移动。
.6.4.数据库(Block)
Oracle最基本的存储单位,他是OS数据块的整数倍。Oracle的操作都是以块为基本单位,一个区间可以包含多个块(如果区间大小不是块大小的整数倍,Oracle实际也扩展到块的整数倍)。