ITPub博客

首页 > 数据库 > Oracle > SCN,RedoLog和 Checkpoint

SCN,RedoLog和 Checkpoint

Oracle 作者:murkey 时间:2014-01-12 23:39:37 0 删除 编辑
转载于dave

1.20 SCN,RedoLog和   Checkpoint

1.20.1    Redo log 作用

数据库异常关机(比如突然断电,shutdown abort :它会立即关闭数据库,等

同于断电)之后,这时已经 commit的事务已经记录到  online redo  log中,下次启

动数据库时,Oracle进行恢复操作,将  online redo log中的事务操作调入内存中,

进行相应操作后将数据记入到数据文件中,数据操作完成。

对于没有 commit而已经写入数据文件或回退段的数据,也要进行回滚操作,

将数据恢复到 rollback的状态,使数据文件和控制文件恢复到崩溃前的一致性状

态。总之,数据库下次打开时会占用比正常关闭更长的时间。

注意:

并不是所有异常关机后,下次启动时都可以恢复到正常状态,异常关机容易

导致坏块的产生,这种情况下数据库是不能正常启动的,如果处理不当,将会导

致大量数据的丢失。

Rolling Forward(前滚)

Oracle启动实例并加载数据库,然后通过  Online Redologs中的重做日志,重

现实例崩溃前对数据库的修改操作。在恢复过程中对于已经提交的事务,但尚未

写入数据文件的那部分数据全部写入数据文件.

Rolling Back(回滚)

Rolling Forward之后,虽然已经提交的修改操作更改的数据都已经被写入数

据文件,但在实例崩溃时,部分未提交的事务操作的数据也被写入到数据文件,

这些事务必须被撤销.

有关前滚和回滚,更多信息,参考  2.6小节。

触发 LGWR进程的条件有:

1.用户提交

2.有   1/3重做日志缓冲区未被写入磁盘

3.有大于   1M的重做日志缓冲区未被写入磁盘

4. 3秒超时

5.  DBWR需要写入的数据的    SCN大于    LGWR记录的    SCN,DBWR触发

LGWR写入。

DBA  总群: 104207940    --近满       DBA 总群_4: 63306533       DBA  总群_2:  62697716 --近满

DBA  总群_5: 62697850   DBA  总群_3:283816689 --有大量空闲     DBA  总群_6:

62697977




 

Tianlesoftware  学习  Oracle

Blog:  http://blog.csdn.net/tianlesoftware

1.20.2    SCN(system change number)

SCN是当 Oracle数据更新后,由  DBMS自动维护去累积递增的一个数字。当

一个事务 commit时,LGWR会将   log buffer写入  redo  log file,同时也会将该事

务的  SCN同步写入到   redo  log  file内(wait-until-completed)。因此当你    commit

transaction时,在成功的讯息返回之前,LGWR必须先完整的完成上述行为之

后,否则你是看不到提交成功的响应讯息。

可以理解的,返回的 SCN,也是目前 redo  log file最新的  SCN 纪录。因为

commit后的交易才会有  SCN,而一旦 commit就会立刻写入  redo log file中。

系统时间标记与 scn之间存在一张表,即   SYS下的   SMON_SCN_TIME。

SQL> desc sys.smon_scn_time

名称

是否为空?类型

----------------------------------------- --------

THREAD

TIME_MP

---------------------------

NUMBER

NUMBER

DATE

TIME_DP

SCN_WRP

SCN_BAS

NUM_MAPPINGS

TIM_SCN_MAP

SCN

NUMBER

NUMBER

NUMBER

RAW(1200)

NUMBER

NUMBER

ORIG_THREAD

每隔   5分钟,系统产生一次系统时间标记与                  scn的匹配并存入

SYS.SMON_SCN_TIME表(由   SMON进程来进行   Update操作),该表中记录了

最近 1440个系统时间标记与 scn的匹配记录,由于该表只维护了最近的   1440条

记录,即最近 5天内的记录。

对系统时间标记与   scn的每   5分钟匹配一次做个说明,比如:

SCN:339988对应    2011-01-25 17:00:00

SCN:339989对应  2011-01-25 17:05:00,

当查询2011-01-25 17:00:00到2011-01-25    17:04:59这段时间点内的SCN时,

oracle都会将其匹配为   SCN:339988。

查看 SCN和    timestamp之间的对应关系:

select scn,to_char(time_dp,'yyyy-mm-dd  hh24:mi:ss') from  sys.smon_scn_time order

by 2;

查询目前系统最新的  SCN:

DBA  总群: 104207940    --近满       DBA 总群_4: 63306533       DBA  总群_2:  62697716 --近满

