Oracle是如何保证数据不丢的

上一篇文章给大家梳理了一条更新语句在Oracle数据库中是如何执行的,我们也提到只要更新记录成功写入到在线重做日志文件,Oracle就能保证数据不会丢失。同时也向大家解释了,其实这个时候数据并没有写入到数据文件,因此这个时候仍然是一个不一致的状态。那么Oracle是如何做到写入的数据不会丢失呢?数据库接下来还会有哪些后续的操作?

两个重要概念

这节内容开始,我们还是给大家介绍两个重要的概念:SCN 和检查点事件。没办法,Oracle的概念实在太多,为了便于大家的理解,我们会在章节开始之前尽量把相关的概念交待清楚。

SCN

SCN的全称是 System Change Number,是一个单调递增的全局逻辑时钟,用于标识事务、跟踪数据库中的所有变更,对于维护多版本下的数据一致性起着非常重要的作用。所有支持事务的数据库基本上都有SCN的概念,不同数据库中的名称和实现上会有所差别。

Oracle SCN是一个6字节(48位)的数字,每提交一个事务时,都会为其分配一个全局唯一的SCN。在Oracle数据库中,SCN和时间戳是一一对应的,每个SCN都可以和时间戳进行换算。不论是在线日志文件、数据文件,还是控制文件,写出的时候都会带上SCN,通过SCN可以关联出一个全局一致性的状态。

以下是一段引用自官方《Concept》文档中的描述:
A system change number (SCN) is a logical, internal timestamp used by Oracle Database. SCNs order events that occur within the database, which is necessary to satisfy the ACID properties of a transaction. Oracle Database uses SCNs to mark the SCN before which all changes are known to be on disk so that recovery avoids applying unnecessary redo. The database also uses SCNs to mark the point at which no redo exists for a set of data so that recovery can stop.

数据库检查点事件

不知道大家是否还记得,前一篇文章中我们提到在线日志是同步写出的,数据块则是异步写出的。Redo Log写出到日志文件后,Buffer Cache中的数据并没有写出到数据文件,此时数据库还是处于一个不一致的状态。那什么时候才能达到一致呢,答案就是检查点发生之后。

检查点的主要功能包括:

  1. 确保内存中修改过的数据块定期写入磁盘,以便在系统或数据库发生故障时数据不会丢失;
  2. 定期进行检查点操作,减少故障发生时需要恢复的数据,降低恢复时间。

在数据库缓冲区中,被修改的数据块被称为“脏块”,所有的脏块会按照操作时间的先后顺序(确切的说是SCN - System Change Number)被放入到一个独立的链表,这个链表构成了需要写出的数据块队列。当检查点发生时,Oracle依次从检查点队列中取出数据,由数据库DBWR进程写出到数据文件中。在Oracle数据库中有一个核心进程专门负责检查点事件的操作,其主要的功能是在检查点事件发生时,将检查点信息更新到数据文件头部和控制文件中,完成一次完整的检查点事件,这时才算是达到了一致的状态。

但是这个时候真的是一致性的状态吗?数据库是 24 * 7 持续对外服务的,不断的会有新的数据被更新,根本不会有绝对的一致性状态。那么Oracle是怎么保证各种异常情况下数据不会丢失呢?

异常恢复的几种场景

数据库是个软件系统,运行在由服务器、网络设备等构成的硬件系统和由操作系统、数据库软件等构建的软件系统之上,每个层面异常都有可能会导致异常的发生。不同的异常对数据造成影响程度会有所差别。

接下来我们讨论常见的数据库异常场景下,Oracle是如何保障数据不丢失的。

实例恢复

实例崩溃是非常典型的数据库异常,服务器异常重启、内存损坏、操作系统和数据库自身的Bug等都可能会导致数据库实例崩溃。实例崩溃通常是没有任何征兆的,数据库系统来不及做任何反应就崩溃了,因此只有在下次重启时进行实例恢复。
在这里插入图片描述

