Oracle数据库物理结构
oracle的数据,实际上是以文件的形式来保存的,文件中出了保存用户的数据之外,还需要保存管理数据和日志数据等等。作为一个DBA,必须需要知道自己的数据分别保存在什么位置上,而且经验丰富的管理员还应该在设计数据库的时候合理的规划文件的保存位置、初始大小以及增量属性等,这样既能满足用户应用程序的需要,还能保证数据库高效的运行。
每个Oracle数据都三种类型的文件组成,即控制文件、数据文件以及日志文件。这些文件提供了真正的数据存储的物理存储。
1、控制文件
每一个Oracle数据库都有一个控制文件,用来保存数据库的物理结构信息。控制文件包含数据库名、数据库数据文件和日志文件的名字、位置和数据库建立日期等信息。
数据库的控制文件用于标识数据库和日志文件,当开始数据库操作时,它们必须被打开。当数据库的组成更改的时候,Oracle自动更新该数据库的控制文件。数据恢复的时候,也需要用到控制文件。
当数据库打开的时候,Oracle数据库必须写控制文件。没有控制文件,数据库将没有办法装在,恢复数据库的时候也非常的困难。
2、数据文件
进行数据操作的时候,系统将从数据文件中读取数据,并且存储到Oracle的内存缓冲区中。新建或者更新的数据不必立即写入到数据文件中,而是把数据临时放到内存中,由数据库写入进程(DBWn)决定在适当的时间一次性写入到数据文件中。这样可以大大降低访问磁盘的次数,从而加强系统的性能。
3、日志文件
每个数据库都有两个或者多个日志文件组,用于收集数据库日志。日志的主要功能就是记录对数据所作的修改,所有对数据库进行的修改都记录在日志中。在出现故障的时候,如果不能将修改数据永久的写入数据文件,则可以通过日志得到修改后的记录,从而保证已经发生的操作结果不会丢失。
日志文件的主要作用是防止数据库在出现故障的时候丢失数据。为了防止日志文件本身的故障,Oracle允许使用镜像日志,在不同的磁盘上维护两个以上的日志副本。
重做日志管理
重做日志(Redo Log)由两个以上的文件组成,用于保护数据库的所有变化信息.每个Oracle数据库实例都有一个相关的重做日志,从而保证数据库的安全.
重做日志由重做记录组成,而每个重做记录由一组变化元素组成,变化元素中记录了数据库中每个单独的数据块的变化情况,例如:当用户修改了表中的某一条数据的时候,系统将会自动的生成一条重做记录。
可以使用重做日志来恢复数据库的变化,保护回滚数据。当使用重做数据恢复数据库的时候,数据库将从重做日志中读取变化元素,然后将变化应用到相关的数据块当中。
数据库中至少包含两个重做日志,一个始终保持可写的状态,用于记录数据库的变化,另外一个用于归档操作(当系统的achievelog模式打开的时候)。
那么Oracle是怎么记录重做日志的呢?日志写入进程LGWR负责记录重做日志。如果重做日志文件已经被填充满了,那么LGWR将变化数据写入下一个重做日志文件;如果最后一个有效的重做日志被填满了,那么LGWR将变化数据写入第一个重做日志。
为了防止重做日志本身被破坏,Oracle提供了一种多元重做日志,也就是说,系统在不同的位置上自动维护日志的两个或者多个副本。从安全的角度出发,这些副本的保存位置应该在不同的磁盘上。
多元性是通过创建重做日志组来实现的,组包括一个重做日志文件和它的多元副本。每个重做日志组由数字来定义,例如组1,组2等等。每个日志文件必须处于激活状态,这样LGWR就可以同时写入这两个日志文件LGWR不会同时写入不同组的日志文件。
在不同的情况下,当重做日志无效的时候,LGWR锁采用的动作如下:
1)LGWR可以写入组中的至少一个成员文件:正常完成写操作。LGWR写入组中的可访问的成员文件,忽略不可访问的成员文件。
2)在日志切换的时候,LGWR无法访问下一个组,因为该组需要被归档:临时停止数据库操作,等待该组可以被访问或者该组已经被归档。
3)在日志切换的时候,由于介质被损坏,下一组的所有成员都无法被访问:ORACLE数据库返回错误,数据库实例被关闭。此时需要从有效的重做日志中执行介质恢复操作(数据库恢复操作)。如果数据库的检查点已经超出了丢失的重做日志,则不需要进行介质恢复了,因为重做日志中记录的数据写入到数据文件中。现在只需要删除无效的重做日志组。如果数据库还没有对失效的日志进行归档操作,则执行ALTER DATABASE CLEAR UNARCHIVED LOG禁止归档操作,这样就可以删除日志文件了。
4)当LGWR写入的时候,所有的组中的成员文件忽然无法访问:Oracle返回错误,数据库实例被关闭。此时,需要从有效的重做日志文件中执行介质恢复操作。如果介质没有被破坏,只是不小心掉线了,则不需要进行介质恢复,只要将介质恢复在线,然后让数据库执行自动实例恢复就可以了。
可以通过如下参数来设置重做日志的数量:
MAXLOGFILES:在CREATE DATABASE语句中使用MAXLOGFILES参数可以指定每个数据库中重做日志文件组的最大数量。
MAXLOGMEMBERS:在CREATE DATABASE语句中使用MAXLOGMEMBERS参数可以指定每个日志文件组中包含的日志文件的最大数量。
归档日志文件和归档模式
归档日志文件是重做日志文件组成员的备份,它由重做项目和唯一的日志序列号组成。当数据库处于归档模式的时候,写日志进程(LGWR)不能够对未归档的重做日志组进行重用和改写操作。如果设置了自动归档模式,则后台进行ARCn将自动的执行归档操作。数据库会启动多个进程归档,确保一旦日志文件被填满马上会被归档。
可以使用归档日志文件达到以下目的:
1)恢复数据库
2)更新备用数据库
3)使用LogMiner获取数据库的历史信息
用户可以选择自动归档或者手动归档,但是自动归档模式更加的方便和快捷。LGWR进程向在线重做日志文件写入日志信息,一旦重做日志被写满,则由ARC0进程进行归档操作。
SCN
SCN是System Change Number的缩写,它是数据库的重要机制,可以用来记录和标识执行数据库操作的先后顺序。在执行回滚事务、备份以及恢复数据库等操作的时候,数据库操作的先后顺序是非常重要的。
SCN是一个只能增大的整数,系统可以保证这个整数是不会越界的。当用户修改数据库中的数据(增加,修改,删除)时,Oracle数据库并不是立即将其保存到数据文件中,而是将数据保存在缓冲区(buffer cache)中,当提交事务的时候,才会将数据写进数据文件。
下面是修改数据的简单过程:
1)开始一个事务,事务是包含一组数据库操作的逻辑工作单元。
2)在缓冲区中寻找要修改的数据,如果没有找到,那么就从数据文件中找到这个数据,并且将其加载到数据缓冲区中。
3)修改缓冲区中的数据块,并将修改的结果保存到日志缓冲区中。因为此时缓冲区中的数据与数据文件中的数据不一致,因此将这种数据称之为“脏数据”
4)当用户提交数据的时候,LGWR进程会将缓冲区中的数据和新生成的SCN写入到重做日志文件中,。但是为了减少I/O操作,Oracle不会立即将脏数据写入到数据文件当中。
5)如果发生检查点(CheckPoint,检查点是一个事件,当这个事件发生的时候,DBWn进程将把SGA中所有改变的数据库缓冲区写入到数据文件中)。则CKPT进程唤醒DBWn进程,更新数据库中的所有的数据文件和控制文件,并且标记最新的检查点,从而下一次更新从最新的检查点开始。
通常在执行SHUTDOWN NORMAL和SHUTDOWN IMMEDIATE语句的时候,会触发Checkpoint事件,当发生Checkpoint事件的时候,Oracle会将SCN写入到下面的四个地方:
1)系统检查点SCN(SYSTEM CHECKPOINT SCN)
当一个CheckPoint动作完成之后,Oracle会将系统检查点的SCN保存到控制文件中,可以从视图V$DATABASE中查看到系统检查点SCN的值,代码如下:
SELECT CHECKPOINT_CHANGE# FROM V$DATABASE;
2)数据文件检查点SCN(DATAFILE CHECKPOINT SCN)
当一个CheckPoint动作完成之后,Oracle会将每个数据文件的SCN保存到控制文件中。可以从系统视图V$DATAFILE中看到数据文件检查点SCN的值,代码如下:
SELECT NAME,CHECKPOINT_CHANGE# FROM V$DATAFILE;
3)启动SCN(START SCN)
Oracle把每个数据文件的检查点SCN存储在每个数据文件的文件头中,称为启动SCN。因为在数据库实例启动的时候,Oracle会检查每个数据库文件的启动SCN与控制文件检查点SCN是否一致,如果不一致的话,则从重做日志文件中找到丢失的SCN,重新写入数据文件中进行恢复。可以从系统视图V$DATAFILE_HEADER中查看到启动SCN的值,代码如下:
SELECT NAME,CHECKPOINT_CHANGE# FROM V$DATAFILE_HEADER;
4)结束SCN(STOP SCN)
每个数据文件的结束SCN都保存在控制文件中。正常情况下,所有处于联机状态读写模式下的数据文件的SCN都为NULL。可以从系统视图V$DATAFILE中查看到结束SCN的值,代码如下:
SELECT NAME,LAST_CHANGE# FROM V$DATAFILE;
数据库正常关闭(执行SHUTDOWN NORMAL和SHUTDOWN IMMEDIATE)的时候,会触发CHECKPOINT事件,将重做日志文件中的数据写入数据文件中,并且将上面的4中SCN都更新为最新的值。
当Oracle数据库正常启动并且运行的时候,控制文件检查点SCN,数据文件检查点SCN,每个数据文件中的启动SCN都是一致的,控制文件中的每个数据文件的结束SCN都是NULL。
在需要的时候,系统会自动根据时间戳自动生成新的SCN,可以从DUAL表中查看到当前系统生成的最新的SCN,代码如下:
SELECT DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER FROM DUAL;
转载:http://blog.csdn.net/ziwen00/article/details/8011138