共计 2937 个字符,预计需要花费 8 分钟才能阅读完成。
丸趣 TV 小编给大家分享一下 oracle 中 SCN 机制的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!
SCN(System Change Number)作为 oracle 中的一个重要机制,在数据恢复、Data Guard、Streams 复制、RAC 节点间的同步等各个功能中起着重要作用。理解 SCN 的运作机制,可以帮助你更加深入地了解上述功能。
在理解 SCN 之前,我们先看下 oracle 事务中的数据变化是如何写入数据文件的:
1、事务开始;
2、在 buffer cache 中找到需要的数据块,如果没有找到,则从数据文件中载入 buffer cache 中;
3、事务修改 buffer cache 的数据块,该数据被标识为“脏数据”,并被写入 log buffer 中;
4、事务提交,LGWR 进程将 log buffer 中的“脏数据”写入 redo log file 中;
5、当发生 checkpoint,CKPT 进程更新所有数据文件的文件头中的信息,DBWn 进程则负责将 Buffer Cache 中的脏数据写入到数据文件中。
经过上述 5 个步骤,事务中的数据变化最终被写入到数据文件中。但是,一旦在上述中间环节时,数据库意外宕机了,在重新启动时如何知道哪些数据已经写入数据文件、哪些没有写呢(同样,在 DG、streams 中也存在类似疑问:redo log 中哪些是上一次同步已经复制过的数据、哪些没有)?SCN 机制就能比较完善的解决上述问题。
SCN 是一个数字,确切的说是一个只会增加、不会减少的数字。正是它这种只会增加的特性确保了 Oracle 知道哪些应该被恢复、哪些应该被复制。
总共有 4 中 SCN:系统检查点(System Checkpoint)SCN、数据文件检查点(Datafile Checkpoint)SCN、结束 SCN(Stop SCN)、开始 SCN(Start SCN)。其中其面 3 中 SCN 存在于控制文件中,最后一种则存在于数据文件的文件头中。
在控制文件中,System Checkpoint SCN 是针对整个数据库全局的,因而之存在一个,而 Datafile Checkpoint SCN 和 Stop SCN 是针对每个数据文件的,因而一个数据文件就对应在控制文件中存在一份 Datafile Checkpoint SCN 和 Stop SCN。在数据库正常运行期间,Stop SCN(通过视图 v$datafile 的字段 last_change# 可以查询) 是一个无穷大的数字或者说是 NULL。
在一个事务提交后(上述第四个步骤),会在 redo log 中存在一条 redo 记录,同时,系统为其提供一个最新的 SCN(通过函数 dbms_flashback.get_system_change_number 可以知道当前的最新 SCN),记录在该条记录中。如果该条记录是在 redo log 被清空(日志满做切换时或发生 checkpoint 时,所有变化日志已经被写入数据文件中),则其 SCN 被记录为 redo log 的 low SCN。以后在日志再次被清空前写入的 redo 记录中 SCN 则成为 Next SCN。
当日志切换或发生 checkpoint(上述第五个步骤)时,从 Low SCN 到 Next SCN 之间的所有 redo 记录的数据就被 DBWn 进程写入数据文件中,而 CKPT 进程则将所有数据文件(无论 redo log 中的数据是否影响到该数据文件)的文件头上记录的 Start SCN(通过视图 v$datafile_header 的字段 checkpoint_change# 可以查询) 更新为 Next SCN,同时将控制文件中的 System Checkpoint SCN(通过视图 v$database 的字段 checkpoint_change# 可以查询)、每个数据文件对应的 Datafile Checkpoint(通过视图 v$datafile 的字段 checkpoint_change# 可以查询)也更新为 Next SCN。但是,如果该数据文件所在的表空间被设置为 read-only 时,数据文件的 Start SCN 和控制文件中 Datafile Checkpoint SCN 都不会被更新。
那系统是如何产生一个最新的 SCN 的?实际上,这个数字是由当时的 timestamp 转换过来的。每当需要产生一个最新的 SCN 到 redo 记录时,系统获取当时的 timestamp,将其转换为数字作为 SCN。我们可以通过函数 SCN_TO_TIMESTAMP(10g 以后)将其转换回 timestamp:
SQL select dbms_flashback.get_system_change_number, SCN_TO_TIMESTAMP(dbms_flashback.get_system_change_number) from dual;
GET_SYSTEM_CHANGE_NUMBER
------------------------
SCN_TO_TIMESTAMP(DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER)
---------------------------------------------------------------------------
2877076756
17-AUG-07 02.15.26.000000000 PM
也可以用函数 timestamp_to_scn 将一个 timestamp 转换为 SCN:
SQL select timestamp_to_scn(SYSTIMESTAMP) as scn from dual;
SCN
----------
2877078439
最后,SCN 除了作为反映事务数据变化并保持同步外,它还起到系统的“心跳”作用——每隔 3 秒左右系统会刷新一次系统 SCN。
下面,在简单介绍一下 SCN 如何在数据库恢复中起作用。
数据库在正常关闭(shutdown immediate/normal)时,会先做一次 checkpoint,将 log file 中的数据写入数据文件中,将控制文件、数据文件中的 SCN(包括控制文件中的 Stop SCN)都更新为最新的 SCN。
数据库异常 / 意外关闭不会或者只更新部分 Stop SCN。
当数据库启动时,Oracle 先检查控制文件中的每个 Datafile Checkpoint SCN 和数据文件中的 Start SCN 是否相同,再检查每个 Datafile Checkpoint SCN 和 Stop SCN 是否相同。如果发现有不同,就从 Redo Log 中找到丢失的 SCN,重新写入数据文件中进行恢复。具体的数据恢复过程这里就不再赘述。
SCN 作为 Oracle 中的一个重要机制,在多个重要功能中起着“控制器”的作用。了解 SCN 的产生和实现方式,帮助 DBA 理解和处理恢复、DG、Streams 复制的问题。
最后提一句,利用 SCN 机制,在 Oracle10g、11g 中又增加了一些很实用的功能——数据库闪回、数据库负载重现等。
以上是“oracle 中 SCN 机制的示例分析”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注丸趣 TV 行业资讯频道!