ORACLE事务中的数据变化是如何写入数据文件的: 1.事务开始; 2.在BUFFER CACHE中寻找需要的数据块,如果没有,则从数据文件读入数据块; 3.生成重做项写入REDO LOG BUFFER(重做日志缓冲区)中,修改BUFFER CACHE(数据库高速缓冲区),该区域被标识为“脏缓冲区”; 4.事务提交,LGWR进程将LOG BUFFER中的重做记录写入ONLINE REDO LOG FILE(联机重做日志文件)中; 5.当发生CHECKPOINT,CKPT进程更新所有数据库文件头的信息,DBWn进程将BUFFER CACHE中的脏数据写入DATA FILE中。
经过上述5个步骤,事务中的数据变化最终被写入到数据文件中。 但是,一旦在上述中间环节时,数据库意外宕机了,那么在重新启动时,ORACLE如 何知道哪些数据已经写入数据文件,哪些没有写呢? 我们知道,SCN机制能比较完善的解决上述问题。 相对我们人类用世纪、年月日、时分秒计时而言,SCN就相当于ORACLE的计时方法。 SCN是一个数字,确切的说是一个只会增加、不会减少的数字。正是它这种只会增加的特性确保了Oracle知道哪些应该被恢复、哪些应该被复制。 总共有4中SCN: 系统检查点(System Checkpoint)SCN、数据文件检查点(Datafile Checkpoint) SCN、结束SCN(Stop SCN)、开始SCN(Start SCN)。
系统最新SCN SQL> select current_scn from v$database;
该SCN一直在发生变化,是系统最新的SCN号。当checkpoin(检查点)完成后,ORACLE将System Checkpoint SCN号(系统检查点SCN)存放在控制文件中。
SQL> select checkpoint_change# from v$database;
该SCN没有发生变化,并且小于系统最新的SCN号。
Datafile Checkpoint SCN(数据文件检查点SCN)
当checkpoint完成后,ORACLE将Datafile Checkpoint SCN 号存放在控制文件中。 我们可以通过下面SQL语句查询所有数据文件的Datafile Checkpoinnt SCN号。 SQL> select name,checkpoint_change# from v$datafile;
Start SCN号(开始SCN) ORACLE将Start SCN号存放在数据文件头中。 这个SCN用于检查数据库启动过程是否需要做media recovery(介质恢复). 我们可以通过以下SQL语句查询: SQL> select name,checkpoint_change# from v$datafile_header;
Stop SCN号(结束SCN) ORACLE将Stop SCN 号存放在控制文件中。 这个SCN号用于检查数据库启动过程是否需要做instance recovery(实例恢复)。 我们可以通过以下SQL语句查询: SQL> select name,last_change# from v$datafile;
四种SCN中,3种SCN存在于控制文件中,Start SCN则存在于数据文件的文件头中。在控制文件中,System Checkpoint SCN是针对整个数据库全局的,因而只存在一个,而Datafile Checkpoint SCN和Stop SCN是针对每个数据文件的,因而一个数据文件就对应在控制文件中存在一份Datafile Checkpoint SCN和Stop SCN。
记录日志时,自动记录最新的SCN到日志中。因此,每一条日志都包含了一个时间。 当DBWn进程启动时,将依照日志记录写入一段数据。这一段日志记录的时间段必定有一个最早时间和一个最新(迟)时间。最早的时间我们称为LOW SCN(即上次清空日志后的第一条记录),最新时间我们称为NEXT SCN(即下次日志清空前的最近一条记录)。 这里, 由CKPT进程将 NEXT SCN的值同步更 新 到 START SCN、SYSTEM CHECKPOINT SCN 和DATAFILE CHECKPOINT SCN中。以确保所有文件的一致性。
SCN号与数据库启动 1)检查是否需要介质恢复 在数据库启动过程中,当System Checkpoint SCN、Datafile Checkpoint SCN和 Start SCN号都相同时,数据库可以正常启动,不需要做media recovery。三者当中有一个不同时,则需要做media recovery. 2)检查是否需要实例恢复 如果在启动的过程中,End SCN 号为NULL,则需要做instance recovery. ORACLE在启动过程中首先检查是否需要media recovery,然后再检查是否需要 instance recovery.
SCN号与数据库关闭 如果数据库的正常关闭的话,将会触发一个checkpoint,同时将数据文件的END SCN 号设置为相应数据文件的Start SCN号。 当数据库启动时,发现它们是一致的,则不需要做instance recovery。在数据库正常启动后,ORACLE会将END SCN 号设置为NULL. 如果数据库异常关闭的话,则END SCN号将为NULL.
为什么需要System SCN号与Datafile号 为什么ORACLE会在控制文件中记录System checkpoint SCN 号的同时,还需要为每个数据文件记录Datafile Checkpoint SCN 号? 1)对只读表空间,其数据文件的Datafile Checkpoint SCN、Start SCN和END SCN号均相同。这三个SCN在表空间处于只读期间都将被冻结。 2)如果控制文件不是当前的控制文件,则System checkpoint会小于Start SCN或END SCN号。记录这些SCN号,可以区分控制文件是否是当前的控制文件。
