本篇内容主要讲解“Oracle的体系结构和物理、逻辑存储结构介绍”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Oracle的体系结构和物理、逻辑存储结构介绍”吧!
1.Oracle体系结构
说到Oracle,Oracle是什么呢?接触过Mysql,SQL Server的人可能下意识就认为不就一个关系型数据库么?其实不然,太笼统的概念不能让我们清醒的看懂Oracle的结构,从严格意义上来讲Oracle由两部分组成:
实例是数据库启动时初始化的一组进程和内存结构,数据库则是指用户存储数据的一些文件。实例是伴随着数据库的启动而存在的,它的存在是为了高效访问和处理数据库中的文件,以及保证故障时数据零丢失。正是如此,才会有启动和关闭实例、加载卸载数据库这些术语。
如果上面那些让你对Oracle有了一点浅显的认知,那么请看下图:
如你所见,以中间空白的为线,上面粉嫩嫩的部分便是Oracle实例部分,下面的便是数据库部分,那接下来我们便逐个进行剖析。
2.Oracle物理存储结构
顾名思义,物理存储结构就是一些能看得见,实际存在的东西,大白话就是一群文件组成了Oracle的物理存储结构。如图
黄黄的部分代表着Oracle的核心组成,分别是数据文件、控制文件以及重做日志文件。除此之外,物理存储结构还包括着一些其他文件,例如参数文件、密码文件以及归档日志文件等等。下面将主要介绍这些文件。
数据文件(Data files)
数据文件是指存储数据库中数据的文件,这些“xxxx.dbf”存储着系统数据、数据字典数据、索引数据以及用户存储的数据,所以这部分也是数据库最核心的部分。数据文件大小是灵活的,可以通过设置让它自动扩展,避免了数据量过大但是数据文件空间有限这种状况;数据文件是专属于一个数据库的,也专属于一个表空间的,但是一个表空间却可以拥有多个数据文件。如果用户读取的数据不在缓冲区内,便会从数据文件中将相对应的数据放到缓冲区中,再进行读取。这部分内容会在之后详细分析。控制文件(Control files)
控制文件是一个很小的二进制文件,这些“xxx.CTL”中存放的数据库的”物理结构信息”,这些物理结构信息包括:数据库的名字、数据文件和联机日志文件的名字及位置.、创建数据库时的时间戳。数据库在启动的时候需要访问控制文件,从中读取数据文件、日志文件的信息;随着Oracle的运行,数据库将不断更新控制文件;相对应的一旦控制文件损坏,数据库便会发生运行故障。所以为了更好的保护数据库,我们可以镜像控制文件,特别是在数据库结构发生变化时,要对其进行备份,保持控制文件的一致性。重做日志文件(Redo Log files)
重做日志文件用于记录数据库所有修改信息 的文件,小名叫做日志文件,这些“.log”文件既可以保证数据库的安全,又可以实现数据库的备份和恢复。为了防止数据出现意外丢失,oracle也允许镜像日志文件,一个日志与其镜像出来的文件构成一个日志文件组,但是镜像文件数量不能超过5个。正所谓所有的鸡蛋不要放在一个篮子里,同一组的文件最好保存在不同的磁盘中,防止物理损坏造成不必要的麻烦。参数文件(Parameter file)
参数文件记录了Oracle数据库的基本参数信息,主要包括数据库名、控制文件所在路径等。参数文件包括文本参数文件(PFILE)和服务器参数文件(SPFILE),前者为init.ora,后者为spfile.ora或spfile.ora的二进制文件。在数据库启动的时候就会读取参数文件,然后根据参数文件中的参数来分配SGA并启动一系列的后台进程。归档日志文件(Archived Log files)
归档日志文件用来对写满的日志文件进行保存复制。其目的是为了长期保存日志以便于恢复。
3.Oracle逻辑存储结构
在oracle数据库中,对数据库操作会涉及逻辑存储结构,它是从逻辑角度分析数据库的构成,描述的是数据库内部数据的组织与管理方式,与操作系统没有关系。
如图,可以明显的看出数据库逻辑结构主要包括表空间、段、区和数据块,所有的结构都是一对多的关系,一个数据库可以拥有多个表空间,一个表空间拥有多个段等等。
表空间
表空间是Oracle最大的逻辑存储结构,与物理上的数据文件相对应,但是一个表空间可以拥有多个数据文件,这里就不一一赘述了。
段
段是一组盘区,它是一个独立的逻辑存储结构,用于存储具有独立存储结构对象的全部数据。段一般是数据库终端用户处理最小的存储单位,当段的数据区已满,Oracle为其分配另一个数据区,段的数据区在磁盘上可能是不连续的。根据段所存储的特征,可将其分为5种类型:数据段:用来存储表中所有数据;在Oracle中,每当用户创建一个表时,系统将自动在默认表空间里分配一个与表名称相同的数据段,方便存储该表的所有数据。
索引段:用来存储表中索引的所有数据;在Oracle中,每当用户创建索引时,系统将自动在默认表空间创建一个与索引名称相同的索引段,方便存储该索引的所有数据。
临时段: 用于存储表排序或汇总时产生的临时数据;每当用户:
临时表空间进行Order by 进行排列或汇总时,系统在该用户的临时表空间自动创建一个临时段,在操作结束时自动消除。
LOB段:LOB用来存储表中大型数据对象,例如CLOB与BLOB
回退段:用于存储用户数据被修改之前的位置和值;当与要对用户的数据进行回退操作时,就要使用回退段。
区
区是Oracle存储分配的最小单位,它是由一个或多个数据块组成的。一个或多个区组成一个段,也就是说段的大小都是由区的个数来决定。当一个段的空间使用完之后,Oracle会自动为该字段分配成一个新的区。块
块是用来管理存储空间的最基本的单位,也是最小的逻辑存储单位。块的大小由初始化参数db_block_size来决定,不同的Oracle版本的大小是不同的,但是数据库一旦创建,其大小便不可更改。虽然每个数据块可以存储不同类型的数据,但是每个数据块都具有一个相同的结构,如图:
1.块头
包含了该数据块一般的属性信息,如数据块的物理地址、所属段类型等
2.表目录
如果数据块中存储的数据时某个表的数据,则这里存放该表的信息
3.行目录
用来存储数据块中有效的行信息
4.空余空间
指数据块还没有使用的存储空间
5.行空间
表或者索引的数据存储在行空间中,所以行空间是数据块中已经使用的存储空间。
所以从描述就可以看出来,一个数据块的容量其实就是行空间与空余空间的容量总和。
4.Oracle实例内存结构与相对应的后台进程
如图所示,Oracle实例结构分为左右两部分,一个叫做SGA,称作系统全局区;一个叫做PGA,称作程序全局区。SGA是系统分配的一组共享的内存结构,用来实现对数据库数据的管理和操作;PGA是用户会话专有的内存区域,每个服务进程、后台进程都有一个PGA。其实从上图可以看出,实例和数据库本来是八竿子打不到一起的两个东西,但是正好中间出来一个媒婆:实例的后台进程,也就是图中示例部分椭圆形一块一块的那个将两者沟通到了一起。下面先对SGA进行分析描述,其中也会涉及到相对应的进程也将进行分析:
如图:
数据库缓冲区缓存(database buffer cache)
-database buffer cache又叫buffer cache,它用来存储从数据文件中读取到的数据块的镜像。在这块区域Oracle将进行执行sql的工作,所以当更新数据时,用户会话先会扫描缓冲区,不会去直接在磁盘上操作,这样就会减少磁盘的IO,从而大幅度提升系统的性能。
举个例子
select user_id,date from customer where user——id>10;
当oracle在执行这个SQL语句的时候,首先由对应的用户进程发送给服务器,监听收到请求后,便创建一个相对应的服务器进程,然后该进程便会先扫描缓冲区是否存在user_id>10 的数据块,如果存在,相关信息便会传到PGA中处理,最后显示给用户;如果没有命中,该进程便会将磁盘上对应的数据块复制到缓冲区中,再执行剩余的操作。
但是有些人会想,如果一直查缓存中不存在的数据块,那磁盘上的数据块不全都要复制到缓冲区了么,那不是更快?其实当你把数据块复制到缓冲区中,无形中增加了缓冲区的负荷,而缓冲区的存在意义便是提高系统的性能,所以便会用LRU这个算法管理着缓冲区内存空间,使其在维持在合理的区间内拥有最高的性能。
在执行一些DML语句的情况下,例如update一个XXX,缓冲区也是如上操作,先扫描缓冲区,缓存命中,便直接更新;缓存没命中,便把磁盘相对应的数据块复制到缓冲区进行更新。这时候问题就来了,更新完缓冲区数据,磁盘数据不是没变么?
这个时候就轮到关键人物出场了:DBWn。DBWn
DBWn又称数据库写进程,他负责的就是将更新完的缓冲区数据写入磁盘中。也就是数据库中的数据文件中。但是这个进程是公认的懒进程,它不是每当缓冲区写入数据的时候便会自动的将其写入磁盘中当下面这些情况发生时,这个懒进程将会执行写的任务:没有可以写入的缓存空间
脏缓存达到限制(会导致搜索时间过长)1/4满
最晚三秒钟:最晚三秒会执行一次写入
遇到检查点:遇到这个checkpoint便会执行写程序。
表空间热备份的时候
表空间离线、只读状态
执行Drop操作的时候
从以上这些时机更能明确的看出,DBWn不是随时随地的执行,并且跟commit操作没任何关系。其实这种懒进程更是能体现缓冲区存在的意义,减少磁盘IO对系统的压力,所以“懒”还是有“懒”的好处的。
如果在DBWn在未执行的时候,大量的脏数据还在缓冲区并没有写入磁盘的时候,突然天降横祸,打雷断电了,数据就丢了?这时候就要引出重做日志和其相对应的后台进程来解决这个问题。日志缓冲区(Redo log buffer)
当我们在执行一些DML操作时,产生的变更向量会写到重做日志文件中去,一旦上面提到的情况发生,例如打雷啊、断电啊使系统突然宕掉,database buffer cache中的脏数据还没等到DBWn将它写入磁盘的时候;当系统重新启动,这时候就会有一个实例恢复的过程,而重做日志中的那些变更向量便会发挥作用,使数据库保持与宕机前的一瞬间的数据一致;常用的一些备份恢复操作原理和这个一样:提取备份集—>应用重做日志文件中的变更记录。
日志文件用于记录对数据库的更改,所以为了减少磁盘IO,减少用户等待时间,数据库的修改操作信息要先写到日志缓冲区中,当日志缓冲区达到一定的限度时,会被日志写入进程LGWR写入磁盘中。相对database buffer cache来说,这个日志缓冲区对数据库的性能影响较小。LGWR
LGWR又称作日志写入器。 顾名思义,日志写入器就是将日志缓冲区的脏数据写进磁盘中,相对于DBWn这种“懒”进程,LGWR可是相对“勤快”的多commit写入
日志缓冲区占用率1/3
DBWn要写入脏缓冲区前
数据库缓冲区缓存和日志缓冲区都是为了提高性能,避免频繁IO而存在的。日志缓冲区相比数据库缓冲区缓存要小的多,并且不能进行自动管理,对于日志缓冲区的修改需要重启实例,数据库缓冲区缓存可进行自动管理。作用在数据库缓冲区缓存上的DBWn进程,为了避免频繁的磁盘IO导致系统性能下降,会尽可能少地执行写入,且DBWn的写入和commit操作没有任何关系;
而作用在日志缓冲区上的LGWR进程,则会非常积极地进行写入,一般情况下,它几乎是实时地将重做日志记录转储到磁盘中去。LGWR是Oracle体系结构中最大的瓶颈之一。DML的速度不可能超过LGWR将变更向量写入磁盘的速度。
共享池
共享池是最复杂的SGA结构,它有许多子结构,我们来看看常见的几个共享池组件:库缓存(library cache):Oracle引入库缓存的目的是共享SQL和PL/SQL代码。服务器进程执行SQL和PL/SQL时,首先会进入库缓存查找是否有相同的SQL,如果有,就不再进行后续的编译处理,直接使用已经编译的SQL和执行计划。Oracle通过比较两条SQL语句的正文来确定两条SQL是否相同,所以如果想共享SQL语句,必须使用绑定变量的方式。如:
select * from emp where sal > 100
和select * from emp where sal > 101
是不同的,而使用绑定变量时,即使v_sal的值不同,Oracle认为select * from emp where sal > &v_sal
也是相同的。Oracle使用LRU队列和算法来管理库缓存,最近使用过的SQL会放在队首,长时间没有使用的SQL放在队尾,当库缓存需要内存空间而又没有空闲的内存空间时,队尾内存中的SQL会被清除,放入最新的SQL,并且队首会指向次段内存。Oracle没有提供直接修改库缓存大小的方法,只能通过修改共享池的大小来间接修改库高速缓存的大小。数据字典缓存(dictionary cache):当Oracle执行SQL时,会将相关的数据文件、表、索引、列、用户、其他的数据对象的定义和权限信息存放到数据字典缓存中。在此之后,如果需要相同的相关数据,Oracle会从数据字典缓存中提取。Oracle没有提供直接修改 数据字典缓存大小的方法,只能通过修改共享池的大小来间接修改 数据字典缓存的大小。
那修改共享池的方法是什么?alter system set shared_pool_size= xxx m
;共享池的大小受限制于SGA_MAX_SIZE参数的大小。大池
大池是个可选的内存区域,可提供一个大的缓冲区供数据库的备份与恢复操作过程使用。需要大池的实际需要一般有以下三种:数据库的备份恢复
具有大量排序操作的SQL语句
并行化的数据库操作
JAVA池
JAVA池在数据库中支持JAVA 的运行,存放JAVA代码和JAVA语句的语法分析表;JAVA池的大小一般不小于20M,便于安装JAVA虚拟机。流池
从重做日志中提取变更记录的进程 和 应用变更记录的进程会用到流池(如实例不正常关闭,譬如断电导致实例关闭,在重启时,Oracle会自动执行实例恢复过程,在此过程需要提取重做日志记录和应用重做日志两个动作)
以上列举了Oracle常见的内存结构,要注意的是,上面列举的内存区域,除了日志缓冲区是固定的,不能动态调整也不能进行自动管理外,其他内存区域都可以进行动态调整,也可以进行自动管理。
5.Oracle程序全局区
PGA包含单个用户或者服务器数据和控制信息,是oracle分配给一个进程的私有内存区域,每当有用户进程连接到数据库并创建一个会话时,便会由Oracle自动分配相对应的空间。
在上面我们介绍了DBWn、LGWR这两个进程,下面将介绍其他的进程信息:
SMON
SMON(System Monitor)又称作系统监控进程,当数据库实例出现故障或者系统崩溃的时候,执行恢复操作。它还定期合并字典管理的表空间中的空闲空间;并且,在系统重启期间,他还可以清理表空间所有临时段。安装和打开数据库,也是由此进程完成的。SOMN会被有规律的唤醒执行,并在其他进程需要时也可以进行调用。PMON
PMON(process monitor)又称进程监视器。用户进程出现故障时执行的恢复操作,负责清理内存存储区和释放该进程所使用的资源;除此之外,PMON还会周期的检查调度进程和服务器进程的状态,对已死的进程进行重启。POMN会被有规律的唤醒执行,并在其他进程需要时也可以进行调用。CKPT
CKPT(checkpoint process)检查点进程。该进程负责发起检查点信号,让DBWn开始工作;并更新控制文件以及数据文件头。ARCn
ARCn(Archive)归档进程,主要负责将日志文件复制到归档日志文件中,来避免日志文件组的循环使用覆盖到已有的日志文件中。只有当数据库在ARCHIVELOG模式下,且自动归档开启的时候,系统便会启动ARCn进程;ARCn包括归档方式和非归档方式。只有在归档方式下,才会存在ARCn进程,当它进行归档操作时,任何进程都不能访问被操作的日志文件。
以上进程除了ARCn之外,全部都是系统必要的进程。对维持物理和内存之间的联系起了重大作用。
6.数据字典
数据字典是Oracle数据库重要的组成部分,由Oracle自动创建并更新,用来存储数据库实例信息的一组表,以表和视图的方式组织其拥有的信息。数据字典中的表是不能直接被访问的,但是可以访问数据字典中的视图。数据字典的拥有者是SYS用户,并存储在默认表空间SYSTEM表空间中。数据字典主要存储以下信息:
数据库中所有模式对象的信息,如表、视图、簇、及索引等。
存储空间的分配信息,分配多少空间,当前使用了多少空间等。
安全信息
实例运行时的性能和统计信息
其他数据库本身的基本信息
Oracle中的数据字典有静态和动态之分;静态数据字典,在用户访问数据字典时不会发生改变,zhelei动态数据字典是依赖数据库运行的性能的,反映数据库运行的一些内在信息,所以在访问这类数据字典时往往不是一成不变的。
静态数据字典中的视图分为三类,它们分别由三个前缀够成:user_*、 all_*、 dba_*。
user视图
user视图的名称以user_为前缀,用来记录用户对象的信息。user视图可以看作是all视图的自己,每个用户都可以查询user视图。使用DESC 可以了解视图结构。all视图
all视图的名称以all_为前缀,用来记录用户对象的信息以及可以访问的所有对象信息,包括该用户自己的方案对象,也包括被授权可以访问其他用户的方案对象。all视图是user视图的扩展。dba视图
dba视图以dba_为前缀,用来记录数据库实例所有对象的信息。一般只有dba角色可以访问dba视图,如果普通用户被授予 Select any dictionary 系统权限的用也可以对此进行访问。
动态性能视图都是以V$开头的视图,V$视图以V$为前缀,用来记录与数据库活动相关的性能统计动态信息。例如V$session视图,可以查看当前会话的详细信息。
7.数据库启动和关闭流程
Oracle启动分3个过程nomount、mount和open,这三个过程具体执行的工作如下:
- nomount状态:启动实例。
首先从环境变量下dbs目录按如下顺序读取参数文件,但是会考虑参数文件重要性,便会通过以下过程进行读取:
首先,读取spfile+实例名.ora这个文件;若未发现这个文件则读取spfile.ora;若未发现这个文件则读取init+实例名.ora这个文件;如果以上文件都没找到,也可以指定pfile参数文件启动以替代默认启动方式。
读取完参数文件之后,便开始分配SGA,启动后台进程,启动预警日志文件(记录实例生命周期内事件,如系统内部错误、数据块损坏、系统参数修改等)和追踪文件(记录SQL操作及时间消耗等。要注意的是,数据库必须用初始参数文件或启动命令中的DB_NAME参数命名。
- mount状态:关联实例与数据库,读取控制文件并获取数据文件和重做日志文件名称状态。
启动完实例之后,便要将实例与数据库相关联,在读取参数文件时,找到控制文件位置并将其打开,从中读取到数据文件以及重做日志文件名称与状态,但是这里不检查数据文件与重做日志文件的存在性。在mount状态下,系统完成了了数据库的装载。
open状态:打开数据库
打开数据库过程承接了mount状态,从控制文件读取到了数据文件、重做日志文件的位置,这里将其打开;如果其中任何一个文件丢失的话,则Oracle会返回一个error,在最后阶段,Oracle数据库验证数据文件和重做日志文件可否打开并检验数据库的一致性,若不一致,SMON后台进程将启动实例恢复。
shutdown有四个参数:normal、transactional、immediate、abort,不带参数默认为normal。
shutdown normal:不断开现在连接用户,阻止任何用户建立新的连接,包括管理员在内。已经连接的用户能够继续他们当前的工作,如递交新的更新事务,直到此用户自行断开连接。这样需要等待的时间长,可以查出现连用户,再通知其自行断开。所有的用户都断开连接,数据库才进行关闭操作,即关闭数据库、卸载数据库、终止例程。在这种情况下关闭的数据库在重新启动后,不会出现问题。启动时不需要实例恢复。
shutdown transactional:阻止任何用户建立新连接,等待所有当前连接用户的未递交的活动事务提交完毕,然后立即断开用户的连接。所有的用户都断开连接则立即关闭数据库,进行关闭数据库、卸载数据库、终止进程等操作。这种方式,用户有可能正在算账,做复杂报表!一次数据库操作做不完的,在刚做了一次数据库操作后,将被断开,这样对用户有一定影响,启动时不需要实例恢复。
shutdown immediate:阻止任何用户新的连接,同时限制当前连接用户开始新的事务。如果已连接用户有未完成的事务,则数据库系统不会等待他们完成,而是直接把当前未递交的事务回退。数据库系统不再等待用户主动断开连接,当未递交的事务回退成功后,系统会直接关闭、卸载数据库,并终止数据库进程,启动时不需要实例恢复。
shutdown abort:当数据库出现故障时,可能以上三种方式都无法正常关闭数据库,则使用这种方法。强制结束当前正在执行的SQL语句,任何未递交的事务都不被回退!这种方法基本上不会对控制文件或者参数文件造成破坏,这比强制关机要好一点(在无法正常关闭数据库的时候),启动时自动进行实例恢复。
startup有7个参数:nomount、mount、open、pfile、force、restrict和 recover
startup nomount:通过参数文件,分配sga,启动数据库后台进程,不打开控制文件和数据文件,不能访问数据库。通常启动到这里可以做create database , create or recreate control file 或者是mount standby database等动作,修改parameter也是可以的。
startup mount:仅给dba进行管理操作,不允许数据库用户访问。仅当前实例的控制文件被打开,数据文件未打开,在这个模式下可以进行如下操作:重命名数据文件、添加取消或重命名重做日志文件、设置归档模式、设置闪回、执行完整的数据库恢复操作等。
startup open:startup的默认参数就是open,打开数据库,允许数据库的访问,当前实例控制文件中所描述的所有文件都已经打开。
startup pfile=FILENAME:以FILENAME为初始化文件启动数据库,不是采用默认初始化文件。
startup force:中止当前数据库的运行,并开始重新正常的启动数据库。
startup restrict:只允许具有restricted session权限的用户访问数据库,该模式下登陆者可做如下操作:执行数据库数据的导出或导入、执行数据装载操作用SQL*Loader、暂时阻止一般的用户使用数据、在某个移植过程和升级操作过程中restricted session登陆后可使用ALTER SYSTEM 语句来禁止RESTRICTED SESSION特性
ALTER SYSTEM DISABLE RESTRICTED SESSION
;如果是在非受限模式下打开的数据库,后来发现需要限制访问,此时可以使用带ENABLE RESTRICTED SESSION 子句的ALTER SYSTEM 语句来完成。startup recover:数据库启动,并开始介质恢复。
附录:常用的数据字典
静态视图
数据字典名称 | 说明 |
---|---|
dba_tablespaces | 关于表空间的信息 |
dba_ts_quotas | 所有用户表空间限额 |
dba_free_space | 所有表空间中的自由分区 |
dba_segments | 描述数据库中所有段的存储空间 |
dba_extents | 数据库中所有分区的信息 |
dba_tables | 数据库中所有数据表的描述 |
dba_tab_columns | 所有表、视图以及簇的列 |
dba_views | 数据库中所有视图的信息 |
dba_synonyms | 关于同义词的信息 |
dba_sequences | 所有用户序列信息 |
dba_constraints | 所有用户表的约束信息 |
dba_indexs | 数据表中所有索引的描述 |
dba_ind_columns | 所有表及簇上压缩索引的列 |
dba_triggers | 所有用户的触发器信息 |
dba_source | 所有用户存储过程信息 |
dba_data_files | 查询关于数据库文件的信息 |
dba_tab_grants/privs | 查询关于对象授权的信息 |
dba_objects | 数据库所有对象 |
dba_users | 关于数据库中所有用户的信息 |
动态视图
数据字典名称 | 说明 |
---|---|
v$database | 描述关于数据库的相关信息 |
v$datafile | 数据库使用的数据文件信息 |
v$log | 从控制文件中提取有关重做日志组的信息 |
v$logfile | 有关实例重置日志组文件名及其位置的信息 |
v$archived_log | 记录归档日志文件的基本信息 |
v$archived_dest | 记录归档日志文件的路径信息 |
v$controlfile | 描述控制文件的相关信息 |
v$instance | 记录实例的基本信息 |
v$system_parameter | 显示实例当前有效的参数信息 |
v$sga | 显示实例的SGA区大小 |
v$sgastat | 统计SGA使用情况的信息 |
v$parameter | 记录初始化参数文件中所有项的值 |
v$lock | 通过访问数据库会话,设置对象锁的所有信息 |
v$session | 有个会话的信息 |
v$sql | 记录SQL语句的详细信息 |
v$sqltext | 记录SQL语句的语句信息 |
v$bgprocess | 显示后台进程信息 |
v$process | 当前进程的信息 |
到此,相信大家对“Oracle的体系结构和物理、逻辑存储结构介绍”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!