首页 > 数据库 > Oracle > SCN,RedoLog和 Checkpoint
|
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 |
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/500314/viewspace-1069837/ ,如需转载,请注明出处,否则将追究法律责任。