oracle - 将脏块写入磁盘仅在提交时执行?
问题描述
据我所知,DBW 将脏块写入磁盘并在提交操作发生时解锁块。但是,它真的会发生吗,因为我相信 DBWn 与提交问题没有直接关系?
如果不是,它如何执行这个写操作?
因为它也被称为“懒惰的作家”。
我很困惑。
解决方案
假设您正在更新表中的记录。在非常高的抽象级别上,一旦保存目标记录的块在(或复制到)数据库缓冲区缓存中被识别,就会发生以下步骤。
- 创建了描述如何将 UNDO 记录插入 UNDO 块的 REDO 更改向量。如果将来需要,则需要此 UNDO 来回滚更改。可能还需要 UNDO 来满足在启动更新之前启动并仍在运行的 SQL。
- 创建一个 REDO 更改向量,描述数据块更改以执行请求的更新。
- 结合两个 REDO 更改向量,创建一个 REDO 记录并将其写入循环重做日志缓冲区 (RLB)。
- UNDO 记录被插入到缓冲区高速缓存中的 UNDO 块中。
- 实际更改是在缓冲区高速缓存中的数据块中进行的。
此时,RLB 可能包含来自多个服务器进程的 REDO 条目。RLB 的一部分由单个 Log Writer 进程 (LGWR) 顺序写入在线重做日志文件。只有当下列情况之一发生时,来自 RLB 的所有重做条目才会写入在线重做日志文件。
一个。服务器进程之一发出 COMMIT。(日志文件同步等待事件)。
湾。发生日志切换(在线重做日志文件已填满,LGWR 从有限数量的在线重做日志文件切换到新的在线重做日志文件,LGWR 以循环方式写入其中)。
C。每 3 秒。
d。RLB 已满三分之一。
e. 当 Database Writer 进程 (DBWn) 需要将脏缓冲区写入磁盘时。(何时会出现这种需求将在后面解释)。
- 请注意,即使现在脏缓冲区(包括我们在缓冲区缓存中修改的块)还没有写入磁盘(数据文件)。现在让我们谈谈DBWn。
与 LGWR 进程不同,可以有多个 DBWn 进程(用后缀 n 表示),它们可以异步地(从实际更改写入缓冲区缓存中的数据块时,当然在对缓冲区进行更改之后)写入脏以并行写入的方式从数据库缓冲区高速缓存缓冲区到磁盘。但这些写入仅在以下情况下发生。
一个。当数据库缓冲区缓存中没有更多干净的缓冲区时
湾。发生检查点时。(检查点是重做日志文件中的点(系统更改号(SCN)),直到脏缓冲区已经写入磁盘(即)在重做日志文件中,数据文件与缓冲区缓存同步.)
因此,据称 DBWn 仅在需要时才执行惰性写入,而不是 LGWR 执行的快速接近实时的写入。
还有一点,Oracle 的粒度逻辑写入单元是 Block。在数据文件的磁盘上,此块被识别,然后复制到缓冲区缓存中。Oracle 从不锁定块。在读取缓冲区之前,它会在缓冲区块的标头上获得一个锁存器。这就是为什么当一些大范围扫描阻止其他进程获取此锁存器时,我们会看到“锁存缓存缓冲区链”等待事件。就我们在更新 Oracle 块中的行时考虑锁定而言,Oracle 在粒度级别锁定我们更新的行。
Oracle 文档中 Oracle 实例架构下的内存和进程架构是理解这些概念的好地方。
推荐阅读
- reactjs - 尽管测试成功,但“npm test”失败(使用 create-react-app 创建的 reactjs 应用程序)
- php - 如何通过从数据库中获取值来制作可靠的下拉列表
- laravel - 加入表并从多对多获取(Laravel)
- javascript - 如何修复“将请求的模式设置为'no-cors'”错误?
- swift - Swift:使用 tableView DidSelect 方法更改单元格的 UIButton 图像
- xml - Xpath 获得预期值但在根标签中
- java - 如何从组合键中设置和获取值
- scala - Spark 驱动程序以代码 137 终止并且没有错误消息。原因是什么?
- javascript - 如何检查数组是否包含任何两个特定字符串
- angular - Angular 发布请求没有 req.user 信息