DBA  总群_5: 62697850   DBA  总群_3:283816689 --有大量空闲     DBA  总群_6:

62697977



 

Tianlesoftware  学习  Oracle

Blog:  http://blog.csdn.net/tianlesoftware

SQL>select dbms_flashback.get_system_change_number from dual;

或者:

SQL> select current_scn from v$database;

CURRENT_SCN

-----------

1428603737

timestamp与    SCN互换的   2个方法:

select   timestamp_to_scn(to_date('2011-01-25  12:10:00','yyyy-mm-dd   hh24:mi:ss'))

from dual;

select scn_to_timestamp(351277605) from dual;

在 Metalink搜到一篇   Timestamp与  SCN之间映射关系的文章,原文参考:

How to map SCN with Timestamp before 10g [ID 365536.1]

http://blog.csdn.net/tianlesoftware/archive/2011/01/25/6163757.aspx

However,

in

earlier

releases,

while

there

is

a

system

object

-

SYS.SMON_SCN_TIME that  will provide  the SCN  to TIME  mapping information.

There is no conversion facility provided.

SYS.SMON_SCN_TIME  will have  a maximum  of 1440  rows  and each  record

will be  for a 5 minute  period.    Oracle maintains  this information for  maximum of 5

days after which the records will be recycled.

This means that data is stored 12 times per hour * 24 hours * 5 days=1440 rows.

SCN value is stored internally as :

i. SCN_wrap

ii. SCN_base

Whenever  the SCN  is  incremented,  the BASE  component  is  incremented  first

unil it reaches it  maximum.    Once the BASE reaches the maximum value  allowed, it

is initialized to zero again after incrementing the WRAP by 1.

--开始时 WRAP为    0,即 SCN_WRP=0.当   BASE增长到最大值后,SCN_BAS

变为 0.同时   SCN_WRP增长到    1

Using this logic, we can calculate the timestamp of the SCN as follows:

(SCN_WRP  * 4294967296)  +  SCN_BAS  should  give  us the  SCN  in  the  number

format

--SCN的计算公式,这里我们看出   SCN是根据   SCN_BAS计算出来的。和系统

时间是没有关系的。只是方便我们来进行操作,如闪回恢复,而将   SCN 和系

统时间每隔  5分钟进行一次映射。映射完后,由     SMON进程将映射关系写入

DBA  总群: 104207940    --近满       DBA 总群_4: 63306533       DBA  总群_2:  62697716 --近满

DBA  总群_5: 62697850   DBA  总群_3:283816689 --有大量空闲     DBA  总群_6:

62697977



 

Tianlesoftware  学习  Oracle

Blog:  http://blog.csdn.net/tianlesoftware

SMON_SCN_TIME表。可以把    SCN看成是   Oracle内部的时间。

To get the time/date for an SCN value in 9i, use the following example:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

-- (a) Get the current SCN base.

SQL>select max(scn_bas) SCN_BASE from smon_scn_time;

1603342197

--(b) Get the complete SCN and the timestamp.

SQL> alter session set NLS_DATE_FORMAT='DD-MON-YY HH:MI:SS';

SQL>  select   time_dp  TIMESTAMP,   scn_wrp*4294967296+SCN_bas  SCN   from

smon_scn_time where scn_bas='1603342197';

TIMESTAMP

------------------

28-JUL-06 05:31:08

SCN

----------

8252235517813

这篇文章讲的是 10g之前的。在     metalink上搜了半天,只找到一条区别,

就是 11g下  smon_scn_time存储的记录可以超过   1440条。

1.20.3    Checkpoint (检查点)

1.20.3.1检查点定义

大多数关系型数据库都采用"在提交时并不强迫针对数据块的修改完成"而是

"提交时保证修改记录(以重做日志的形式)写入日志文件"的机制,来获得性能

的优势。即:当用户提交事务,写数据文件是"异步"的,写日志文件是"同步"的。

这就可能导致数据库实例崩溃时,内存中的 DB_Buffer中的修改过的数据,

可能没有写入到数据块中。数据库在重新打开时,需要进行恢复,来恢复     DB

Buffer中的数据状态,并确保已经提交的数据被写入到数据块中。

检查点是这个过程中的重要机制,通过它来确定,恢复时哪些重做日志应该

被扫描并应用于恢复。

先看一下 checkpoint  queue概念,检查点发生后,触发   DBWn,CKPT获取

发生检查点时对应的 SCN,通知 DBWn要写到这个  SCN为止,  DBWR写   dirty

buffer是根据    buffer在被首次    modify的时候的时间的顺序写出,也就是   buffer

