Oracle体系结构初探:聊聊REDO

上一篇文章写了undo(文章链接:聊聊UNDO),这篇和大家一起聊聊redo。redo如果按照我的傻瓜翻译,意为再次去做、重新去做。Oracle官方对于redo的描述是:记录对数据所做的所有更改,包括未提交和已提交的更改;通过REDO来保证数据库的事务可以被重演,从而使得在故障之后,数据可以被恢复。

事务重演,这个名词稍微抽象一点点;我个人在抽象事务理解上比较愚笨,最开始在学习的时候花了不少功夫才理解这个名词。所以也想在这里举个例子和大家分享下我的拙见:

2024-04-18 00:00:00,我启动了Oracle数据库实例ORCL;

从此刻开始,ORCL对应的应用系统开始正常运行,开始向ORCL中增删改查数据;

2024-04-18 18:05:20,ORCL所在服务器突然意外关机了;

在关机的此时此刻有个INSERT操作,已经提交,但数据还未来得及写入磁盘;

2024-04-18 18:13:14,服务器恢复,开始启动ORCL数据库实例(此时的这个操作,其实应该叫做恢复ORCL实例);但是关机时提交的INSERT数据并没有写入磁盘,这不就造成了数据丢失嘛!Oracle多聪明,它此时会根据redo日志(online redo log)里的内容,将INSERT操作重新执行一遍,这就避免了此问题。

上面将INSERT操作重新执行一遍的过程,就是事务重演。

上面的例子,其实还有个专业的叫法:前滚;即已提交未写入的数据再次写入。

前滚是发生在Oracle实例恢复时的一个步骤。

那么正好在此处简单描述下实例恢复的过程:Oracle实例崩溃,进行实例恢复;① 先发生前滚,② 再打开数据库,③然后发生回滚。

以上是实例恢复的三个阶段,可以发现除了redo以外,undo也参与了实例恢复,因为发生了回滚。这也是在上一篇文章 《聊聊UNDO》中没有提到的UNDO的一个功能。

下面开始和大家分享下redo相关的一些基本知识内容,先看目录。

目录

redo相关组件

redo日志循环写

归档模式 

非归档模式 

redo日志状态

redo日志切换

redo日志操作


redo相关组件

在数据库中,redo的功能主要通过3个组件来实现:Redo Log Buffer、LGWR后台进程和Redo Log File。下面分别对这3个组件进行介绍。

  • Redo Log Buffer

Redo Log Buffer位于SGA中,是一块循环使用的内存区域,用来保存数据库变更的相关信息。这些信息以Redo Entries(重做条目)形式存储。

Redo Entries包含重构、重做数据库变更的重要信息(包括INSERT、UPDATE、DELETE、CREATE、ALTER或者DROP等)。而这些Redo Entries内容是被Oracle数据库进程从PGA复制到SGA中的Redo Log Buffer中的;多提一句的是SQL的语义解析,语法解析,执行计划都是在PGA中进行的,所以我们也就能推测到Redo Entries的信息格式大概是什么了。

Redo Entries主要是scn、时间戳、sql_redo等信息,这些信息可以通过Oracle的LogMiner工具去分析查看(配合v$logmnr_contents视图)。其中sql_redo就是产生redo的具体sql内容。

  • 后台进程LGWR

LGWR的作用是循环把Redo Log Buffer中的内容写出到Redo Log File中。当满足以下条件时,会触发LGWR进程:

  1. 事务提交时
  2. 每3秒钟
  3. 彻底关机前
  4. 在DBWN写入之前
  • Redo Log Files

重做日志文件,以组(group)出现。可以通过v$logfile查询相关日志文件信息。

select * from v$logfile

在这里重做日志文件又可以分为:ONLINE REDO LOG(在线重做日志)和 ARCHIVE REDO LOG(归档重做日志) 

ONLINE REDO LOG

Oracle以SQL脚本的形式实时记录数据库的数据更新,换句话说,按特定的格式实时保存已执行的SQL脚本到在线日志文件中,这个格式其实就是前文提到Redo Entries。

ARCHIVE REDO LOG

