数据库在运行过程当中,不可避免地要遇到各类可以致使数据库损坏的状况。好比忽然断电、Oracle或者操做系统的程序bug致使数据库内部逻辑结构损坏、磁盘介质损坏等,都有可能形成数据库崩溃,从而致使数据丢失的现象发生。数据库
为了不,或者说为了修复这些情况所致使的数据丢失现象,Oracle引入了日志缓冲区和日志文件的概念。所谓日志,就是将数据库中全部改变数据块的操做,都原本来本地记录下来。这些改变数据块的操做不只包括对数据表的DML命令或者引发数据字典内容变化的DDL命令,还包括对索引的改变、对回滚段数据块的改变等。只有将数据库中全部的变化都记录下来,当发生数据库损坏时,才可以经过从新应用这些变化,从而达到恢复数据库的目的。安全
既然是要记录,那就必然引出一个问题,就是如何记录这些变化?比较容易想到的有两种方式。oracle
第一种是使用逻辑的记录方式,也就是用描述性的语句来记录整个变化过程。好比对于某个update更新操做来讲来讲,能够记录为两条语句:delete 旧值以及insert 新值。这种方式的优势是很是节省空间,由于对每一个操做,只须要记录几条逻辑上的语句便可。可是缺点也很明显,就是一旦须要进行恢复,就会很是消耗资源。设想一下,某个update操做更新了很是多的数据块,因为buffer cache内存有限,不少脏数据块都已经写入了数据文件。但就在更新快结束时,忽然发生断电,所作的更新丢失。那么从新启动实例时,Oracle须要应用日志文件里的记录,因而从新发出delete旧值以及insert新值的语句。这个过程须要从新查找数据文件中符合条件的数据块,而后再挑出来进行更新。这个过程将很是消耗时间,并且会占用大量的buffer cache。ide
第二种方式是使用物理的记录方式,也就是将每一个数据块改变前的镜像和改变后的镜像都记录下来。这种方式优势就是恢复起来速度很是快,直接根据日志文件里所记录的数据块地址和内容更新数据文件中对应的数据块。可是缺点也很明显,就是很是占用磁盘空间。测试
而Oracle在记录日志的方式上,采用了逻辑和物理相结合的方式。也就是说,Oracle针对每一个数据块,记录了插入某个值或者删除某个值的描述语句。假如某个update更新了100个数据块,则Oracle会针对每一个数据块记录一对delete 旧值和insert 新值的语句,共有100对这样的描述语句。在每一对描述语句中,都记录了相关数据块的物理地址。经过这种逻辑与物理相结合的方式,Oracle在记录变化时可以尽可能节省空间,同时在应用变化时,又能比较快速。操作系统
为了临时存放所产生的日志信息,Oracle在SGA中开辟了一块内存区域。这块区域就叫作日志缓冲区(log buffer),当知足必定条件之后,Oracle会使用名为LGWR的后台进程将log buffer中的日志信息写入联机日志文件里。日志
可使用初始化参数log_buffer来设置日志缓冲区的大小,单位是字节。日志缓冲区会进一步细分为多个块,每一个块的尺寸与操做系统的一个块的尺寸相同,基本都是512字节。咱们能够用以下方式来得到日志缓冲区的块尺寸。视频
SQL> select distinct lebsz as redo_block_size from x$kccle;教程
REDO_BLOCK_SIZE索引
---------------
512
也能够用下面的方式来计算出日志缓冲区的块尺寸。
SQL> select round((a.redosize+b.redowast)/c.redoblks) + 16 as
redo_block_size from
2 (select value redosize from v$sysstat where name='redo
size') a,
3 (select value redowast from v$sysstat where name='redo
wastage') b,
4 (select value redoblks from v$sysstat where name='redo
blocks written') c;
REDO_BLOCK_SIZE
---------------
512
日志缓冲区只是日志信息临时存放的区域,这块区域是有限的,并且其中的每一个块都是可以循环使用的。这也就说明,日志缓冲区中的内容必需要写入磁盘的文件里,才能永久保留下来,才能在数据库崩溃时可以用来进行恢复。这个文件就叫作联机日志文件。在每一个日志缓冲区中的日志块被重用以前,其内容必然已经被写入了磁盘上的联机日志文件中。
联机日志文件就是日志缓冲区的彻底副本,组成日志文件的每一个日志块的内容都来自于日志缓冲区的日志块。每一个日志缓冲区中的日志块都对应到日志文件中的一个日志块。日志缓冲区中的日志块按照发生的前后顺序,放入联机日志文件。
因为日志文件在故障恢复中的重要性,建议至少使用两个日志文件组成一个日志文件组。同一个日志文件组中的日志文件内容如出一辙,由于日志缓冲区中的日志块同时会写入日志文件组中的每一个日志文件中。每一个数据库都必须至少拥有两个日志文件组。这是因为只要数据库一天不中止运行,就会不断产生日志信息,就会不断写入联机日志文件,联机日志文件总会有写满的时候。咱们不可能让联机日志文件无限大,也不可能放无限多的联机日志文件,因此联机日志文件必须是循环使用的,在若干个日志文件中轮流的进行写入。一个日志文件写满之后转换到另一个日志文件继续写的过程叫作日志切换(log switch)。
当一个联机日志文件写满时,能够选择将其归档为脱机日志文件,一般叫作归档日志文件。归档也就是副本,归档的过程也就是将写满的联机日志文件复制到预先指定的目录的过程。只有当一个联机日志文件完成归档之后,该联机日志文件才可以被再次循环使用。强烈建议在生产库中选择这种归档方式,只有在测试环境中能够选择不归档。
能够说,日志缓冲区和日志文件存在的惟一目的就是为了保证被修改的数据不会被丢失。反过来讲,也就是为了可以在数据库崩溃的时候,能够用来将数据库恢复到崩溃的那个时间点上。这也就是说,只有将被修改的数据块的日志信息写入了联机日志文件之后,该被修改的数据块才能够说是安全的。若是日志信息在没有被写入日志文件时发生实例崩溃,这时对数据的修改仍将丢失。由此咱们能够看出,将日志缓冲区中的日志信息写入日志文件是一个很是重要的过程,这个过程是由一个名为LGWR的后台进程完成的。LGWR 承担了维护系统数据完整性的任务,它保证了数据在任何状况下都不会丢失。
触发LGWR进程将日志缓冲区中的日志信息写入联机日志文件条件包括如下几种。
前台进程触发,包括两种状况。最显而易见的一种状况就是用户发出commit或rollback语句进行提交时,须要触发LGWR将内存里的日志信息写入联机日志文件,由于提交的数据必须被保护而不被丢失;另一种状况就是在日志缓冲区中找不到足够的内存来放日志信息时,也会触发LGWR进程将一些日志信息写入联机日志文件之后,从而释放一些空间。
每隔三秒钟,LGWR启动一次。
在DBWn启动时,若是发现脏数据块所对应的重作条目尚未写入联机日志文件,则DBWn触发LGWR进程并等待LRWR写完之后才会继续。
日志信息的数量达到整个日志缓冲区的1/3时,触发LGWR。
日志信息的数量达到1MB时,触发LGWR。
oracle视频教程请关注:http://down.51cto.com/4202939/up