被 modify的时候会进入一个    queue(checkpoint    queue),DBWr就根据    queue

从其中批量地写到数据文件。由于这里有一个顺序的关系,所以    dbwr的写的

进度就是可衡量的,写到哪个 buffer的时候该  buffer的首次变化时候的  scn就是

DBA  总群: 104207940    --近满       DBA 总群_4: 63306533       DBA  总群_2:  62697716 --近满

DBA  总群_5: 62697850   DBA  总群_3:283816689 --有大量空闲     DBA  总群_6:

62697977



 

Tianlesoftware  学习  Oracle

Blog:  http://blog.csdn.net/tianlesoftware

当前所有数据文件 block的最新  scn,但是由于无法适时的将 dbwr的进度记录下

来,所以 oracle选择了一些策略。其中就包括     ckpt进程的检查点和心跳。

检查点发生以后,CKPT进程检查  checkpoint  queue(也就是脏块链表)是否过

长,如果是,则触发 DBWn,将一部分脏块写入数据文件,从而缩短  checkpoint

queue。

Checkpoint发生时,一方面通知    dbwr进行下一批写操作,(dbwr写入的时

候,一次写的块数是有一个批量写的隐藏参数控制的);另一方面,oracle采用了

一个心跳的概念,以 3秒的频率将  dbwr写的进度反应到控制文件中,也就是把

dbwr当前刚写完的  dirty  buffer对应的  scn写入数据文件头和控制文件,这就是

检查点 scn。

这个 3秒和增量检查点不是一个概念,3秒只是在控制文件中,ckpt进程去

更新当前  dbwr写到哪里了,这个对于     ckpt进程来说叫     heartbeat,heartbeat

是 3秒一次,3秒可以看作不停的检查并记录检查点执行情况(DBWR的写进度)。

检查点发生之后数据库的数据文件、控制文件处于一致状态的含义是不需要

进行介质恢复,只表示数据文件头一致,但是并不表示数据文件内容一致,因为

数据文件内容可能在没有发生检查点的其它情况下的 dbwr写数据文件,这样数

据文件内容就不一致,若掉电需要进行崩溃恢复。

oracle8以后推出了   incremental checkpoint(增量检查点)的机制,在以前的版

本里每 checkpoint时都会做一个 full thread checkpoint(完全检查点),这样的话所有

脏数据会被写到磁盘,巨大的 i/o对系统性能带来很大影响。

为了解决这个问题,oracle引入了  checkpoint queue机制,每一个脏块会被移

到检查点队列里面去,按照 low rdb(第一次对此块修改对应的 redo block address)

来排列,靠近检查点队列尾端的数据块的 low rba值是最小的,而且如果这些赃

块被再次修改后它在检查点队列里的顺序也不会改变,这样就保证了越早修改的

块越早写入磁盘。每隔 3秒钟 ckpt会去更新控制文件和数据文件,记录   checkpoint

执行的情况。

触发 DBWR进程的条件有:

1.    DBWR超时,大约  3秒

2.系统中没有多余的空缓冲区来存放数据

3.    CKPT进程触发    DBWR

checkpoint有两个目的:

1、确保数据一致性。

2、使数据库能快速地恢复。

Checkpoint期间会有下面进程发生:

1. DBWR写所有脏数据到数据文件;

2. LGWR更新控制文件和数据文件的  SCN。

DBA  总群: 104207940    --近满       DBA 总群_4: 63306533       DBA  总群_2:  62697716 --近满

DBA  总群_5: 62697850   DBA  总群_3:283816689 --有大量空闲     DBA  总群_6:

62697977



 

Tianlesoftware  学习  Oracle

Blog:  http://blog.csdn.net/tianlesoftware

1.20.3.2 Checkpoints相关优化参数

Checkpoints是一个数据库优化的难点。频繁的  Checkpoints可以实现快速的

恢复,但也会使性能下降。怎样处理这个问题呢?

依赖于数据库数据文件的数量,一个 Checkpoint可能是高速的运行。因为所

有的数据文件在 Checkpoint期间都会被冻结。更频繁的  Checkpoints可以快速恢

复数据库。这也客户对不按规定系统宕机的容忍的原因。然而,在一些特殊情况

下,频繁的 Checkpoints也不能保证可以快速恢复。我们假设数据库在  95%的时

间内是正常运行,5%由于实例失败导致不可用,要求恢复。对大多数客户而言,

他们更希望调整 95%的性能而不是 5%的宕机时间。这个假设表明,性能是摆在

第一位的,所以我门的目标就是在优化期间减少 Checkpoints的频繁度。