归档重做日志,简称归档日志,指当条件满足时,Oracle将在线重做日志以文件形式保存到硬盘(持久化)

从实际情况来看 ARCHIVE REDO LOG 其实就是 ONLINE REDO LOG 的备份。

redo日志循环写

那么ONLINE REDO LOG(在线重做日志)和 ARCHIVE REDO LOG(归档重做日志) 是如何参与Oracle的工作的呢?

先不急,我们再进一步探究下Redo Log File的细节信息:

Ⅰ:每个Oracle数据库都至少有2个Online重做日志组,每个组中至少有1个重做日志文件,这些Online重做日志组以循环方式使用。

Ⅱ:每组内的日志文件的内容完全相同,且保存在不同的位置,用于磁盘日志镜像,以做多次备份提高安全性。

Ⅲ: 我们是可以根据实际情况自定义添加、修改、删除日志组和日志文件的。

Ⅳ:在默认情况下,Oracle只有1个重做日志组处于活动状态;

数据库在开启归档模式状态下 和 非归档模式下的重做日志工作方式是不一样的,我们先来一起看下归档模式下的重做日志是如何工作的。

归档模式 

假设Oracle数据库有3个日志组:1#、2#、3#。

LGWR进程循环地向 1#日志组的 ONLINE REDO LOG 中写入特定格式的SQL脚本;

当1#日志组的 ONLINE REDO LOG 写满时,则将在线日志归档到硬盘,成为 ARCHIVE REDO LOG;

当1#日志组的 ONLINE REDO LOG 写满后,Oracle切换到2#日志组,开始向ONLINE REDO LOG写入特定格式的SQL脚本;

 如果1#日志组的 ARCHIVE REDO LOG 已经写完(归档结束),且2# 日志组ONLINE REDO LOG已经写满,那么2#日志组开始归档

⑤ 2# 日志组ONLINE REDO LOG已经写满,则切换至 3# 日志组,开始向ONLINE REDO LOG写入特定格式的SQL脚本;

 如果2#日志组的 ARCHIVE REDO LOG 已经写完(归档结束),且3# 日志组ONLINE REDO LOG已经写满,那么3#日志组开始归档

3# 日志组ONLINE REDO LOG已经写满,则重新切换至 1# 日志组,开始向ONLINE REDO LOG写入特定格式的SQL脚本;

循环以上过程

如果我们细心一点,可以发现一个细节:如果服务器磁盘性能差,归档速度慢,那么重做日志组切换就会出现问题。比如上述循环过程中,3#日志组的ONLINE REDO LOG写满后,1#日志组还在归档,那么此时是不会切换到1#日志组的,只能使用日志缓冲区,等待归档完毕之后才能覆盖写入。

非归档模式 

至于非归档模式状态下的redo日志循环写流程,就比较简单了,因为没有归档过程,如下图所示。还是假设有3个日志组:1#、2#、3#。只不过这次流程十分精简:

 LGWR进程循环地向 1#日志组的 ONLINE REDO LOG 中写入特定格式的SQL脚本;

② 1#日志组写满后,切换至2#日志组,LGWR进程循环地向 2#日志组的 ONLINE REDO LOG 中写入特定格式的SQL脚本;

2#日志组写满后,切换至3#日志组,LGWR进程循环地向 3#日志组的 ONLINE REDO LOG 中写入特定格式的SQL脚本;

3#日志组写满后,重新切换至1#日志组,LGWR进程循环地向 1#日志组的 ONLINE REDO LOG 中写入特定格式的SQL脚本;

循环以上过程

非归档模式下redo日志循环写

 

redo日志状态

关于redo日志状态,需要分成两块去讲。一块是redo日志组的状态,一块是redo日志文件的状态。

  • redo日志组状态

可以通过v$log视图查询redo日志组状态。

select group#,bytes,status from v$log;
SQL> select group#,bytes,status from v$log;GROUP#      BYTES STATUS
---------- ---------- ----------------1  209715200 INACTIVE2  209715200 CURRENT3  209715200 INACTIVE

通过上述输出结果可以看到这里已经有两种状态为INACTIVE和CURRENT,那么现在把REDO LOG组所有的状态都列出来。并给出相应解释:

Ⅰ:INACTIVE 

实例恢复不再需要联机重做日志组,它可能已经归档也可能未归档。

Ⅱ:ACTIVE

联机重做日志组是活动的,但是并非当前联机重做日志组,实例崩溃恢复需要该状态的日志,它可能用于块恢复,它可能已经归档也可能未归档。

Ⅲ:CURRENT

当前的联机重做日志组,这意味着该联机重做日志组是活动的。

Ⅳ:UNUSED

从未对联机重做日志组进行写入,这种状态的日志文件要么是刚增加的,要么是当日志不是current redo log时RESETLOGS操作后的状态。

Ⅴ:CLEARING

在ALTER DATABASE CLEAR LOGFILE 命令后正在将该日志重建为一个空日志,日志清除后其状态更改为UNUSED。

Ⅵ:CLEARING_CURRENT

正在清除当前日志文件中的已关闭线程,如果切换时发生某些故障,如写入新日志标题时的I/O错误,则该日志可以停留在该状态。

  • redo日志文件状态

可以通过v$logfile视图查询redo日志文件状态。

select group#,member,status from v$logfile;
SQL> select group#,member,status from v$logfile;GROUP# MEMBER                                   STATUS
---------- ---------------------------------------- -------3 /u01/app/oracle/oradata/ORCL/redo03.log2 /u01/app/oracle/oradata/ORCL/redo02.log1 /u01/app/oracle/oradata/ORCL/redo01.log

通过上述输出结果,可以看到这里STATUS(状态)列下并无数据,但实际上现在这个列中的值为NULL,那么我们把REDO LOG文件所有的状态都列出来。并给出相应解释: 

Ⅰ:INVALID

该文件不可访问

Ⅱ:STALE

该文件内容不完全,例如正在添加一个日志文件成员

Ⅲ:DELETED

该文件已不再使用

Ⅳ:NULL

该文件正在使用中

redo日志切换

redo日志切换,其实指的是redo日志组切换。redo日志组可以用两种方法去切换。但推荐的是用正常方式去切换。

  • 正常切换
alter system switch logfile;

切换例子如下 

 

  • 用发生检查点的方式去切换 
alter system checkpoint;

redo日志操作

  •  添加组成员

假如需要给1#日志组添加组成员;

先通过 select member from v$logfile;查询出对应redo日志文件路径。

再替换到下列语句中。

ALTER DATABASE
ADD LOGFILE MEMBER '/u01/app/oracle/oradata/ORCL/redo01.rdo'
TO GROUP 1

添加组成员有2个需要注意的地方:

Ⅰ:新增组成员不需要指定大小,因为每个组内的成员日志内容是一样的,所以大小和已存在的组成员一致。

Ⅱ:当组成员刚刚被添加时,它的日志文件状态是INVALID不可访问状态,如下图。

 那咋办嘞?

这时候就用到上文叙述过的redo日志组切换操作,操作结果如下图所示。

 

  • 删除组成员

删除语法很简单,如下所示,删除之前添加的1#日志组新成员redo01.rdo。

ALTER DATABASE DROP LOGFILE MEMBER '/u01/app/oracle/oradata/ORCL/redo01.rdo';

删除组成员有两个需要注意的地方:

Ⅰ:上述的删除语法只是在控制文件中,将日志组成员删除了;未真正在物理磁盘上将redo01.rdo文件删除;所以需要手动去对应路径下删除对应的redo01.rdo文件。

Ⅱ: 不能删除CURRENT状态下的日志组成员。

  • 添加组

还是和添加组成员一样,先找到其他组成员的存储路径,再替换到下面的代码中。

新建的组,可以指定组成员默认大小是多少。如下代码,指定的是组成员大小是200M。

ALTER DATABASE ADD LOGFILE GROUP 4 ('/u01/app/oracle/oradata/ORCL/redo04.log') 
SIZE 200M

添加组有2个需要注意的点:

Ⅰ:无法改变已存在的日志组成员大小;

Ⅱ:刚创建的日志组状态是UNUSED的,也可以进行手动切换日志组,进行状态的调整。