如上图所示,最后一次检查点之前的数据已经提交并且被更新到数据文件,其状态是一致性,实例恢复过程中不需要做任何操作,这里我们不做过多的讨论。因此,实例恢复的起始位置是最后一次检查点的位置,实例恢复的终点是在线重做日志文件的最末端,这之间的数据包括两种状态:

  1. 已更新但是还没有提交的数据,对于这部分数据并不需要保证其数据完整性,因此Oracle会调用UNDO中的“前镜像”数据进行回滚,恢复到修改之前的状态;
  2. 已更新且已完成提交、但“脏块”还没来得及写出到数据文件的数据,对于这部分数据,Oracle会读取在线重做日志中的数据,将最新的数据内容应用到数据文件。
    简单来说,未提交的数据回滚,已提交的数据前滚,Oracle通过这种方式将数据拉齐到一致性的状态后,即可完成实例恢复,之后打开数据库对外提供服务。

如图,假设崩溃瞬间的数据库数据文件、在线日志文件和控制文件的状态如下:
在这里插入图片描述

  1. 在线日志文件最大的SCN为143,最小的SCN为74;
  2. 控制文件中记录的SCN和在线日志文件最大SCN一致,为143;
  3. 数据文件最大SCN为140,最小SCN为99。
    此时进行实例恢复,需要应用的日志范围则是从99至143。

实例恢复的动作是由SMON进程来完成的,实际案例中,经常会遇到由于UNDO、REDO等文件或数据块的损坏,无法构造一致性导致实例恢复失败,数据库无法正常打开的情况。这个时候需要采取其他手段来强制打开,通常这种手段都会破坏数据的完整性,只有万不得已的情况才会考虑。

介质恢复

在计算机环境中,我们经常把涉及到文件的对象称为“介质”。所谓介质恢复,是由于数据文件损坏或丢失而导致需要进行的恢复,比如存储损坏导致的数据文件丢失、人为误删除了某个数据文件等。根据损坏文件类型的不同,采取的技术手段也不同。

数据文件的恢复

数据文件是保存数据的最终所在,如果数据文件丢失或损坏,轻则访问其所保存的数据会报错,如果丢失的是SYSTEM和UNDO等系统数据文件,还会导致数据库崩溃而永远无法正常启动。

数据文件的恢复通常包括恢复(restore)和修复(recover)两个阶段。恢复阶段将相关文件从之前的备份中恢复出来,备份文件是过去某个时间产生的,和最新的数据状态存在一定的差距。因此需要使用归档日志和在线日志来弥补历史备份数据和最新数据之间的GAP,将数据从历史备份中恢复到最新状态,这是修复阶段所做的操作。

在线日志文件的恢复

在上一篇文章中我们也提到,在线日志文件是Oracle数据库的“软肋”,而且由于更新非常频繁,CURRENT状态的日志文件是不会备份的,只有写满切换到下一个日志文件之后,之前的文件才会被备份为归档日志文件。但如果CURRENT状态的日志文件出现丢失和损坏,会导致数据库实例的崩溃,而且无法正常完成实例恢复,这时常规的方法只能利用历史备份对数据库进行不完全恢复,根据日志的损坏情况,会造成一定程度的数据丢失。

为了避免在线日志成为“软肋”,通常我们建议在生产环境中为每组在线日志添加两个成员,理想状态是将两个成员放到不同的存储或不同的磁盘驱动器的不同文件系统中,避免存储等硬件故障或人为误操作导致在线日志文件的错误。对于两个成员的磁盘组,其中一个成员损坏不会影响数据库的正常运行,可以手工删除损坏的日志成员,添加一个新成员,完成在线日志文件的修复。

控制文件的恢复

Oracle的控制文件是一个二进制文件,记录了数据库的结构信息,包含数据文件、在线日志文件的位置和大小,以及归档日志、数据库备份等信息,是Oracle数据库体系中非常重要的文件。

和在线日志文件类似,控制文件由于更新频繁,也无法对其进行实时备份,所以在实际生产环境中也同样建议设置2到3个控制文件,分别放置到不同的存储或不同的磁盘驱动器的不同文件系统中。当其中一个备份文件出现错误时,可以从正常的控制文件拷贝出新的文件。不过,数据库运行过程中控制文件始终处于工作状态,因此拷贝操作需要将数据库完全关闭才能进行,这会涉及到一定的生产停机时间,修复成本相对更高。