优化 Checkpoints包括  4个关键的初始化参数:

- FAST_START_MTTR_TARGET

- LOG_CHECKPOINT_INTERVAL

- LOG_CHECKPOINT_TIMEOUT

- LOG_CHECKPOINTS_TO_ALERT

1.20.3.2.1 FAST_START_MTTR_TARGET

Oracle9i以来  FAST_START_MTTR_TARGET参数是调整   checkpoint的首选

的方法。FAST_START_MTTR_TARGET可以指定单实例恢复需要的秒数。基于

内部的统计,增长的       checkpoint会自动调整的         checkpint的目标以满足

FAST_START_MTTR_TARGET的需求。

v$instance_recovery.estimated_mttr显示当前估计需要恢复的秒数。这个值会

被显示即使 FAST_START_MTTR_TARGET没有被指定。

v$instance_recovery.target_mttr表明在短时间内   MTTR的目标。

v$mttr_target_advice显示这个当前   MTTR设置的工作量产生的 I/O数量和其

他 I/O。这个视图帮助用户评定这个在优化和恢复之前的平衡。

1.20.3.2.2 LOG_CHECKPOINT_INTERVAL

LOG_CHECKPOINT_INTERVAL参数指定这个最大的重做块的间隔数目。

如果  FAST_START_MTTR_TARGET被指定,LOG_CHECKPOINT_INTERVAL

不能被设置为 0。

在大多数          Unix系统的            OS块大小是              512字节。设置

LOG_CHECKPOINT_INTERVAL=10000意味着这个增长的   checkpoint不能追加

到当前日志,因为多于 5M。如果你的重做日志是 20M,你将发出 4个   checkpoint

对每个重做日志。

LOG_CHECKPOINT_INTERVAL会发生影响当一个    checkpoint发生时,小

心设置这个参数,保持它随着重做日志文件大小变化而变化。checkpoint频繁是

DBA  总群: 104207940    --近满       DBA 总群_4: 63306533       DBA  总群_2:  62697716 --近满

DBA  总群_5: 62697850   DBA  总群_3:283816689 --有大量空闲     DBA  总群_6:

62697977



 

Tianlesoftware  学习  Oracle

Blog:  http://blog.csdn.net/tianlesoftware

这个影响数据库恢复的原因之一。短的 checkpoint间隔意味数据库将快速恢复,

也增加了资源的利用。这个参数也影响数据库向前回滚的时间。实际的恢复时间

是基于这个时间,当然还有失败的类型和需要归档日志的数量。

1.20.3.2.3 LOG_CHECKPOINT_TIMEOUT

这个参数指定 checkpoint发出的时间间隔。换句话说,它指定一次脏数据多

少时间写出一次。checkpoint频率会影响这个数据库恢复的时间。长时间的间隔

会要求数据库恢复要求更久。

Oracle建议用       LOG_CHECKPOINT_interval去控制      checkpoint 而不用

LOG_CHECKPOINT_TIMEOUT,LOG_CHECKPOINT_TIMEOUT每  n秒发一次

checkpoint,不顾事务提交的频率。这可能会导致一些没有必要的  checkpoint在

事务已经变化的情况下。不必要的 checkpoint必须被避免。

还有一个容易误解的地方: LOG_CHECKPOINT_TIMEOUT会间隔性地发

出 log switch。而 Log switch会触发一个  checkpoint,但 checkpoint不会导致一个

log switch。唯一手工方式 alter  system switch logfile或者重新设置  redo logs大小

可以导致频繁 switch。

SQL> alter system set log_checkpoint_timeout=300;[单位是秒]

1.20.3.2.4 log_checkpoint_to_alert

设置为真,可以在告警日志中观察到增量检查点的触发。

SQL> alter system set log_checkpoints_to_alert=true;

对于优化和恢复,在线重做日志的大小是关键的。

1.20.3.3 Checkpoint触发条件

1.20.3.3.1触发完全检查点条件

发完全检查点,促使 DBWR将检查点时刻前所有的脏数据写入数据文件。

另外,一般正常运行期间的数据库不会产生完全检查点。

1.通过正常事务处理或者立即选项关闭例程时(shutdown               immediate 或者

Shutdown normal).

2.当通过设置初始化参数:

LOG_CHECKPOINT_INTERVAL,

LOG_CHECKPOINT_TIMEOUT ,

FAST_START_IO_TARGET强制时;

3.当数据库管理员手动请求时:

ALter system checkpoint;

DBA  总群: 104207940    --近满       DBA 总群_4: 63306533       DBA  总群_2:  62697716 --近满