以上是关于redo的基本知识内容,按我自己的拙见是比较全面了。但redo与备份和恢复的关系没有提到太多。因为觉得内容太多,一章说完比较困难,后面再补吧。


另外也记录下一件小事:昨天,我对象发现了我头上长了一根白头发;这是我第一次长白头发,我真的要开始变老了,欸。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/1170.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Vue3——组件基础

组件基础 1. 组件定义与使用 1.1 代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>组件基础&l…

Docker - 镜像、容器、仓库

原文地址&#xff0c;使用效果更佳&#xff01; Docker - 镜像、容器、仓库 | CoderMast编程桅杆Docker - 镜像、容器、仓库 提示 这个章节涉及到 Docker 最核心的知识&#xff0c;也是在使用过程中最常使用到的&#xff0c;需要重点学习。 什么是Docker镜像、容器、仓库&…

leetcode:438. 找到字符串中所有字母异位词

给定两个字符串 s 和 p&#xff0c;找到 s 中所有 p 的 异位词 的子串&#xff0c;返回这些子串的起始索引。不考虑答案输出的顺序。 异位词 指由相同字母重排列形成的字符串&#xff08;包括相同的字符串&#xff09;。 示例 1: 输入: s "cbaebabacd", p "…

前端工程化01-复习jQuery当中的AJAX

4.1、基础概念 什么是服务器 一台存储网站内容、网站文件的电脑 什么是资源 网站中使用的文件&#xff08;html、css、图片、…&#xff09;这些东西就叫做资源数据也是服务器上的资源&#xff0c;而且是一个网站的灵魂 客户端 客户端应该指上网的设备但是在前端开发中&a…

Web后端-请求响应

黑马程序员JavaWeb开发教程 文章目录 一、请求1、简单参数2、实体参数3、数组集合参数&#xff08;1&#xff09;数组参数&#xff08;2&#xff09;集合参数 4、日期参数5、json参数&#xff08;1&#xff09;在Postman中怎么发起请求来传递JSON格式的请求参数&#xff08;2&a…

精通MongoDB聚合操作API:深入探索高级技巧与实践

MongoDB 聚合操作API提供了强大的数据处理能力&#xff0c;能够对数据进行筛选、变换、分组、统计等复杂操作。本文介绍了MongoDB的基本用法和高级用法&#xff0c;高级用法涵盖了setWindowFields、merge、facet、expr、accumulator窗口函数、结果合并、多面聚合、查询表达式在…

卷王问卷考试系统/SurveyKing调查系统源码

SurveyKing是一个功能强大的开源调查问卷和考试系统&#xff0c;它能够快速部署并适用于各个行业。 这个系统提供了在线表单设计、数据收集、统计和分析等功能&#xff0c;支持20多种题型&#xff0c;提供多种创建问卷的方式和设置。 项 目 地 址 &#xff1a; runruncode.c…

C++相关概念和易错语法(7)(初始化列表、隐式类型转换、友元)

1.初始化列表 初始化列表是集成在构造函数里面的&#xff0c;对象在创建的时候一定会调用构造函数&#xff08;就算不显式定义&#xff0c;也会自动生成并调用&#xff09;。初始化列表就是这些对象的成员变量在创建的时候初始化的地方。 下面是使用的例子&#xff0c;可以先…

香港服务器_免备案服务器有哪些正规的?企业、建站方向

香港服务器&#xff0c;是最受欢迎的外贸、企业建站服务器&#xff0c;在个人建站领域&#xff0c;香港服务器、香港虚拟主机都是首选的网站服务器托管方案&#xff0c;不仅其具备免备案的特点&#xff0c;而且国内外地区访问速度都很快。那么&#xff0c;现今2024年个人和企业…

项目如何部署

我们平常写的项目通常只能在本机上运行&#xff0c;要想项目能被远程访问就不得不谈到项目部署的知识&#xff0c;接下来我通过实际操作的操作让大家来上线一个vuespringBoot项目。 1.在windows上将vue部署到nginx服务器上 介绍nginx Nginx是一款高性能的Web服务器和反向代理服…