总结

本篇文章给大家介绍了Oracle数据一致性的保障体系,在这个体系中,检查点是非常重要的环节,它定期将“脏数据"从内存写出到数据文件。由于数据库是持续运行的,没有绝对的一致性状态,因此检查点队列被设计成一个先进先出的链表,依次从检查点对列写出到数据文件中,完成数据的持久化。对于已经进入检查点队列但没有写出到数据文件的脏块,实例恢复时会通过在线日志前滚将已修改的数据恢复出来应用到数据文件中,从而保证数据的一致性。

最后我们也提到在线日志文件和控制文件是Oracle的“软肋”,建议通过多成员的方式来弥补架构上的单点。大家知道Oracle还有哪些单点的隐患吗,又该如何规避?

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

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

相关文章

为什么不用postman做自动化

面试的时候被问到:为什么不用postman做自动化 打开postman,看到用例集管理、API 管理、环境管理这三个功能,用户体验感算得上品牌等级了 为什么不用呢,文心一言给了一些答案 不适合大规模自动化测试:Postman 主要是为…

React 后台管理项目 入门项目 简洁清晰保姆级内容讲解

序章 React Hook的后台管理项目,从0到1搭建,内容非常丰富涵盖项目搭建、路由配置、用户鉴权、首页报表、用户列表、前后端联调等功能,推荐指数:5颗星! 视频学习链接: React 通用后台管理-零基础从0到1详细的入门保姆…

数据结构(5.5_3)——并查集的进一步优化

Find操作的优化(压缩路径) 压缩路径——Find操作,先找到根节点,再将查找路径上所有结点都挂到根结点下 代码: //Find "查"操作优化,先找到根节点,再进行"路径压缩" int Find(int S[], int x) {…

50 mysql 的 “where 1 = 1“ 的优化处理

前言 问题是来自于 chinaunix 问题 ”mysql查询后面加 where 1 1 影响效率吗?” mysql 中在 java 代码中我们经常会使用到 ”where 1 1 and username ‘jerry’ ” 之类的条件 然后 我们这里 来看一下 “where 1 1” 的相关处理 where 条件在 select_lex, QUP_shared…

LeetCode面试150——14最长公共前缀

题目难度:简单 默认优化目标:最小化平均时间复杂度。 Python默认为Python3。 目录 1 题目描述 2 题目解析 3 算法原理及代码实现 3.1 横向扫描 3.2 纵向扫描 3.3 分治 3.4 二分查找 参考文献 1 题目描述 编写一个函数来查找字符串数组中的最长…

【面试题】设计模式-责任链模式

设计模式-责任链模式 前言责任链简历案例代码小结 前言 我们知道,设计模式是面试时经常被问到的问题之一,这是因为设计模式能够体现出代码设计的美感,且在很多框架的底层也都会使用到各种设计模式,所以对设计模式的考察&#xff…

用Manim创建条形图【BarChart】