DBA  总群_5: 62697850   DBA  总群_3:283816689 --有大量空闲     DBA  总群_6:

62697977



 

Tianlesoftware  学习  Oracle

Blog:  http://blog.csdn.net/tianlesoftware

alter tablespace ... offline;

4.每次日志切换时;

alter system switch logfile

注意:

1. alter system switch logfile也将触发完全检查点的发生。

2. alter database datafile ... offline不会触发检查点进程。

如果是单纯的 offline datafile,那么将不会触发文件检查点,只有针对  offline

tablespace的时候才会触发文件检查点,这也是为什么  online  datafile需要   media

recovery而  online tablespace不需要。

对于表空间的 offline后再  online这种情况,最好做个强制的  checkpoint比较好。

关于 offline datafile和   tablespace的区别也可以参考   1.25节。

1.20.3.3.2触发增量检查点

1.在联机热备份数据文件前,要求该数据文件中被修改的块从DB_Buffer写

入数据文件中。所以,发出这样的命令:

ALTER TABLESPACE tablespace_name BIGEN BACKUP / end backup;

也将触发和该表空间的数据文件有关的局部检查点;

2.另外,

ALTER TABLESPACE tablespace_name READ ONLY;

ALTER TABLESPACE tablespace_name OFFLINE NORMAL;

等命令都会触发增量检查点。

1.20.3.4检查点的一些讨论

1.20.3.4.1. Commit成功后,数据还会丢失吗?

对于 Oracle来说,用户所做的 DML操作一旦被提交,则先是在 database  buffer

cache中进行修改,同时在修改之前会将数据的前镜像保存在回滚段中,然后将

修改之前和修改之后的数据都写入到 redo log buffer中,当接收到  commit命令之

后,则 redo log buffer开始写  redo log file,并且记录此时的   scn,当 redo log file

写完了之后,表示这次事务提交操作已经确认被数据库记录了,只有当 redo log

file写成功了,才会给用户    Commit completed的成功字样。

而对于 Database buffer cache中的  dirty buffer则会等待触发   DBWn才写入,

但是如果此时断电,则数据已经被记录到了 redo log  file中,系统在重新启动的

时候,会自动进行嵌滚和回滚来保证数据的一致。所以,只要是 commit成功的

DBA  总群: 104207940    --近满       DBA 总群_4: 63306533       DBA  总群_2:  62697716 --近满

DBA  总群_5: 62697850   DBA  总群_3:283816689 --有大量空闲     DBA  总群_6:

62697977



 

Tianlesoftware  学习  Oracle

Blog:  http://blog.csdn.net/tianlesoftware

了,数据不会丢失!

1.20.3.4.2.数据库发生一次   DBWn,是否将所有 buffer  cache中的   dirty  buffer

都写入,还是先将脏队列中的数据写入?

这话看起来有道理,但实际上,dbwr在写的时候又不断地在产生  dirty buffer ,

所以说检查点发生的时候是期望把该时间点之前的所有脏缓冲区写入数据文件。

所有的 buffer,不在 LRU list上就在   dirty list上,   dbwr写入的时候,一次写的块

数是有一个批量写的隐藏参数控制的。

所以说要是  dbwr将   dirty list也好,   lru list上的也好,要实现全部写入,都

是一个现实系统中很难存在的现象。dirty总是在不断的产生,dbwr总是在不断

地写,增量检查点发生的时候也并不意味着一定要更新数据文件头,检查点开始

的时候只表示该次检查点结束的时候要更新数据文件头的话数据文件头具有该

时间点的一致性。

1.20.3.4.3.关于检查点等待事件:

有些事件的产生必须等待检查点的完成,才能开始数据库的其它操作:日志

文件切换就是其中一个事件,日志切换必须等待检查点完成。

log file switch (checkpoint incomplete)这个等待事件本身也说明,日志切换时

产生的检查点是需要等待的,这个日志文件所对应脏块全部写完后,检查点进程

更新控制文件和数据头,然后这个检查点才能算完成。

也就是说日志切换必须等待检查点完成,而检查点在等待 DBWn完成。

这种等待   DBWn完成的检查点,最后一步写入控制文件和数据文件头的

SCN,肯定是 DBWn完成的最后一块的  SCN。

1.20.3.4.4.检查点为什么要等待   dbwr完成后才进行切换(log  switch)?

log switch时,是不能立即  switch到  active状态的,log  group必须等待。

active表示该  log group还没有完成归档(归档模式下)或者该  log group有进行

instance recovery的需要用到的日志。所以当  checkpoint发生时,如果  dbwr还没