C#语法知识之循环语句

5、循环语句 文章目录 1、while思考1 斐波那契数列思考2 判断一个数是否为质数思考3 找出100以内的质数 2、do...while3、for思考1 找水仙花数思考2 乘法表 1、while 1、作用 让代码重复去执行 2、语法相关 while(bool类型值){//当满足条件时&#xff0c;就会执行while语句…

【GIS教程】ArcGIS做日照分析(附练习数据下载)

我国对住宅日照标准的规定是:冬至日住宅底层日照不少于1小时或大寒日住宅层日照不少于2小时(通常以当地冬至日正午12时的太阳高度角作为依据)。因冬至日太阳高度角最低&#xff0c;照射范围最小&#xff0c;如果冬至日12&#xff1a;00建筑物底层能够接收到阳光&#xff0c;那么…

Python数据可视化库—Bokeh与Altair指南

&#x1f47d;发现宝藏 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。 在数据科学和数据分析领域&#xff0c;数据可视化是一种强大的工具&#xff0c;可以帮助我们…

Docker - HelloWorld

原文地址&#xff0c;使用效果更佳&#xff01; Docker - HelloWorld | CoderMast编程桅杆https://www.codermast.com/dev-tools/docker/docker-helloworld.html 开始之前 在学习本小节之前&#xff0c;你必须确保你正确安装了 Docker&#xff0c;正确安装 Docker 是后续学习的…

墨子web3实时周报

蚂蚁集团Web3研发进展与布局 国内Web3赛道的领军企业——蚂蚁集团&#xff0c;凭借其在前沿科技领域的深耕不辍&#xff0c;已在Web3技术研发疆域缔造了卓越战绩。特别是在引领行业革新的关键时刻&#xff0c;集团于今年四月末震撼推出了颠覆性的Web3全套解决方案&#xff0c;…

java通过maven导入本地jar包的三种方式

一、引入lib下加载&#xff08;加载过后打包&#xff0c;以后再次使用不用再次导入&#xff09; 首先创建一个用于创建jar包的项目&#xff0c;并测试能否成功运行 讲项目打包 在需要引入的项目中创建lib目录 并把刚才打包的jar复制进去 通过dependency引入jar包 groupId、art…

读天才与算法:人脑与AI的数学思维笔记05_算法的幻觉

1. 自下而上 1.1. 代码在未来可以自主学习、适应并进行自我改进 1.2. 程序员通过编程教会计算机玩游戏&#xff0c;而计算机却会比教它的人玩得更好&#xff0c;这种输入寡而输出众的事情不大可能实现 1.3. 早在20世纪50年代&#xff0c;计算机科学家们就模拟该过程创造了感…

人工智能论文GPT-3(3):2020.5 Language Models are Few-Shot Learners;架构;训练数据集;开源

2.1 模型与架构 我们使用了与GPT-2相同的模型和架构&#xff0c;包括其中描述的改进初始化、预归一化和可逆分词技术&#xff0c;但有所不同的是&#xff0c;我们在Transformer的各层中使用了交替的密集和局部带状稀疏注意力模式&#xff0c;类似于Sparse Transformer 。为了研…

Flutter 的 showDialog 和 showCupertinoDialog 有什么区别?

我将我的 App 里用的 Flutter 升级到了 3.19&#xff0c;没想到&#xff0c;以前我用 showDialog 和 AlertDialog 组合创建的二次确认框&#xff0c;变得无敌难看了&#xff0c;大幅度增加了整个框的圆角和里面默认按钮的圆角。不得已&#xff0c;我必须修改一下&#xff0c;以…

算法练习|Leetcode189轮转数组 ,Leetcode56合并区间,Leetcode21合并两个有序链表,Leetcode2两数相加,sql总结

目录 一、Leetcode189轮转数组题目描述解题思路方法:切片总结 二、Leetcode56合并区间题目描述解题思路方法:总结 三、Leetcode21合并两个有序链表题目描述解题思路方法:总结 四、Leetcode2两数相加题目描述解题思路方法:总结 sql总结: 一、Leetcode189轮转数组 题目描述 给定…