本文档旨在使数据库管理员更好地了解增量检查点(Checkpoint),并对检查点(Checkpoint)优化所用的下列四个初始化参数进行了描述:
- FAST_START_MTTR_TARGET
- LOG_CHECKPOINT_INTERVAL
- LOG_CHECKPOINT_TIMEOUT
- LOG_CHECKPOINTS_TO_ALERT
此外,本文档还介绍了如何解释和处理检查点错误:ALERT.LOG 文件中报告的“Checkpoint not Complete(检查点未完成)”和“Cannot Allocate New Log(无法分配新日志)”。
目录:
1. 什么是检查点?
2. 检查点和性能
3. 与增量检查点相关的参数
4. Redo(重做)日志和检查点
5. 了解检查点错误消息(“Cannot allocate new log”和“Checkpoint not complete”)
6. Oracle 版本信息
7. 使用 Statspack 确定检查点问题
检查点优化和错误处理
1. 什么是检查点?
检查点是一种将内存中的已修改数据块与磁盘上的数据文件进行同步的数据库事件。通过Checkpoint Oracle 确保了被 transaction 修改过数据可以被同步至磁盘。Oracle transaction 提交的时候不会将已修改数据块同步写入磁盘上。检查点有两个用途:(1) 确保数据一致性,和 (2) 实现更快的数据库恢复。如何更快地恢复?由于直至检查点生成时所有的数据库更改均已记录在数据文件中,因此无需再应用先于检查点的 redo 日志条目。检查点必须确保高速缓存中所有已修改的缓冲数据均已切实写入到相应的数据文件中,以避免在发生崩溃(实例或磁盘故障)时可能会出现的数据丢失。
Oracle 只有在特定条件下才会将脏缓存写入磁盘:
- shadow process 需要扫描的数据块个数超过 db_block_buffers 参数的四分之一。
- 每三秒钟。
- 生成一个检查点时。检查点通过五种类型的事件来实现:
- 每次切换 redo 日志文件时。
- 达到 LOG_CHECKPOINT_TIMEOUT 的延迟时。
- 当前 redo 日志文件中已存在了大小为 (LOG_CHECKPOINT_INTERVAL* OS块的大小(bytes))的数据。
- 直接由 ALTER SYSTEM SWITCH LOGFILE 命令实现。
- 直接使用 ALTER SYSTEM CHECKPOINT 命令实现。
在检查点期间会发生以下操作:
- DBWR 将缓冲区缓存中所有已修改的数据库块写回到数据文件中,
- 检查点进程 (ckpt) 更新所有数据文件的文件头,以反映上一个检查点发生的时间 (SCN)
2. 检查点和性能
检查点的优化常常会使数据库管理员左右为难。频繁的检查点会实现更快的数据库恢复,但也会导致数据库性能降低。那么,DBA 如何解决这一问题呢?根据数据库中的数据文件数量,检查点将会是一种高度占用资源的操作,因为所有数据文件头在检查点期间都会被冻结。关于检查点的频率设置,需要对性能进行权衡。检查点频率越高,就能在数据库崩溃后更快地实现恢复。这也是为什么一些不太能忍受意外系统停机的客户现场常常会选择此选项的原因。但是,在很多情况下,频繁的检查点可能会导致性能降低,这使得上述观点并不能完全站稳脚跟。 我们假设数据库已启动,且有 95% 的时间处于运行状态,剩下 5% 未运行时间是由于出现偶发的实例崩溃或硬件故障,需要进行数据库恢复。对于大多数的客户现场而言,优化 95% 的性能相比于极少的 5% 停机时间要更具意义。
本文档假设性能是您的首要考虑事项,并由此给出相应的建议。因此,您的目标是通过优化尽量减少检查点的频率。
优化检查点涉及到下面四个关键初始化参数:
- FAST_START_MTTR_TARGET
- LOG_CHECKPOINT_INTERVAL
- LOG_CHECKPOINT_TIMEOUT
- LOG_CHECKPOINTS_TO_ALERT下面将详细讨论这些参数。
同时,还针对alert日志中出现的“checkpoint not complete”消息给出了处理建议,这些消息说明redo 日志和检查点需要优化。
3. 与增量检查点相关的参数
注意:日志文件切换将始终覆盖由以下参数引起的检查点。
自 Oracle 9i 以来,FAST_START_MTTR_TARGET 参数已成为优化增量检查点目标的首选方法。通过 FAST_START_MTTR_TARGET,您可以指定数据库执行单实例的崩溃恢复所要花费的秒数。基于内部统计信息,增量检查点会自动调整检查点目标,以满足 FAST_START_MTTR_TARGET 的要求。
V$INSTANCE_RECOVERY.ESTIMATED_MTTR 显示当前预计的平均恢复时间 (MTTR)(以秒为单位)。即使未指定 FAST_START_MTTR_TARGET,也同样会显示此值。
V$INSTANCE_RECOVERY.TARGET_MTTR 显示由系统强制执行的有效 MTTR 目标(以秒为单位)。
V$MTTR_TARGET_ADVICE 显示在当前的 MTTR 设置下由当前的工作负载产生的 I/O 数量,以及在其他 MTTR 设置下将由当前的工作负载产生的预计 I/O 数量。此视图可帮助用户在运行时性能和设置 FAST_START_MTTR_TARGET 以实现快速恢复之间进行权衡。
LOG_CHECKPOINT_INTERVAL 参数指定增量检查点目标应滞后于当前日志尾的最大 redo 块数量。
如果指定了 FAST_START_MTTR_TARGET,就不应设置 LOG_CHECKPOINT_INTERVAL 或将其设置为 0。在大多数 Unix 系统上,操作系统块大小都是 512 字节。
也 就是说,将 LOG_CHECKPOINT_INTERVAL 的值设置为 10,000 就意味着增量检查点目标相对于当前日志尾的滞后不得超过 5,120,000 (5M) 字节。以此计算,如果 redo 日志的大小为 20M,则会对每个日志产生 4 个检查点。
LOG_CHECKPOINT_INTERVAL 会影响检查点的发生时间,这意味着应特别注意此参数的设置,保持其随 redo 日志文件的大小变化而更新。检查点的频率是影响数据库从意外故障中恢复所需时间的因素之一。检查点之间的间隔越长,则在发生系统崩溃时,数据库恢复所需的 时间就越长。检查点间隔越短意味着数据库的恢复速度越快,但是代价是检查点操作会消耗更多的资源。
此参数还会影响在恢复的前滚阶段期间完成数据库恢复操作所需的时间。实际的恢复时间取决于此时间,以及其他因素,例如故障类型(实例或系统崩溃、介质故障等)以及需要应用的归档 redo 日志数量。
LOG_CHECKPOINT_TIMEOUT 参数指定增量检查点目标应滞后于当前日志尾的最长秒数。
换句话说,它指定缓冲区缓存中的脏缓存可以保持脏状态的时间。
检查点频率影响数据库从意外故障中恢复所需的时间。检查点之间的间隔越长,数据库恢复所需的时间就越多。
Oracle 建议使用 LOG_CHECKPOINT_INTERVAL 而不是 LOG_CHECKPOINT_TIMEOUT 来控制检查点间隔,后者会每“n”秒启动一次检查点,而不管事务频率。这可能会导致在事务量变化的情况下出现不必要的检查点。只要可能,就必须避免不必要的检查点,以实现最佳性能。
许多人会有这样一种误解:将 LOG_CHECKPOINT_TIMEOUT 设置为给定值之后,系统就会按该间隔启动日志切换,从而启用用于stand-by数据库配置的恢复窗口。日志切换会引起检查点,但检查点并不会引起日志切换。引起日志切换的唯一方式是使用 ALTER SYSTEM SWITCH LOGFILE 进行手动操作或重新调节 redo 日志大小,以引起更为频繁的切换。这由操作系统块而非时间间隔控制。
在线 redo 日志的大小对性能和恢复至关重要。
有关 redo 日志和检查点的信息,请参考以下其他部分。
通过 LOG_CHECKPOINTS_TO_ALERT,您可以将检查点记录到alert日志中。
这样做有助于确定检查点是否按所需频率发生。
在 Oracle9i 之前,此参数为静态参数。
Oracle 通常建议将此参数设置为 TRUE,因为开销很小,可以忽略不计,但alert日志中的信息可能会非常有用。
有关上述实例参数会如何影响检查点的更多详细信息,请参阅 Note:76713.1
4. Redo 日志和检查点
每次切换日志时都会发生一次检查点。如果上一个检查点已在进行中,由日志切换引起的检查点将覆盖当前检查点。此时就需要大小合适的 redo 日志,以避免因频繁的日志切换而引起不必要的检查点。另外,增量检查点目标和日志尾之间的间隔也会受“最小在线日志文件大小的 90%”设置所限制。这样可确保在大多数情况下,日志切换不必等待检查点。因此,日志文件大小应配置得足够大。一个好的办法是,最多每二十分钟切换一次日志。日志文件过小会增加检查点活动并降低性能。Oracle 建议用户将所有在线日志文件设置为同一大小,且每个线程至少拥有两个日志组。若要监视日志切换发生的速度,以及随后的检查点发生的速度,alert日志是一个很有价值的工具。
以下是通过alert日志发现日志切换过于频繁的示例:
Fri May 16 17:15:43 1997
Thread 1 advanced to log sequence 1272
Current log# 3 seq# 1272 mem# 0: /prod1/oradata/logs/redologs03.log
Thread 1 advanced to log sequence 1273
Current log# 1 seq# 1273 mem# 0: /prod1/oradata/logs/redologs01.log
Fri May 16 17:17:25 1997
Thread 1 advanced to log sequence 1274
Current log# 2 seq# 1274 mem# 0: /prod1/oradata/logs/redologs02.log
Thread 1 advanced to log sequence 1275
Current log# 3 seq# 1275 mem# 0: /prod1/oradata/logs/redologs03.log
Fri May 16 17:20:51 1997
Thread 1 advanced to log sequence 1276
Current log# 1 seq# 1276 mem# 0: /prod1/oradata/logs/redologs01.log
如果 redo 日志每 3 分钟切换一次,您就会察觉到性能降低。这表明 redo 日志不够大,不能有效地处理该事务负载。
有关如何估计 redo 日志文件的适当大小的详细信息,请参阅 Note:1038851.6 。有关如何重新调节在线 redo 日志文件大小的示例,请参阅 Note:1035935.6 。
5. 了解检查点错误消息(“Cannot allocate new log”和“Checkpoint not complete”)
有时,您可以在 alert.log 文件中看到以下相应消息:Thread 1 advanced to log sequence 248
Current log# 2 seq# 248 mem# 0: /prod1/oradata/logs/redologs02.log
Thread 1 cannot allocate new log, sequence 249
Checkpoint not complete
此信息表明 Oracle 希望重新使用某个 redo 日志文件,但当前的检查点位置仍位于该日志中。在这种情况下,Oracle 必须等到检查点位置通过该日志。由于增量检查点目标相对于当前日志尾的滞后绝不会超过最小日志文件大小的 90% 以上,因此,如果 DBWR 写入速度过慢,或者在日志全满之前发生日志切换,或者日志文件过小,就会遇到这种情况。在数据库等待检查点时,redo 生成过程会停止,直到完成日志切换。
6. Oracle 版本信息
在 Oracle8i 中,初始化参数 FAST_START_IO_TARGET 会使增量检查点自动调整其目标,从而使恢复所需的数据块数量不多于 FAST_START_IO_TARGET 设置的值。自 Oracle 9i 开始,已弃用此参数,取而代之的是参数 FAST_START_MTTR_TARGET。
7. 使用 Statspack 确定检查点问题
您可以每 15 分钟左右收集一次 Statspack 快照,这些快照报告将收集有关在该时间段已开始的检查点数量、已完成的检查点数量及检查点发生时写入的数据库缓冲数量的有用信息。此外,还包含关于 redo 活动的统计信息。通过收集和比较这些快照报告,您可以完整地了解不同时期的检查点性能。Statspack 报告中另一个值得关注的内容是等待事件,下面的等待事件明确指出了 redo 日志吞吐量和检查点的问题:
log file switch (checkpoint incomplete)
log file switch (archiving needed)
log file switch/archive
log file switch (clearing log file)
log file switch completion
log switch/archive
log file sync
如果上述等待事件中的一个或多个频繁地出现,且相关数值较大,那您就需要采取行动了,例如添加更多的在线 redo 日志文件,或增加其大小和/或修改检查点参数。
NOTE:76713.1 - 8i Parameters that Influence Checkpoints
NOTE:1038851.6 - How to Estimate Size of Redo Logs