有写完它该写完的 dirty buffers(该 checkpoint时间点以前产生的  dirty  buffers,靠

scn判断),则该  log  group处于   active状态,不会进行日志切换,当然也不会发

生日志文件被覆盖的问题了。

1.20.3.4.5.如果没有设置   archive log,在检查点发生后,发生   log switch一个轮

回,log file是否会被覆盖掉?

当检查点发生后,会触发 lgwr,lgwr会把此时  SCN以前在  redo  buffer中的

所有操作写到 redo  log file,同时 lgwr也会触发  dbwr进程,dbwr也开始把此刻

以前 database buffer中的  dirty buffer队列中的操作写入  data file。

DBA  总群: 104207940    --近满       DBA 总群_4: 63306533       DBA  总群_2:  62697716 --近满

DBA  总群_5: 62697850   DBA  总群_3:283816689 --有大量空闲     DBA  总群_6:

62697977



 

Tianlesoftware  学习  Oracle

Blog:  http://blog.csdn.net/tianlesoftware

其实检查点发生后,就是 lgwr和  dbwr写  buffer到磁盘文件的过程,但是两

者的读写速度时不同的,dbwr写  buffer到数据文件的过程相对较慢,因为   dbwr

写过程是一个随机读取存储的过程。Lgwr写   buffer到   redo文件的过程比    dbwr

要快很多,因为 lgwr是顺序读取写入的。

由于以上 lgwr和  dbwr写操作的速度不同,就产生了一个等待问题。即当   lgwr

轮循一圈后,要进行日志切换,覆盖 redo log file,但是此时 dbwr还没有写完,

那么 lgwr就会出现等待,oracle也会   hang在那里,同时  alter文件中会提示一个

相应的提示 checkpoint not complete。等检查点完成后数据库自动恢复正常。

如:

Thread 1 advanced to log sequence 14215 (LGWR switch)

Current log# 1 seq# 14215 mem# 0: /u03/oradata/newccs/redo01.log

Mon Nov 30 17:35:54 2009

Thread 1 cannot allocate new log, sequence 14216

Checkpoint not complete

Current log# 1 seq# 14215 mem# 0: /u03/oradata/newccs/redo01.log

Mon Nov 30 17:35:55 2009

Thread 1 advanced to log sequence 14216 (LGWR switch)

Current log# 2 seq# 14216 mem# 0: /u03/oradata/newccs/redo02.log

log switch时,会触发检查点,标记检查点时,DBWR要把   log file中   covered

by the log being checkpointed的数据写入到数据文件上,如果  Dbwr没有写完,那

么前一个  logfile是不能被覆盖的。因此必须等检查点完毕,也可以说是将要被

覆盖的日志相关的数据块全部写入数据文件后,该日志文件才能被覆盖!

果这种情况出现,alert文件中会记录  checkpoint not complete事件,这通常表

明你的 dbwr写入过慢或者  logfile组数过少或  log file太小。

1.20.3.4.6.检查点发生时,出现日志切换,但是   dbwr还没有写完,是否会覆盖

redo log file,如果此时掉电,dbwr挂起,会出现丢失数据吗?

会覆盖 redo文件,要等待  dbwr写完才覆盖。或者说要等待检查点完成才覆

盖。

如果 DBWn正在写的脏块是指对应到即将被覆盖的那个日志文件的,那么,

因为在这些操作完成之前,不可能有覆盖这件事发生,假设你预料的掉电发生了,

不会有什么问题,实例恢复时的前滚从刚才准备覆盖的那个日志文件开始。

如果正在写的脏块是指对应到刚刚被写满的那个日志文件的,肯定一时半会

也写不完,日志切换也不会等它,如果切换成功后 dbwr挂了,后面的写脏块操

作估计也还没完成,但是,刚写满的那个文件并没有被覆盖,也不会有任何问题。

因此不会出现数据丢失!

当一个很大的 dml发生时,用户在  commit后,需要将  redo log buffer中的脏

DBA  总群: 104207940    --近满       DBA 总群_4: 63306533       DBA  总群_2:  62697716 --近满

DBA  总群_5: 62697850   DBA  总群_3:283816689 --有大量空闲     DBA  总群_6:

62697977



 

Tianlesoftware  学习  Oracle

Blog:  http://blog.csdn.net/tianlesoftware

数据写入 redo log file中。如果在写的过程中,发现一个  redo log file写不下的话,

需要写另外一个 redo log file,这时应该触发 checkpoint,接着触发 DBWn,将脏

数据写入 datafile,这时发生掉电,导致 DBWR失败。这时其实就可以说   commit

失败了。以上所述其实就是 commit没有提交成功。