BarChart是Manim库中用于创建条形图的函数。它允许用户通过一组值创建一个条形图,其参数可以调整条形的外观和布局。 BarChart(values, bar_namesNone, y_rangeNone, x_lengthNone, y_lengthNone, bar_colors[#003f5c, #58508d, #bc5090, #ff6361, #ffa600],bar_w…

js第四天-函数

例1&#xff1a;选出最大值&#xff1a; <script>function getmax(x, y) {return x > y ? x : y}let max getmax(1, 3)</script> 例2&#xff1a;返回数组的最大值 <script>function getArrValue(arr []) {let max arr[0]for (let i 1; i < arr.…

基于Hadoop的共享单车分布式存储与计算

文章目录 有需要本项目的代码或文档以及全部资源&#xff0c;或者部署调试可以私信博主项目介绍研究背景研究目的和意义国内外研究现状总体研究思路数据可视化每文一语 有需要本项目的代码或文档以及全部资源&#xff0c;或者部署调试可以私信博主 项目介绍 共享单车的普及带…

Elastic 基于 RAG 的 AI 助手:使用 LLM 和私有 GitHub 问题分析应用程序问题

作者&#xff1a;来自 Bahubali Shetti 作为 SRE&#xff0c;分析应用程序比以往任何时候都更加复杂。你不仅必须确保应用程序以最佳方式运行以确保出色的客户体验&#xff0c;而且在某些情况下还必须了解内部工作原理以帮助排除故障。分析基于生产的服务中的问题是一项团队运动…

HTML “文本处理基础”--文本格式化——WEB开发系列05

HTML 的主要工作之一是赋予文本结构&#xff0c;使浏览器能够按照开发者的意图显示 HTML 文档。 在创建网页时&#xff0c;文本格式化是至关重要的&#xff0c;它不仅可以影响用户的阅读体验&#xff0c;还可以增强网页的可读性和美观性。HTML 如何通过添加标题和段落、强调单词…

中央空调系统

1.水机 它首先通过主机将水变成7度左右的冷水&#xff08;制冷&#xff09;&#xff0c;然后通过水管通过水泵输送到房间的每一端。末端的风机盘管与室内空气进行热交换&#xff0c;达到制冷的目的。供暖也是如此&#xff0c;但主机先把水变成50度左右的热水这种空调的优点是舒…

前端已经学会vue,做粒子效果

目录 1. Canvas API 2. WebGL 3. 粒子系统 4. 动画与性能优化 5. 现有库和框架 6. Vue 组件和状态管理 实践项目建议 案例1 案例2雪花 已经熟悉了 Vue、TypeScript 和 JavaScript&#xff0c;下面是一些你可以学习的内容&#xff0c;以帮助你实现粒子效果的界面&#…

享界S9+问界M9,华为智选车的高端局

作者 |老缅 编辑 |德新 8月6日&#xff0c;鸿蒙智行在北京发布D级纯电旗舰轿车&#xff0c;也是北汽 - 华为智选车合作的第一款车型&#xff0c;享界S9。 享界S9搭载了包括华为乾崑ADS 3.0在内的多项首发技术&#xff0c;全系标配100kWh华为800V巨鲸电池。 而在价格上&#…

记2024-08原生微信小程序开发

继2024.08 最近需要开发一个微信小程序的一个功能模块&#xff0c;但是之前在学的时候都是好几年前的东东了&#xff0c;然后重新快速过了一遍b站大学的教程&#xff0c;这篇文章就是基于教程进行的一些总结&#xff0c;和自己开发过程当中使用到的一些点和一些技巧什么的吧。 …

计算机网络408考研 2019

计算机网络408考研2019年真题解析_哔哩哔哩_bilibili 2019 1 1 1 1

仿RabbiteMq简易消息队列基础篇(gtest的使用)

TOC gtest介绍 gtest是google的一个开源框架&#xff0c;它主要用于写单元测试&#xff0c;检查自己的程序是否符合预期行为。可在多个平台上使用&#xff08;包含Linux&#xff0c;MAC OC&#xff0c;Windows等&#xff09;。它提供了丰富的断言&#xff0c;致命和非致命失败…

Spring Boot 3.x Filter实战:记录请求日志

上一篇&#xff1a;Spring Boot 3.x Web单元测试最佳实践 下一篇&#xff1a;Spring Boot 3.x Web MVC实战&#xff1a;实现流缓存的request 前面我们在《Spring Boot 3.x Rest API最佳实践之统一响应结构》中学习响应的统一拦截处理&#xff0c;顺带完成了响应结果的记录&am…

06:【stm32】OLED模块的简单使用

OLED模块的简单使用 OLED简单的使用 OLED简单的使用 OLED驱动函数是使用B站UP江科大的。我们直接调用即可&#xff0c;是使用软件模拟I2C协议进行通信的。具体的I2C协议可查看上官嵌入式开发中的C51单片机开发。 驱动函数文件&#xff1a;通过百度网盘分享的文件&#xff1a;…

2024 年的 Node.js 生态系统

数据来源于 Node.js Toolbox&#xff0c;网站展示了 Node.js 生态系统中积极维护且流行的库。