控制文件与数据库初始化 控制文件与数据库初始化
在上一章中我们探讨了数据库的启动和关闭过程,在这一过程中,Oracle 的控制文件起着
极其重要的作用,我习惯打的一个比喻是:控制文件是数据库的大脑,而 SYSTEM 表空间
是数据库的心脏。在这一章里,我们将继续对控制文件以及数据库的初始化过程进行进一步
的探讨。
2.1 控制文件的内容
既然控制文件在数据库中扮演着重要的角色,那么控制文件中到底存储了哪些重要信息,
在数据库运行过程中又是如何发挥重要作用的呢?
首先从文档上得知控制文件中保存着下列信息:
• 数据库名称以及数据库创建时间等
• 所有数据文件和重做日志文件的名称和位置信息
• 表空间信息
• OFFLINE 数据文件信息
• 重做日志及归档日志信息
• 备份集及备份文件信息、
• 检查点(checkpoint)及 SCN 信息等
当然这些只是一个粗略的介绍,由于控制文件是个二进制文件,无法直接打开查阅,但
是通过上一章介绍的如下命令可以将控制文件内容转储出来便于查看:
alter session set events 'immediate trace name controlf level 8';
以下是来自 Oracle Database 11g 的转储测试:
SQL> alter session set events 'immediate trace name controlf level 8';
Session altered.
SQL> select value from v$diag_info where name='Default Trace File';
VALUE
--------------------------------------------------------------------------------
/opt/oracle/diag/rdbms/11gtest/11gtest/trace/11gtest_ora_5910.trc
注意:从 11g 开始,可以通过 v$diag_info 获得当前会话转储文件的名称。
打开这个跟踪文件现在就可以清晰的看到控制文件的内容,最开始的一段是关于数据库
ID、名称等的概要信息:
V10 STYLE FILE HEADER:
Compatibility Vsn = 185597952=0xb100000
Db ID=1478080230=0x5819b6e6, Db Name='11GTEST'
《深入解析 Oracle》
·2·
Activation ID=0=0x0
Control Seq=1707=0x6ab, File size=594=0x252
File Number=0, Blksiz=16384, File Type=1 CONTROL
接下来是数据库条目的详细信息,包括了数据库的名称、数据文件及日志文件的数量、
数据库的检查点及 SCN 信息等:
***************************************************************************
DATABASE ENTRY
***************************************************************************
(size = 316, compat size = 316, section max = 1, section in-use = 1,
last-recid= 0, old-recno = 0, last-recno = 0)
(extent = 1, blkno = 1, numrecs = 1)
07/04/2008 13:51:34
DB Name "11GTEST"
Database flags = 0x00404001 0x00001200
Controlfile Creation Timestamp 07/04/2008 13:51:35
Incmplt recovery scn: 0x0000.00000000
Resetlogs scn: 0x0000.00000001 Resetlogs Timestamp 07/04/2008 13:51:34
Prior resetlogs scn: 0x0000.00000000 Prior resetlogs Timestamp 01/01/1988 00:00:00
Redo Version: compatible=0xb100000
#Data files = 4, #Online files = 4
Database checkpoint: Thread=1 scn: 0x0000.0008718a
Threads: #Enabled=1, #Open=1, Head=1, Tail=1
enabled threads: 01000000 00000000 00000000 00000000 00000000 00000000
....
Max log members = 3, Max data members = 1
Arch list: Head=1, Tail=1, Force scn: 0x0000.0007fe17scn: 0x0000.0008ebd0
Activation ID: 1478075366
Controlfile Checkpointed at scn: 0x0000.0008ec14 07/07/2008 08:00:29
thread:0 rba:(0x0.0.0)
enabled threads: 00000000 00000000 00000000 00000000 00000000 00000000
....
再接下来是检查点记录信息,这部分内容包含了 Low Cache RBA 和 On Disk RBA 信息,在
执行数据库实例恢复时,前者是恢复的起点,后者是恢复的终点,其分别指向了日志文件中的确
定地址:
***************************************************************************
CHECKPOINT PROGRESS RECORDS
***************************************************************************
(size = 8180, compat size = 8180, section max = 11, section in-use = 0,
last-recid= 0, old-recno = 0, last-recno = 0)
第 2 章 控制文件与数据库初始化
·3·
(extent = 1, blkno = 2, numrecs = 11)
THREAD #1 - status:0x2 flags:0x0 dirty:688
low cache rba:(0x1b.16c04.0) on disk rba:(0x1c.a1c.0)
on disk scn: 0x0000.0008ed61 07/07/2008 08:01:59
resetlogs scn: 0x0000.00000001 07/04/2008 13:51:34
heartbeat: 659440589 mount id: 1478276654
好了,我们先引用到这里,大家在学习时应该仔细阅读接下来的每个条目。
在上面的引用中,已经频繁出现了 checkpoint 和 SCN 信息,Oracle 数据库在内部通过 SCN
和检查点来保证数据库的一致性、可恢复性等重要属性,下面就让我们来详细了解一下 Oracle
的 SCN 与 检查点机制。
2.2 SCN 的说明
SCN 在 Oracle 的文档上以多种形式出现,一种是 System Change Number,一种是 System
Commit Number,在大多数情况下,Systems Change Numbers 的定义更为确切。
2.2.1 SCN 的定义
SCN(System Change Number),也就是通常我们所说的系统改变号,是数据库中非常重要
的一个数据结构,用以标识数据库在某个确切时刻ᨀ交的版本。在事务ᨀ交时,它被赋予一个
唯一的标示事务的 SCN。SCN 同时被作为 Oracle 数据库的内部时钟机制,可以被看作逻辑时
钟,每个数据库都有一个全局的 SCN 生成器。
作为数据库内部的逻辑时钟,数据库事务依 SCN 而排序,Oracle 也依据 SCN 来实现一致
性读(Read Consistency)等重要数据库功能,另外对于分布式事务(Distributed Transactions),
SCN 也极为重要。
SCN 在数据库中是唯一的,并随时间而增加,但是可能并不连贯。除非重建数据库,SCN
的值永远不会被重置为 0。
一直以来,对于 SCN 有很多争议,很多人认为 SCN 是指,System Commit Number,而通
常 SCN 在ᨀ交时才变化,所以很多时候,这两个名词经常在文档中反复出现。即使在 Oracle
的官方文档中,SCN 也常以 System Change/Commit Number 两种形式出现。
到底是哪个词其实不是最重要的,重要的是我们需要知道 SCN 是 Oracle 内部的时钟机制,
Oracle 通过 SCN 来维护数据库的一致性,并通过 SCN 实施 Oracle 至关重要的恢复机制。
SCN 在数据库中是无处不在的,常见的事务表、控制文件、数据文件头、日志文件、数
据块头等都记录有 SCN 值。冠以不同前缀,SCN 也有了不同的名称,比如检查点 SCN
(checkpoint scn), Resetlogs SCN 等等。
SCN 由两部分组成,高位 SCN Wrap 由 2 Bytes 记录,低位 SCN Base 由 4 Bytes 记录:
《深入解析 Oracle》
·4·
SCN 的 6 Bytes 记录,理论上可以存储 281 trillion (兆)的数值,这是 SCN 的极限值:
SQL> select power(2,48) from dual;
POWER(2,48)
--------------------
281474976710656
虽然 SCN 理论上可以容纳如此大的值,但是为了控制 SCN 的异常增长,Oracle 也做出了
一些限制,在 Oracle 11g 以前,每秒增进的 SCN 值不能超过 16K,这个数字在 11g 中增加到
32K/秒,最大值可以达到 256K/秒。据此计算,在 11g 之前,SCN 至少可以用 500 年左右:
SQL> select trunc(power(2,48)/12/31/24/3600/16/1024,2) Year from dual;
YEAR
--------------------
534.51
基于每秒产生 SCN 的限制,SCN 在任意时间的最大允许值就可以被计算出来.
以下两个参数在 11g 中引入以控制 SCN 的可能合理值,_max_reasonable_scn_rate 用于限
制每秒最大产生 SCN 的数量,_reasonable_scn_offset_seconds 用于设定一个用于计算时间的偏
移量:
_max_reasonable_scn_rate 32768 Max reasonable SCN rate
_reasonable_scn_offset_seconds 0 Reasonable SCN offset seconds
最大可能 SCN 的计算是基于一个固定时间,Oracle 内部使用了一个 4G 范围的数据来表
示 01/01/1988 00:00:00 ~ 08/18/2121 06:28:15 这段时间,它的算法简单,每个月都是用 31 天来表
示时间,每增加 1 秒,这个数值就增加 1,有了这个时间起点,再加上每秒允许产生 16384 个 SCN
(11g 之前),就可以计算当前最大的允许 SCN:
col scn for 999,999,999,999,999,999
select
(
(
(
(
(
(
to_char(sysdate,'YYYY')-1988
)*12+
第 2 章 控制文件与数据库初始化
·5·
to_char(sysdate,'mm')-1
)*31+to_char(sysdate,'dd')-1
)*24+to_char(sysdate,'hh24')
)*60+to_char(sysdate,'mi')
)*60+to_char(sysdate,'ss')
) * to_number('ffff','XXXXXXXX')/4 scn
from dual
/
SYSDATE SCN
--------- ------------------------
16-JUN-12 12,879,847,825,800
当数据库的 SCN 超过合理值意外增长后,将会出现 ORA-00600 2552 错误。以下信息就
是在数据库出现 SCN 异常之后抛出的警告:
Mon May 14 17:55:54 2012
Errors in file /t3/orat3/product/admin/ora1020410/bdump/ora1020410_mmon_25386.trc:
ORA-00600: internal error code, arguments: [2252], [2988], [9], [], [], [], [], []
Mon May 14 17:56:06 2012
Errors in file /t3/orat3/product/admin/ora1020410/bdump/ora1020410_smon_23805.trc:
ORA-00600: internal error code, arguments: [2252], [2988], [13], [], [], [], [], []
SCN 的大小问题在很长时间内并未得到关注,但是自 2012 年初,Oracle 发布了一个重要的
补丁修正,声明数据库可能遇到 SCN 异常增长导致耗尽的问题,这一问题应当引起关注.
2.2.2 SCN 的获取方式
可以通过如下几种方式获得数据库的当前或近似 SCN。
1.从 Oracle9i 开始
可以通过可以使用 dbms_flashback.get_system_change_number 来获得
SQL> select dbms_flashback.get_system_change_number from dual;
GET_SYSTEM_CHANGE_NUMBER
------------------------
2982184
2.Oracle9i 前
可以通过查询 x$ktuxe 获得系统最接近当前值的 SCN:
X$KTUXE-------------[K]ernel [T]ransaction [U]ndo Transa[x]tion [E]ntry (table)
SQL> select max(ktuxescnw*power(2,32)+ktuxescnb) from x$ktuxe;
MAX(KTUXESCNW*POWER(2,32)+KTUXESCNB)
------------------------------------
2980613
《深入解析 Oracle》
·6·
3.从 Oracle10g 开始
在 v$database 视图中增加了 current_scn 字段,通过查询该字段可以获得数据库的当前 SCN
值:
SQL> select current_scn from v$database;
CURRENT_SCN
-----------
612842
4.从内存中取得 SCN 信息
通过 oradebug 工具可以直接读取内存中用于记录 SCN 的内存变量:
SQL> oradebug setmypid
Statement processed.
SQL> oradebug DUMPvar SGA kcsgscn_
kcslf kcsgscn_ [2000C848, 2000C868) = 00000000 000959EA 00000000 00000000 00000000 00000000
00000000 2000C654
SQL> select to_number('959EA','xxxxxx') SCN from dual;
SCN
---------------------------
612842
2.2.3 SCN 的进一步说明
系统当前 SCN 并不是在任何的数据库操作发生时都会改变,SCN 通常在事务ᨀ交或回滚
时改变,在控制文件,数据文件头,数据块,日志文件头,日志文件 change vector中都有 SCN,但其作
用各不相同。
1.数据文件头中包含了该数据文件的检查点信息
其中包括 Checkpoint SCN,表示该数据文件最近一次执行检查点操作时的 SCN。
从控制文件的 dump 文件中,我们可以得到以下内容:
DATA FILE #1:
(name #4) /opt/oracle/oradata/conner/system01.dbf
creation size=32000 block size=8192 status=0xe head=4 tail=4 dup=1
tablespace 0, index=1 krfil=1 prev_file=0
unrecoverable scn: 0x0000.00000000 01/01/1988 00:00:00
Checkpoint cnt:273 scn: 0x0000.0023aff1 11/22/2004 17:10:11
Stop scn: 0xffff.ffffffff 11/22/2004 16:58:49
Creation Checkpointed at scn: 0x0000.00000008 10/20/2004 20:59:35
thread:1 rba:(0x1.3.10)
。。。。。
对于每一个数据文件都包含一个这样的条目,记录该文件的检查点 SCN 的值以及检查点
第 2 章 控制文件与数据库初始化
·7·
发生的时间,这里的 Checkpoint SCN、Stop SCN 以及 Checkpoint Cnt 都是非常重要的数据结
构,我们将会在下面检查点部分详细介绍。
同样可以通过命令转储数据文件头,观察其具体信息及检查点记录等:
SQL> alter session set events 'immediate trace name file_hdrs level 8';
Session altered.
SQL> @gettrcname
TRACE_FILE_NAME
----------------------------------------------------------------------------------
/opt/oracle/admin/conner/udump/conner_ora_5862.trc
从跟踪文件中摘取 SYSTEM 表空间的记录作为参考(摘要信息):
DATA FILE #1:
(name #4) /opt/oracle/oradata/conner/system01.dbf
creation size=32000 block size=8192 status=0xe head=4 tail=4 dup=1
tablespace 0, index=1 krfil=1 prev_file=0
unrecoverable scn: 0x0000.00000000 01/01/1988 00:00:00
Checkpoint cnt:319 scn: 0x0000.002e3016 12/03/2004 06:42:18
Stop scn: 0xffff.ffffffff 12/01/2004 23:37:33
Creation Checkpointed at scn: 0x0000.00000008 10/20/2004 20:59:35
thread:1 rba:(0x1.3.10)
Offline scn: 0x0000.001cff67 prev_range: 0
Online Checkpointed at scn: 0x0000.001cff68 11/16/2004 14:10:35
thread:1 rba:(0x1.2.0)
Hot Backup end marker scn: 0x0000.00000000
aux_file is NOT DEFINED
FILE HEADER:
Software vsn=153092096=0x9200000, Compatibility Vsn=134217728=0x8000000
Db ID=3152029224=0xbbe02628, Db Name='CONNER'
Activation ID=0=0x0
Control Seq=1093=0x445, File size=32000=0x7d00
File Number=1, Blksiz=8192, File Type=3 DATA
Tablespace #0 - SYSTEM rel_fn:1
Creation at scn: 0x0000.00000008 10/20/2004 20:59:35
Backup taken at scn: 0x0000.001aca21 11/14/2004 09:08:34 thread:1
reset logs count:0x20541edb scn: 0x0000.001cff68 recovered at 12/01/2004 23:07:30
status:0x4 root dba:0x004001a1 chkpt cnt: 319 ctl cnt:318
Checkpointed at scn: 0x0000.002e3016 12/03/2004 06:42:18
thread:1 rba:(0x35.2.10)
Backup Checkpointed at scn: 0x0000.001aca21 11/14/2004 09:08:34
thread:1 rba:(0xc6.4fff.10)
《深入解析 Oracle》
·8·
注意,在以上输出中,FILE HEADER 部分之前信息来自控制文件,之后信息来自数据文
件头,在数据库的启动过程中,需要依赖两部分信息进行比对判断,从而确保数据库的一致性
和判断是否需要进行恢复。
2.日志文件头中包含了 Low SCN,Next SCN
这两个 SCN 标示该日志文件包含有介于 Low SCN 到 Next SCN 的重做信息,对于 Current
的日志文件(当前正在被使用的 Redo Logfile),其最终 SCN 不可知,所以 Next SCN 被置为
无穷大,也就是 ffffffff。
我们来看一下日志文件的情况:
SQL> select * from v$log;
GROUP# THREAD# SEQUENCE# BYTES MEMBERS ARC STATUS FIRST_CHANGE# FIRST_TIM
------- -------- ---------- ---------- ---------- --- -------- ------------- ---------
1 1 50 10485760 1 YES ACTIVE 2973017 02-DEC-04
2 1 51 10485760 1 NO CURRENT 2984378 02-DEC-04
3 1 49 10485760 1 YES INACTIVE 2966611 01-DEC-04
SQL> select dbms_flashback.get_system_change_number from dual;
GET_SYSTEM_CHANGE_NUMBER
------------------------
2984476
SQL> alter system switch logfile;
System altered.
SQL> select * from v$log;
GROUP# THREAD# SEQUENCE# BYTES MEMBERS ARC STATUS FIRST_CHANGE# FIRST_TIM
------- -------- ---------- ---------- ---------- --- -------- ------------- ---------
1 1 50 10485760 1 YES INACTIVE 2973017 02-DEC-04
2 1 51 10485760 1 YES INACTIVE 2984378 02-DEC-04
3 1 52 10485760 1 NO CURRENT 2984481 02-DEC-04
我们看到,SCN 2984476 显然位于 Log Group#为 2 的日志文件中,该日志文件包含了 SCN
自 2984378 至 2984481 的 redo 信息。Oracle 在进行恢复时就需要根据低 SCN 和高 SCN 来确
定需要的恢复信息位于哪一个日志或归档文件中。
如果通过控制文件转储,我们可以在控制文件中找到关于日志文件的信息:
LOG FILE #1:
(name #1) /opt/oracle/oradata/conner/redo01.log
Thread 1 redo log links: forward: 2 backward: 0
siz: 0x5000 seq: 0x00000011 hws: 0x2 bsz: 512 nab: 0x2 flg: 0x1 dup: 1
Archive links: fwrd: 0 back: 0 Prev scn: 0x0000.0023ac36
Low scn: 0x0000.0023afee 11/22/2004 17:10:06
Next scn: 0x0000.0023aff1 11/22/2004 17:10:11
LOG FILE #2:
第 2 章 控制文件与数据库初始化
·9·
(name #2) /opt/oracle/oradata/conner/redo02.log
Thread 1 redo log links: forward: 3 backward: 1
siz: 0x5000 seq: 0x00000012 hws: 0x2 bsz: 512 nab: 0x19 flg: 0x1 dup: 1
Archive links: fwrd: 0 back: 0 Prev scn: 0x0000.0023afee
Low scn: 0x0000.0023aff1 11/22/2004 17:10:11
Next scn: 0x0000.0023b01e 11/22/2004 17:10:54
LOG FILE #3:
(name #3) /opt/oracle/oradata/conner/redo03.log
Thread 1 redo log links: forward: 0 backward: 2
siz: 0x5000 seq: 0x00000013 hws: 0x1 bsz: 512 nab: 0xffffffff flg: 0x8 dup: 1
Archive links: fwrd: 0 back: 0 Prev scn: 0x0000.0023aff1
Low scn: 0x0000.0023b01e 11/22/2004 17:10:54
Next scn: 0xffff.ffffffff 01/01/1988 00:00:00
从以上信息可以注意到,Log File 3 是当前的日志文件,该文件拥有的 Next SCN 为无穷
大。同样我们可以通过直接 dump 日志文件的方式来进行转储:
SQL> select * from v$logfile;
GROUP# STATUS TYPE MEMBER
------- -------- ------- ------------------------------------------------------
1 ONLINE /opt/oracle/oradata/conner/redo01.log
2 ONLINE /opt/oracle/oradata/conner/redo02.log
3 ONLINE /opt/oracle/oradata/conner/redo03.log
SQL> alter system dump logfile '/opt/oracle/oradata/conner/redo01.log';
System altered.
在 trace 文件中我们可以看到关于 SCN 的详细的内容:
DUMP OF REDO FROM FILE '/opt/oracle/oradata/conner/redo01.log'
Opcodes *.*
DBA's: (file # 0, block # 0) thru (file # 65534, block # 4194303)
RBA's: 0x000000.00000000.0000 thru 0xffffffff.ffffffff.ffff
SCN's scn: 0x0000.00000000 thru scn: 0xffff.ffffffff
Times: creation thru eternity
FILE HEADER:
Software vsn=153092096=0x9200000, Compatibility Vsn=153092096=0x9200000
Db ID=3152029224=0xbbe02628, Db Name='CONNER'
Activation ID=3154332244=0xbc034a54
Control Seq=1084=0x43c, File size=20480=0x5000
File Number=1, Blksiz=512, File Type=2 LOG
descrip:"Thread 0001, Seq# 0000000050, SCN 0x0000002d5d59-0x0000002d89ba"
thread: 1 nab: 0x15be seq: 0x00000032 hws: 0x2 eot: 0 dis: 0
reset logs count: 0x20541edb scn: 0x0000.001cff68
《深入解析 Oracle》
·10·
Low scn: 0x0000.002d5d59 12/02/2004 11:25:40
Next scn: 0x0000.002d89ba 12/02/2004 15:29:42
Enabled scn: 0x0000.001cff68 11/16/2004 14:10:35
Thread closed scn: 0x0000.002d5d59 12/02/2004 11:25:40
Log format vsn: 0x8000000 Disk cksum: 0xd79c Calc cksum: 0xd79c
我们不打算详细介绍具体命令的用法及更进一步的内容,因为对于一本书来说,这些内
容还是太广阔了。在这里只希望给大家直观的认识,有兴趣的自然可以由此开始进一步的探索。
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。
Oracle DataGuard高可用性解决方案详解
孙莹
578次阅读
2025-03-26 23:27:33
Oracle RAC 一键安装翻车?手把手教你如何排错!
Lucifer三思而后行
537次阅读
2025-04-15 17:24:06
【纯干货】Oracle 19C RU 19.27 发布,如何快速升级和安装?
Lucifer三思而后行
439次阅读
2025-04-18 14:18:38
XTTS跨版本迁移升级方案(11g to 19c RAC for Linux)
zwtian
432次阅读
2025-04-08 09:12:48
【ORACLE】记录一些ORACLE的merge into语句的BUG
DarkAthena
430次阅读
2025-04-22 00:20:37
墨天轮个人数说知识点合集
JiekeXu
430次阅读
2025-04-01 15:56:03
Oracle SQL 执行计划分析与优化指南
Digital Observer
430次阅读
2025-04-01 11:08:44
【ORACLE】你以为的真的是你以为的么?--ORA-38104: Columns referenced in the ON Clause cannot be updated
DarkAthena
407次阅读
2025-04-22 00:13:51
Oracle数据库一键巡检并生成HTML结果,免费脚本速来下载!
陈举超
395次阅读
2025-04-20 10:07:02
Oracle 19c RAC更换IP实战,运维必看!
szrsu
367次阅读
2025-04-08 23:57:08