1.20.3.4.7. alter systen  switch logfile会触发完全检查点;但是为什么,日志切换

以后检查点只能记录到上一次归档日志产生的时间呢?而不是现在归档日志产

生的时间呢?

因为这时的 checkpoint  enqueue队列中,也就是脏块队列中脏块还不够多,

还不足以触发 DBWn写脏块。所以,内存里需要写入的脏块所对应的  redo还存

在于上一个 redo log里,这时你去看该  redo log的  status为  active。

我们可以通过一下语句查看相关信息:

SQL> select * from x$kccrt;

1.20.4    checkpoint 和   scn 的关系

checkpoint发生的目的就是要把储存在   buffer内的已提交的事务写回   disk,

否则一旦发生 crash,需要进行 recovery时,你就必须花很多的时间从  redo log file

内最后的 SCN交易开始进行   recovery,这样在商业应用上是很浪费时间和没有

效率的。

重点在于当 commit一个事务时,只会立刻将  redo buffer写入  redo log file内,

但是并不会马上将该 update后的  block(dirty block)同步写回 disk datafile中,这是

为了减少过多 disk IO的考虑,所以采取  batch的方式写入。

When  a checkpoint  occurs,  Oracle  must  update the  headers  of all  datafiles  to

record the  details of  the checkpoint.  This is  done by  the CKPT  process. The  CKPT

process does not write blocks to disk; DBWn always performs that work.

在 shutdown normal or shutdown immediate下,也就是所谓的  clean shutdown,

checkpoint也会自动触发,并且把  SCN纪录写回。

当发生 checkpoint时,会把  SCN写到四个地方去。三个地方于  control  file内,

一个在 datafile header。

Control file三个地方为

(1)System checkpoint SCN

SQL> select checkpoint_change# from v$database;

CHECKPOINT_CHANGE#

--------------------



292767

(2)Datafile checkpoint SCN

SQL>    select

name,checkpoint_change#

from    v$datafile    where    name

like

'%users01%';

NAME CHECKPOINT_CHANGE#

----------------------------------- --------------------

/u02/oradata/OMFD1/users01.dbf 292767

(3)Stop SCN

SQL> select name,last_change# from v$datafile where name like '%users01%';

NAME LAST_CHANGE#

----------------------------------- ------------

/u02/oradata/OMFD1/users01.dbf

正常 datafile在  read-write mode下     last_change#一定是  NULL

Datafile header中的一个  SCN:Start SCN在    datafile header

SQL>  select   name,checkpoint_change#  from  v$datafile_header   where  name  like

'%users01%';

NAME CHECKPOINT_CHANGE#

----------------------------------- --------------------

/u02/oradata/OMFD1/users01.dbf 292767

1.20.5 相关问题

1.20.5.1为什么储存在             CONTROL   FILE中要分为两个地方              (SYSTEM

CHECKPOINT SCN,DATAFILE CHECKPOINT SCN) ?

当你把一个 tbs设为   read-only时,他的  SCN会冻结停止,此时    DATAFILE

CHECKPOINT SCN是不会再递增改变的,但是整体的  SYSTEM CHECKPOINT

SCN却仍然会不断递增前进。所以,这就是为什么需要分别在两个地方储存

SCN。

1.20.5.2正常   shutdown database后,SCN会发生什么变化?

我们可以把数据库开在 mount mode

SQL>select checkpoint_change# from v$database;

CHECKPOINT_CHANGE#

--------------------

293184

DBA  总群: 104207940    --近满       DBA 总群_4: 63306533       DBA  总群_2:  62697716 --近满

DBA  总群_5: 62697850   DBA  总群_3:283816689 --有大量空闲     DBA  总群_6:

62697977



 

Tianlesoftware  学习  Oracle

Blog:  http://blog.csdn.net/tianlesoftware

SQL>select name,checkpoint_change#,last_change# from v$datafile  where name like

'%user%';

NAME CHECKPOINT_CHANGE# LAST_CHANGE#

----------------------------------- -------------------- --------------

/u02/oradata/OMFD1/users01.dbf 293184 293184

可以看到储存在control  file中的三个SCN位置都是相同,注意此时的stop   scn

不会是 NULL,而是等于 start scn

我们来查询 datafile header SCN:

SQL>select   name,checkpoint_change#  from   v$datafile_header   where   name  like

'%users01%';

NAME CHECKPOINT_CHANGE#

----------------------------------- --------------------

/u02/oradata/OMFD1/users01.dbf 293184

当 clean shutdown时,checkpoint会进行,并且此时    datafile的  stop scn和   start

scn会相同。等到我门开启数据库时,Oracle检查     datafile  header中的   start  scn

