【问题标题】:Writing dirty-blocks to the discs is only performed on commit?将脏块写入磁盘仅在提交时执行?
【发布时间】:2020-02-21 03:41:30
【问题描述】:

据我所知,DBW 将脏块写入磁盘并在提交操作发生时解锁块。但是,它真的会发生吗,因为我相信 DBWn 与提交问题没有直接关系?

如果不是,它是如何执行这个写操作的?

因为它也被称为“懒惰的作家”。

我很困惑。

【问题讨论】:

  • 我不确定我是否理解所提出的问题。提交期间不需要将脏块写入磁盘。对这些块进行更改所需的重做信息确实需要作为提交的一部分写入。 DBW 进程将脏块写入磁盘,但这与事务完全异步发生——脏块可能在事务提交之前很久或之后很久才写入。对于脏块,没有什么可以“解锁”的。我不确定您是在问 DBW 在做什么、提交操作在做什么还是其他什么。

标签: oracle oracle12c database-performance database-administration sql-tuning


【解决方案1】:

假设您正在更新表中的记录。在非常高的抽象级别上,一旦保存目标记录的块在数据库缓冲区缓存中被识别(或复制到),就会发生以下步骤。

  1. 创建了描述如何将 UNDO 记录插入 UNDO 块的 REDO 更改向量。如果将来需要,则需要此 UNDO 来回滚更改。可能还需要 UNDO 来满足在启动更新之前启动且仍在运行的 SQL。
  2. 创建了描述数据块更改以执行请求更新的 REDO 更改向量。
  3. 结合两个 REDO 更改向量,创建一个 REDO 记录并将其写入循环重做日志缓冲区 (RLB)。
  4. UNDO 记录被插入到缓冲区缓存中的 UNDO 块中。
  5. 实际更改是在缓冲区缓存中的数据块中进行的。
  6. 此时,RLB 可能包含来自多个服务器进程的 REDO 条目。 RLB 的一部分由单个 Log Writer 进程 (LGWR) 顺序写入在线重做日志文件。只有当下列情况之一发生时,来自 RLB 的所有重做条目才会写入在线重做日志文件。

    一个。服务器进程之一发出 COMMIT。 (日志文件同步等待事件)。

    b.发生日志切换(在线重做日志文件已填满,LGWR 从有限数量的在线重做日志文件切换到新的在线重做日志文件,LGWR 以循环方式写入其中)。

    c。每 3 秒一次。

    d。 RLB 已满三分之一。

    e。当 Database Writer 进程 (DBWn) 需要将脏缓冲区写入磁盘时。 (何时会出现这种需求将在后面解释)。

  7. 请注意,即使现​​在脏缓冲区(包括我们在缓冲区缓存中修改的块)还没有写入磁盘(数据文件)。现在让我们谈谈 DBWn。
  8. 与 LGWR 进程不同,可以有多个 DBWn 进程(由后缀 n 表示),它们可以异步(在实际更改写入缓冲区缓存中的数据块时,当然是在更改缓冲区之后)将数据库缓冲区缓存中的脏缓冲区以并行写入的方式写入磁盘。但这些写入仅在以下情况下发生。

    一个。当数据库缓冲区缓存中没有更多干净的缓冲区时

    b.发生检查点时。 (检查点是重做日志文件中的点(系统更改号(SCN)),直到脏缓冲区已经写入磁盘(即)在重做日志文件中,数据文件与缓冲区缓存同步.)

因此声称 DBWn 仅在需要时执行惰性写入,而不是 LGWR 执行的快速接近实时的写入。

还有一点,Oracle 的粒度逻辑写入单元是 Block。在数据文件的磁盘上,此块被识别,然后复制到缓冲区缓存中。 Oracle 从不锁定块。在读取缓冲区之前,它会在缓冲区块的标头上获得一个锁存器。这就是为什么当一些大范围扫描阻止其他进程获取此锁存器时,我们会看到“锁存缓存缓冲区链”等待事件。就我们在​​更新 Oracle 块中的行时考虑锁定而言,Oracle 在粒度级别锁定我们更新的行。

Oracle documentation中Oracle实例架构下的内存和进程架构是理解这些概念的好地方。

【讨论】:

    猜你喜欢
    • 2019-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-03
    • 1970-01-01
    • 2016-12-30
    • 2014-12-16
    • 2021-08-18
    相关资源
    最近更新 更多