checkpointandredologWord格式.docx
- 文档编号:17526161
- 上传时间:2022-12-07
- 格式:DOCX
- 页数:13
- 大小:27.83KB
checkpointandredologWord格式.docx
《checkpointandredologWord格式.docx》由会员分享,可在线阅读,更多相关《checkpointandredologWord格式.docx(13页珍藏版)》请在冰豆网上搜索。
大多数关系型数据库都采用"
在提交时并不强迫针对数据块的修改完成"
而是"
提交时保证修改记录(以重做日志的形式)写入日志文件"
的机制,来获得性能的优势。
这句话的另外一种描述是:
当用户提交事务,写数据文件是"
异步"
的,写日志文件是"
同步"
的。
这就可能导致数据库实例崩溃时,内存中的DB_Buffer
中的修改过的数据,可能没有写入到数据块中。
数据库在重新打开时,需要进行恢复,来恢复DB
Buffer
中的数据状态,并确保已经提交的数据被写入到数据块中。
检查点是这个过程中的重要机制,通过它来确定,恢复时哪些重做日志应该被扫描并应用于恢复。
要了解这个检查点,首先要知道checkpoint
queue概念,检查点发生后,触发DBWn,CKPT获取发生检查点时对应的SCN,通知DBWn要写到这个SCN为止,
DBWR写dirty
buffer
是根据
在被首次
modify的时候的时间的顺序写出,也就是
buffer被modify
的时候会进入一个queue
(checkpoint
queue),DBWr
就根据queue从其中批量地写到数据文件。
由于这里有一个顺序的关系,所以
dbwr的写的进度就是可衡量的,写到哪个buffer的时候该buffer的首次变化时候的scn就是当前所有数据文件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写数据文件,这样数据文件内容就不一致,若掉电需要进行崩溃恢复。
触发DBWR进程的条件有:
DBWR超时,大约3秒
系统中没有多余的空缓冲区来存放数据
CKPT
进程触发DBWR
2.2
Checkpoint
触发条件
oracle8以后推出了incremental
checkpoint(增量检查点)的机制,在以前的版本里每checkpoint时都会做一个full
thread
checkpoint(完全检查点),这样的话所有脏数据会被写到磁盘,巨大的i/o对系统性能带来很大影响。
为了解决这个问题,oracle引入了checkpoint
queue机制,每一个脏块会被移到检查点队列里面去,按照low
rdb(第一次对此块修改对应的redo
block
address)来排列,靠近检查点队列尾端的数据块的low
rba值是最小的,而且如果这些赃块被再次修改后它在检查点队列里的顺序也不会改变,这样就保证了越早修改的块越早写入磁盘。
每隔3秒钟ckpt会去更新控制文件和数据文件,记录checkpoint执行的情况。
触发CheckPoint(检查点)
条件有很多,比如:
通过正常事务处理或者立即选项关闭例程时(shutdown
immediate或者Shutdown
normal),
当通过设置初始化参数:
LOG_CHECKPOINT_INTERVAL,
LOG_CHECKPOINT_TIMEOUT
FAST_START_IO_TARGET
强制时;
当数据库管理员手动请求时:
ALter
system
checkpoint;
alter
tablespace
...
offline;
每次日志切换时;
switch
logfile
logfile也将触发完全检查点的发生。
database
datafile
offline
不会触发检查点进程。
如果是单纯的offline
datafile,那么将不会触发文件检查点,只有针对offline
tablespace的时候才会触发文件检查点,这也是为什么online
datafile需要media
recovery而online
tablespace不需要。
对于表空间的offline后再online这种情况,最好做个强制的checkpoint比较好。
关于offline
和tablespace
的区别也可以参考我的blog:
ALTER
DATABASE
与
TABLESPACE
OFFLINE的区别
以上的触发条件将触发完全检查点,促使DBWR
将检查点时刻前所有的脏数据写入数据文件。
另外,一般正常运行期间的数据库不会产生完全检查点。
下面很多事件将导致增量检查点,比如:
在联机热备份数据文件前,要求该数据文件中被修改的块从DB_Buffer
写入数据文件中。
所以,发出这样的命令:
tablespace_name
BIGEN
BACKUP
&
end
backup;
也将触发和该表空间的数据文件有关的局部检查点;
另外,
READ
ONLY;
OFFLINE
NORMAL;
等命令都会触发增量检查点。
2.3
关于检查点的一点具体应用讨论
2.3.1.
Commit成功后,数据还会丢失吗?
对于Oracle来说,用户所做的DML操作一旦被提交,则先是在database
cache
中进行修改,同时在修改之前会将数据的前镜像保存在回滚段中,然后将修改之前和修改之后的数据都写入到redo
buffer中,当接收到commit命令之后,则redo
buffer开始写redo
file
,并且记录此时的scn,当redo
写完了之后,表示这次事务提交操作已经确认被数据库记录了,只有当redo
写成功了,才会给用户
Commit
completed
的成功字样。
而对于Database
cache中的dirty
buffer则会等待触发DBWn才写入,但是如果此时断电,则数据已经被记录到了redo
file中,系统在重新启动的时候,会自动进行嵌滚和回滚来保证数据的一致。
所以,只要是commit成功的了,数据不会丢失!
2.3.2.
数据库发生一次DBWn,是否将所有buffer
中的dirty
都写入,还是先将脏队列中的数据写入?
这话看起来有道理,但实际上,dbwr在写的时候又不断地在产生dirty
所以说检查点发生的时候是期望把该时间点之前的所有脏缓冲区写入数据文件。
所有的buffer,不在LRU
list上就在dirty
list上,
dbwr写入的时候,一次写的块数是有一个批量写的隐藏参数控制的。
所以说要是
dbwr将
dirty
list也好,
lru
list上的也好,要实现全部写入,都是一个现实系统中很难存在的现象。
总是在不断的产生,dbwr总是在不断地写,增量检查点发生的时候也并不意味着一定要更新数据文件头,检查点开始的时候只表示该次检查点结束的时候要更新数据文件头的话数据文件头具有该时间点的一致性。
2.3.3.
关于检查点等待事件:
有些事件的产生必须等待检查点的完成,才能开始数据库的其它操作:
日志文件切换就是其中一个事件,日志切换必须等待检查点完成。
incomplete)
这个等待事件本身也说明,日志切换时产生的检查点是需要等待的,这个日志文件所对应脏块全部写完后,检查点进程更新控制文件和数据头,然后这个检查点才能算完成。
也就是说日志切换必须等待检查点完成,而检查点在等待DBWn完成。
这种等待DBWn完成的检查点,最后一步写入控制文件和数据文件头的SCN,肯定是DBWn完成的最后一块的SCN。
2.3.4.
检查点为什么要等待dbwr完成后才进行切换(log
switch)?
switch时,是不能立即switch到active状态的,log
group必须等待。
active表示该log
group还没有完成归档(归档模式下)或者该log
group有进行instance
recovery的需要用到的日志。
所以当checkpoint发生时,如果dbwr还没有写完它该写完的dirty
buffers(该checkpoint时间点以前产生的dirty
buffers,
靠scn判断),则该log
group处于active状态,不会进行日志切换,当然也不会发生日志文件被覆盖的问题了。
2.3.5.
如果没有设置archive
,在检查点发生后,发生log
switch一个轮回,log
file是否会被覆盖掉?
当检查点发生后,会触发lgwr,lgwr会把此时SCN以前在redo
buffer中的所有操作写到redo
file,同时lgwr也会触发dbwr进程,dbwr也开始把此刻以前database
buffer中的dirty
buffer队列中的操作写入data
file。
其实检查点发生后,就是lgwr和dbwr写buffer到磁盘文件的过程,但是两者的读写速度时不同的,dbwr写buffer到数据文件的过程相对较慢,因为dbwr写过程是一个随机读取存储的过程。
Lgwr写buffer到redo文件的过程比dbwr要快很多,因为lgwr是顺序读取写入的。
由于以上lgwr和dbwr写操作的速度不同,就产生了一个等待问题。
即当lgwr
轮循一圈后,要进行日志切换,覆盖redo
file,但是此时dbwr还没有写完,那么lgwr就会出现等待,oracle也会hang在那里,同时alter文件中会提示一个相应的提示checkpoint
not
complete。
等检查点完成后数据库自动恢复正常。
当log
switch时,会触发检查点,标记检查点时,DBWR要把log
file中covered
by
the
being
checkpointed的数据写入到数据文件上,如果Dbwr没有写完,那么前一个logfile是不能被覆盖的。
因此必须等检查点完毕,也可以说是将要被覆盖的日志相关的数据块全部写入数据文件后,该日志文件才能被覆盖!
如果这种情况出现,alert文件中会记录checkpoint
complete事件,这通常表明你的dbwr写入过慢或者logfile组数过少或log
file太小。
Log
和Checkpoint
complete
2.3.6.
检查点发生时,出现日志切换,但是dbwr还没有写完,是否会覆盖redo
file,如果此时掉电,dbwr挂起,会出现丢失数据吗?
不会覆盖redo文件,要等待dbwr写完才覆盖。
或者说要等待检查点完成才覆盖。
如果DBWn正在写的脏块是指对应到即将被覆盖的那个日志文件的,那么,因为在这些操作完成之前,不可能有覆盖这件事发生,假设你预料的掉电发生了,不会有什么问题,实例恢复时的前滚从刚才准备覆盖的那个日志文件开始。
如果正在写的脏块是指对应到刚刚被写满的那个日志文件的,肯定一时半会也写不完,日志切换也不会等它,如果切换成功后dbwr挂了,后面的写脏块操作估计也还没完成,但是,刚写满的那个文件并没有被覆盖,也不会有任何问题。
因此不会出现数据丢失!
当一个很大的dml发生时,用户在commit后,需要将redo
buffer中的脏数据写入redo
file中。
如果在写的过程中,发现一个redo
file写不下的话,需要写另外一个redo
file,这时应该触发checkpoint,接着触发DBWn,将脏数据写入datafile,这时发生掉电,导致DBWR失败。
这时其实就可以说commit失败了。
以上所述其实就是commit没有提交成功。
2.3.7.
systen
logfile会触发完全检查点;
但是为什么,日志切换以后检查点只能记录到上一次归档日志产生的时间呢?
而不是现在归档日志产生的时间呢?
因为这时的checkpoint
enqueue队列中,也就是脏块队列中脏块还不够多,还不足以触发DBWn写脏块。
所以,内存里需要写入的脏块所对应的redo还存在于上一个redo
log里,这时你去看该redo
log的status为active。
我们可以通过一下语句查看相关信息:
SQL>
select
*
from
x$kccrt;
三.
SCN(system
change
number)
3.1
SCN
定义:
SCN是当Oracle数据更新后,由DBMS自动维护去累积递增的一个数字。
当一个事务commit时,LGWR会将log
buffer写入redo
file,同时也会将该事务的
SCN同步写入到redo
file内(wait-until-completed)。
因此当你commit
transaction时,
在成功的讯息返回之前,LGWR必须先完整的完成上述行为之后,否则你是看不到提交成功的响应讯息。
我们可以查询目前系统最新的SCN
dbms_flashback.get_system_change_number
dual;
可以理解的,这里返回的SCN,也是目前redo
file最新的SCN纪录。
因为commit后的交易才会有SCN,而一旦commit就会立刻写入redo
3.2
CHECKPOINT
和
的关连
checkpoint发生的目的就是要把储存在buffer内的已提交的事务写回disk,否则一旦发生crash,需要进行recovery时,你就必须花很多的时间从redo
file内最后的SCN交易开始进行recovery,这样在商业应用上是很浪费时间和没有效率的。
重点在于当commit一个事务时,只会立刻将redo
file内,但是并不会马上将该update后的block(dirty
block)同步写回disk
datafile中,这是为了减少过多disk
IO的考虑,所以采取batch的方式写入。
When
a
occurs,
must
update
headers
of
all
datafiles
to
record
details
checkpoint.
This
is
done
process.
The
process
does
write
blocks
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
===========>
(SYSTEM
in
control
file)
checkpoint_change#
v$database;
CHECKPOINT_CHANGE#
--------------------
292767
2.Datafile
===============>
(DATAFILE
name,checkpoint_change#
v$datafile
where
name
like
'
%users01%'
;
NAME
-----------------------------------
/u02/oradata/OMFD1/users01.dbf
3.Stop
======================>
(STOP
name,last_change#
LAST_CHANGE#
------------
/u02/oradata/OMFD1/users01.dbf
正常datafile在read-write
mode下
last_change#一定是NULL
另外一个地方在datafile
header内
4.Start
================================>
HEADER)
v$datafile_header
3.3
相关问题
3.3.1
为什么储存在CONTROL
FILE中要分为两个地方(SYSTEM
SCN,DATAFILE
SCN)
?
当你把一个tbs设为read-only时,他的SCN会冻结停止,此时DATAFILE
SCN是不会再递增改变的,
但是整体的SYSTEM
SCN却仍然会不断递增前进。
所以,这就是为什么需要分别在两个地方储存SCN。
3.3.2
正常shutdown
database后,SCN会发生什么变化?
我们可以把数据库开在mount
mode
293184
name,checkpoint_change#,last_change#
%user%'
CHECKPOINT_CHANGE#
--------------------
--------------
293184
可以看到储存在control
file中的三个SCN位置都是相同,注意此时的stop
scn不会是NULL,而是等于start
scn
我们来查询datafile
header
SCN:
name,checkpoint_change#
29
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- checkpointandredolog