和存于 control  file中的  datafile的  scn是否相同,如果相同,接着检查    start scn

和 stop scn是否相同,如果仍然相同,数据库就会正常开启,否则就需要   recovery...

等到数据库开启后,储存在 control file中的  stop scn就会恢复为  NULL值,此时

表示 datafile是  open在正常模式下了。

如果不正常 SHUTDOWN (shutdown abort),则 mount数据库后,你会发现  stop

scn并不是等于其它位置的   scn,而是等于   NULL,这表示  Oracle在    shutdown

时没有进行 checkpoint,下次开机必须进行 crash recovery。

crash recovery

必须先进行 roll forward(从 redo log file中从目前的  start SCN开始,重做后面

的已提交之交易)。再从 roll back  segment做   rollback未完成(dead   transaction)交

易。检验 controlfile中的  SCN会等于  datafile header的  SCN。

这个就是我们在 2.6节里前滚和后滚的顺序问题。

SQL>select  'controlfile'  "SCN  location",name,checkpoint_change#  from  v$datafile

where name like '%users01%'

union

select 'file header',name,checkpoint_change# from  v$datafile_header where name like

'%users01%';

SCN location NAME CHECKPOINT_CHANGE#

-------------- ----------------------------------- --------------------

DBA  总群: 104207940    --近满       DBA 总群_4: 63306533       DBA  总群_2:  62697716 --近满

DBA  总群_5: 62697850   DBA  总群_3:283816689 --有大量空闲     DBA  总群_6:

62697977



 

Tianlesoftware  学习  Oracle

Blog:  http://blog.csdn.net/tianlesoftware

controlfile /u02/oradata/OMFD1/users01.dbf 293188

file header /u02/oradata/OMFD1/users01.dbf 293188

1.20.5.3 crash recovery和   media recovery的比较

启动数据库时,如果发现 STOP SCN = NULL,表示需要进行 crash recovery;

启动数据库时,如果发现有  datafile   header的    START  SCN不等于储存于

CONTROLFILE的  DATAFILE SCN,表示需要进行 Media recovery

1.20.5.4 RECOVERY DATABASE两种常见问题

(1)  recover database until cancel ==> open database resetlog

这种情况下 DATAFILE  HEADER中的   SCN一定会小于  CONTROLFILE中

的 DATAFILE SCN。

如果你有进行RESTORE  DATAFILE,则该RESTORE的DATAFILE  HEADER

SCN一定会小于目前  CONTROLFILE的  DATAFILE SCN,此时会无法开启数据

库,必须进行    media  recovery。重做     archive   log直到该     datafile  header的

SCN=current scn

restore  datafile后,可以   mount  database然后去检查   controlfile  and  datafile

header的  SCN:

SQL>select  'controlfile'  "SCN  location",name,checkpoint_change#  from  v$datafile

where name like '%users01%'

union

select 'file header',name,checkpoint_change# from  v$datafile_header where name like

'%users01%';

SCN location NAME CHECKPOINT_CHANGE#

-------------- ----------------------------------- --------------------

controlfile /u02/oradata/OMFD1/users01.dbf 313551

file header /u02/oradata/OMFD1/users01.dbf 313401

(2)recover  database  until  cancel using  backup  controlfile;  ===>  open  database

resetlog

这种情况下,DATAFILE HEADER中的   SCN一定会大于  CONTROLFILE的

DATAFILE  SCN 。因为控制文件是旧的控制文件。所以它保存的信息也是以前

的信息。

如果只是某 TABLE被  DROP掉,没有破坏数据库整体数据结构,还可以用

NCOMPLETE RECOVERY解决;

如果是某个 TABLESPACE  OR  DATAFILE被  DROP掉,因为档案结构已经

破坏,目前的  CONTROL  FILE内已经没有该      DATAFILE的信息,就算你只

RESTORE DATAFILE然后进行 INCOMPLETE RECOVERY也无法救回被   DROP

的 DATA FILE。

只好  RESOTRE之前备份的      CONTROL  FILE(里头被   DROP  DATAFILE

Metadata此时还存在),不过  RESTOREC CONTROL FILE后此时    Oracle会发现

CONTROL FILE内的  SYSTEM SCN会小于目前的  DATAFILE  HEADER SCN,

也不等于目前储存于     LOG  FILE内的     SCN,此时就必须使用       RECOVER

DATABASE   UNTIL   CANCEL  USING   BACKUP   CONTROLFILE到 drop datafile or drop tablespace 之前的SCN

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/500314/viewspace-1069837/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2008-07-29

  • 博文量
    137
  • 访问量
    558588